0x00 题目分析

关于AutoIt:https://www.autoitscript.com/site/autoit/

感觉autoit可以类比为lua,都是脚本语言,而且都利用到了虚拟机技术

不过autoit设计用于Windows GUI(图形用户界面)中进行自动化操作,其他脚本语言好像不能做到

使用动调或者IDA比较耗时间,据官方说法在v3.2.5.1后autoit不再拥有自带的反编译工具,不过对应的虚拟指令含义有大哥分析出来了,而且有工具可以快速获取源码

AutoIt-Ripper:https://github.com/nazywam/AutoIt-Ripper

0x01 解

查壳,这次换个软件

运行一下,随便输点东西看看

用pip安装autoit-ripper后直接扒皮

打开.au3,搜一下”wrong”

分析加密流程,首先判断输入是否满足38位,如果满足,则将输入经过ENC函数加密,ENC函数如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Func ENC ( $DATA , $KEY )
$DATA = Binary ( $DATA )
Local $DATALEN = BinaryLen ( $DATA )
If $DATALEN = 0 Then
Return ""
ElseIf $DATALEN < 8 Then
$DATALEN = 8
EndIf
Local $OPCODE = "0x83EC14B83400000099538B5C2420558B6C242056578B7C9DFCF7FB89C683C606C74424180000000085F68D76FF0F8EEA000000896C24288D4BFF8D549D00894C2410895424148974242081442418B979379E8B4C2418C1E90281E103000000894C241C31F6397424107E568B5424288BCF8B6CB204C1E9058D14AD0000000033CA8BD58BC7C1EA03C1E00433D003CA8B5424188BDE81E303000000335C241C8B4424308B1C9833D533DF03D333CA8B542428010CB28B0CB2463974241089CF7FAA8B5424288BCF8B2AC1E9058D14AD0000000033CA8BD58BC7C1EA03C1E00433D003CA8B5424188BDE81E303000000335C241C8B4424308B1C9833D533DF03D3FF4C242033CA8B542414014AFC8B4AFC8B54242089CF420F8F2DFFFFFF5F31C05E5D5B83C414C21000"
Local $CODEBUFFER = DllStructCreate ( "byte[" & BinaryLen ( $OPCODE ) & "]" )
DllStructSetData ( $CODEBUFFER , 1 , $OPCODE )
Local $V = DllStructCreate ( "byte[" & Ceiling ( $DATALEN / 4 ) * 4 & "]" )
DllStructSetData ( $V , 1 , $DATA )
Local $K = DllStructCreate ( "byte[16]" )
DllStructSetData ( $K , 1 , $KEY )
DllCall ( "user32.dll" , "none" , "CallWindowProc" , "ptr" , DllStructGetPtr ( $CODEBUFFER ) , "ptr" , DllStructGetPtr ( $V ) , "int" , Ceiling ( $DATALEN / 4 ) , "ptr" , DllStructGetPtr ( $K ) , "int" , 0 )
Local $RET = DllStructGetData ( $V , 1 )
$CODEBUFFER = 0
$V = 0
$K = 0
Return $RET
EndFunc

函数动态加载了一个dll,然后再从dll调用加密函数进行加密

OPCODE写入文件再用IDA分析

老朋友TEA但是是XXTEA

编脚本

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
39
40
41
42
43
44
45
46
47
48
49
50
import binascii
from ctypes import *
import struct


def MX(z, y, total, key, p, e):
temp1 = (z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value << 4)
temp2 = (total.value ^ y.value) + (key[(p & 3) ^ e.value] ^ z.value)

return c_uint32(temp1 ^ temp2)


def decrypt(n, v, key):
delta = 0x61C88647
rounds = 6 + 52 // n

total = c_uint32(-rounds * delta)
y = c_uint32(v[0])
e = c_uint32(0)

while rounds > 0:
e.value = (total.value >> 2) & 3
for p in range(n - 1, 0, -1):
z = c_uint32(v[p - 1])
v[p] = c_uint32((v[p] - MX(z, y, total, key, p, e).value)).value
y.value = v[p]
z = c_uint32(v[n - 1])
v[0] = c_uint32(v[0] - MX(z, y, total, key, 0, e).value).value
y.value = v[0]
total.value += delta
rounds -= 1

return v


if __name__ == "__main__":
ct = "7218181A02F79F4B5773E8FFE83FE732DF96259FF2B86AAB945468A132A83D83CF9D750E316C8675"
ct = binascii.a2b_hex(ct)
flag = ""
key = "Wowww111auUu3"
v = struct.unpack('<10I', ct)
k = struct.unpack('<4I', key.encode() + b'\x00' * 3)
v = list(v)
k = list(k)
n = 10
res = decrypt(n, v, k)
for r in res:
print(r.to_bytes(4, 'little').decode(), end='')

# DASCTF{Oh1_autO1t_iS_so_Co0oL_aNd_Fun}