全国大学生信息安全竞赛—创新实践能力赛初赛部分wp
前两天打了国赛的初赛,再次被自己菜哭555
MISC
签到
the_best_ctf_game
下载下来附件拖入notepad++,看到有类似flag的字样
再放到010editor里
看到了头和尾,直接一个个输入拼起来就好了
flag{65902f26-0d6e-463f-bc63-2df733e47fbe}
WEB
easyphp
打开环境看到显示的源码
这段代码大体意思就是先建立一个子进程,然后创建成功后去进行进程控制,如果进城异常退出的话,就返回phpinfo,后面就是对传参a进行过滤。
审计过后发现有个敏感函数call_user_func_array(),这个函数是回调函数,并把一个数组参数作为回调函数的参数。
在代码中还发现了会用正则过滤变量a,不能直接传pcntl_wait()而使子进程终端
后来想到我们可以通过给a变量传入call_user_func(),然后给b传pcntl_wait()来绕过正则过滤从而得到phpinfo
Payload: ?a=call_user_func&b=pcntl_wait
可以得到phpinfo页面,本来想通过phpinfo来看一下有没有可利用的函数来getshell的,结果发现flag就在phpinfo中
easytrick
拿到题目发现是反序列化。目的是执行echo file_get_contents(“/flag”)语句。因此需要构造对象的两个成员,trick1和trick2长度小于5,md5相等,但是两者不相等。
由于在代码刚开始的部分有强制类型转换
!==当判断两者类型不同后,就会直接返回True。因此只要传入的trick1和trick2是同类型但不是String类型即可。
!=则会先转换二者类型,因此需要使用传入的参数在强制类型转换为String后,再次转换不能复原的类型。
实验发现使用NAN(Not a Number)符合以上条件:
使用如下代码构造payload:
O:5:”trick”:2:{s:6:”trick1″;d:NAN;s:6:”trick2″;d:NAN;}
传入payload获得最终结果:
rceme
打开发现有源码
将$_GET[\’a\’]的值传入了parserIfLabel函数
经过信息搜集后发现本题代码为CVE-2019-9041漏洞的魔改题
传入的a需要满足次正则要求,即{if:}开头,{end if}结尾
之后经过多层过滤后在{if:}的:与}之间的语句会被拼接到
而被执行,在经过多次本地调试后发现形似?a={if:1)*要执行代码*if(1}{end if}
的payload可以被成功拼接并执行
下一步表示绕过过滤函数danger_key()
发现过滤的很死,eval,assert以及回调函数啥的都被ban了
想到用字符串拼接来绕过,但是回调函数被ban了,后查阅资料发现array_map()也能用来调用函数
后来构造payload ?a={if:1)array_map(\'sys\'.\'tem\',[\'cat /flag\']);if(1}{end if}
并成功的到flag
Reverse
Re_Z3
拖进IDA进行反编译
找到main函数后进行反汇编出伪代码
可以整理出其中的逻辑,首先将unk_404020处的字符串读入Dst赋给Dst。然后读取用户42位的输入。以七个字母为一组组成七元一次方程组,等式左侧的部分即是Dst中的值。后续的方程参数都相同,仅仅是方程左侧的数值不同。
这里使用python的scipy库解方程,exp如下:
import numpy as np
from scipy.linalg import solve
Dst=[
[0x4f17,0x9cf6,0x8ddb,0x8ea6,0x6929,0x9911,0x40a2],
[0x2f3e,0x62b6,0x4b82,0x486c,0x4002,0x52d7,0x2def],
[0x28dc,0x640d,0x528f,0x613b,0x4781,0x6b17,0x3237],
[0x2a93,0x615f,0x50be,0x598e,0x4656,0x5b31,0x313a],
[0x3010,0x67fe,0x4d5f,0x58db,0x3799,0x60a0,0x2750],
[0x3759,0x8953,0x7122,0x81f9,0x5524,0x8971,0x3a1d]]
a=np.array([[12,53,6,34,58,36,1],
[83,85,12,73,27,96,52],
[78,53,24,36,86,25,46],
[39,78,52,9,62,37,84],
[23,6,14,74,48,12,83],
[27,85,92,42,48,15,72],
[4,6,3,67,0,26,68]])
for i in Dst:
b=np.array(i)
x=solve(a,b)
for j in x:
print(chr(int(round(j))),end=\'\')
运行得到最终答案:flag{7e171d43-63b9-4e18-990e-6e14c2afe648}
Hyperthreading
程序有反调试,调用win下的IsDebuggerPresent,先使用IDA搜索字符串,找到debug字段,查看交叉引用,定位到反调函数进行patch,之后拖进Ollydbg,随便输入一个值,发现flag长度42位,验证方式是逐字符对用户输入的字符做加密后进行对比。
找到关键cmp,位置在0x401306(基址401000),对cmp下的jnz进行patch,改为nop,并将0x40130F处的2Ah改成FFh,即去除对比后不成功的跳转,并且将程序的flag对比操作次数从0x2a改为0xff。
之后拖入OLLYDBG 关键cmp处下断。
输入abcdefghijklmnopqrstuvwxyz1234567890-{}
按顺序记录cl的值,获得一个每个字母对应十六进制的映射表
通过字符串定位方法发现sub_401270中的byte_402150即为加密的flag,逐位与用户输入对比。
根据前一步动态调试patch后的程序获得的abcdefghijklmnopqrstuvwxyz1234567890-{}映射表就可解出flag{a959951b076ca047840add7093583251ca92}
提交后发现不正确,观察flag发现需要把0换为减号
最终flag为flag{a959951b-76ca-4784-add7-93583251ca92}
Crypto
bd
使用CTF-RSA-TOOLS 解出m
M转为16进制为
666c61677b64333735323533382d393064302d633337332d636665662d3932343764336531363834387d
发现是16进制的flag
两个一组,写脚本解出flag{d3752538-90d0-c373-cfef-9247d3e16848}
PWN
babyjsc
根据题目尝试连接:
可以根据报错得知,题目环境使用python搭建,并使用input读入
根据得到的源码也可以验证这一点,因此可以使用input的漏洞,input()函数如果接收的是计算式,会执行得到结果。
此处尝试根据该漏洞传入代码执行,利用的os模块的system()方法执行系统命令 __import__(\’os\’).system(\’ls\’)。命令成功被执行,说明漏洞存在:
发现flag并不在根目录,尝试查找flag:
找到flag位置读取,得到最终结果: