reverse-write-up

第三届上海市大学生网络安全大赛Crackme

download
用PEID查壳,发现结果如下:

1_1
用od加载手动脱壳:
1_2
看见pushfd pushad,用ESP定律脱壳,先调试到004061AD,然后在寄存器窗口右键单击ESP 0018FF68,选择HW break[ESP](下硬件断点)。然后F9,跳到popfd
1_3
看见下面的跳转指令跨度很大,说明接近OEP了。F8跳转,如果出现大段dd,按Ctrl+A让od重新识别。
1_4
看见004101621,F7进去后看见OEP,脱壳成功。

接下来查找字符串Please Input Flag:,找到之后跳转,我们来到了主要的处理部分,下断dump程序。
1_5

利用LordPE成功dump程序后(注意管理员权限),IDA打开,F5,可以看见程序逻辑。
1_6

可以看出flag长度为42,且与402130异或后为402150的数据,我们用od打开,修改代码。
1_7
运行到这里时,我们修改ecx的值为0x2A(42),让它继续运行。
1_8
在这里我们看到了算法代码,那么我们修改代码,让this_is_not_flag和402150的数据异或,就能得到flag了。
1_9

感谢吴神的指导

JCTF 2014 re200

download
拿到文件查看文件格式是MS-DOS,拖到IDA发现PE结构有问题,修改PE结构。将Offset to New EXE Header从E9改为E8。往下看,PE开头还有问题,将FF改为00。保存文件,拖到IDA打开。
2_1
可以看到题目要求输入长度为9位,前三位要满足相应的条件:

1
2
3
i * j * k / 11 = 106 
k = i ^ j
(i + j + k) % 100 = 34

继续看。
2_2
我们发现了flag的构成方式,是由jlflag{和中间三个数再加上abc}拼接而成,中间三个数只和我们输入的前三个数有关,尽管之后还有判断流程,但是为了省事,我们直接写题解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void re200()
{
for (size_t i = 0; i < 0x100000; ++i)
{
for (size_t j = 0; j < 0x100000; ++j)
{
size_t k = (i ^ j) + 4;
if (i * j * k / 0xb == 0x6a && (i + j + k) % 100 == 0x22)
{
printf("jlflag{");
printf("%d%d%d", i, j, k);
printf("abc}\n");
// return 1;
}
}
}
return;
}

然后挨个试,最后结果是jlflag{15613abc}

得复习一下PE头的知识了

2017全国大学生信息安全竞赛

填数游戏

download

题目是填数游戏,做题的时候就朝着这个方向去想。

把题目拖进IDA,就能够看到主要的函数。
3_1_1
发现要success要checkv4的值,我们进入check函数。
3_1_2
进入check函数,看见有三个部分:
check_block(),check_col(),check_row函数,分别查看这三个函数:
3_1_3
3_1_4
3_1_5
可见check_col()check_row()几乎一样,一个检查列,一个检查行,而check_block()则是检查一个3x3的块,这让我们想到了数独。继续看:
3_1_6
除了检查函数,我们还发现了相关set_data()函数,进入函数,我们看到这里是来填数字的,那么这个函数在主函数的参数一定有这个数独的数据,果不其然,我们查看__data_start__,发现了一个很大的数组:
3_1_7
将数据拷贝出来,处理格式。

本人不会idc……就只能拷出来处理了,注意处理的时候要把db改成dd。

1
2
3
4
5
6
7
8
9
0 0 7 5 0 0 0 6 0
0 2 0 0 1 0 0 0 7
9 0 0 0 3 0 4 0 0
2 0 1 0 0 0 0 0 0
0 3 0 1 0 0 0 0 5
0 0 0 0 0 0 7 1 0
4 0 0 0 0 8 2 0 0
0 0 5 9 0 0 0 8 0
0 8 0 0 0 1 0 0 3

放到在线解数独的网站上,解出结果。
3_1_8
然后把题目原有的数字都替换成0,即为题解:
340089102508406930016207058060875349709064820854392006093650071170023604602740590

感谢 https://www.cnblogs.com/zhaijiahui/p/7876005.html 给我的提示,不然确实想不到是数独……

溯源

download

实话说,这道题没做出来……参考链接如下:

把文件拖入IDA,然后直接就能看到关键字符串,对核心代码进行分析:
3_2_1
详细的分析可以看我上面发的两个链接……然后写题解……

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python2
# -*- coding:utf-8 -*-

import string
import copy

