buuReserve(4)
[FlareOn6]Overlong
打开ida看:
有个sub_401160函数,然后里面有一组字符串,还有个28的长度
但是这个字符串长度并不只有28,很长
打开这个程序,展示的字符串有28长度,那后面的去哪里了,继续往下看
有个加密函数,好复杂,没见过
不如修改程序,把后面的给展示出来,上od,28的hex是1C,然后一步一步走,看看出现对话框的时候是哪里,然后,下个断点,再找1C,改为AF
[FlareOn3]Challenge1
看主函数,逻辑很简单,v5经历一个函数,然后跟v6对比就行了
那就看看函数sub_401260
这个是base64加密的模板,主要问题就是表有没有被改变,看一下
表变了,那就去cyberchief上改表解密把
得到flag
[UTCTF2020]basic-re
这道题白给,就一个计算器,flag可以查找字符串
[BJDCTF2020]BJD hamburger competition
这道题是一个unity,没见过,查阅资料得知,看这个文件
放入ida,找到一个函数能看到有个sha1还有md5
可以看到,在flag里面是有个md5,那md5是干啥呢,还有sha1干啥呢,看不懂,没有足够的信息进入下一步
查阅资料,我们下载一个dnSpy
进入dnSpy,我们直接找那个函数,还好跟ida里面的名字一样
看到函数体,先把str进行sha1解密,然后解密后的字符串进行md5加密,且大写,取前20位(X2就是大写,substring的作用就是截取父字符串的某一部分)
将sha1解密得到1001
那么就用1001进行md5加密,得到
取前二十位得到flag
[ACTF新生赛2020]Oruga
进入ida看主函数:
进入一个主要函数,可以看到,两个while循环,还有四个分支,得出是个迷宫,在最下面的while循环可以知道是个16x16的地图,而最下面的while也给出了我们的活动范围,第一行,在最左边不能左走,以此类推,而迷宫的结束条件就是到达!(33)
理解:那我们走迷宫,就是在数组里面走动,而v2在数组里面(也就是地图),所以v2代表我们,然后v4给出了范围,在第二个while循环里面:条件如果道路是0,那就一直走下去,最后有个v2 += v4(说明是一直沿这条路走到障碍前,也就是不是0的前面)
画出迷宫,走出路径得到flag
[Zer0pts2020]easy strcmp
进入ida看主函数,看到flag,输入不对
仔细观察,函数很少,一个一个看看,发现sub_6EA函数和init函数有明显逻辑
sub_6EA函数就是一个
加密过程:每八位与一个数组进行减法,第一个for循环是计算数组长度,第二个是进行加密。但是查看sub_6EA函数的引用的时候发现,并没有被引用,但没被用为什么会出现伪代码呢?
就看init函数:里面有其他函数的引用第一个sub_6E0函数没啥用,第二个sub_6E0函数有来头
第二个sub_6E0函数:把off_201028函数地址赋上了sub_6EA函数的地址
而查看off_201028函数的引用发现strcmp函数会跳到这个函数的地址,也就是说,strcmp就是一个加密函数了,加密的步骤是sub_6EA函数里面的,那就直接看sub_6EA函数吧
给的假flag总共33位,所以第一个for循环之后i是33,除8+1就是5,所以v4是5,然后qword_201060数组里面有四个数据,那就对着了。
第二个for循环里面是一个加密:对假flag每八位进行一次减法,那么逆过来就是加法
我先测试了一下
1 | char flag[] = "zer0pts{********CENSORED********}"; |
可以看到第一个*被解密为l,而星号的hex是2a,数组数据里面的第一个是41,相加不是6c,那就是加上数组数据的最后两个42,刚好是l,(说明是小端存储,倒着计算)
于是多个验证
写出脚本
1 |
|
但是flag2的解密有几个一直都是相差1,我不理解,手算也是相差1
只得到,看来我还是太菜了😓
特殊的 BASE64
进入ida看主函数,给了字符串那就是用base64解密
但看题目,那表肯定变了,我查找字符串发现有一个表很可疑,就用了
也是很幸运😁
[ACTF新生赛2020]Universe_final_answer
进入ida看主函数,可以看到两个关键函数,一个sub_860函数,一个sub_C50函数
先看sub_860函数:一看就头疼,十元一次方程,还是用python解吧
用numpy库也可以用z3(z3更简单)
Z3库可以进行约束求解,即解任何方程(只要有解),常用的包括整数求解、有理数求解、位向量求解(二进制位运算求解)。
解出来之后,有的顺序是错的,换一下
[WUSTCTF2020]level4
进去先看ida主函数
长久分析,得出是二叉树遍历
看文章二叉树
那么看type1和2
type1:
type2:
再结合资料:
得出type1是中序,type2是后序,那么已知中序后序求前序
改写一下代码即可:
1 |
|
crackMe
进入ida看主函数,有很多函数,从后往前看吧,看半天sub_401830函数最重要,像sub_401000函数是检查输入的用户名和密码是否合法,而sub_401830函数也影响着后面两个printf,很重要
进入sub_401830函数,从后面看:sub_401470函数的结果要满足v14=43925才行,进去
sub_401470函数:可以看到里面是对v17的条件判断,不过里面了、那个f冲突了,到最后试了试把f去掉了,因为从外面的while语句看出,长度是8,加上f就是9了,而其他的判断都没有那个( *((_DWORD *)NtCurrentPeb()->ProcessHeap + 3) != 2 )语句(好像是:如果是debug,则执行这行代码,动调这个函数会进入陷阱吗?),于是我就默认去除了
所以知道了v17是:dbappsec
当然,这里得到的v17还是经历一个函数之后的v17,前面的sub_401710函数也用到了v17.
首先,a3是外面的v6,而v6在外面的while条件很清楚可以看出是小于8的(也就是len),那么,这个if条件语句只会执行else if语句(也就是result = (const char *)(name[a3] ^ *(unsigned __int8 *)(a3 + a1));)
那么我们上面得到的v17就是result,只需要跟name异或就得到最终的v17了
看这一段代码:
30行:检查是否是十进制数字
32行:将0-9的字符改为十进制的0-9存储
34行:检查是否是十六进制数字
36-37行:反调试不管,debug执行
38行:输入的abcdef转为十六进制abcdef存储
42行:如果输入的不是abcdef区间的,那就按abcdef区间的顺序存储为abcdef
47行:if条件:奇数停止一次,那么v10就加了两次,所以两两一组存到v16里面(也就是最终密码)
这边圈到的上下两个if语句是反调试的,不用管
所以得到真v17想求v16,还差个byte_416050数组,我们看汇编,需要动调,因为静态没有值
可以看到:在xor之前,值存入了ecx里面,所以调试的时候,在xor添加断点,然后f9执行8次看ecx的值(为什么不是eax,因为eax是个定值)
得到:2a d7 92 e9 53 e2 c4 cd
如何在dgb里面找到:
然后脚本:
1 | flag="" |