ACTF 2019 初赛 Writeup
- 2019-05-24
- Phosphorus15
前言
为时一星期的ACTF初赛结束了。这次比赛让我体验到了相对更进阶一些的CTF夺旗制下的题目。题目出得都挺用心,虽然有的做起来想打人,但总结时感觉很多部分都是经过精心思考设计的。(表白出题人(们)~)
Albeit,尽管初赛前三天因为身体缘故没能做题,但最后还是侥幸拿到了Rank 1。
就我个人而言,主要还是得益于有一些基础,而且比较愿意肝。正则表达式两题占了很大的分值,对我这种相对熟悉正则的人无疑是一种幸运。
不过身为二进制手,居然因为不熟悉IDA Python而在一些逆向题上手足无措,确实暴露了我的知识缺陷。同时,对各种堆利用也不甚熟练,导致堆题解题缓慢,没法及时拿到更多分,也是需要关注的问题。
Crypto
naive_PRNG0
真正的白给题
通过nc连接服务器,发现是一个伪随机器。而且连随机数种子都没有设置。
直接记录下第一个随机数,nc重连一次,输入,获得flag。
Reverse
SimpleCheck
反编译之后是一个简单的安卓应用,主要逻辑如下:
1 | package com.example.xiaosai1; |
主要的难点在于要解16个不同参数的三次方程,这里可以把数据处理后导入python repl用sympy库解决。
取方程在可见字符范围内的整数解,就能获得flag。
Web
easy_php
- 阅读首页源代码,发现可以通过修改
action参数直接跳转。 - 跳转后发现是一个可以通过
POST直接提交php代码的页面 - 经过尝试
system,passthru等均不可用。通过phpinfo发现disable_function被打开 - 考虑使用
LD_PRELOAD+mail。
1 |
|
- 利用
AntSword快速上传编译好的.so和相应php - 通过提示文件发现
flag在sql中,再次上传.so找到mysqld所在的端口
1 | ... |
- 用php爆破mysql密码,并读取flag,下面直接给出POC
1 |
|
1 |
|
Pwn
又一个复读机
经过一系列“检查”(瞎按键盘),发现在整型转换时有一个符号溢出。因此实际可以输入任意长payload。又因为NX没有关闭,可以直接用ret2shell。
POC
1 | from pwn import * |
babystack
耗时比较久的一道题,基本思路是利用多出的0x10个字节利用leave;ret;的Gadget将ip劫持到栈的更低位,在低位布置好栈,首先将__libc_start_main泄露以获取libc,然后劫持到system函数,完成攻击
POC
1 | from pwn import * |
babyheap
平凡的UAF攻击,利用fastbin操控display最终调用的函数地址,又因为plt中system函数存在,可以很方便地运行/bin/sh
POC
1 | from pwn import * |
一个复读机
观察发现有可以自由控制的printf,因此利用FmtStr进行攻击,首先泄露__libc_start_main的got表地址,然后找到对应libc,再通过覆写printf的got表地址为相应system的地址。手动将printf字符串设为/bin/sh,完成攻击。
POC
1 | from pwn import * |
学术前沿 : 幽灵
出题人辛苦了,帮我把复现环境搭好了
按照论文中的方法,参考其中的C代码行为进行复现。由于网络原因,对一个地址只进行了攻击100次诱导和攻击操作,但任然获得了可观的效果。
唯一的弯在于确定偏移,这个在IDA里就能看到。
POC
1 | from pwn import * |
程序输出如下
1 | [(97, 85), (0, 76), (1, 17), (3, 7), (5, 6)] |
通过脚本对0进行移除后,剩下cache hit最多的就是flag对应的字符
Misc
nc
用Wireshark打开nc.pcapng,第一个数据包里所含的疑似Base64字符串解码后,获得以下python代码
1 | #!/usr/bin/env python |
观察发现程序是一个通过loopback回传一段由时间戳生成的key在经过sha512后的结果。并且,flag在与key进行异或后也进行了一次传输。
通过数据包可以获取key的哈希值和flag的密文。再用数据包产生的时间戳进行简单的爆破,可以获得原key。从而恢复flag。
regular expression 0
考正则表达式
POC:
1 | ^[^o]*$ |
第一个通过字符集查重很快就能发现,是要排除所有o
第二个的自动机结构长这样,顺便安利一下这个网址:
类似的还有regex101
第三个稍微用了点小花招,因为不匹配列表里没有一个是8的倍数,所以匹配规则很有限。
regular expression 1
任然是正则表达式
POC:
1 | ^(x+)(x+)-\1=\2$ |
因为有提示,前三个都非常好解
第四个参考了一篇博文:链接
第五个,考虑到表达式长度上限很长,可以直接进行特例匹配。