dir_array = [160, 142, 226, 128, 189, 158, 130, 145, 29, 181, 223, 138, 200, 152, 4, 76, 25, 83, 197, 181, 50, 204, 116, 198, 72, 96, 183, 251, 41, 63, 46, 254, 237, 155, 86, 206, 116, 155, 94, 132, 228, 54, 226, 88, 104, 140, 83, 246, 81, 19, 145, 255, 1, 140, 65, 82, 71, 102, 206, 34, 69, 75, 228, 220, 104, 128, 91, 76, 206, 194, 115, 158, 123, 2, 4, 114, 85, 189, 0, 149, 132, 45, 219, 153, 154, 31, 179, 30, 108, 199, 224, 34, 223, 110, 235, 106, 181, 124, 175, 250, 214, 172, 45, 74, 147, 120, 191, 60, 26, 210, 224, 47, 221, 70, 99, 142, 20, 78, 84, 83, 237, 163, 210, 66, 34, 140, 192, 251, 98, 166, 145, 195, 245, 35, 254, 190, 229, 70, 14, 21, 245, 32, 14, 145, 27, 151, 6, 43, 154, 205, 10, 91, 151, 60, 229, 182, 26, 188, 125, 81, 160, 163, 207, 130, 19, 22, 144, 144, 124, 173, 222, 182, 135, 239, 83, 56, 250, 207, 186, 211, 238, 53, 103, 198, 56, 67, 145, 218, 190, 192, 235, 210, 103, 131, 231, 18, 156, 113, 172, 180, 93, 155, 219, 96, 41, 176, 29, 167, 33, 158, 1, 13, 137, 166, 13, 148, 195, 115, 121, 129, 189, 232, 133, 94, 41, 78, 195, 120, 91, 187, 114, 187, 153, 30, 51, 223, 142, 239, 127, 105, 200, 47, 149, 88, 65, 223, 1, 4, 46, 203, 181, 6, 38, 237, 131, 167, 107, 60, 241, 161, 110, 221, 175, 181, 236, 90, 226, 96, 22, 113, 30, 135, 136, 212, 26, 111, 131, 31, 187, 131, 106, 71, 91, 235, 254, 43, 8, 52, 166, 83, 62, 151, 36, 29, 250, 97, 202, 131, 236, 159, 172, 40, 21, 61, 192, 62, 173, 26, 191, 168, 121, 115, 227, 37, 198, 87, 235, 204, 51, 45, 220, 155, 84, 104, 50, 37, 212, 59, 175, 177, 104, 156, 119, 110, 195, 202, 217, 188, 160, 122, 51, 180, 239, 20, 133, 232, 58, 235, 166, 68, 38, 209, 4, 187, 209, 41, 133, 28, 230, 60, 234, 69, 194, 213, 214, 14, 206, 241, 60, 239, 167, 126, 216, 175, 184, 138, 229, 125, 254, 30, 50, 122, 24, 4, 150, 33, 139, 127, 65, 58, 104, 102, 80, 76, 37, 29, 25, 65, 14, 61, 58, 101, 30, 94, 205, 242, 78, 63, 124, 163, 60, 45, 85, 0, 18, 78, 74, 215, 49, 147, 80, 138, 185, 30, 43, 169, 157, 223, 169, 77, 131, 97, 151, 75, 147, 251, 99, 23, 251, 32, 19, 122, 166, 209, 129, 120, 90, 204, 165, 28, 51, 79, 104, 19, 31, 75, 111, 167, 37, 201, 35, 248, 120, 215, 234, 80, 82, 255, 2, 92, 64, 105, 3, 93, 22, 39, 1, 139, 231, 71, 46, 214, 24, 67, 22, 230, 3, 213, 188, 20, 110, 180, 122, 237, 48, 132, 184, 238, 205, 40, 177, 198, 29, 201, 88, 100, 102, 253, 178, 56, 201, 223, 156, 105, 251, 137, 234, 121, 171, 236, 154, 232, 228, 203, 35, 131, 230, 83, 185, 250, 68, 200, 192, 93, 101, 223, 191, 77, 130, 122, 205, 18, 100, 135, 199, 68, 22, 236, 63, 81, 2, 154, 210, 222, 127, 18, 113, 32, 114, 18, 114, 205, 1, 140, 82, 178, 180, 226, 71, 165, 91, 57, 246, 111, 169, 97, 45, 194, 116, 127, 232, 124, 11, 69, 71, 17, 26, 4, 50, 241, 18, 39, 116, 81, 70, 72, 109, 26, 134, 206, 15, 241, 49, 64, 97, 16, 133, 176, 96, 247, 184, 228, 238, 189, 177, 80, 103, 73, 2, 102, 232, 152, 93, 2, 15, 190, 127, 157, 39, 138, 91, 13, 150, 252, 49, 193, 212, 145, 209, 180, 21, 88, 140, 233, 8, 113, 236, 2, 118, 141, 204, 110, 209, 36, 229, 212, 149, 76, 110, 57, 166, 196, 22, 16, 207, 98, 77, 40, 156, 117, 192, 120, 203, 174, 49, 251, 25, 197, 140, 9, 156, 203, 37, 21, 76, 100, 184, 201, 240, 36, 214, 236, 38, 183, 167, 27, 125, 150, 245, 186, 248, 163, 192, 236, 107, 237, 104, 31, 0, 46, 231, 137, 38, 161, 73, 44, 235, 239, 187, 145, 212, 110, 84, 37, 159, 51, 155, 137, 197, 175, 118, 225, 142, 77, 36, 71, 198, 132, 27, 209, 207, 168, 57, 70, 11, 120, 22, 115, 96, 201, 160, 229, 95, 248, 182, 43, 24, 60, 102, 119, 13, 159, 30, 111, 254, 195, 65, 97, 111, 161, 140, 45, 160, 87, 106, 195, 50, 131, 54, 126, 60, 232, 29, 54, 76, 68, 99, 45, 107, 56, 238, 187, 148, 246, 83, 42, 69, 225, 248, 162, 17, 116, 117, 47, 249, 148, 150, 32, 158, 137, 110, 3, 218, 80, 13, 121, 22, 227, 113, 241, 154, 238, 191, 10, 247, 126, 59, 232, 251, 162, 49, 151, 109, 18, 204, 1, 101, 173, 129, 112, 236, 75, 73, 214, 98, 211, 216, 228, 4, 100, 67, 114, 143, 62, 212, 214, 124, 167, 189, 136, 161, 228, 56, 77, 165, 76, 222, 111, 138, 184, 163, 98, 113, 103, 19, 74, 59, 233, 199, 242, 151, 129, 51, 15, 60, 102, 237, 134, 205, 1, 14, 212, 57, 13, 167, 193, 171, 80, 133, 193, 46, 186, 251, 157, 222, 169, 201, 160, 44, 185, 123, 129, 215, 72, 251, 250, 211, 242, 92, 83, 142, 98, 116, 189, 184, 95, 167, 138, 238, 125, 169, 137, 124, 60, 33, 234, 161, 206, 143, 15, 31, 180, 54, 185, 130, 77, 252, 237, 37, 180, 218, 240, 17, 43, 189, 184, 238, 234, 154, 166, 68, 204, 164, 209, 72, 212, 17, 24, 123, 46, 117, 132, 87, 125, 27, 204, 190, 12, 187, 85, 202, 159, 86, 41, 205, 52, 238, 208, 88, 122, 46, 139, 252, 72, 163, 162, 156, 125, 91, 154]

