攻防世界逆向刷题笔记(新手模式9-1?)
bad_python
看样子是pyc文件损坏了。利用工具打开,发现是MAGIC坏了。搜下也没有头绪。
攻防世界-难度1- bad_python - _rainyday - 博客园
python Magic Number对照表以及pyc修复方法 - iPlayForSG - 博客园
看WP才知道36已经提示了pyc版本了。参考第二个文章,除了魔法数字还有8字节的额外信息。
但是我填充之后还是bad magic,再看看WP咋说的。原来代表文件大小的地方还不能为0.也就是第12个字节。
我们只需要修复一下就可以了。 妈的,用FF也不行,看来必须中规中矩才行。用E5成功了。、
识别出是XTEA加密,写出解密即可。后期我这又出问题了,这一步就不搞了吧
ereere
左边没有main了,依据start必定会出现main函数,一个个点找到了疑似main的函数。
base64换表+RC4。思路同攻防世界RE_ereere_攻防世界ereere-CSDN博客
用cyberchef解决的
easyEZbaby_app
定位到关键代码。主要看checkpass和checkUsername函数
首先是username,密码是zhishixuebao的MD5,以2为步长取。结果是:7afc4fcefc616ebd
pass则是如下。长度显然是15位,注意算法要求是char数组=0,说明赋值等式右边值是0(也就是48)。写出Python代码即可。
a=''
for i in range(15):a+=chr(((255 - i) + 2) - 98-48)
print(a)
toddler_regs
导入pdb文件,放进IDA分析。
持续跟踪,首先看到stage1,要求参数必须是要求的值,只能动调修改这个参数。
但是看起来没啥用啊,看看stage2.
发现stage1的用处了,他会把黄框部分设置为23.我们直接找到这个对应的值即可。注意team是个字符串数组,我们导出来看看,直接在C里面运行吧。
第一个team输出了:0Int
第二个代码和上面一样,结果是:nTJnU
组合起来就是flag{0Int_1s_n1c3_but_nTJnU_is_we1rd}
上面显然是错误的,可能会遇到这个地方刚好是\0直接截断。保险的做法是先定义好数组大小(如char[512][10],再直接去掉&运行即可)
exp:
也可以动调做,我电脑不知为何运行不起来这个软件,只能静态分析了。
easyre-xctf
看题目简介估计有壳。是UPX原版壳,官方工具就可以脱壳了。
但并没有明显的算法,只在字符部分看到了疑似flag的后半段。双击这里有一个符号名part2。
动调看看有没有提示,拿拿数据。
在内存发现了疑似的部分
根据其地址定位到函数,这就是第一个flag。函数名字有个part1,对应着part2.两个16进制转换为字符后就是part1.
七分靠猜,这里有运气成分,正常来说估计得搜part1了。
CatFly(还没有写出来)
看主函数很复杂。慢慢来看吧。
运行出来是个这,输入的东西会在左下角显示。那么main函数有的部分就可以不看了。
看到一个提示:
要记住逃逸密码??
难道是迷宫,分析这部分,\x1Bxxx是终端转义啊,看着是打印图形用的。
百思不得姐,还是看看WP吧。
re学习(29)攻防世界-CatFly(复原反汇编)_攻防世界catfly-CSDN博客
粗略浏览下发现没有我想要的,不过突然想到可以给main函数拷贝到VC,删去已知功能的函数再仔细分析看看。
暂时跳过,下次再看。
IgniteMe
跟进到主函数。
首先str长度需要大于4.
先来一个循环把str循环复制给v7。后两个if判断意思是大写转小写,小写转大写。
最关键的在后院吗,str2我们已经知道了,这就是目标。byte我们也知道,目标就是求v7。接下来的sub_4013c0跟进一下。
是一个表达式,相当于v7^0x55+72.那就很明显了,写出对应exp:
str2='GONDPHyGjPEKruv{{pj]X@rF'
byte=[ 0x0D, 0x13, 0x17, 0x11, 0x02, 0x01, 0x20, 0x1D, 0x0C, 0x02, 0x19, 0x2F, 0x17, 0x2B, 0x24, 0x1F, 0x1E, 0x16, 0x09, 0x0F, 0x15, 0x27, 0x13, 0x26, 0x0A, 0x2F, 0x1E, 0x1A, 0x2D, 0x0C, 0x22, 0x04]
flag=''
#根据str2猜测长度是24
for i in range(24):flag+=chr(((byte[i]^ord(str2[i]))-72)^0x55)
print(flag)
print(flag.lower())
出来的flag都是大写,不要忘记两个if判断是大写转小写小写转大写,因此再次转为小写即可
BABYRE
main函数看着很简单
需要注意:在 C 语言中,(*judge)(s)
这种语法表示通过函数指针调用函数。在 C 语言中,函数名本质上是指向函数代码起始地址的指针。可以将这个地址存储在一个函数指针变量中,然后通过该变量调用函数。
也就是说这是一段自修改代码。judge是函数,需要解密这段judge。
先用AI生成(因为我不太会IDA python)一段解密的脚本在IDA运行,然后C--P加载为函数即可
import idautils
import idaapibase = 0x600b00# 处理182个字节(与原始代码一致,0到181共182次)
for i in range(182):# 读取原始字节original_byte = idaapi.get_byte(base + i)# 异或解密decrypted_byte = original_byte ^ 0xC# 写入解密后的字节idaapi.patch_byte(base + i, decrypted_byte)# 标记为数据(这一行删了就行)无用idaapi.create_data(base + i, FF_BYTE, 1, idaapi.BADADDR)print(f"已解密 {base:X} 开始的182个字节")
再次从main函数进入judge即可了。 直接点进去judge好像部分代码还是错误,重新从main进去就好了。
这个加密逻辑就很明显了。
a='fmcd\x7Fk7d;V`;np'
flag=''
for i in range(len(a)):flag+=chr(ord(a[i])^i)
print(flag)
parallel-comparator-200
这一题直接给了C代码。有点意思。
注意到代码的flag_len是20.
首先认识一个新函数
逐步分析,main函数调用了下图的highly_.....函数。
跟进此函数。根据is_ok的判断条件,着重关注此部分,说明result值是0.因为is_ok的条件为generated==just_a_string。
查找用到result的地方。注意到只有first_letter未知,user_string是我们的目标。
最后一行代码实际上经过上文知识点铺垫,调用了checking函数。
由于result==0,说明argument[0]+argument[1]严格相等于argument[2]。会循环20次这个checking函数(因为pthread_creat函数在for循环内部循环了20次)
0我们不知道,(起码知道是某个小写字母)2是目标,1知道了。而且2就等于1+0.但是这还不太够啊,看看还有没有其余条件,似乎没了。
先尝试写一个爆破脚本试试。这里要注意,一定要多生成几个flag,因为不同的frist_letter对应不同的flag,我们试着a~z都搞一遍。第一次没想到这样遍历。而且代码美观不如豆包写的,还得多写多练。
、注意{}是占位符,可以写任意的表达式。
a = [0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7]# 尝试所有可能的基准值b (97-122)
for base in range(97, 123):flag = []valid = Truefor i in a:char_code = base + iif 32 <= char_code <= 126:flag.append(chr(char_code))else:valid = Falsebreak # 这个基准值无效if valid:print(f"基准值 {chr(base)} ({base}): {''.join(flag)}")
发现flag
很让我开心的是我找到了大致思路!哈哈哈哈哈。只是脚本功底还比较薄弱。