周报2
ACTFeasyre
先查壳,是简单的upx脱壳
然后放入ida分析
主要找这个函数
得出:让if语句里面的条件,左边的等于右边即可,那么v4+i是已知的,就剩下右边的_data_start__了,点进去
看见字符串
b = ‘~}|{zyxwvutsrqponmlkjihgfedcba`_^][ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$# !”‘
还有
a = 42,70,39,34,78,44,34,40,73,63,43,64
看ASCII码,v19 = A,HIBYTEv19 = C,v20 = T,v21 = F,v22 = {,v23 = },那么我猜flag的内容就在v16,17,18,23,24,25里,但是为啥是互相等…….
有点明白了:
a中的ascii码是flag内容的ascii码-1的值
所以代码
1 | # 无注释 |
rsa
题目提示四位数字密码,那么直接爆破
得到两个文件
题目是rsa,那就说明pub文件里面有钥匙,010打开
得到公钥,放到网站里去
得到n,那么用n去求解q和p
拿出工具求解d
d = 81176168860169991027846870170527607562179635470395365333547868786951080991441
那么写一个Python脚本
1 | # 无注释 |
注意key = 这一行,里面的nepdq的顺序不能有错
得出flag
[ACTF新生赛2020]rome
看题:
显然,v5—v9是actf{,然后v14是},那么内容就在v1234,v10、11、12、13、14里,也可能是我ida版本不行,这里反正咋看咋不对,但不影响写题。
首先有
1 | int b[] = {81,115,119,51,115,106,95,108,122,52,95,85,106,119,64,108,0}; |
从后面看,让v1+i = v15 + i,就是让经过前面两个if之后的a[i]的ascii值等于b[i]的值即可,就是爆破思想,强行从可见字符串里面找到flag。
所以前面两个if直接在脚本里照抄就行。然后字符串长度是16.
就加个在128个字符串中,一个一个赋值,然后进行两个if语句,然后再和b数组进行==判断,最后赋值给flag数组,然后输出
脚本:
1 |
|
crackRTF
先查壳,32位无壳
用shift+f12查找字符串找到主函数
大致一看,这个程序是需要输入两个密码,并且有两个函数对密码由操作
进入第一个函数
看到了0x8004u,那是标识码,不同的标识码代表不同的加密方式,标识符代表加密方式。
这个是sha1加密
第二个函数是0x8003u是md5加密
上网查阅资料:
SHA1对任意长度明文的预处理和MD5的过程是一样的,即预处理完后的明文长度是512位的整数倍,但是有一点不同,那就是SHA1的原始报文长度不能超过2的64次方,然后SHA1生成160位的报文摘要。SHA1算法简单而且紧凑,容易在计算机上实现。
所以我就想:直接把加密后需要对比的字符串进行MD5解密不就得到密码了吗
123321是第一个密码
~!3a@0是第二个密码
程序内输入得到rtf文件
打开得到flag
但实际上做没这么简单,属于是抄近道了
第一个函数是sha1加密,直接python用hashlib包,进行爆破
1 | import hashlib |
第二个是md5加密,但是没有给范围,上一个函数是给了范围,数字大于10000
那就往下看
FindResourceA:找到模块中的资源,这句话是找到AAA类型的叫0x65的资源
SizeRecource:根据名字也容易知道函数返回的是字节数
LockResource:返回资源地址
LoadResource:意思是装载指定资源到全局存储器。 函数功能:该函数装载指定资源到全局存储器。
CreateFileA:函数创建或打开下列对象,并返回一个可以用来访问这些对象的句柄。
WriteFile:将数据写入一个文件或者I/O设备。
CloseHandle:只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了。并没有结束线程。
还有一个sub函数
还像是要读取“AAA”文件里的数据然后跟我们输入的密码2传入sub函数,然后函数就是异或,那么我们逆过来也是异或,现在就是找“AAA”文件里的数据,然后因为我们输入的是六位密码,不出意外的话,“AAA”文件里的数据也应该是六位,启用Resource Hacker:
因为我们的数据需要通过WriteFile函数写入到文件里,然后产生rtf文件,那么写入什么会产生文件呢,我猜是文件头,于是打开一个rtf文件,取文件头前六位:{\rtf1
写脚本逆一下:
1 | # 无注释 |
得到密码2:~!3a@0
[FlareOn4]login
下载后得到一个html文件
1 | <!DOCTYPE Html /> |
关键:
1 | var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);}); |
分三个部分吧:
(① ? c : c - 26);
① = ② >= ③
② = (c <= “Z” ? 90 : 122)
③ = (c = c.charCodeAt(0) + 13)
第一种:小于等于90且+13依旧,返回本身+13
第二种:小于等于90且+13大于90,本身-13
第三种:大于90且+13小于等于122,返回本身+13
第四种:大于90且+13大于122,本身-13
写出代码:
1 |
|
原本我写的前两个条件语句不含>=65,结果我发现出来的@什么的符号都被改变了,看了看别人的wp发现他们都控制了最小ascii值得范围就是大于等于65,虽然对答案没有影响因为给了规范答案,但是还是不严谨,最后给加上了条件,我感觉就是没有闭区间才导致的不完整
然后我发现这道题跟rot13一样:
[2019红帽杯]easyRE
这一题对我来说很难,还是看很多大佬的wp才写出来的,还需要加油
拖入ida,shift+f12查看字符串,找到函数
出现continue,说明有阶段性的解密,那就先解出上面的加密,发现就是个异或,脚本:
1 | char flag[36]; |
结果:
说明flag的前四位是flag。。。。。
接下去看
sub_400e44是典型的base64加密,调用了10次的base64加密,然后比较,那就解十次
发现是个网站,进去有一部分是想方设法坑解题人的,好吧。
那问题来了,到底关键函数在哪里?
在这里能看到,还有个函数,点进去
102是f,103是g,这里有在判断fg,感觉flag就住在这里
分两个部分:
①利用byte_6CC0A0的前三位和byte_6CC0A3 的前一位,去和“flag”进行四次循环异或,作为下一个部分的条件,
②将全部25位与①的结果进行25次循环异或,不过①的序号需要%4
代码
1 | char flag1[25]; |
这一步吧,我觉得对我来说疑点很大,就是判断出,v3是四位数组,且跟另一个数组异或后是“flag”,这个我感觉很关键,从而找出了v3
对这道题的部分代码做个解释:
sub_4406E0:写入数据给v53
LODWORD(v1) = sub_424BA0((const __m128i *)v51):将v53长度给v1
memset(&v54, 0, 0x40uLL):V54的值设置为零,memset通常是C/C++初始化函数,作用是将一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作
HIBYTE()函数的作用是获取高字节也就是数组的最后一位,同时还有BYTE()、BYTE1()、BYTE2()第一个是获取数组的第一位,第二个就是获取第二位,依次类推。
这一段数据的话,是关键,但是要怎么发现呢?
出题人不会无缘无故给数据,就找找看,看看引用:
这段数据被函数sub_400D35给用了而且函数的头头是fini段
fini段的解释:
此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。
所以就很关键