Challenge
Application Challenge 16 (medium)
官方只给了难度等级,没有标题和描述:目标是找出程序要求输入的
password,然后到 challenge 页面提交。
程序包里只有一个 Windows 控制台 exe:app16win.zip →
app16win.exe。
Solution
file 显示
PE32 executable for MS Windows 4.00 (console), Intel i386, 8 sections。
strings
搜不到任何明文校验逻辑:grep -i freedom 和
grep -i speech 都是 0
命中,但命中了一条打包器横幅(Quick Batch File Compiler)。
- 这说明 exe
是把批处理脚本编译出来的壳:程序运行时才把真正的
.bat 释放到 %TEMP%,再交给
cmd.exe
解释执行。真正的密码校验在释放出来的批处理里,所以静态搜索字符串无法命中。
1 2 3 4 5 6 7 8 9 10
| $ file app16win.exe app16win.exe: PE32 executable for MS Windows 4.00 (console), Intel i386, 8 sections
$ strings -n 6 app16win.exe | grep -i -m3 -E 'batch|compiler' Quick Batch File Compiler
$ strings -n 4 app16win.exe | grep -i -c freedom 0 $ strings -n 4 app16win.exe | grep -i -c speech 0
|
密码被编译进了释放时才解压出来的批处理。
程序是 set /p + pause
的交互式脚本,直接跑会停在等待输入;同时它释放的临时 .bat
会在退出时被清理。用 FIFO 顶住输入、抢时间把临时文件复制出 Wine
前缀:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #!/usr/bin/env bash
set -u cd <hts-workspace>/challenges/hts-app/app16 rm -f /tmp/app16fifo; mkfifo /tmp/app16fifo ( sleep 20 > /tmp/app16fifo ) & HOLDER=$! timeout 20 wine app16win.exe < /tmp/app16fifo > /tmp/app16_out.txt 2>/dev/null & WPID=$! sleep 5 BAT=$(find ~/.wine -type f -iname "*.bat" -newermt "-30 seconds" 2>/dev/null | head -1) echo "found: $BAT" if [ -n "$BAT" ]; then cp "$BAT" ./extracted.bat ls -la ./extracted.bat fi sleep 1
find ~/.wine -type f -iname "*.bat" 2>/dev/null -exec cp {} ./extracted_2.bat \; wait $WPID 2>/dev/null kill $HOLDER 2>/dev/null echo "done"
|
1 2 3 4
| $ bash capture_bat.sh found: ~/.wine/drive_c/users/<user>/AppData/Local/Temp/bt2136.bat -rw-r--r-- 1 <user> <user> 199 Sep 11 15:44 ./extracted.bat done
|
释放路径在 Wine 里对应宿主机的
~/.wine/drive_c/users/<user>/AppData/Local/Temp/,文件名是
bt<随机数>.bat。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ cat -A extracted.bat @shift 1^M$ @echo off^M$ echo Enter Password:^M$ set pass=^M$ set /p pass=^M$ if "%pass%"=="speech" goto pass2^M$ Echo wrong password!^M$ pause^M$ exit^M$ :pass2^M$ Echo Congrats! HTS password is freedom.^M$ pause^M$ exit^M$
|
逻辑一目了然:输入字符串和 speech 比较,相等就跳到
:pass2 并打印明文答案。.bat
里的回显会把答案原样念出来,所以只要拿到释放出来的脚本,既知道输入口令也知道
HTS 要提交的密码。
把口令喂给原程序,确认它自己打印出密码:
1 2 3 4 5 6 7 8 9
| $ printf 'speech\n\n' | timeout 40 wine app16win.exe 2>/dev/null | tr -d '\r' Enter Password: Congrats! HTS password is freedom. Press any key to continue...
$ printf 'wrong\n\n' | timeout 40 wine app16win.exe 2>/dev/null | tr -d '\r' Enter Password: wrong password! Press any key to continue...
|
程序自身的输出即为验证依据,无需提交到 HTS 也能确认答案正确。
Vulnerabilities
编译成 exe
只是打包,不是保护。批处理校验逻辑会以明文形式释放到用户可写的临时目录,任何能在同一台机器上观察进程/临时目录的人都可直接读取口令,并且程序自身会在成功路径上回显答案。修复方向:不要把秘密放在客户端可执行的脚本里;如果必须做本地校验,使用真正的编译语言并把校验值与用户输入做不可逆校验(而不是可回读的明文比较),同时避免在成功路径输出敏感信息。
freedom