whctf2016 re100 wp

Author Avatar
Xzhah 7月 02, 2017
  • 在其它设备中阅读本文章

####whctf2016 re100(wp)
cflag.png

* 目的

哇,为什么2017年还要贴2016的题呢。本来是最近在学符号执行,想着找个简单的题用angr跑一跑,学习一个。
结果发现,我真的是图样图森破啊!angr在里面给跑死了。个人觉得原因是里面的加密处理的时候后面会把一
个变量左移30多位(乘以2的30多次方),还有这种操作。angr怕是想哭。

* 思路

这道题very简单,其核心加密如下
encry.png
就是如果输入的字符串中有字符是”Just try your best and enjoy yourself!”其中一个的话,把他*16+k就行了。
(k就是”Just…”里的某个字符)
如果不是其中一个…就没天理了啊!循环到后面,seeda可以取30多,k左移三十多位,你遭不遭得住?

* 解决办法

输入字符在与左移了seeda位后的k值异或然后取余。
因为a^b=m 就有m^a=b。所以我们只要求得m和k,就能得到要输入的字符串啦。因为要求取余后的数等于以下数组的元素
encry1.png
所以我们知道,m为该数组元素+k*2500.a为一个字符的话,|a^b-a|<256。所以有如下脚本:

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
28
29
30
31
32
33
34
35
36
37
38
def getclose(a,b,c,d): #使a,b绝对值相差不超过256,因为输入的值的ASCII码不会超过256.异或处理低八位会受影响,但是高位不受影响所以差值不超过256
if abs(a-b)<256:
return a
if b>a:
a=(b/c-1)*2500+a
while abs(a-b)>=256:
if a>b:
print "error"
os._exit(0)
a=a+c
if b<0:
a=(b/2500)*2500+a
while abs(a-b)>=256:
if a<b:
print "error"
os._exit(0)
a=a-c
if abs(a-b)>=256:
print "error"
return a
key1="Just try your best and enjoy yourself!"
key2=[157,2400,2215,1971,1732,1527,2053,1878,1988,787,1584,1856,1717,2187,1971,34,1732,1259,1669,1726,1946,1967,1369]
flag=""
k=1
for a in key2:
m=a-ord(key1[k])
if m<0:
m=m+2500
m=m/16
if not(chr(m) in key1):
m=a
z=ord(key1[k])<<k
m=getclose(m,z,2500,256)
m=m^z
flag=flag+chr(m)
k=(k+5)%len(key1)
print flag

* 最后

answer.png

得到flag是whctf{you_are_the_best}