to be a hardcore reverser
新手练习
re1
最简单的exe题…wp说直接strings就好,不过一开始字符串被打散了,不好直接看出来
试着直接符号执行,惊讶的是exe在ubuntu的angr里直接跑起来了,不过占资源太多被杀掉好几次,设置了系统参数也没办法解决,就放弃了
后来尝试了下IDA的动态调试,在cmp处下断点就解决了
game
一个游戏通关后输出flag的题
先在IDA中shift+F12
查找字符串,发现the flag is
,跟踪到输出处
认定前面没有陷阱之后,发现就是2个字符数组的异或…
还是得多刷题,一开始并没有想到查找字符串哎
Hello,CTF
一串硬编码的十六进制数据,转成字符串就可以了
1 |
|
我就是要用C解…
open-source
给了源码,值得注意的是命令行参数的问题
比如输入./hash 1 2 3
,这样argc==4
argv[0]=="./hash",argv[1]=="1",argv[2]=="2",argv[3]=="3"
不过我试了试直接符号执行,发现终于成功了一次…记录于符号执行-angr
simple2
从52pojie找了2个查壳工具,发现是upx壳,直接upx -d
脱壳即可,flag是硬编码明文比较
logmein
题目名字的意思好像是一个远程接入软件
简单的异或题,不过一开始跑出来是乱码,后来看了网上的wp才发现…
IDA里字符串常量已经加上了转义符号,也就是说那串字符串里没有反斜杠
1 |
|
本题也符合angr的适用范围
1 | import angr |
insanity
虽然没完全理解程序逻辑,不过既然flag都明文存好了……
no_strings_attached
这题似乎牵涉到编码……wp说动态调,算了算了……
输出wprintf,应该是宽字节吧
我反正直接int当%c输出了…发现没啥问题
如果要解释一下的话…可能是这个编码在32bits的高24位都为0时,和ASCII等价吧
解密部分,看了好久…
总之就是38个字符都会减去某个数值x,x从一个5个数的数组中依次取
一旦x取到数组结束,那么再从头开始
于是用个取余就好了
1 |
|
csaw2013reversing2
程序不会执行到解密部分,patch改控制流即可
key-patcher好像有bug,还要我手动算jmp的偏移…
反正计算偏移时,减去的是当前指令的下一条指令的地址
基本思路就是:让程序执行解密部分,再控制跳转到MessageBox函数
getit
在0x400832处下断点,不断c就可以每次发现flag的一个字符
没什么意思
python-trade
pyc逆向题,pyc在线反编译
1 | import base64 |
解密脚本
1 | import base64 |
base64我还真懒得找C库……
maze
迷宫问题,参考链接
萌新入坑
reverse100
.NET平台的逆向,exe文件,题目名字叫apk…
网上找了个ILSpy,反编译
算了还是直接搜wp吧
程序会往本地31337端口发flag,于是用python写个监听的脚本
1 | import BaseHTTPServer |
就这么收到了flag,虽然不知道程序里具体flag在哪
原来直接nc就可以了…
1 | nc -l 127.0.0.1 31337 |
rock
C++的题,输入一个string
后面的三个函数应该仅用于混淆
这个函数的第一个参数应该是一个类
1 | a->vtable = 0x401bf0; |
虚表赋值,一个字段置0,后面2个字段保存输入的字符串,最后一个字段存放拼接的字符串
跟进下一个对此类进行操作的函数
首先检查长度为30,接下来是简单的字符操作
1 | for(int i = 0; i < len; i++) { |
用于检查的函数,转换过后的字符串要等于类中最后一个字段保存的字符串
而最后输出的flag就是我们保存的input副本,也就是输入值
解密代码
1 |
|
提交flag的时候题目有问题…
总结一下就是做C++逆向不要慌…
去掉无关信息还是可以看的
不过我不是很了解string这些的底层,指针引用等,逆向时只能选择相信出题人没有那么变态了
elf.re
就是angr的第一个例题,提交flag格式仍然不对
re-for-50-plz-50
mips架构的…
IDA不能反编译,不过这题就是硬编码字符串和0x37异或,至于复杂的题…以后再说吧
babyRE
做过的题,judge函数被异或加密了
IDC脚本
1 |
|
IDC>decrypt(0x600B00,181,0xC);
然后 U C P
三连,F5即可
取消定义,看作代码,再看作函数过程
不过平台上flag格式又不对
zorro_bin
一开始理解错解题思路了
第一个输入的数k,然后就让输入k个值,一堆异或之后得到seed
,这里需要注意到,因为seed的取值会被检验,取值集合是固定的,而一堆数异或就等价于一个数异或,也就是说这里k的取值无关紧要,因此我们令k=1
即可
然后就是常见的随机种子固定,rand()
的输出序列固定了
是可以爆破出所有的seed值,也就是k=1时输入的那个值,但是没有必要,因为得到了取值集合之后还是需要一个一个喂给程序
由于范围不大,我们直接爆破1-65535
即可,不符合的值会让程序直接退出,没有必要先爆破可能的seed值再喂
其中只有输入预期的seed值时,才会通过MD5
检验,可以考虑把jz改成jmp,但是没有必要,因为输入了错误的seed时,flag也是乱码,让程序直接退出也是一样的
最后给出wp中的shell
脚本
有时间学一下shell脚本的使用,想着可以用pwn的思路起进程,不过比较麻烦
1 | for i in $(seq 1 65535); do echo -e "1\n$i" | ./zorro_bin | grep -i nullcon ; done |
这个脚本”猜测”了flag中会出现nullcon
,也可以人工看……
最后输出 The flag is nullcon{nu11c0n_s4yz_x0r1n6_1s_4m4z1ng}
最后的思考:MD5占用了程序运行的很多时间,如果seed的取值范围更大,可以考虑nop掉
pingpong待做
BCTF2017的题,android没有接触过,先放一下了
licensable待做
感觉应该要黑盒逆,以前熟悉过的OD现在全忘了…
存着吧,附:wp
RM
序列号就是flag
baby_flash-222待做
C++编译到flash的题目,wp中有swf文件的反编译,待做
easyre-153
IDA打开发现没有main,我又忘记查壳了
upx -d
后,程序流程中输入当前子进程的pid
然后就会输出假的flag……
在IDA里有这一段
lol是输出的函数,不过没看出来buf和输出有什么关联
好吧还是看writeup吧
因为1!=0
,所以永远会跳转到loc_80486D3,可以修改跳转指令,也可以直接通过lol的算法取得
这可能是upx加壳后的问题,反编译后看不到这一段,还是得看看汇编
flag在这段”花指令”中……还是太年轻了
修改跳转指令后,运行输入pid即可得到flag
另外,发现(看了wp以后猜测)这段数据经过一些算法就是flag
1 |
|
直接当作char型运算即可,不用转换
总结一下: 查壳,遇到假flag时看看汇编,也许flag在”花指令”中
re2
C++的string的逆向题,命令行参数输入
其中遍历一个字符串时,从begin()开始,到end()结束,迭代器如果等于end(),就表示遍历结束
这里应该是迭代器相同就退出,而不是迭代器中的字符相同
一顿分析以后发现,密文:
L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t
正确的flag就是密文错位后的结果
不过这里内层的数组好像有点问题,因为是逐字符比较,gdb动态调一下
把跳转指令patch一下,比较失败也继续执行,这样我们只要不断从rax中获取数值就可以拼出flag了
ALEXCTF{W3_L0v3_C_W1th_CL45535}
动态调试加上脚本爆破,脚本我不会写……
逐字符比较,尝试patch掉跳转指令,直接动态调试
Catch_Me待做
题目给的附件有点问题好像
wp完全看不懂
rev100
解压后看起来是个十六进制文件
用xxd
让它恢复到原来的样子
xxd -r -p rev100
好吧,大部分都是垃圾文字,但是中间夹杂着一下ASCII字母,可以看到flag…什么的。每个’h’后面都有两个有用的,我们把他们挑出来:
1 | bash $ sed "s/ / /g" rev100 | xxd -r | strings -n 1 | grep '^h' | cut -c 2- | tr -d '\n' |
flag{poppopret}
这题…乏趣
reverseme120
这个题卡了很久……经验不足
第一个函数对输入字符串v11进行了操作,不过很迷……根本看不出来它在干嘛
当时就一直在逆这部分的逻辑
后来看了wp才发现其中一段关键代码与base64有关
wp说显然这个这一串数组是base64的码表…对不起我不认识
黑盒测出v13就是base64加密后的结果
这里TM竟然是分两部分异或0x25……
最后解密就简单了….
把固定的字符串you_know_how_to_remove_junk_code
异或0x25
得到\JPzNKJRzMJRzQJzW@HJS@zOPKNzFJA@
再base64加密,XEpQek5LSlJ6TUpSelFKeldASEpTQHpPUEtOekZKQUA
base64的原理之前了解不多,试了试”@@@@”这种也可以加密…
关于做题:各种查表需要熟悉…
多动态调试,看看字符串被处理成什么样了
dMd-50
md5(flag) == “780438d5b6e29db0898bc4f0225935c0”
查一下就好了
Leaked_Lisence待做
file之后发现是.xz文件,ubuntu和mac都解压失败,windows里加个后缀名.xz就解压出来了……
然后再file一下,发现还是tar文件,再改后缀名解压……
好了然后我就看不懂了,好像是和导出dll有关?
ReverseMe
IDA打开后发现一大堆windows相关的函数,迷失在了库函数之中
我又忘了看字符串窗口了
找到关键函数
ROL1是循环左移,比如0x12345678变成0x78123456
异或的key是从函数中取得的,发现每次运行都是
解密代码有点诡异,windows下用BYTE才成功输出,或者直接用unsigned char,再%c输出
之前也有char输出乱码的情况,应该是溢出的问题
1 |
|
还有wp里的python写法,取模256
1 | key= [26, 162, 47, 249, 148, 67, 60, 196, 77, 216, 140, 197, 91, 182, 110, 234, 163, 60, 201, 155, 188, 202, 173, 215, 126, 224] |
总结一下,还是查找字符串,看程序的功能交互
不要迷失在库函数之中
还有就是循环左移的解密
reverse_box
./reverse_box ${FLAG}
95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a
题目逻辑:fill_buffer
函数中,随机取一个1-255之间的数值,根据这个数值生成一个256字节的数组
这个数组的可能性只有255种,然后就是爆破所有情况,看TWCTF在不在里面,据说和SBox有关
看了好几份wp,总之是人为设置这个种子,遍历所有情况,得到所有可能的数组
但是我学不来……….然后看TWCTF在不在输出值中
放弃了……..
crackme
exe逆向,先IDA打开发现没有main,显然是加壳了….PEID等工具查一下发现是nSPack
壳,PEID自带的脱壳器还不起作用,后来看雪上找了个工具(还自带BGM…)
然后分析就很简单了,异或数组
1 |
|
handcrafted-pyc
暂时还不想学pyc逆向,先放着吧
RE100
程序中一开始有很多pipe、fork等操作…不是很懂,不过和解题没什么关系
输入的字符串分块后,交换位置就是flag
每10个字符为一块,原本的1234共四个字符串的排列转变成为3412的排列顺序,变化排列顺序后
与{daf29f59034938ae4efd53fc275d81053ed5be8c}
进行比较
re3-100待做
千万不要运行这个程序,如果想体验死机的话当我没说
这个**程序,一般IDA看的复杂都交互一下吧…结果一个输入,开始满屏弹窗cmd,还在目录里面创建了几万个文件夹我艹,虚拟机卡死任务管理器都开不出来
最后继续运行虚拟机,让它继续弹窗,几秒钟后内存占用17G,最后在活动监视器里杀掉进程,向运维投诉…
不过看了wp以后发现,这题是一个pyc的exe,存了wp再说
gametime
题目比较简单,基本就是看到需要的字符时就按下回车
失败的话会输出FAILURE
IDA打开,搜索字符串,分析后发现只要把跳转指令改一下,这样就不用按空格了
只要让游戏自己玩就可以最后得出key了
有两处有FAILURE,这是其中一处,patch成jz就可以了
notsequence
杨辉三角,没什么意思,wp
exp(感谢uns3t师傅…)
xctf的wp没有排版,真难受……
1 | import hashlib |
不过官方exp出的flag也不对…….
CRACKME
无壳,没有main函数,看上去是MFC写的(别人说的)
字符串窗口中也没有相关显示
看MessageBox
的交叉引用,发现有两个函数调用了它
看汇编时发现这两个函数的call都是来源于同一个函数,并且还是分支关系
在IDA中按P,再F5
回到汇编状态找到sub_401720和sub_4016e0的地址,在OD中下断,再点击注册按钮果然被401720断下来了,说明这里就是关键跳
if的判断中是关键的flag_check
初始以10作为种子,rand[0]为0x47(71);以1作为种子,rand[0]为0x29(41)
也就是说seed代入数组运算时恒为1
MFC的updateData可以理解为读入字符串
因为这里是指针调用函数,if的条件又太乱了,直接看汇编
看出要求输出的字符串长度为0x21,然后进行检查(再回去看看F5的结果也能得到)
这种直接把输入进去比较,当然是直接动态调了
可以直接断几十次记录下应有的输入,第一个是0x68也就是f
不过这里既然已经分析出逻辑了
v3[v5 + 96 + seed] // (v3+97)[10x]
找到这个字符串,IDA里提取一下
输出第(10n+1)个字符就可以了
flag{The-Y3ll0w-turb4ns-Upri$ing}
有一点问题就是……没看出来为什么a2就是我们的输入
最后的一些思考:
又学习到了srand、rand的一个特性,通过初始种子,随机出的第一个数经过一定运算再作为种子,输出随机数,以此往复,最后输出的值可以是固定的
还有就是一长串字符串,跳着比较输出,可以一定的混淆
MFC程序的一些特征,API等
Shuffle
题目描述:找到字符串在随机化之前
好的,结果一找就找到了,送分题
高手进阶
Newbie_calculations
程序会自己跑出flag,主要是代码中用了故意耗时的计算函数
都是加减乘,分析一下不难看出,网上找了一个改好函数名的代码
每一位字符都是独立的
1 | // all flag chars are set to 1 |
最后的flag CTF{daf8f4d816261a41a115052a1bc21ade}
actually_cpp.swf待做
swf文件,再说
internet-of-what
TMD也太难了吧,放弃放弃,和固件什么有关
myDriver待做
驱动逆向,wp上和hook无关,直接逆的算法,存了pdf
一个简单的Inlinehook,hook NtCreateFile 函数。
在任意路径打开文件名为 P_giveMe_flag_233.txt 的文件超过8次,在第9次打开 P_giveMe_flag_233.txt 的时候就会在里面写入flag。 文件名进过简单的加密,加密的 key 是自己构造的一段 win64 的汇编生成
另外的wp,等学了hook再看看
还是得看看《加密与解密》
家徒四壁-void
hitcon2017的题….elf注入
对不起,看不懂
攻防世界的wp比较详细,但是我看不懂
debg.exe
没打错,题目就是叫debg
又是一个.net逆向,发现做过的几题都是下断点然后就明文比较出flag了…..
不过这题需要用32位的dnSpy
吐槽一句,这个平台上的难度评级就是闹着玩的…
HW-RE
18年国赛的一题
通过strtok
切割flag,flag类似于CISCN{flag1_flag2_flag3}
第二、三段存入变量显示是循环+数组方式,实际上是后文会直接用到的一个变量,观察栈布局偏移可以看出来
后面就是把这三段flag分别检查了
第一个检查我感觉各种wp不太严谨
前面一大段是一个md5,不过一开始不太好猜,后面是根据加密过的hash值反推出原本的hash值再去查找
wp说:明文hash中的A-F字符,经过运算后可以生成大于F的字符,这样就可以反推出原来hash里的字符
问题:比如字符K,可能是由A-F经过运算得出的,也可能本身就是K
(没有仔细分析,也有可能前面限制了明文hash中英文字母都是A-F)
不管了,跳过这一步,就认为原来明文hash英文字母都是A-F
1 | def check1(str0): |
解密后结果:yubu
第二个检查:
明文hash异或一组数据后,再经过前面检查的同样的运算,得到一个hash
解密:先同样用上面的方法,再异或,最后查询md5,得到kulo
第三个检查,感觉没什么意思(不太喜欢图片那些),贴wp了
flag3和flag2的算法一样,只是flag3长度为16位,很难破解查询,但随后提供了一个方法可以获取到flag3。如下:
1)取flag2的哈希(16进制)的16字节之和(记为total),然后使用total产生两个值。 x1 = total/16 x2 = total%16
2)将x1和x2分别和flag3的第4、5位进行异或得到xor1和xor2,即
1 | xor1 = x1^flag3[3] |
3)全局变量中预置了一段数据data,将上面的xor1和xor2分别和data的奇偶字节进行异或得到数据data1,使用fwrite写入文件
4)只要输入的flag3[3]、 flag3[4]合适,就会产生一张图片,里面记录了完整的flag3。
5)所以需要通过写文件这个操作能联想到写入的文件是图片文件,然后根据图片文件的头部固定字节就可以反推出flag3[3]、 flag3[4]
6)本来开始是在写文件的时候加上后缀,这样就可以降低题目难度,后面想了下还是先不加后缀,可以将这个后缀放到提示里面。
另外一个wp提到,2个char数据可以爆破,因为出题人给了一张png,所以可以查找图片头尾字段
题目做到这里,感觉md5、hash的那些还是需要一些直觉
看到一堆函数,一段类似(加密过的)hash,应该先解密原先的hash,而不是直接拿头逆函数
还有就是代码里有一段malloc没看懂,也许是混淆?感觉没什么用
uwp-454
uwp逆向,再见
catalyst
做过的题,主要的一点就是随机种子确定,随机序列也确定
unvm_me.pyc待做
shamecontrol-200待做
SE壳脱壳,.net
存了wp
TankGame
题目给了一个rar文件,解压后发现有游戏exe,一些地图之类,通关给flag
看了网上的wp,有的是用IDA把敌方数量降成1,有的是改地图
而我就比较厉害了,我连游戏都打不开,再见
what-does-this-button-do
jar文件,看到FlagActivity()
1 | for (;;){ |
直接转成ASCII,flag{w4nn4_j4r_my_d3x}
Sharif_app
反编译之后
看到关键逻辑是isCorrect
函数,还提到了Native
apk中输入正确即输出flag,可以直接跟算法,但是我看不懂这些API
于是找到生成libadnjni.so
,IDA中看到其实是一个strcmp,变量获取下来转成字符串即可
应该就是反编译看不出来函数体的就去lib里找吧…
libdroid
看起来比较麻烦,不做了…
hi-200待做
程序被VMP保护,会输出windows系统一些参数,如果参数都与要求的相同则输出flag
需要了解windowsAPI,动态调试,但是实际上手可能比较难…