BUUCTF逆向工程-3
BUUCTF逆向工程-3
[2019红帽杯]childRE
很神奇的一道题,不过为啥红帽杯的题都多多少少有点阴间成分?
首先看到它的验证部分,这个很好逆。
运行如下代码:
1 |
|
就可以得到
private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
而前文中存在UnDecorateSymbolName()函数。因此我们得到的字符串是某个函数去修饰后的样子。
根据这篇文章可以知道函数去修饰前应该是?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
继续跟踪它与输入的关系可以找到找到这个函数:
不用怀疑,这个b绝对是二叉树。为什么呢?被恶心多了就记住了。看规则是后序遍历,手动算一下遍历顺序,写出代码:
1 |
|
运行得到Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP
将其32位小写md5加密后得到flag:63b148e750fed3a33419168ac58083f5
[SWPU2019]ReverseMe
这道题代码写得很神奇,反正我没看得太懂,所以嗯逆非常滴恶心。
下面这一段是本题唯一可以看得懂的东西。其中v29很奇怪,会莫名其妙地变掉从而执行if。
接着是sub_6525C0()函数中加密的部分。
然后是主函数中的对比部分。
它的代码写得非常莫名其妙,所以采用动调回事一种很好的方法。动调的时候一定要对着汇编码,随便输入点啥,然后把跟Str异或之后的东西前几位记一下。接着就不停地找哪个寄存器是这一串东西,它的值什么时候变了,就能找到加密的地方。写出代码:
1 |
|
得到flag:Y0uaretheB3st!#@_VirtualCC
[羊城杯 2020]login
是一个简单的pyinstaller逆向,下载这个,在命令行里输入
python pyinstxtractor.py attachment.exe
会得到一个文件夹,在文件夹里找到login.pyc,把它传到这里就可以了。
是个简单的异或和z3,得到flag:58964088b637e50d3a22b9510c1d1ef8
[QCTF2018]Xman-babymips
简单的异或加密,注意要取后两位,即x & 0xFF。
得到flag:ReA11y_4_B@89_mlp5_4_XmAn_
[安洵杯 2019]crackMe
很牛逼的一道题。
根据findcrypt插件或者运行后搜索弹出的提示词可以找到:
上面一大段是对base表进行更改,下面一段看不懂。跟进得到:
其中sub_411172()是生成SM4加密所需轮秘钥(RK)。查看RK的交叉引用可以得到SM4的加密过程:
跟进TopLevelExceptionFilter可以找到校验部分:
在base64加密过程中有魔改的地方:
即:base表需要向前移动24个,同时最后的等号由叹号代替。
解密得到flag:SM4foRExcepioN?!
官方文档介绍说这个程序在main函数之前hook了MessageBoxW()函数,之后又调用了这个函数。因此在执行MessageBoxW()前先修改base表并创建VEH向量。执行函数后注册SEH并触发异常。在VEH中构造轮秘钥并注册UnhandledExceptionFilter。在SEH中进行SM4加密。在UnhandledExceptionFilter中修改对比结果并进行变种base64。最后执行比较函数。挺好的,都是中国字==我看懂了。
[UTCTF2020]babymips
没啥技术含量。
得到flag:mips_cpp_gang_5VDm:~`N]ze;\)5%vZ=C’C(r#q=\*efD"ZNY_GX>6&sn.wF8v*mvA@’
[GKCTF 2021]QQQQT
根据字符串找到base58加密
得到flag:12t4tww3r5e77
[NPUCTF2020]你好sao啊
这题有意思,需要对给定的数据进行base64加密,然后才可以得到结果
得到flag:w0w+y0U+cAn+r3lllY+dAnc3
[WUSTCTF2020]funnyre
五个花指令和1000+行的屎山,没什么技术含量
得到flag:1dc20f6e3d497d15cef47d9a66d6f1af
[GUET-CTF2019]encrypt
先魔改RC4,再魔改base64:
魔改RC4部分的Sbox可以通过动调get_key()函数获得,sub_4007DB()函数如下:
这个部分比较简单,逆的时候抄下来跑一边就行。而魔改base64如下:
可以发现它采用的base表是以=开头的,依照ascii码递增的64位字符串,即
=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|
可以写出代码:
1 |
|
得到flag:e10adc3949ba59abbe56e057f20f883e
[WMCTF2020]easy_re
本题采用没听过的perl语言编写,在通过perlapp编译。此类文件会在运行前先将代码解压,然后再执行。
再解压前会有script关键字,同时解压后的代码会存在rax中。通过x64dbg看到:
复制出来是一段perl的代码:
1 | $flag = "WMCTF{I_WAnt_dynam1c_F1ag}"; |
得到flag:I_WAnt_dynam1c_F1ag
[CISCN2018]2ex
魔改base64,但是题目给的输出多了一个"|",不是很理解。
得到flag:change53233
[RoarCTF2019]polyre
很牛逼的一道题。打开看见ollvm混淆,夹杂了控制流平坦化和虚假控制流。采用脚本去除后看见:
P.S.官方题解给出的debcf脚本在IDA7.7中已无法运行,需要自己更新一下,或者用我的。
可以看见它又一些莫名其妙地语句。整体算法发现是可逆的,如果数据大于0,执行后必定为偶数,否则必定为奇数。可以写出代码:
1 |
|
运行得到flag:6ff29390-6c20-4c56-ba70-a95758e3d1f8
[watevrCTF 2019]Timeout
通过010 editor或者exeinfoPE可以知道这家伙是一个elf文件。把.com后缀删掉拖到IDA里,然后翻一翻各种函数,可以找到flag。
得到flag:3ncrytion_is_overrated_youtube.com/watch?v=OPf0YbXqDm0
[SCTF2019]babyre
非常傻逼的题目。
首先干掉4个花指令。
然后处理三组加密。第一个走迷宫,第二个硬爆破,第三个嗯逆。
1 | //爆破 |
1 | //嗯逆 |
血的教训:写循环位移要定义成unsigned类型。不unsigned的话,右移时整数补0,负数补1,然后就错啦!
得到flag:ddwwxxssxaxwwaasasyywwdd-c2N0Zl85MTAy(fl4g_is_s0_ug1y!)
[ACTF新生赛2020]fungame
题出的很好,下次别出了。
见面看到一个加密,这个很简单。
解出来交上去就可以发现错啦!
看看下一个函数:
这个函数很神奇,它把16字节的东西赋值给了12字节的空间,这会造成栈溢出。对,这其实是一个pwn题。
跟踪x可以发现
于是解得flag:Re_1s_So0_funny!=#@a1s0_pWn
[羊城杯 2020]Bytecode
傻逼python字节码,有种硬读汇编的美。抄一个脚本。
1 | from z3 import * |
得到flag:cfa2b87b3f746a8f0ac5c5963faeff73
[FlareOn2]very_success
打开一看函数这么少还以为它加壳了呢,没想到它就是这么少。
逻辑很简单,通过动调可以发现v11始终为1。写出脚本:
1 |
|
得到flag:a_Little_b1t_harder_plez@flare-on.com
[2019红帽杯]Snake
Unity3D的游戏,去找Assembly-CSharp.dll。可以看见他调用了一个外部的Interface.dll。
在Snake_Data/Plugins文件夹下可以找到对应dll。用IDA打开,找到flag关键字的位置可以看见一坨非常抽象的东西,nnd看不懂一点。
去搜的大佬的博客知道这个东西可以爆破。python的ctypes库允许爆破dll文件中的特定函数。
1 | import ctypes |
在地19次是可以得到flag:Ch4rp_W1th_R$@
从结果来看,这个b用C++写了一个RSA…只能说不愧是红帽杯…
[SCTF2019]Strange apk
安卓的SMC。打开看见程序的入口点应该是sctf.demo.myapplication.t,但是找不到。
看见这个里面存在代码西修改的部分。它将data文件经过__()函数和_()函数解密(都tm什么函数名字)。
有用的解密代码部分:
写脚本运行
1 | def get_byte(v): |
打开解密后的文件,这回找得到t部分了,但是看不懂。不过他总共就t、s、f三个有用的,找一找可以才出来加密的流程。下面这一部分在s里。前12个字符由f.sctf()函数加密。
后18个字符由f.encode()函数加密。
后半部分加密后的东西在t中
挺离谱的,我不理解为什么会是这么个执行流程。看大佬的博客说跟安卓的父子组件通信机制有关。
得到flag:W3lc0me~t0_An4r0id-w0rld
[安洵杯 2019]game
OLLVM代码混淆。用脚本除了trace()函数之外都可以反混淆。但是只有三个check函数是有意义的,其余的不用管它。
check1()函数对输入进行了一波操作:
check3()函数就是将输入复制到Dog3[]里再与sudoku[]对比。
因此,我们可以让程序运行起来,下断点之后将sudoku的内容提取出来。
接下来就是写一个脚本的过程:
1 |
|
运行脚本得到flag:KDEEIFGKIJ@AFGEJAEF@FDKADFGIJFA@FDE@JG@J
[GWCTF 2019]babyvm
最瞧不起这种真flag在本地打不通,但假flag能打通的题目。
传统虚拟机逆向。尽管它在执行VMrun函数的时候会跳转到VMrun_another函数很神奇,但并不影响我瞧不起它。我觉得很奇怪,你明明能做到这个,为什么不将VMrun_another函数改成真正需要选手破解的那一段。然后再把VMcheck执行的时候用同样的技术跳转到VMcheck_another函数。这样不就是一个在本地能打通的题目了???
没什么可说的,解题脚本如下:
1 |
|
运行得到flag:Y0u_hav3_r3v3rs3_1t!
[网鼎杯 2020 青龙组]bang
安卓脱壳。
使用这个脚本查壳,然后使用模拟器和frida脱壳。
脱壳后会生成两个dex文件,使用dex2jar工具将其转为jar文件。再使用jadx-jui打开jar文件。
可以找到flag:borring_things
[SUCTF2018]babyre
这个题不好评价。输入key,正确的key会吐出flag。直接爆破。
1 |
|
运行得到flag:Flag_8i7244980f
[HDCTF2019]MFC
好神奇的东西。看见vmp壳的时候想着可以学学怎么脱了,然后一搜发现都是在教怎么破mfc。没事,反正mfc也没见过。
运行程序看见:
将xspy的放大镜拖到这个框上面可以得到:
发现其中的0x0464这条消息不是系统的,写脚本发送消息。此处要用Visual Studio。
1 |
|
之后得到:
将xspy上方的数据拿出来解DES可以得到:
可以得到flag:thIs_Is_real_kEy_hahaaa
[BSidesSF2019]blink
拖到jadx中,在r2d2方法里找到base64,解出来转成图片:
用JEB的话它会吞掉一部分字符串,用[...]
代替,很傻逼。
得到flag:PUCKMAN
[SCTF2019]creakme
做的时候很痛苦,做完了觉得痛苦的原因应该还是自己太菜了。。。
打开看见:
值得关注的是sub_402320()和sub_4024A0()。首先看sub_402420():
可以发现程序自己使用DebugBreak陷入异常,同时使用SEH执行sub_402450()。
再看sub_4024A0(),这个函数将某一段数据作为代码执行了,可以推测sub_402320()是在做相应的SMC。反正没到输入,修改后的代码在干啥其实不用管。
将这两个函数中的反调试跳转语句稍作修改,再动调并根据FindCrypt插件我们可以发现encrypt()函数中的AES和Base64:
这时我们可以发现原先的对比数据>pvfqYc,4tTc2UxRmlJ,sB{Fh4Ck2:CFOb4ErhtIcoLo
变成了nKnbHsgqD3aNEB91jB3gEzAr+IklQwT1bSs3+bXpeuo=
然后我们就可以请出CyberChef了:
BAKE得到flag:Ae3_C8c_I28_pKcs79ad4
[MRCTF2020]EasyCpp
只能说,不愧是CPP。
整个程序没有添加各种奇奇怪怪的东西,只看main即可。先看这一部分:
总结一下就是它输入了9个int数。这道题它虽然用到了vector,但是并没有做什么有关vector的高级操作,完全可以用数组代替。
然后是接下来的加密部分:
代码挺神奇的,还是第一次知道lambda表达式在程序里面长这个样子。要注意depart()函数拆完后拼接的时,会在每一个质数前加一个空格。这也就是为什么要对比的数据里面有很多等于号。开始做的时候没注意这一点,于是就在不停地想,它到底是怎么把数字给弄成空格的。。。
然后是对比部分,可以动调一下找到:
数据量不大,手搓就行了,然后异或1回去,得到2345 1222 5774 2476 3374 9032 2456 3531 6720
,再输入给程序。
运行程序得到flag:4367FB5F42C6E46B2AF79BF409FB84D3
[SCTF2019]Who is he
挺神奇的一道题,不是很理解它怎么做到的,网上也没能搜到相应的解释。
常规地,进入Assembly-CSharp.dll查找相关代码,很简单的base64+DES。
解出He_P1ay_Basketball_Very_We11!Hahahahaha!
但提交发现这是错的。
用CheatEngine可以搜索到额外的几组密文:
写一个解密脚本:
1 | import base64 |
解得flag:She_P1ay_Black_Hole_Very_Wel1!LOL!XD!
不知道它是怎么把这些东西藏起来的。。。
[NPUCTF2020]Baby Obfuscation
看题目名字我还以为能够用脚本一把梭呢。。。结果是做着自己写的混淆。。。
整个代码分析一遍可以得到下面的样子:
其中A_minus_B()函数非常有意思,~(~a + b)
等价于a-b
然后就可以写出解题脚本:
1 |
|
运行得到flag:0bfu5er
[NPUCTF2020]BasicASM
纯汇编,还是CPP的汇编。。。没什么技术含量。。。
1 |
|
运行得到flag:d0_y0u_know_x86-64_a5m?
[ACTF新生赛2020]Splendid_MineCraft
一个劲往下动调就行了。加了有SMC,再加上跳转是依靠jmp寄存器进行的,伪代码可读性其实不高,不如汇编流程图来得实在。可以写出这么个代码:
1 |
|
得到flag:yOu0y*_knowo3_5mcsM<