Whali3n51's blog

  • 主页
  • 关于
  • 友链
  • 标签
  • 分类
Writeup

桂电RE全解WriteUp

Whali3n51 发布于 2019-05-29

0x01
这个题我首先就没有思路,我一直认为是有函数对代码段进行破坏了,然后动调一直无果,所以这题没有做出来。最后还是看北联大佬说了一句加了UPX壳。对不起,我真的很菜,我真的看不出来这里加了壳,linux程序加upx壳我还是第一次听说。然后这我是我赛后做出来的。
知道了加了upx壳,这个简单了,脱掉就好了,使用工具upx -d,直接脱掉了
载入IDA,程序主流程如下

关键判断地方
Sub_4009ae如下

看到一堆判断

到这了才不会返回零,然后计算出前几个判断,发现这些判断就是flag

最后脚本解密

1
2
3
4
5
6
7
8
9
10
key=[0x9E77500,0x2B9740C0,0x154B2280,0x4009EFA8,489211344,518971936,406741500,294236496,177305856,650683500,298351053,386348487,438258597,249527520,445362764,174988800,981182160,493042704,257493600,767478780,312840624,1404511500,316139670,619005024,372641472,373693320,498266640,452465676,208422720,515592000,719890500]
key2=[1629056,6771600,3682944,10431000,3977328,5138336,7532250,5551632,3409728,13013670,6088797,7884663,8944053,5198490,4544518,3645600,10115280,9667504,5364450,13464540,5488432,14479500,6451830,6252576,7763364,7327320,8741520,8871876,4086720,9374400,5759124]
index=0
flag=''
for i in range(len(key)):
index=key[i]//key2[i]
flag+=chr(index)
print(flag)

flag:flag{e65421110b0a3099a1c039337}

但是验证不对,再回看函数

没对*(a1+6)进行判断,第六位输入任意的值就OK
Flag: flag{e565421110ba03099a1c039337}

0x02

整个程序的大致流程就在这里了
到第一个函数去看看

在看这个函数的参数,这个函数和我们输入的值一点关系都没有,这里只是在生成一些数

在到这一步,看到生成的值和我们输入的值每一个字节的异或。

这一步就是改了base64的加密算法。正常的base64的a3数组存放的事索引值,但是这里没有用到base64的码表,而是隐式的使用了码表,这里就是将base64的每一个索引值都加上61,所以这里理解了也就是常规的加密了。

最后就是将加密好的字符串和这个字符串做比较

好了,程序理解到这里了,很简单,但是写出解题脚本就有点坑了。
现在我们可以这样思考,将字符串的每一位减去61就是我们正常base64加密的索引值了。然后我们根据这个索引值去正常的码表找字符最后得到的就是正常的base64加密了,然后用正常的base64解题脚本,就会解除这么一堆数字。

1
0x75,0xd5,0xfd,0xf5,0x7d,0x47,0xfe,0x95,0x13,0x7a,0x26,0x59,0x3f,0xff,0x31,0xa1,0x85,0x7c,0x63,0x2,0x6e,0xbd,0x93,0x6a,0x3e,0x4d,0x8d,0xd7,0x27,0x73,0x2d,0x5e,0xcc,0x62,0xf2,0xdf,0xe5,0xd2

然后就需要和前面生成好的数字异或回去,生成好的数字可以动调出来

1
0x10,0x59,0x9c,0x92,0x06,0x22,0xcf,0xa5,0x72,0x1e,0x45,0x6a,0x06,0xcb,0x08,0xc3,0xe4,0x49,0x5a,0x63,0x0c,0xdf,0xf6,0x5f,0x08,0x28,0xbd,0xe2,0x10,0x15,0x1f,0x6e,0xaa,0x5a,0xca,0xec,0x80,0xaf,0x9b,0x16,0xbb,0x3d,0x13,0x2f,0x6a,0xa4,0xc7,0x2e,0xbc

最关键的就是在这个地方了吗,还是自己太菜了,这个异或之后会出现负数,当时我解出来的时候就一直没明白这个负数是怎么生成的,我一直怀疑base64的算法出了问题,我就一点点分析base64的算法。可是最后问题出在unsigned这里。我一直没明白过来,直到最后我自己试着将异或之后的值转换为unsigned char之后这一题就解出来了。关键的坑就是在unsigned这个地方,这位置我爬了两天,哭了,太菜了。

0x03
这一题很无脑,400分,爆破出来的

函数主流程
第一个判断

判断输入的字符串是0~4,然后10位的长度
在看后面的算法



没整明白什么事,然后看字符大小和长度可以爆破,直接爆破了
Exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import os

def Judge(i):
result = os.popen('echo ' + str(i) + '|./number_game')
res = result.read()
for line in res.splitlines():
print(line)
if line.find('flag') != -1:
return True
return False

for i1 in range(0, 5):
for i2 in range(0, 5):
for i3 in range(0, 5):
for i4 in range(0, 5):
for i5 in range(0, 5):
for i6 in range(0, 5):
for i7 in range(0, 5):
for i8 in range(0, 5):
for i9 in range(0, 5):
for i10 in range(0, 5):
password = str(i1) + str(i2) + str(i3) + str(i4) + str(i5) + str(i6) + str(
i7) + str(i8) + str(i9) + str(i10)
print('Password:' + password)
if Judge(password):
print(password)
exit(0)

大概花了40几分钟
Flag:flag{1134240024}
直接出来了。

  • #RE
Newer

强网杯:强网先锋_AP_Pwn writeup

Older

西湖论剑testre

© 2023 Whali3n51