程序刚下载下来就被杀了,似乎“来者不善”。试运行下:
静态分析,发现有壳,而且壳的代码里比较大,其中的大量的栈上异或编码过的字串和crc32计算代码。纯静态比较难看出什么了,于是转动态。
由于静态没有看出OEP在哪,于是直接运行,然后attach上去,dump出PE文件。此时dump的PE文件主要代码是可以看的,只不过区段信息不正确,入口不对,导入表未修复。继续静态看dump出来的PE文件。从字符串入手,找到了主函数,从而找到了入口在0x402F59,此过程中发现了一些反调试,如:主函数的crc32校验、ZwQueryInformationProcess调用、32位和64位代码执行环境的转换等。然后反调试细看了下,包括壳运行期间起的反调试线程,发现其对于业务流程和算法没有影响,所以并没有过多的纠结,主要分析主函数sub_4012B0。
这部分代码涉及导入函数的不多,可以不用修复导入表,壳将导入函数地址写在了堆上,并用异或操作进行的处理,虽说恢复不难,但没有必要。个别的手动标注下就好。整理代码后,了解到,主函数的主要流程是:
所以大概意思是:从0-89(360的输入长度,可取的最大非负数字为89)取12个数字记为n,要求n中的数字两两之差唯一,且n[1]-n[0] < n[11]-n[10]。找到满足条件的12个数后,再将其转换成相应的随机数,这些随机数就是答案了。
手动凑了下,发现11个满足条件的数是比较容易找到的。于是在小伙伴的帮助下,开始以差唯一为突破口,开始暴力搜索。代码如下:
结果:12个非负数为[0, 2, 6, 24, 29, 40, 43, 55, 68, 75, 76, 85],答案为675E7A025B4786190D65933042199F472513AB5E312AB8753E41C40C4A58D023566FDD3A6306E9516F1DF5687B340100D3490E1794621A2EA0793450AD10335CB9273F73C53E4B0AD1555821DE6C64387111704FF61ADE2E0332897D0F4995141B60A12B2877AE42340EBA59402594244D3CD3075953DF1E656AEB357101F84C7E1804648A2F107BC44E1D12A35D2929AF743540BB0B193E93724E6ED4395A05E050661CED677333F97EDC4A
由于输入并未超过最大输入长度,且后面加负数对应的随机值对程序校验没有影响,所以还有4个解,分别附加0516、05168B61、05168B61112D、05168B61112D9878。
PS C:\Users\admin\Downloads\kctf2020\
2
> .\CrakMe.exe
Input
Serial:
123
一个礼貌的开场白还是要的
PS C:\Users\admin\Downloads\kctf2020\
2
> .\CrakMe.exe
Input
Serial:
123
一个礼貌的开场白还是要的
def
check(n):
n_len
=
len
(n)
n_num
=
(n_len
-
1
)
*
n_len
/
/
2
t
=
[]
for
i
in
range
(n_len):
for
j
in
range
(i
+
1
,n_len):
t.append(n[j]
-
n[i])
return
len
(
list
(
set
(t)))
=
=
n_num
def
g(n):
n_len
=
len
(n)
t
=
[]
for
i
in
range
(n_len):
for
j
in
range
(i
+
1
,n_len):
t.append(n[j]
-
n[i])
return
t
class
node:
def
__init__(
self
,state,lmin):
self
.state
=
state
self
.lmin
=
lmin
def
search():
while
len
(s)>
0
:
x
=
s.pop()
base
=
[i
for
i
in
range
(x.lmin
+
1
,
90
)]
q
=
list
(
set
(base)
-
set
(g(x.state)))
for
i
in
q:
if
i > x.lmin:
y
=
x.state.copy()
y.append(i)
y.sort()
if
check(y):
s.append(node(y,i))
if
len
(y)
=
=
12
:
print
(y)
input
(
'next?'
)
search()
return
s
=
[]
t
=
node([
0
],
0
)
s.append(t)
search()
def
check(n):
n_len
=
len
(n)
n_num
=
(n_len
-
1
)
*
n_len
/
/
2
t
=
[]
for
i
in
range
(n_len):
for
j
in
range
(i
+
1
,n_len):
t.append(n[j]
-
n[i])
return
len
(
list
(
set
(t)))
=
=
n_num
def
g(n):
n_len
=
len
(n)
t
=
[]
for
i
in
range
(n_len):
for
j
in
range
(i
+
1
,n_len):
t.append(n[j]
-
n[i])
return
t
class
node:
def
__init__(
self
,state,lmin):
self
.state
=
state
self
.lmin
=
lmin
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课