XCTF 渗透测试战役 WP
Web
sqlcheckin
考点:SQL 注入 · 万能密码
题目提供了一个登录页面及源码。初步判断可能存在堆叠注入,但经过 fuzz 测试发现大量字符被过滤,包括堆叠注入必需的分号 ;。
Tip
过滤检查清单:union, select, from, where, order, group, having, limit, insert, update, delete, drop, exec, execute, ;, --, #, /*, */ 等关键字符均被拦截。
重新分析源码后发现,账号和密码是直接拼接查询的,且只需满足 username == 'admin' 即可获取 flag。由于大多数字符被过滤,但括号 () 和减号 - 未被过滤,可以构造如下万能密码:
Warning
以下 payload 仅用于 CTF 学习,不可用于非法用途。
Payload:
账号:admin
密码:'- (0)-'该 payload 利用 MySQL 中 '-' 运算符的优先级和类型转换特性,使条件恒为真。
webtemp
考点:Python Pickle 反序列化 · GLOBAL 指令绕过
本题要求满足以下条件获取 flag:
I will give you the flag if we share the same animal as our favourite.
解题思路:
常规的 Pickle 反序列化利用 __reduce__ 方法(指令码 R),但题目禁用了 R 指令。此时可以利用全局指令 C(GLOBAL),通过重写 find_class 方法来控制可导入的模块。
如果出题人只允许 c 指令包含 __main__ 模块,我们可以通过构造特定的序列化数据来实现攻击。
核心思路:控制 secret 类的属性,使其与 Animal 类的对应属性值相等。
步骤:
- 使用调试器生成正常的
Animal类序列化数据:
b'\x80\x03c__main__\nAnimal\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x02\x00\x00\x00aaq\x04X\x08\x00\x00\x00categoryq\x05X\x02\x00\x00\x00bbq\x06ub.'- 在序列化数据前添加对
secret对象的篡改:
b'\x80\x03cmain\nsecret\n}(Vname\nVaa\nVcategory\nVbb\nub0c__main__\nAnimal\n)\x81}(X\x04\x00\x00\x00nameX\x02\x00\x00\x00aaX\x08\x00\x00\x00categoryX\x02\x00\x00\x00bbub.'- 将篡改后的数据 Base64 编码后提交,即可获取 flag。
Note
nweb
考点:越权访问 · 盲注 · Rogue-MySQL-Server
题目标题「俺不会注入」暗示应从注入方向入手。
解题步骤:
注册与越权:尝试注册
admin用户提示已存在。注册普通用户登录后,在注册页面发现注释<!-- 110 -->。修改type=110可实现越权注册。SQL 盲注:访问
flag.php发现存在有回显的盲注漏洞。
数据库名:ctf
表名:admin, fl4g, jd, user- 提取 flag 表:
fl4g 表只有一列:flag使用正则匹配提取 flag 内容,注意大小写不敏感,建议使用 ASCII 码逐字符提取。
Warning
正则匹配在匹配到 flag{Rogue-M 时出现异常,建议使用 ASCII 码方式逐字符提取。
初步获得 flag 前半部分:flag{Rogue-MySql-Server
- 提取 admin 表:
username: admin
pwd: MD5 加密(解密后为 whoamiadmin)目录扫描:使用 admin/whoamiadmin 登录常规页面仍提示密码错误。通过目录扫描发现隐藏页面
database.php,使用该账号成功登录。Rogue-MySQL-Server 利用:利用 Rogue-MySQL-Server 漏洞,通过伪造 MySQL 服务器截获另一半 flag:
-is-nday}
最终 Flag:flag{Rogue-MySql-Server-is-nday}
Tip
Rogue-MySQL-Server 任意文件读取漏洞曾在 DDCTF 和国赛中出现过,建议深入研究其原理。
Misc
ez_mem&usb
考点:USB 内存取证 · Volatility
题目附件为 pcap 包,需要进行 USB 内存取证分析。
解题步骤:
提取压缩包:使用 Wireshark 打开 pcap 包,过滤 HTTP 协议,发现文件上传记录,导出压缩包。
获取内存镜像:解压后得到虚拟内存文件
data.vmem。Volatility 分析:
# 分析操作系统volatility -f data.vmem imageinfo# 查看进程列表(profile: WinXPSP2x86)volatility -f data.vmem --profile=WinXPSP2x86 pslist# 导出 explorer.exe 内存(PID: 1476)volatility -f data.vmem --profile=WinXPSP2x86 memdump -p 1476 -D ./# 提取 ASCII 信息strings 1476.dmp > 1476.txt# 搜索 flag 相关信息cat 1476.txt | grep flag- 查找并导出 flag.img:
# 搜索 flag 文件volatility -f data.vmem --profile=WinXPSP2x86 filescan | grep flag# 导出 flag.img(物理地址:0x0000000001155f90)volatility -f data.vmem --profile=WinXPSP2x86 dumpfiles -Q 0x0000000001155f90 --dump-dir=./# 重命名(导出文件名与原始文件名不同)cp file.None.0xff425090.dat flag.img- 分析磁盘镜像:
file flag.img # DOS/MBR boot sector, FAT12binwalk -e flag.img提取后发现 usbdata.txt 为空,存在 F400.zip 压缩包,需要密码。
- 获取密码:通过命令历史查找密码线索:
volatility -f data.vmem --profile=WinXPSP2x86 cmdscan发现密码线索 passwd,解压 F400.zip 得到 usbdata.txt。
- 解析 USB 键盘数据:
usbdata.txt 包含 USB 键盘扫描码,使用 Python 脚本解析:
import sysimport osusb_codes = { 0x04: "aA", 0x05: "bB", 0x06: "cC", 0x07: "dD", 0x08: "eE", 0x09: "fF", 0x0A: "gG", 0x0B: "hH", 0x0C: "iI", 0x0D: "jJ", 0x0E: "kK", 0x0F: "lL", 0x10: "mM", 0x11: "nN", 0x12: "oO", 0x13: "pP", 0x14: "qQ", 0x15: "rR", 0x16: "sS", 0x17: "tT", 0x18: "uU", 0x19: "vV", 0x1A: "wW", 0x1B: "xX", 0x1C: "yY", 0x1D: "zZ", 0x1E: "1!", 0x1F: "2@", 0x20: "3#", 0x21: "4$", 0x22: "5%", 0x23: "6^", 0x24: "7&", 0x25: "8*", 0x26: "9(", 0x27: "0)", 0x2C: " ", 0x2D: "-_", 0x2E: "=+", 0x2F: "[{", 0x30: "]}", 0x32: "#~", 0x33: ";:", 0x34: "'\"", 0x36: ",<", 0x37: ".>", 0x4f: ">", 0x50: "<"}def code2chr(filepath): lines = [] pos = 0 for x in open(filepath, "r").readlines(): code = int(x[6:8], 16) if code == 0: continue if code == 0x51 or code == 0x28: pos += 1 continue if code == 0x52: pos -= 1 continue while len(lines) <= pos: lines.append("") if code in range(4, 81): if int(x[0:2], 16) == 2: lines[pos] += usb_codes[code][1] else: lines[pos] += usb_codes[code][0] for x in lines: print(x)if __name__ == "__main__": if len(sys.argv) != 2: print("Usage:\n\tpython keyboardScanCode.py datafile.txt\nhow to get datafile:\t tshark -r file.usb.pcapng -T fields -e usb.capdata > datafile.txt") exit(1) else: filepath = sys.argv[1] code2chr(filepath)Flag:flag[69200835784ec3ed8d2a64e73fe913c0](注意将方括号改为花括号)
Note
参考文章:从 CTF 中学 USB 流量捕获与解析
2019-nCoV
Note
本题较为简单,解题过程略。
简单 MISC
考点:隐写术 · 密码学
解题步骤:
压缩包分析:解压得到一个加密的
flag.zip和一张图片photo.jpg。图片修复:
photo.jpg文件头被修改(非标准 JPEG 头FFD8FF),将其修复为FFD8FF后图片可正常打开。隐藏压缩包:在
photo.jpg中发现隐藏的 ZIP 压缩包,提取后得到ctf.txt,包含摩尔斯电码。摩尔斯解码:
摩尔斯电码 → EPIDEMICSITUATIONOFUNIVERSITYWAR解压 flag.zip:使用上述字符串作为密码成功解压,得到
flag.txt。Base64 解码:
flag.txt包含 Base64 编码内容,解码后得到Th1s_is_FlaG_you_aRE_rigHT。
Flag:flag{Th1s_is_FlaG_you_aRE_rigHT}
隐藏的信息
考点:二维码隐写 · 音频隐写 · Base64 编码
解题步骤:
二维码分析:补全二维码后未能获取有效信息。
伪加密修复:使用 WinHex 打开发现 ZIP 伪加密,修改标志位后打开
wav音频文件。音频隐写:音频文件开头和末尾存在隐藏的拨号音。
Base64 提示:WinHex 中发现二维码提示:
USE BASE64 TO GET YOUR FLAG
- 拨号音解析:将拨号音切割为 2-3 位一段,解析得到数字序列:
187485618521- Base64 编码:将上述数字进行 Base64 编码后提交获取 flag。
Tip
音频隐写题需要耐心分析,建议先确认音频格式和编码方式,再针对性提取隐藏信息。