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搜不到任何明文校验逻辑,但命中了一条打包器横幅(Quick Batch File Compiler)。- 这说明 exe 是把批处理脚本编译出来的壳:程序运行时才把真正的
.bat释放到%TEMP%,再交给cmd.exe解释执行。真正的密码校验在释放出来的批处理里,所以静态搜索字符串无法命中。
$ file app16win.exeapp16win.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 freedom0$ strings -n 4 app16win.exe | grep -i -c speech0密码被编译进了释放时才解压出来的批处理。
程序是 set /p + pause 的交互式脚本,直接跑会停在等待输入;同时它释放的临时 .bat 会在退出时被清理。用 FIFO 顶住输入、抢时间把临时文件复制出 Wine 前缀:
#!/usr/bin/env bash# Run app16, grab the QBFC-extracted .bat, copy it OUT of the prefix, kill app.set -ucd <hts-workspace>/challenges/hts-app/app16rm -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 5BAT=$(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.batfisleep 1# copy again by inode snapshot in case of renamefind ~/.wine -type f -iname "*.bat" 2>/dev/null -exec cp {} ./extracted_2.bat \;wait $WPID 2>/dev/nullkill $HOLDER 2>/dev/nullecho "done"$ bash capture_bat.shfound: ~/.wine/drive_c/users/<user>/AppData/Local/Temp/bt2136.bat-rw-r--r-- 1 <user> <user> 199 Sep 11 15:44 ./extracted.batdone释放路径在 Wine 里对应宿主机的 ~/.wine/drive_c/users/<user>/AppData/Local/Temp/,文件名是 bt<随机数>.bat。
$ 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 要提交的密码。
把口令喂给原程序,确认它自己打印出密码:
$ 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...