CGCTF-homuraVM

题目地址

ida打开F5主函数代码,要求输入一个字符串s

然后input[i+1]=s[i]
input[0]=s[len(s)-1]

之后把两个很长的字符串分别赋值到v39,v40

sub_8DC函数根据这两个字符串对input进行操作

sub_8AA不知道是干啥的,后百度得知是反调试

最后将处理过的input与给定的值对比,相同则ok

value1和value2初始值为0 i为很长的字符串的下标

读取到每个字符对应到的操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
case "C":*value2-=2*(*value1&*ipnut) ++i
case "G":--*value2 ++i
case "M":*value2=*value1+*input ++i
case "T":++*value2 ++i
case "[":if *input!=0 ++i
else i为]后一位
case "]":if *input!=0 i为[后一位
else ++i
case "a":--*value1 ++i
case "h":input=input+4 ++i
case "m":++*input ++i
case "o":input=input-4 ++i
case "r":++*value1 ++i
case "u":--*input ++i
case "v":*value2=*value1 ++i
case "{":if *value2!=0 ++i
else i为}后一位
case "}":if *value2!=0 i为{后一位
else ++i

注意到h是对input进行下标+1的操作,所以以h为分界线把很长的字符串分割开如下

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
h[ur]ovMCh{mG}
hv{aG}[ur]ovaaaMCh{mG}
hv{aG}[ur]ovrrMCh{mG}
hv{aG}[ur]ovrararaMCh{mG}
hv{aG}[ur]ovrararrrMCh{mG}
hv{aG}[ur]ovararaaMCh{mG}
hv{aG}[ur]ovrararraraMCh{mG}
hv{aG}[ur]ovrrrarrrMCh{mG}
hv{aG}[ur]ovaarrarrMCh{mG}
hv{aG}[ur]ovaaarrarMCh{mG}
hv{aG}[ur]ovrrrarrMCh{mG}
hv{aG}[ur]ovaarrraaMCh{mG}
hv{aG}[ur]ovarraarMCh{mG}
hv{aG}[ur]ovrrraaarrMCh{mG}
hv{aG}[ur]ovaaarrrrarrMCh{mG}
hv{aG}[ur]ovrrrraarrarrMCh{mG}
hv{aG}[ur]ovrrarraMCh{mG}
hv{aG}[ur]ovaaraarMCh{mG}
hv{aG}[ur]ovrrarraMCh{mG}
hv{aG}[ur]ovaarrrarMCh{mG}
hv{aG}[ur]ovrraarraMCh{mG}
hv{aG}[ur]ovrrarMCh{mG}
hv{aG}[ur]ovaarrarMCh{mG}
hv{aG}[ur]ovrrraarMCh{mG}
hv{aG}[ur]ovrrrraaMCh{mG}
hv{aG}[ur]ovrrarraMCh{mG}
hv{aG}[ur]ovrrrrrrMCh{mG}
hv{aG}[ur]ovaaaarMCh{mG}
hv{aG}[ur]ovrraaaMCh{mG}
hv{aG}[ur]ovaarraMCh{mG}
hv{aG}[ur]ovrrarMCh{mG}
hv{aG}[ur]ovaarraaMCh{mG}
hv{aG}[ur]ovaarraraMCh{mG}
hv{aG}[ur]ovaarrararMCh{mG}

其中,每条都有的部分为hv{aG}[ur]ov……MCh{mG}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[ur]: *value1=*input    *input减到0 
{aG}: *value1-=*value2 *value2减到0
{mG}: *input+=*value2 *value2减到0
hv{aG}[ur]ov……MCh{mG}:
input+=4
*value2=*value1
*value1-=*value2
*value2=0
*value1=*input
*input=0
input-=4
*value2=*value1
.
. 此部分仅ar数量及顺序不同,控制*value1
.
*value2=*value1+*input
*value2-=2*(*value1&*ipnut)
input+=4
*input+=*value2
*value2=0

作用为:
input[i+1]=(input[i]+ar处理过的input[i+1])-2*(ar处理过的input[i+1]&input[i])

不知道怎么逆运算,只能尝试爆破了,打算先求出被ar处理过的input[i+1]

1
2
3
4
5
6
7
8
import string
final=[27,114,17,118,8,74,126,5,55,124,31,88,104,7,112,7,49,108,4,47,4,105,54,77,127,8,80,12,109,28,127,80,29,96,]
ar=''
for i in range(33):
for s in string.printable:
if ord(s)+final[i]-2*(ord(s)&final[i])==final[i+1]:
ar+=s
print ar

得到ar处理后的flag从第二位开始为icg~B4{2KcG0oww6]h++m_{2wX\aqc/M}

接下来根据ar的个数进行逆运算即可:

1
2
3
4
5
6
operate=[+3,-2,0,-3,+2,-1,-5,-1,+1,-4,+1,0,-2,-2,-5,-2,+2,-2,-1,-1,-2,0,-2,-2,-2,-6,+3,+1,+1,-2,+2,+1,0]
final=list('icg~B4{2KcG0oww6]h++m_{2wX\\aqc/M}')
for i in range(len(operate)):
final[i]=chr(operate[i]+ord(final[i]))
flag=''.join(final)
print flag

得到flag第二位开始为lag{D3v1L_H0mur4_f**k_y0uR_bra1N}

很明显第一位为f 手动添加上

flag get

文章目录
|