dir_arr = [0, 1, 0, -1, 1, 0, -1, 0]

def make_target():
target = []
# init target
for i in xrange(10):
target.append([])
for j in xrange(10):
target[i].append(i*10 + j)
return target

def do_traceback(x, y):
#print '----'
target = make_target()
for i in xrange(1000):
v7 = dir_array[i]
for j in xrange(4):
v8 = (v7 >> ((3 - j) * 2)) & 3
v9 = 5 - v8
if v8 < 2: v9 = 1 - v8
last_x = x - dir_arr[v9 * 2]
last_y = y - dir_arr[v9 * 2 + 1]
if last_x < 0 or last_x >= 10 or last_y < 0 or last_y >= 10:
return None
# swap
tmp = target[last_x][last_y]
target[last_x][last_y] = target[x][y]
target[x][y] = tmp
x = last_x
y = last_y

if target[x][y] != 0:
print 'No'
return None
return target

def find_start(target):
for i in xrange(10):
for j in xrange(10):
if target[i][j] == 0:
return i, j
raise Exception("No zero in matrix");

def do_run(target, x, y):
for i in range(1000)[::-1]:
v7 = dir_array[i]
for j in xrange(4):
v8 = v7 & 3
v7 = v7 >> 2
v9 = 5 - v8
if v8 < 2: v9 = 1 - v8
next_x = x + dir_arr[v9*2]
next_y = y + dir_arr[v9*2+1]
if next_x >= 10 or next_x < 0 or next_y >= 10 or next_y < 0:
return False
tmp = target[next_x][next_y]
target[next_x][next_y] = target[x][y]
target[x][y] = tmp
x = next_x
y = next_y

for i in xrange(10):
for j in xrange(10):
if target[i][j] != i * 10 + j:
return False

return True

for k in xrange(10):
for l in xrange(10):
result = do_traceback(k, l)
if result:
print result
backup = copy.deepcopy(result)
x, y = find_start(result)
if do_run(result, x, y) == True:
encoded = ''
for i in xrange(10):
for j in xrange(10):
hi = backup[i][j] / 0x10
lo = backup[i][j] % 0x10
encoded += string.ascii_uppercase[hi]
encoded += string.ascii_uppercase[lo]

print encoded

3_2_2
嗯……就这样吧……虽然操作步骤看懂了,但是到现在都没明白用户输入是在那个函数里处理的。难受。
CEBGAMBEBHDBBNCPBKBLABADCCACBIBFEOCGAOBCEGCACIEAAPBDBMCNBABBDJANCMAIAFDMAECHDACBDDCJFPBOALDHEEDGBPCFEHEIBJDLFNAGAJDKFIFHAKECEJCDAHDNEPFJFGGBDOFADCCKFDDIEDELEMCOFLFCFBDPFMCLFFGCGDENFKAADEDFFOEBEKFEEFGA