beginCTF WP(Reverse部分)
新手wp,大佬轻点喷
一.俄语学习
1.查壳,然后无壳,32位c++程序
2.运行看了一眼,果真还是俄语题目,蚌埠住了,寻思难道直接劫持控制流出?然后拖进ida看了下主程序的流程图,更难崩。。。
3.没错就是这一坨,没事儿还好还好,不就多劫持几下吗,然后一路劫持控制流下去,总共30道题。。。(操作如下,我就不详述了)随便输入点东西然后控制流到jz跳转的时候将ZF标志位置为1就行了,然后一路f8往下就行。
4.最难崩的东西来辣!
5.好好好这么玩是吧,一路f8手都给我摁酸了,你玩这一招,一气之下不小心把程序结束掉了,然后重拖进来看最后那个函数。分析下来就下图中框出的两个函数起作用。
6.先看第二个,然后发现了本题的密文,还有一个RC4加密
7.然后返回到上面第一个函数xor中瞅一眼,又一个RC4,不过密码变了,然后还有一个简易的混淆
8.再往上就没啥加密的了,ok直接开搞开搞,刚刚忘瞅RC4的密码了,结果静态调试的时候一瞅(之前一气之下给结束程序了),啥都没有,好好好,我又得劫持一边。。。。
9.省略劫持之后又到了最后一步,然后拿出本文中WAWA密码为:35F1DA197AF6319CD92CC1FCE2D81D8D4F978126C0B89627D55BAA1885FA61E4A1BCF8A4563743582BC97764CC6B986575388009113DD0E68FA9579906105DC569BD2D687EE367D1FF5EF9F5418CDD214BA747866DC32A9A9F2048BB94B9B49202747D1B1E5FBA49D6E75304CB283FE8333E009B6AFDBE1C90EDDF4D256FB513703C9E160C054A73DEB18A513B5414E05ADC9162A395D33A17EE32F27CAFB388EC0EAE9D5C0D554EFB46224445BF52126607D236936E421A0FE960CAB26C83F00376A81F63EFA5CD797B0A0BABDBD47F01342359E129C6ACA240C8ADC489C2B671A0EB2F78F3B0FECEF78472F4CFC7D7B78E4C8230502E24870839E5EAA68B15
本文中kb1密码为:35F1DA197AF6319CD92CC1FCE2D81D8D4F978126C0B89627D55BAA1885FA61E4A1BCF8A4563743582BC97764CC6B986575388009113DD0E68FA9579906105DC569BD2D687EE367D1FF5EF9F5418CDD214BA747866DC32A9A9F2048BB94B9B49202747D1B1E5FBA49D6E75304CB283FE8333E009B6AFDBE1C90EDDF4D256FB513703C9E160C054A73DEB18A513B5414E05ADC9162A395D33A17EE32F27CAFB388EC0EAE9D5C0D554EFB46224445BF52126607D236936E421A0FE960CAB26C83F00376A81F63EFA5CD797B0A0BABDBD47F01342359E129C6ACA240C8ADC489C2B671A0EB2F78F3B0FECEF78472F4CFC7D7B78E4C8230502E24870839E5EAA68B15
捏马原来是一样的,那这个RC4没啥用啊woc
文中bbq1为
unsigned char bbq1[] =
{
0x35, 0x6D, 0x35, 0x64, 0x35, 0x77, 0x35, 0x64, 0x35, 0x62,
0x35, 0x6E, 0x35, 0x6D, 0x35, 0x64, 0x35, 0x77, 0x35, 0x64,
0x35, 0x62, 0x35, 0x6E, 0x35, 0x6D, 0x35, 0x64, 0x35, 0x77,
0x35, 0x64, 0x35, 0x62, 0x35, 0x6E, 0x8E
};
10.ok,那就直接用密文去做混淆就行了,脚本如下,bbq1换成了10进制数:
bbq1 = [53,109,53,100,53,119,53,100,53,98,53,110,53,109,53,100,
53,119,53,100,53,98,53,110,53,109,53,100,53,119,53,100,53,98,53,110,142]
bbq2 = [43,105,38,91,64,89,58,103,56,91,38,108,36,102,56,83,56,118,36,89,38,101,62,123]
input_str = ""
for i in range(len(bbq2)):
if i >= len(bbq1):
break
input_char = chr(bbq2[i] - bbq1[i] + 112)
input_str += input_char
#print(ord(input_char),end=' ')
print("Recovered input:", input_str)
#flag{Russian_is_so_easy}
二.xor
1.查壳,然后一个upx壳,直接小工具脱一下就行。
2.一开始居然没找到主函数,随便下了个断点才找到主函数,直接看最后一个函数(此处我已重命名了)
3.一路跟进之后发现函数还挺多,确实也都是异或,出题人还真没骗人,就是比较绕感觉,直接跟进到最后一个函数看密文
4.发现密文传值给v5与temp作比较,然后下面只需要对于temp进行逆向即可(提一嘴,图中call3函数应该是作初始化一类的,不用管),继续往上溯源,看到上一处对于temp变量进行处理的函数call12,然后又继续往上翻了几个函数,异或的逻辑都是一样的,就是把一个32位的数字拆成两半,分别与对应的部分进行异或,运算逻辑是简单的,但是call相对较多,所以会感觉很绕。
5.只需要往上一直找就会找到异或对象的来源于两个密码串
6.然后直接开搞,从最终的密文一直往上逆,一步步异或,一开始我想一步直接到位,爆破一手,后面发现好像做不到,就老实一步步逆回去,下图是其中一个脚本实例,为了逆向过程不混乱,我每一个过程都写了相应的脚本,就是为了弄错之后不用重头再来。
7.连续写了大概3个脚本左右,大体都是不变的,我不过是换了其中异或更新后的数字,然后最终结果如下:
#include <stdio.h>
int main()
{
int temp[32] = {96, 97, 103, 104, 123, 94, 98, 118, 117, 119, 84, 111, 111, 97, 104, 108, 89, 111,
99, 80, 116, 109, 121, 105, 105, 106, 106, 124, 101, 107, 39, 112};
int temp7[16] = {81,90,86,94,77,100,88,65,77,69,104,84,90,94,94,81};
int temp6[16] = {105,81,87,102,68,82,75,89,91,94,86,67,84,81,20,69};
int temp5[32] = {94,111,101,90,118,100,122,108,105,111,105,117,103,97,33,112,103,97,97,98,121,87,97,115,117,114,87,102,109,107,110,108};
int src2[32] = {54, 51, 50, 57, 48, 55, 57, 52, 50, 48,
55, 55, 49, 53, 53, 56, 55, 54, 55, 57,
54, 50, 49, 51, 56, 54, 55, 51, 53, 48,
48, 48};
int fu1[16] = {54, 51, 50, 57, 48, 55, 57, 52, 50, 48,
55, 55, 49, 53, 53, 56};
int fu2[16] = {55, 54, 55, 57, 54, 50, 49, 51, 56, 54,
55, 51, 53, 48, 48, 48};
int k,l;
for ( k = 0; k < 16; ++k )
{
temp7[k] ^= fu2[k];
printf("%d,",temp7[k]);
//result = k + 1;
}
printf("\n");
for ( l = 0; l < 16; ++l )
{
temp6[l] ^= fu1[l];
printf("%d,",temp6[l]);
//result = l + 1;
}
flag = 102,108,97,103,123,86,105,114,117,115,95,103,111,110,110,97,95,98,101,95,116,101,114,109,105,110,97,116,101,100,33,125
//flag{Virus_gonna_be_terminated!}
return 0;
}
8.方法确实有点小笨了,但还是做出来了捏!
三.红白机
1.这题没啥好说的,一开始拿到一个看不懂的汇编的代码,还是个txt文件,直接复制出来给GPT分析一手,ok,那就浅运行一手,这段汇编代码是为6502微处理器设计的,常见于一些早期的计算机系统,比如Commodore 64。如果想运行这段代码并查看结果,需要一个能够模拟或实际运行6502指令集的环境。直接上网搜了一个在线模拟器(Easy 6502 (codediy.github.io))
2.运行截图如下:
flag{6502_I_LOVE_u}
四.real checkin xor
1.这题是第二天主办方出的真的签到题,直接贴出脚本:
src = "ez_python_xor_reverse"
for i in range(len(secret)):
print(chr(secret[i]^ord(src[i%len(src)])),end='')
#begin{3z_PY7hoN_r3V3rSE_For_TH3_Be9inNEr!}
五.stick game
1.一道js逆向,我直接把js中所有的分数都修改成了目标分数,然后正常运行游戏,就出了。
2.如图
六.逆向工程(reverse)入门指南(Forensics)
1.打开是一个pdf文件,然后全选一手,左上角露出了马脚。
2.粘到记事本,就看到flag了。
begin{0kay_1_thiNK_YoU_Ar3_a1Re@DY_rE4D_6uiDe8ooK_AnD_9OT_FL46}