avatar

目录
2020网鼎杯RE WP

2020网鼎杯RE WP

re_bang

jeb拖进去一看,梆梆加固免费版,掏出Frida直接dump,具体可看之前写的这篇 使用Frida给apk脱壳并穿透加固Hook函数

dump出三个dex,看下大小基本确定了解密后的dex

由于分析dex不太舒服,就直接转jar拿jd-gui看了,没想到flag直接硬编码。

signal

简易VM,没什么可说的,进去就能看到逻辑

先把opcode提取出来,456个字节,把0去了,还剩114字节(456/4)

Code
10,4,16,8,3,5,1,4,32,8,5,3,1,3,2,8,11,1,12,8,4,4,1,5,3,8,3,33,1,11,8,11,1,4,9,8,3,32,1,2,81,8,4,36,1,12,8,11,1,5,2,8,2,37,1,2,54,8,4,65,1,2,32,8,5,1,1,5,3,8,2,37,1,4,9,8,3,32,1,2,65,8,12,1,7,34,7,63,7,52,7,50,7,114,7,51,7,24,7,167,255,255,255,7,49,7,241,255,255,255,7,40,7,132,255,255,255,7,193,255,255,255,7,30,7,122

然后看vm操作,就12个case

解法1

直接写脚本提取一下看看(骚操作之print指令)

python
code=[
10,4,16,8,3,5,1,4,32,8,5,3,1,3,2,8,
11,1,12,8,4,4,1,5,3,8,3,33,1,11,8,
11,1,4,9,8,3,32,1,2,81,8,4,36,1,12,
8,11,1,5,2,8,2,37,1,2,54,8,4,65,1,2,
32,8,5,1,1,5,3,8,2,37,1,4,9,8,3,32,1,
2,65,8,12,1,7,34,7,63,7,52,7,50,7,114,
7,51,7,24,7,167,255,255,255,7,49,7,241,
255,255,255,7,40,7,132,255,255,255,7,
193,255,255,255,7,30,7,122]

i = 0
v9 = 0
v8 = 0
v7 = 0
v6 = 0

while ( 1 ):
result = i
#print(code[i])
if i >= 114 :
print(result)
exit(0)
elif code[i] == 1:
print("v4[v7] = v5")
i+=1
print("v7+=1")
print("v9+=1")
elif code[i] == 2:
print("v5 = code[i + 1] + Str[v9]")
i += 2
elif code[i] == 3:
print("v5 = Str[v9] - LOBYTE(code[i + 1])")
i += 2
elif code[i] == 4:
print("v5 = code[i + 1] ^ Str[v9]")
i += 2
elif code[i] == 5:
print("v5 = code[i + 1] * Str[v9]")
i += 2
elif code[i] == 6:
i+=1
elif code[i] == 7:
print("if ( v4[v8] != code[i + 1] ){ printf(\"what a shame...\");exit(0);}v8+=1")
i += 2
elif code[i] == 8:
print("Str[v6] = v5")
i+=1
print("v6+=1")
elif code[i] == 10:
print("read(Str)")
i+=1
elif code[i] == 11:
print("v5 = Str[v9] - 1")
i+=1
elif code[i] == 12:
print("v5 = Str[v9] + 1")
i+=1
else:
i+=1
continue

得到

python
read(Str)

v5 = code[i + 1] ^ Str[v9]
Str[v6] = v5
v6+=1
v5 = Str[v9] - LOBYTE(code[i + 1])
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] ^ Str[v9]
Str[v6] = v5
v6+=1
v5 = code[i + 1] * Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = Str[v9] - LOBYTE(code[i + 1])
Str[v6] = v5
v6+=1
v5 = Str[v9] - 1
v4[v7] = v5
v7+=1
v9+=1

v5 = Str[v9] + 1
Str[v6] = v5
v6+=1
v5 = code[i + 1] ^ Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] * Str[v9]
Str[v6] = v5
v6+=1
v5 = Str[v9] - LOBYTE(code[i + 1])
v4[v7] = v5
v7+=1
v9+=1

