常年不去上早八课的人,今天居然在八点前就醒了,要问为什么?这比赛从早上八点打到晚上八点>...<(悲)
不过,咱们队伍在下午就把逆向题ak了~居然没有坐牢到晚上(●'◡'●)
动态调试,题目里有个inline hook,在这里打个断点
那么网址就是Just_An_APIH00k11.com
die查一下壳
有sleep反调试,把sleep nop掉
这里读取了名称为cod的资源,用resource hacker
把资源复制下来
然后向下执行,这里是一个对cod资源进行解密的地方
这里要注意的是如果检测到调试器,那么byte_7FF6DA64F000[3]
将会被赋值为36
所以要把这个if语句通过修改ZF标志位的方式来绕过反调试
cod资源解密脚本如下
用ida打开,看到有花指令
nop一下,主要的改动有这几处
于是得到如下的伪代码
看算法是魔改的RC4,exp如下
查个壳,是python逆向
用pyinstxtractor
脱一下
用在线网站看一下ez_py.pyc的源代码
用ida反编译bin1失败,看来是被加密了
用这个代码看一下字节码
在最后面得到了这个
那么解密代码如下
反编译出来是这个
那根据提示我们把上面的解密脚本稍作修改
然后用ida反编译bin2__
那么这就是正常的逆向题了
btea
函数里面是这个,这是一个xxtea算法
写一下exp
在这个地方动调
可以发现数组的下标在0~12之间循环
我们随便打开一个BMP类型的文件,用010看看
对于BMP类型的文件前两个字节必定是43 4D
既然这个加密的bmp的每一个字节进行的都是异或,那我们可以将前两个字节异或看看
n和c是密钥enc_by_dasctf
的第2个和第3个字符,按照这个序列,我们向后将密钥向后延申看看后面的情况如何
所以我们写个脚本,从密钥的第二位开始,循环异或
得到flag
查一下壳,是go逆向
用这个脚本恢复一下go符号https://github.com/renshareck/IDAGolangHelper_SupportGo1.20
依次点击如下按钮
首先判断key正确与否,看来这是个rsa
用yafu解一下p和q
然后解出密钥
再往后看,
动调了一下看到iv和key都是一样的
所以直接写个exp把加密的文件解密
运行一下解密出的exe,就得到flag了
arr
=
[
0x18
,
0x57
,
0x68
,
0x64
]
with
open
(
'COD101.bin'
,
'rb'
) as f:
b
=
f.read()
b
=
bytearray(b)
for
i
in
range
(
len
(b)):
b[i]
=
b[i] ^ arr[i
%
4
]
with
open
(
'COD_de.bin'
,
'wb'
) as f:
f.write(b)
arr
=
[
0x18
,
0x57
,
0x68
,
0x64
]
with
open
(
'COD101.bin'
,
'rb'
) as f:
b
=
f.read()
b
=
bytearray(b)
for
i
in
range
(
len
(b)):
b[i]
=
b[i] ^ arr[i
%
4
]
with
open
(
'COD_de.bin'
,
'wb'
) as f:
f.write(b)
class
RC4:
def
__init__(
self
, key)
-
>
None
:
self
.key
=
key
self
.S
=
0
self
.__rc4_init__()
def
__rc4_init__(
self
):
S
=
[i
for
i
in
range
(
256
)]
j
=
0
for
i
in
range
(
256
):
j
=
(
2
*
j
+
S[i]
+
key[i
%
len
(key)])
%
256
S[i], S[j]
=
S[j], S[i]
self
.S
=
S
def
rc4_encrypt(
self
, plain)
-
>
list
:
i
=
0
j
=
0
cipher
=
[]
cnt
=
0
for
p
in
plain:
p
=
(p
+
256
-
cnt
%
0xd
)
%
256
cnt
+
=
1
i
=
(i
+
j)
%
256
j
=
(j
+
self
.S[i])
%
256
self
.S[i],
self
.S[j]
=
self
.S[j],
self
.S[i]
tmp
=
self
.S[(
self
.S[i]
+
self
.S[j]
+
j)
%
256
]
k
=
p ^ tmp
cipher.append(k)
return
cipher
key
=
[
0x5D
,
0x42
,
0x62
,
0x29
,
0x3
,
0x36
,
0x47
,
0x41
,
0x15
,
0x36
]
data
=
[
0xF7
,
0x2E
,
0x34
,
0xF0
,
0x72
,
0xCF
,
0x5E
,
0x0A
,
0xBB
,
0xEC
,
0xB1
,
0x2B
,
0x70
,
0x88
,
0x88
,
0xED
,
0x46
,
0x38
,
0xDB
,
0xDA
,
0x6C
,
0xBD
,
0xD4
,
0x06
,
0x77
,
0xF2
,
0xCF
,
0x56
,
0x88
,
0xC6
,
0x31
,
0xD2
,
0xB7
,
0x5A
,
0xC1
,
0x42
,
0xB0
,
0xF4
,
0x48
,
0x37
,
0xF5
,
0x2C
,
0xF5
,
0x58
]
rc4
=
RC4(key)
plain
=
rc4.rc4_encrypt(data)
print
(''.join(
map
(
chr
,plain)))
class
RC4:
def
__init__(
self
, key)
-
>
None
:
self
.key
=
key
self
.S
=
0
self
.__rc4_init__()
def
__rc4_init__(
self
):
S
=
[i
for
i
in
range
(
256
)]
j
=
0
for
i
in
range
(
256
):
j
=
(
2
*
j
+
S[i]
+
key[i
%
len
(key)])
%
256
S[i], S[j]
=
S[j], S[i]
self
.S
=
S
def
rc4_encrypt(
self
, plain)
-
>
list
:
i
=
0
j
=
0
cipher
=
[]
cnt
=
0
for
p
in
plain:
p
=
(p
+
256
-
cnt
%
0xd
)
%
256
cnt
+
=
1
i
=
(i
+
j)
%
256
j
=
(j
+
self
.S[i])
%
256
self
.S[i],
self
.S[j]
=
self
.S[j],
self
.S[i]
tmp
=
self
.S[(
self
.S[i]
+
self
.S[j]
+
j)
%
256
]
k
=
p ^ tmp
cipher.append(k)
return
cipher
key
=
[
0x5D
,
0x42
,
0x62
,
0x29
,
0x3
,
0x36
,
0x47
,
0x41
,
0x15
,
0x36
]
data
=
[
0xF7
,
0x2E
,
0x34
,
0xF0
,
0x72
,
0xCF
,
0x5E
,
0x0A
,
0xBB
,
0xEC
,
0xB1
,
0x2B
,
0x70
,
0x88
,
0x88
,
0xED
,
0x46
,
0x38
,
0xDB
,
0xDA
,
0x6C
,
0xBD
,
0xD4
,
0x06
,
0x77
,
0xF2
,
0xCF
,
0x56
,
0x88
,
0xC6
,
0x31
,
0xD2
,
0xB7
,
0x5A
,
0xC1
,
0x42
,
0xB0
,
0xF4
,
0x48
,
0x37
,
0xF5
,
0x2C
,
0xF5
,
0x58
]
rc4
=
RC4(key)
plain
=
rc4.rc4_encrypt(data)
print
(''.join(
map
(
chr
,plain)))
import
ctypes
from
time
import
*
from
ctypes
import
*
from
ctypes
import
wintypes
from
hashlib
import
md5
class
_STARTUPINFO(Structure):
_fields_
=
[
(
'cb'
, c_ulong),
(
'lpReserved'
, c_char_p),
(
'lpDesktop'
, c_char_p),
(
'lpTitle'
, c_char_p),
(
'dwX'
, c_ulong),
(
'dwY'
, c_ulong),
(
'dwXSize'
, c_ulong),
(
'dwYSize'
, c_ulong),
(
'dwXCountChars'
, c_ulong),
(
'dwYCountChars'
, c_ulong),
(
'dwFillAttribute'
, c_ulong),
(
'dwFlags'
, c_ulong),
(
'wShowWindow'
, c_ushort),
(
'cbReserved2'
, c_ushort),
(
'lpReserved2'
, c_char_p),
(
'hStdInput'
, c_ulong),
(
'hStdOutput'
, c_ulong),
(
'hStdError'
, c_ulong)]
class
_PROCESS_INFORMATION(Structure):
_fields_
=
[
(
'hProcess'
, c_void_p),
(
'hThread'
, c_void_p),
(
'dwProcessId'
, c_ulong),
(
'dwThreadId'
, c_ulong)]
StartupInfo
=
_STARTUPINFO()
ProcessInfo
=
_PROCESS_INFORMATION()
key1
=
bytes(md5(b
'bin1bin1bin1'
).hexdigest().encode())
file
=
open
(
'bin1'
,
'rb'
).read()
arr
=
range
(
len
(
file
))()
open
(
'bin1'
,
'wb'
).write(bytes(arr))
sleep(
0
)
bet
=
ctypes.windll.kernel32.CreateProcessA(b
'bin1'
, ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), byref(StartupInfo), byref(ProcessInfo))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ProcessInfo.hProcess), ctypes.c_int(
-
1
))
open
(
'bin1'
,
'wb'
).write(
file
)
import
ctypes
from
time
import
*
from
ctypes
import
*
from
ctypes
import
wintypes
from
hashlib
import
md5
class
_STARTUPINFO(Structure):
_fields_
=
[
(
'cb'
, c_ulong),
(
'lpReserved'
, c_char_p),
(
'lpDesktop'
, c_char_p),
(
'lpTitle'
, c_char_p),
(
'dwX'
, c_ulong),
(
'dwY'
, c_ulong),
(
'dwXSize'
, c_ulong),
(
'dwYSize'
, c_ulong),
(
'dwXCountChars'
, c_ulong),
(
'dwYCountChars'
, c_ulong),
(
'dwFillAttribute'
, c_ulong),
(
'dwFlags'
, c_ulong),
(
'wShowWindow'
, c_ushort),
(
'cbReserved2'
, c_ushort),
(
'lpReserved2'
, c_char_p),
(
'hStdInput'
, c_ulong),
(
'hStdOutput'
, c_ulong),
(
'hStdError'
, c_ulong)]
class
_PROCESS_INFORMATION(Structure):
_fields_
=
[
(
'hProcess'
, c_void_p),
(
'hThread'
, c_void_p),
(
'dwProcessId'
, c_ulong),
(
'dwThreadId'
, c_ulong)]
StartupInfo
=
_STARTUPINFO()
ProcessInfo
=
_PROCESS_INFORMATION()
key1
=
bytes(md5(b
'bin1bin1bin1'
).hexdigest().encode())
file
=
open
(
'bin1'
,
'rb'
).read()
arr
=
range
(
len
(
file
))()
open
(
'bin1'
,
'wb'
).write(bytes(arr))
sleep(
0
)
bet
=
ctypes.windll.kernel32.CreateProcessA(b
'bin1'
, ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), ctypes.c_int(
0
), byref(StartupInfo), byref(ProcessInfo))
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ProcessInfo.hProcess), ctypes.c_int(
-
1
))
open
(
'bin1'
,
'wb'
).write(
file
)
import
marshal, dis
f
=
open
(
"ez_py.pyc"
,
"rb"
).read()
code
=
marshal.loads(f[
16
:])
dis.dis(code)
import
marshal, dis
f
=
open
(
"ez_py.pyc"
,
"rb"
).read()
code
=
marshal.loads(f[
16
:])
dis.dis(code)
Disassembly of <code
object
<listcomp> at
0x00000297CC7F8E70
,
file
"ez_py.py"
, line
59
>:
59
0
RESUME
0
2
BUILD_LIST
0
4
LOAD_FAST
0
(.
0
)
>>
6
FOR_ITER
50
(to
108
)
8
STORE_FAST
1
(i)
10
LOAD_GLOBAL
0
(key1)
22
LOAD_FAST
1
(i)
24
LOAD_GLOBAL
3
(NULL
+
len
)
36
LOAD_GLOBAL
0
(key1)
48
PRECALL
1
52
CALL
1
62
BINARY_OP
6
(
%
)
66
BINARY_SUBSCR
76
LOAD_GLOBAL
4
(
file
)
88
LOAD_FAST
1
(i)
90
BINARY_SUBSCR
100
BINARY_OP
12
(^)
104
LIST_APPEND
2
106
JUMP_BACKWARD
51
(to
6
)
>>
108
RETURN_VALUE
Disassembly of <code
object
<listcomp> at
0x00000297CC7F8E70
,
file
"ez_py.py"
, line
59
>:
59
0
RESUME
0
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2023-6-5 13:09
被oacia编辑
,原因: