近期题目复现
一些比赛的复现
¶0x00-Zer0pts2022-service
¶分析过程
先定位到正确的判断,进入加密函数
可以看到有几个api函数,并且只有所有的值都相等,才能实现return的值为1
但是动调的时候很多函数看不到,而且这里面有很多东西未被正确识别,所以使用X64DBG打开并定位到加密函数
首先我们要知道x64的函数调用机制
所以在call前的那几个mov就是函数的参数
先看循环的次数
很明显这段就是循环的判断
循环内部,可以看到有三个api函数,先不管
因为刚才在ida看到,最后是有一个比较的,我们先确定存储加密后字符串的位置,根据这个跳转和0x1F也就是31,确定这就是判断
可以看到在这之前先把两个地址存放的一个byte放入edx和eax中,我们就可以定位过去,先运行到这
可以看到,我们通过64FD80-0x40得到了存放加密字符串的地址,那么这一段就是循环判断
接下来我们重新运行一下,然后这次我们先右键锁定堆栈,观察他的变化
先来看一下第一个API函数
1 | BOOL CryptCreateHash( |
而前面的一些是函数的参数,关键的是下面这个,我们点进这个链接
0x800C,和我们的参数对应上了,那么这个应该就是加密的方式
再看第二个函数
1 | BOOL CryptHashData( |
关键是是我们加密的数据和数据的长度,也就是说每次取出2长度的字符串生成hashdata
再看第三个
1 | BOOL CryptGetHashParam( |
具体的可以不用细看,只需知道这一段是真正的加密,因为在执行前,目标地址没有数据
执行后
所以整个过程就是将我们输入的每两位进行sha256加密,然后和他给我们的hash表进行表,那我们就可以先生成两字符的sha256彩虹表,然后反查
验证一下
flag格式是zer0pts,取前两个字符进行sha256加密,正好对应
¶脚本
1 | hash = [ |
zer0pts{m0d1fy1ng_PE_1mp0rts_1s_4n_34sy_0bfusc4t10n}
https://www.cnblogs.com/xxxxxxxxx/p/11544432.html
这里介绍了itertools.product,其实目的就是生成2位字符的彩虹表,然后和密文对比
¶SpaceHeroesCtf2022-Shai-Hulud
¶0x00-前言
比较有趣的一道题,当时专注于改源码搞定游戏,然后一直失败,主要是自己写的C语言生成的随机数和调试得到的不同(其实是没注意linux和windows生成随机数的不同),所以就想玩游戏得到flag
另外的解法
https://breaking-bits.gitbook.io/breaking-bits/spaceheros-ctf-2022/re-shai-hulud
¶0x01-分析过程
运行程序知道这是个贪吃蛇小游戏,通过不等于0x295判断这就是贪吃蛇长度,然后SHA256_Init可以看出这是sha256加密
前面的一些函数就是生成地图,初始化游戏等操作
主要看下面这个函数,是随机生成需要吃掉的点的
这两个函数是一些规则,告诉你wasd是移动
主要看frame函数
下面这个函数是说不能碰到尾巴,继续往下看
可以看到等于-2的时候,而-2刚好对应随机生产点函数的-2,然后对该值进行sha256加密,并且重新生成-2的点,然后长度+1
所以我们接下来只需要跑到最后的长度即可得到最后的sha256加密值,然后在print_flag函数中,最后进行了一次异或
本来修改好规则打算玩到0x294的,但是在长度为195的时候随机点找不到。所以只能老实做
在导入表可以看到SHA256_Init,SHA256_Update,SHA256_Final函数,可以知道调用了OPENSSL,版本为1.1.0
安装好之后,模仿该过程生成SHA256加密,注意因为每次都会Update,所以不能将最后一次生成的值直接SHA256加密,这样得到的结果不一样
这也就是前面说的,每加密完一次,hash初始值都会被改变
1 |
|
编译
g++ -o openssl-sha256 openssl-sha256.c -std=c++11 -lssl -lcrypto
也可以动调得到最后的sha256值
最后异或一下即可
1 |
|
上面介绍了openssl的一些加密算法使用,下面这个是函数说明
https://www.jianshu.com/p/3c59291f8f98
¶SpaceHeroesCtf2022-Timesup
进去就是输入三个数满足一个方程式
计算方法就不多说了,可以看这篇wp
https://ctftime.org/writeup/32973
主要看第二个限制,可以看到这里有个限制应该是在16到17秒之间,但是wp里说的是17分,我自己写了代码发现第一个参数是秒,这里也有说明
https://www.runoob.com/cprogramming/c-function-localtime.html
那么我们就需要借助工具来进行传送参数,需要pwntools
1 | process是连接本地连接 |
1 | val = 0xa4c570 |
直接贴代码吧,感觉需要系统学pwntools
¶Hgame2022-week4-hardasm
一打开有几千行的汇编代码,先定位到关键判断
可以看到有很多的比较+跳转,而跳转的位置都是error
那么只需要保证不符合等于0即可
构造flag:hgame{12345678901234567890}动调
可以看到只要输入正确,最后得到的值是0xFF,不正确则为0,可以采取爆破的方式爆破出flag
可以看到printf的参数是通过rcx传入的,所以我们可以patch程序,让他打印[rsp+70h+var_50]的值,而不是success或error
edit->patch Program->Assemble,不知道为什么KeyPatch改不了
¶subprocess模块
subprocess模块可以生成新的进程,连接到它们的input/output/error管道,同时获取它们的返回值
我们可以使用该模块进行爆破
1 | import subprocess |
代码来源-https://blog.csdn.net/weixin_45582916/article/details/122909419
POpen参数说明
1 | stdin stdout和stderr: |
1 | stdin.write()#输入 |
¶Foobarctf2022-Matrix
一道vm题+angr求解
vm分析部分
1 | unsigned char opcode[124] = { |
angr求解,因为最后的结果字符串存在GLUG,所以直接angr
1 | import angr |
不知道为啥只能在linux跑,在windows跑会报错
¶*CTF2022-Simplefs
根据附件里的描述,可以知道这是关键函数
这三段都很类似,不同的在于这里传入的参数
进去看看,根据不同的参数产生不同的结果,然后写入
当传入2时,生成的是随机数,而且以时间为种子,所以我们不可逆
当传入1时,移位和异或操作,通过动调可以得到异或的值
¶解题思路
遍历文件所有字节流,进行解密,然后和*CTF比较,比对成功就打印其后面的32位
也可以先将*CTF进行加密,然后将得到的十六进制去加密的文件搜索,取出之后爆破即可(NU1L的题解就是爆破的)
¶IDA命令行参数动调
本体涉及命令行参数,红色框输入的是命令行的参数
¶脚本
下面贴一下我的脚本,调试了挺久emmm,太菜了
1 |
|
要注意的是
BYTE是unsigned char型,所以前面的代码不需要加上&0xff,因为给Buffer定义为unsigned char,所以赋值时会截断,