v5 = Str[v9] - 1
Str[v6] = v5
v6+=1
v5 = Str[v9] - 1
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] ^ Str[v9]
Str[v6] = v5
v6+=1
v5 = Str[v9] - LOBYTE(code[i + 1])
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] + Str[v9]
Str[v6] = v5
v6+=1
v5 = code[i + 1] ^ Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = Str[v9] + 1
Str[v6] = v5
v6+=1
v5 = Str[v9] - 1
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] * Str[v9]
Str[v6] = v5
v6+=1
v5 = code[i + 1] + Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] + Str[v9]
Str[v6] = v5
v6+=1
v5 = code[i + 1] ^ Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] + Str[v9]
Str[v6] = v5
v6+=1
v5 = code[i + 1] * Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] * Str[v9]
Str[v6] = v5
v6+=1
v5 = code[i + 1] + Str[v9]
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] ^ Str[v9]
Str[v6] = v5
v6+=1
v5 = Str[v9] - LOBYTE(code[i + 1])
v4[v7] = v5
v7+=1
v9+=1

v5 = code[i + 1] + Str[v9]
Str[v6] = v5
v6+=1
v5 = Str[v9] + 1
v4[v7] = v5
v7+=1
v9+=1

if ( v4[v8] != code[i + 1] )
{
printf("what a shame...");exit(0);
}
v8+=1

还是挺有规律的,一组就是一个handle,借个看雪的分析吧,自己的太乱

Code
10h ^ input[1]-5 = 22h
(20h ^input[2])*3=3Fh
input[3]-2-1=34h
(input[4]+1 )^4 =32 h
input[5]*3-21h=72h
input[6]-1-1=33h
9^input[7]-20=18
(51h +input[8])^24h=FA7
input[9]+1-1=31h
2*input[10]+25h=F1h
(36h+input[11]) ^41h =28h
(20h + input[12])*1=F84h
3*input[13]+25h=C1h
9^input[14]-20h=1E h
41h + input[15] +1 =7A h

这么头铁的解法当然是不够优雅的,且看下面符号执行

解法2

angr直接跑

python
import angr
p = angr.Project('signa.exe')
st = p.factory.entry_state()
sm = p.factory.simulation_manager(st)
sm.explore(find=0x40179E, avoid=0x4016E6)
print(sm.found[0].posix.dumps(0))

几秒钟完事,十分枯燥

jocker

这道题怎么说,男默女泪,最后四个字节还得靠猜???

ida看一下,是简单的SMC

直接od调到解密后dump出来,要解密的地址是401500

dump以后再用ida看看,一共解密出两个函数

查看401500

写脚本逆一下

python
key2 = [0x0E, 0x0D, 0x09, 0x06, 0x13, 0x05, 0x58, 0x56, 0x3E, 0x06, 0x0C, 0x3C, 0x1F, 0x57, 0x14, 0x6B, 0x57, 0x59, 0x0D]
key3 = [37,116,112,38,58]
code = list("hahahaha_do_you_find_me?")

for i in range(19):
str = key2[i]^ord(code[i])
print(chr(str),end="")

得到一部分flag

Code
flag{d07abccf8a410c

未解密前有个假flag

python
key1=[0x66, 0x6B, 0x63, 0x64, 0x7F, 0x61, 0x67, 0x64, 0x3B, 0x56, 0x6B, 0x61, 0x7B, 0x26, 0x3B, 0x50, 0x63, 0x5F, 0x4D, 0x5A, 0x71, 0x0C, 0x37, 0x66]

for i in range(len(key1)):
if i & 1:
key1[i] +=i
else:
key1[i] ^=i
print(chr(key1[i]),end="")

# flag{fak3_alw35_sp_me!!}

比较发现还少5个字符,当然了,最后一个肯定是}

再看看另一个函数

看到剩下五个字符,不过被加密了

这就纯靠猜了

最后v7肯定是}加密过来的,试试这两个异或,得到71,其他四个字符都异或71,最后得到b37a}拼起来就行。

或者。。。直接爆破

python
import subprocess

li=['a', 'b', 'c', 'd', 'e', 'f','0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

pname='C:\\jocker.exe'

for i in li:
for j in li:
for k in li:
for m in li:
print(i,j)
source="flag{d07abccf8a410c"+i+j+k+m+"}"
p = subprocess.Popen(pname, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
source = source.encode(encoding='UTF8')
result = p.communicate(input=source)
res=result[0].decode()[0:]
if 'Really' in res:
print(result)
print(source)
文章作者: kabeor
文章链接: https://kabeor.github.io/2020%E7%BD%91%E9%BC%8E%E6%9D%AFRE_WP/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 K's House

评论