hctf2017-level1Tolevel3-reverse

level1-Evr_Q

思路:程序有TLS反调试和NtQueryInformationProcess的反调试,过了就能动调了。首先是Check输入的UserName,接着Check输入的PassWord,长度要满足35,接着对PassWord统一进行了异或0x76,我将35长度的字符串分为5组,程序紧接着对中间三组分别进行了简单的操作,如下图,最后和硬编码的值比较。

Check_UserName函数:

Check_UserName

对中间三组的分别处理:

Evr_Q2

Evr_Q3

Evr_04

写脚本得flag,第一个脚本求UserName,第二个求flag,写第二个的时候爆破的范围小了,导致有两位数出来是错的,浪费了很多时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python
#-*- coding:utf-8 -*-

u1 = [164,169,170,190,188,185,179,169,190,216,190]
username = ''
for i in range(len(u1)):
for x in range(32,128):
tmp = ((((i ^ 0x76) - 52) ^ 0x80) + 43) ^ x
if tmp == u1[i]:
username += chr(x)
break
#print username
print username[::-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
#include<stdio.h>

BYTE cmp_ans[35] = {0x1E,0x15,0x02,0x10,0x0D,0x48,0x48,0x6F,0xDD,0xDD,0x48,0x64,0x63,0xD7,0x2E,0x2C,0xFE,0x6A,0x6D,0x2A,0xF2,0x6F,0x9A,0x4D,0x8B,0x4B,0xCA,0xBF,0x42,0x10,0x46,0x12,0x43,0x41,0x0B};

int main()
{
BYTE a1[8]={0,};
BYTE ans[8] = {0,};
int i,j;
for(i=0;i<7;i++)
{
ans[i] = char(cmp_ans[i] ^ 0x76);
}
printf("%s\n",ans);
for(i=28;i<35;i++)
{
ans[i-28] = char(cmp_ans[i] ^ 0x76);
}
printf("%s\n",ans);
for ( i = 0; i < 7; ++i )
{
for(int x=32;x<128;x++)
{
*(BYTE *)(i + a1) = x ^ 0xAD;
*(BYTE *)(i + a1) = 2 * *(BYTE *)(i + a1) & 0xAA | ((*(BYTE *)(i + a1) & 0xAA) >> 1);
if (*(BYTE *)(i + a1) == cmp_ans[7+i])
{
ans[i] = x;
// break;
}
}
}
for(i=0;i<7;i++)
{
ans[i] = BYTE(ans[i] ^ 0x76);
}
printf("%s\n",ans);
for ( i = 0; i < 7; ++i )
{
for(int x=32;x<128;x++)
{
*(BYTE *)(i + a1) = x ^ 0xBE;
*(BYTE *)(i + a1) = 4 * *(BYTE *)(i + a1) & 0xCC | ((*(BYTE *)(i + a1) & 0xCC) >> 2);
if (*(BYTE *)(i + a1) == cmp_ans[14+i])
{
ans[i] = x;
// break;
}
}
}
for(i=0;i<7;i++)
{
ans[i] = BYTE(ans[i] ^ 0x76);
}
printf("%s\n",ans);
for ( i = 0; i < 7; ++i )
{
for(int x=0;x<128;x++){
*(BYTE *)(i + a1) = x ^ 0xEF;
*(BYTE *)(i + a1) = 16 * *(BYTE *)(i + a1) & 0xF0 | ((*(BYTE *)(i + a1) & 0xF0) >> 4);
if (*(BYTE *)(i + a1) == cmp_ans[21+i])
{
printf("\n");
printf("%c %x %x\n",x,*(BYTE *)(i + a1),cmp_ans[21+i]);
ans[i] = x;
// break;
}
}
}
for(i=0;i<7;i++)
{
ans[i] = BYTE(ans[i] ^ 0x76);
}
printf("%s\n",ans);
system("pause");
}

level2-ez_crackme

第二个逆向,我的方法可能是解法里面最笨的(想看其他表哥的做法233),跟程序流程走了7个多小时,在快放弃的时候,终于看到了cmp,瞬间出了一口气。

思路:个人做法就是下条件断点,但是条件断点只有四个,要根据程序流程灵活取消条件断点和下新的条件断点,在输入flag的地方下4字节断点,反复多试几次可以很快确定,程序取的第一个字符是下标为19的字符,然后跟踪字符,适当下读写断点,注意超过4个,条件断点就无效了,有耐心的慢慢跟下去,在跟的过程中,看逻辑,猜算法,有耐心,如果算法猜对了,将很节约时间。由于不好截图,接下来直接说明算法流程。

共三层变换

第一层

算法首先将输入的32个字符,以长度为19的循环规律(第一个字符就是下标为19的字符),放到申请的堆中,具体规律如下代码:

1
2
3
for i in range(len(fake_flag)):
tmp = (19 * (i+1)) % 32
transform_flag += fake_flag[tmp]

第二层

将新得到的32个字符,从字符串头部开始,取第一个字符的低5位左移3位,和第二个字符的高3位右移5位以后结合在一起,然后一直到字符结束,最后取最后一个字符的低5位左移3位和第一个字符的高3位右移5位以后结合在一起。代码如下:

1
2
3
4
5
6
7
for i in range(transform_flag_len):
first = ord(transform_flag[i])
second = ord(transform_flag[(i+1)%transform_flag_len])
lower = ((first & 0x1F) << 3) & 0xFF
higher = ((second & 0xE0) >> 5) & 0xFF
tmp = lower + higher
transform_again_flag.append(hex(tmp))

第三层

将第二层得到的新32个字符,和一个table里的32个字符一一异或,异或以后的值加上对应的下标,得到新的32个字符,与程序中最后的32个字符比较,成功,则为正确的输入。table里的32个字符是根据假的输入,得到的输出,反过去求的table。最后比较的32个字节也是改写了判定条件,动调得到的32个字节。

1
2
3
4
for i in range(transform_flag_len):
tmp = table1[i] ^ int(transform_again_flag[i][2:],16)
tmp = tmp - i
table2.append(hex(tmp))

最后附上自己输入假的flag,正向推导获得一些值的代码,和逆向求解flag的代码。

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
#!/usr/bin/env python
#-*- coding:utf-8 -*-

fake_flag = '1234567890abcdefghijABCDEFGHIJop'
transform_flag = ''
table1 = [0x8F,0x14,0xF3,0xE9,0x61,0xFB,0x76,0xDD,0xF5,0xCD,0x89,0x50,0xC9,0xB0,0x9F,0xC7,0x4C,0xA7,0x52,0x49,0xC3,0x58,0xC5,0xCC,0xB5,0xEF,0x4A,0x03,0x38,0xF1,0xFD,0x85]
table2 = []
ttable2 = ['0xde', '0xad', '0xbe', '0xef', '0xde', '0xad', '0xbe', '0xef', '0xde', '0xad', '0xbe', '0xef', '0xde', '0xad', '0xbe', '0xef', '0xde', '0xad', '0xbe', '-0x11', '0xde', '0xad', '0xbe', '-0x11', '0xde', '0xad', '0xbe', '-0x11', '0xde', '0xad', '0xbe', '-0x11']
cmp_table = [0xF7,0x0C,0x3B,0x81,0x08,0x49,0x86,0x0D,0x4D,0x9D,0x8B,0x20,0x80,0x8B,0x65,0x45,0xDC,0x0C,0x29,0xCB,0x79,0x60,0x2D,0x9D,0xC5,0x7D,0xC2,0xD9,0x4B,0x78,0x27,0x4C]
transform_again_flag = []

#-----------------正向推导代码------------------------

'''
for i in range(len(fake_flag)):
tmp = (19 * (i+1)) % 32
transform_flag += fake_flag[tmp]
print transform_flag

transform_flag_len = len(transform_flag)
for i in range(transform_flag_len):
first = ord(transform_flag[i])
second = ord(transform_flag[(i+1)%transform_flag_len])
lower = ((first & 0x1F) << 3) & 0xFF
higher = ((second & 0xE0) >> 5) & 0xFF
tmp = lower + higher
transform_again_flag.append(hex(tmp))

print transform_again_flag,len(transform_again_flag)

for i in range(transform_flag_len):
tmp = table1[i] ^ int(transform_again_flag[i][2:],16)
tmp = tmp - i
table2.append(hex(tmp))
print table2
'''

#-----------------正向推导代码------------------------

#-----------------逆向求解flag------------------------

for i in range(len(cmp_table)):
if '-' in ttable2[i]:
tmp = int(ttable2[i][3:],16) * (-1)
else:
tmp = int(ttable2[i][2:],16)
tmp = tmp + i
tmp = tmp ^ cmp_table[i]
transform_again_flag.append(hex(tmp))

tmp = int(transform_again_flag[31][2:],16)
first = ((tmp & 0xF8) >> 3) & 0xff #最后一个字符的低5位
second = ((tmp & 0x07) << 5) & 0xff #第一个字符的高三位
tmp = int(transform_again_flag[0][2:],16)
first = ((tmp & 0xF8) >> 3) & 0xff # 第一个字符的低5位
transform_flag += chr(second | first)


for i in range(len(transform_again_flag)):
tmp = int(transform_again_flag[i][2:],16)
first = ((tmp & 0xF8) >> 3) & 0xff #第一个字符的低5位
second = ((tmp & 0x07) << 5) & 0xff #第二个字符的高3位
if i != 0:
transform_flag += chr(last_second | first)
last_first = first
last_second = second

print transform_flag

flag = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
for i in range(len(transform_flag)):
flag[(19 * (i+1)) % 32] = transform_flag[i]
print ''.join(flag)

#-----------------逆向求解flag------------------------

level3-Are_U_OK

思路:该题使用了proc/self/status的traceID反调试,以及fork子进程的方式反调(这里是不是反调忘了),使用了ptrace的编程方法,我是静态写脚本破的题目,动调没去调试,因为估计要设计到内核,关键函数的进入,我想应该就是从内核进去的。

类rc4算法解密隐藏代码

Are_U_OK1

红色标注的地方就是需要解密的函数,图中已经解密了,所以显示正常。

类rc6算法获取flag

对解密以后的函数进行交叉引用,发现调用其的位置,在没有解密前是没有的。

Are_U_OK2

分析解密以后的代码,是类rc6算法,rc6的代码很长,就用一张图表示一下好了。

Are_U_OK3

从rc6出来以后的值和硬编码的两组16字节比较,相同,则成功。附上类rc4和求解flag的代码。

类rc4解密隐藏代码。

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include<Windows.h>
#include<stdio.h>
#include<string.h>

BYTE hide_func[] = {0x55,0x0C,0xB3,0x6E,0xCF,0x2B,0xC0,0x03,0x96,0x66,0xC8,0x14,0x32,0x6D,0x3F,
0xE6,0x17,0x83,0xEA,0xCD,0x04,0x2B,0xF1,0xCA,0x74,0xAC,0xE2,0x85,0x8B,0x29,0x20,
0xC3,0x48,0xCB,0xD3,0xF0,0x1C,0x24,0xF7,0xDE,0xF9,0xED,0x36,0x3A,0xC8,0x94,0xAB,
0x6D,0x62,0x3B,0xD7,0x09,0xAB,0xCC,0xE0,0x4B,0x03,0x5E,0x69,0xE1,0xC3,0x7D,0x26,
0x4F,0xA6,0x5E,0xC2,0x89,0x81,0xCA,0x14,0x91,0xCE,0x02,0x35,0x2A,0x56,0x33,0xA4,
0x3D,0x2B,0x13,0xE2,0x70,0xC8,0xE6,0x03,0x44,0xFE,0x86,0x31,0x2F,0x56,0xD3,0xD1,
0x07,0x71,0x9C,0x1F,0x37,0x28,0x30,0x6C,0x77,0x72,0x1C,0x64,0xF1,0x06,0xDA,0x6A,
0x52,0xE8,0x4E,0x37,0x47,0x24,0x6A,0xA4,0x7D,0xE4,0x82,0x20,0xDD,0xCA,0xD3,0xED,
0x18,0x6A,0x06,0x94,0x7E,0xCB,0x7D,0x8F,0x9A,0xB3,0xBD,0x19,0x07,0x81,0x7B,0xCF,
0xE9,0x66,0x7C,0xB9,0x72,0x86,0x01,0xF8,0x1A,0xC9,0x79,0xD4,0x34,0xCD,0x8D,0xEB,
0x99,0x14,0xAB,0xA1,0xE8,0x73,0x17,0x25,0xC9,0xED,0xE1,0xE7,0xF5,0x9A,0xF1,0x59,
0xA5,0xA2,0xEA,0x43,0x7E,0x71,0x13,0x77,0xB5,0x70,0x16,0x48,0xA3,0x3A,0x5D,0xBE,
0xD5,0x0C,0xBD,0x12,0x10,0x41,0x45,0xFB,0xAC,0xC0,0x0C,0x78,0x8F,0x86,0xF8,0x60,
0x64,0xF6,0xB3,0xDF,0xF8,0x5E,0xEA,0x51,0xE4,0xC4,0x4E,0xB5,0x6F,0xC7,0x7B,0xA6,
0xBE,0xF5,0x07,0x85,0xE0,0x59,0xDE,0x1B,0xB8,0x32,0xC9,0xBE,0x48,0xF1,0xE4,0x8C,
0x16,0xDF,0x10,0x6F,0x04,0x82,0x5F,0xC4,0x19,0x63,0xFF,0x74,0x03,0x6D,0x75,0x31,
0x9F,0xB5,0x56,0x06,0x18,0xBB,0x1B,0x06,0xFA,0x3B,0x7B,0x60,0x0B,0x8B,0x2F,0xF8,
0x72,0x49,0x60,0xAD,0x80,0x74,0xBF,0x6F,0xD7,0x9E,0xB0,0x02,0xE7,0xF7,0x2C,0xDF,
0x4B,0xC7,0xC5,0xC5,0x92,0x10,0xC5,0xE4,0xDD,0x5F,0x37,0x5B,0xA3,0x67,0xC2,0x28,
0xBC,0x1B,0x26,0x55,0x9C,0x02,0x15,0xAD,0x17,0x62,0x61,0xF8,0x3F,0xA6,0x46,0x92,
0x53,0x68,0xF6,0x41,0x9C,0x00,0xF8,0x0E,0xAC,0x58,0xC2,0xAC,0x08,0xD5,0x72,0xD2,
0x6E,0x7B,0x1C,0x5B,0x2F,0x18,0xBD,0x30,0xEB,0x72,0x5C,0xC5,0xF9,0x5D,0xDB,0x67,
0x11,0xC8,0xB2,0x99,0x5A,0x50,0xB1,0xE8,0xD7,0x0B,0xCF,0xA0,0xF0,0xF1,0x19,0xEC,
0x3E,0x52,0x2F,0x01,0x6C,0x31,0xA6,0x0E,0xF5,0x6D,0x7B,0x69,0x5C,0x31,0xFF,0xD3,
0x91,0x62,0x89,0x9C,0x4B,0xFF,0x48,0x5F,0xD7,0xBF,0x81,0x5F,0x96,0xEB,0x28,0xC1,
0xAC,0xA2,0x3C,0xCF,0x0E,0xD3,0x67,0x68,0x9B,0x25,0x71,0x5A,0x09,0x67,0xE0,0x57,
0x15,0x5E,0x04,0x9B,0x08,0x99,0xEA,0x8A,0x8C,0x29,0x13,0x90,0xF3,0x87,0xB8,0xC4,
0xB0,0xA6,0x40,0xDC,0xB5,0x6B,0x17,0x6A,0xF3,0x34,0x88,0x1B,0x48,0xA9,0x95,0x19,
0x22,0xF0,0x83,0x5E,0x92,0xB4,0x3A,0xA6,0xF5,0x9B,0x47,0x6E,0x13,0x9A,0x97,0xF9,
0xBB,0xEF,0x41,0x14,0xE4,0x7A,0xA9,0x04,0x1E,0x9C,0xDC,0x15,0x87,0xA7,0xBC,0x99,
0x0E,0xB7,0xDB,0x58,0x28,0x18,0x74,0xC2,0x4C,0xDA,0x4D,0xF6,0x54,0xE2,0x43,0xAE,
0x8B,0xC6,0xA5,0x7B,0xD9,0xA8,0x5B,0x56,0x78,0x9D,0x40,0x03,0x50,0xD7,0x28,0xB6,
0x17,0x8B,0xC1,0x82,0x75,0x78,0x55,0x64,0xDA,0x12,0x7E,0x37,0xA3,0x44,0x98,0x7C,
0x9D,0xF8,0x83,0x5D,0xBB,0x3A,0xEB,0x86,0xB0,0x63,0x1A,0x94,0xEF,0x7B,0x5C,0x5A,
0x2C,0xD3,0x7C,0xA7,0x7F,0x79,0x08,0x7E,0x5B,0x15,0x5B,0x40,0x80,0x78,0x2E,0xEE,
0x35,0x16,0x41,0xE0,0x7C,0x14,0x3B,0x21,0x47,0x76,0xA8,0x69,0xE1,0x74,0x31,0x26,
0x83,0xA7,0x5E,0xC2,0x02,0xC1,0xC6,0x9D,0x97,0x87,0x20,0x34,0x2A,0xE1,0xBF,0x56,
0x0D,0x5F,0x69,0xC1,0x05,0x37,0x18,0xCE,0x25,0x14,0xFC,0xCE,0x67,0xD5,0x56,0x99,
0x73,0x0B,0x6B,0xE4,0x80,0x5C,0xFD,0x6D,0x58,0x06,0xF3,0x64,0x74,0xDB,0xA1,0x61,
0x53,0x9E,0x25,0xFA,0xE4,0x5E,0x95,0xA4,0x01,0x9E,0x5A,0x19,0xA7,0xE9,0x2C,0xF9,
0x20,0xAD,0x83,0x7C,0x80,0xB7,0x3F,0x30,0x35,0xAD,0xF5,0xCD,0x8D,0xDA,0x65,0x30,
0x16,0x66,0xF7,0x3C,0x9E,0xFB,0x43,0xDB,0xE5,0xF6,0x05,0x3F,0x42,0xE4,0xA9,0xEB,
0xA9,0x14,0xAB,0xA1,0xA2,0x26,0xFA,0x52,0xB3,0xEA,0x96,0x8C,0x8F,0x51,0x8B,0x52,
0xA4,0xDC,0xB8,0xAA,0x40,0x0D,0x2C,0x31,0x3C,0x17,0xF2,0x3F,0xD8,0x19,0x5C,0x80,
0xEA,0x08,0xDF,0x46,0x2B,0x3A,0x5E,0xFA,0xD8,0xBA,0xE4,0x86,0x70,0x79,0x40,0x60,
0x78,0xF6,0xB3,0xDF,0xF8,0x19,0x81,0x2A,0xE7,0xC5,0x3A,0xCF,0x06,0xF8,0x57,0x9B,
0x7F,0xFB,0x5E,0x7B,0xE0,0x59,0xAA,0x15,0x64,0xCD,0xE6,0xC8,0x44,0x9C,0xF6,0x8D,
0x16,0x68,0x18,0x6F,0xE8,0x83,0x5F,0xC4,0x94,0x6D,0x92,0x7A,0x02,0x6D,0x0B,0xBF,
0xFE,0xB7,0x57,0x06,0x64,0x32,0xD9,0x8D,0x70,0x44,0x53,0x9F,0xF4,0x02,0x65,0xAE,
0x6C,0xFF,0x14,0xD7,0x0B,0x1F,0xC5,0xD0,0xA3,0x61,0x4E,0x59,0xEB,0x9A,0x22,0xDE,
0x4B,0x39,0x4F,0xCD,0x92,0xFC,0xC4,0xE4,0xDD,0x5A,0x6C,0x1F,0x8B,0x9A,0xB4,0x15,
0xBE,0x1B,0x02,0x55,0x9C,0x02,0x17,0xBC,0x7E,0xDC,0x61,0xF8,0x49,0xA8,0x2B,0xB0,
0x52,0x68,0x82,0x4F,0xE8,0x7B,0x47,0x0E,0xDA,0x22,0xA7,0xD7,0x1F,0xD4,0x06,0xA8,
0x11,0x00,0x03,0x5A,0x59,0x62,0xC6,0x5A,0x91,0xAD,0x28,0xBF,0xFE,0x28,0xA1,0x70,
0x66,0xB2,0xB9,0x66,0x67,0x24,0xB7,0x81,0xF5,0x0A,0xCF,0xD2,0xC5,0x1A,0x81,0x86,
0x29,0x53,0x98,0x75,0x62,0xB4,0xB5,0x0F,0xF5,0x19,0x7A,0xB8,0x50,0x18,0xD2,0xEA,
0xE7,0xD8,0x81,0x9C,0xAB,0xFE,0x48,0x5F,0x5A,0x63,0x8F,0xFA,0x69,0xEB,0x28,0xB5,
0xA2,0x42,0xC3,0xB5,0x01,0xA6,0x1C,0x12,0xF3,0x59,0x0B,0xA5,0x7F,0x1D,0xF3,0xAD,
0xA2,0x2A,0x02,0x06,0x2B,0x98,0xEA,0xFE,0x18,0x4A,0x60,0xB3,0xF2,0xF1,0x57,0x36,
0x98,0xA8,0x76,0x99,0xC3,0x5C,0x6B,0x1D,0x96,0x1A,0xB6,0x0C,0xC4,0x92,0x51,0x7D,
0x80,0xB4,0x12,0x69,0xE4,0xCE,0x6D,0xCD,0xFA,0x9A,0x3B,0x14,0x7A,0x34,0x60,0x4E,
0x31,0xE9,0xFC,0x0B,0xE5,0x7A,0xDD,0x96,0x69,0xE7,0xC7,0x14,0xF1,0x08,0xB1,0xE0,
0x5C,0xC3,0x61,0x5F,0x04,0xDD,0xC2,0x86,0x96,0x0D,0xB2,0xBE,0xDD,0x13,0x46,0xB9,
0xA8,0xC9,0x12,0x0F,0x95,0xAB,0xF0,0xE1,0x0E,0x30,0x81,0x05,0xAC,0x78,0x9F,0xC0,
0x22,0xB8,0x20,0x72,0x00,0x83,0x8F,0x04,0x53,0x97,0x66,0x80,0xD5,0xFE,0x28,0xC6,
0xD8,0x2F,0x39,0x6A,0x44,0xB1,0xEB,0x0F,0xF2,0xCE,0x28,0x6B,0x10,0x33,0xD7,0x5C,
0x41,0xE4,0x82,0x27,0x97,0xB2,0x49,0x3F,0x1F,0x19,0xA1,0xF7,0xE7,0x78,0x28,0x3E,
0xF5,0xA1,0xBF,0xDD,0x7C,0x11,0xFB,0x69,0x22,0x82,0x1E,0xF5,0xD6,0x74,0x31,0xE6,
0x2B,0x10,0xA0,0xF5,0xC1,0x08,0x0C,0xAB,0xD2,0x42,0xBE,0xCB,0x3D,0x19,0xCF,0x2C,
0xF2,0x2B,0xD3,0xF6,0x4F,0xD7,0x1D,0x03,0x51,0xA2,0x8E,0xB9,0x8F,0x67,0xB3,0x99,
0x07,0xB1,0x5C,0x21,0x28,0xD3,0x30,0xF5,0xEF,0x74,0x59,0x3F,0x3C,0xDB,0xF4,0x2F,
0xBD,0x61,0xDA,0xB2,0x2F,0x52,0x5B,0x13,0x77,0xA6,0xB6,0x5F,0xD2,0xCA,0x2D,0x0F,
0x9A,0x61,0x00,0x39,0x48,0x35,0x69,0x7B,0x48,0x2F,0xC6,0xDE,0xF7,0x49,0x3A,0x68,
0x27,0x06,0x7C,0x51,0x8A,0xEA,0x43,0xDB,0x5B,0x36,0x86,0xFF,0x43,0x03,0x28,0x9F,
0xBA,0x15,0xEB,0x36,0x52,0x86,0xFF,0x33,0xD2,0xFD,0x97,0x8C,0xCF,0x5A,0x3F,0xC6,
0x5A,0xCB,0x9D,0x44,0x7F,0x71,0x53,0x30,0x33,0xB8,0x77,0x23,0x36,0x17,0x5C,0xBE};

unsigned char key[] = {0x5A,0x98,0x2C,0x36,0x5F,0xEA,0x90,0xC0,0xB1,0x51,0x71,0x1A,0x32,0xD5,0x86,0x4B,
0x4F,0x33,0xB7,0xD9,0x15,0xF6,0x5B,0x99,0x10,0xBD,0x81,0x2E,0x73,0x33,0xDE,0x07};


void rc4_init(unsigned char* IV, unsigned char* Key, int Len)
{
int i = 0, j = 0;
unsigned char k[256] = {0};
unsigned char tmp = 0;
for (i = 0; i<256; i++)
{
IV[i] = i;
k[i] = Key[i%Len];
}
for (i = 0; i<256; i++)
{
j = (j + IV[i] + k[i]) % 256;
tmp = IV[i];
IV[i] = IV[j];//交换IV[i]和IV[j]
IV[j] = tmp;
}
}

void rc4_crypt(unsigned char* IV, unsigned char* Data, int Len)
{
int i = 0, j = 0, t = 0;
long k = 0;
unsigned char tmp;
int row = 0;
for (k = 0; k<Len; k++,row++)
{
i = (i + 1) % 256;
j = (j + IV[i]) % 256;
// tmp = IV[i];
// IV[i] = IV[j];//交换IV[x]和IV[y]
// IV[j] = tmp;
t = (IV[i] + IV[j]) % 256;
Data[k] ^= IV[t];
if (row % 16 == 0) printf("\n");
printf("%02X ",Data[k]);
}
printf("\n");
}

int main()
{
unsigned char IV[257];
rc4_init(IV,key,32);
int hideFuncLen = strlen((char *)hide_func);
rc4_crypt(IV,hide_func,1215);
system("pause");
return 0;
}

类rc6算法获取flag

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<Windows.h>

const unsigned int r=20;
const unsigned int w=32;
const unsigned int b=16;
const unsigned int c=8;
const unsigned int p=0xb7e15163;
const unsigned int q=0x9e3779b9;
unsigned int moveleft(unsigned int x,unsigned int y);
unsigned int moveright(unsigned int x,unsigned int y);
void keyextend(unsigned int *s,unsigned int *l);
void encryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S);
void decryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S);

unsigned int moveleft(unsigned int x,unsigned int y)
{
unsigned int i,temp;
if(y/32!=0)
y=y%32;
for (i=0; i<y; i++)
{
temp=x&0x80000000;
x=x<<1;
x=x+((temp>>31)&0x00000001);
}
return x;
}

unsigned int moveright(unsigned int x,unsigned int y)
{
unsigned int i,temp;
if(y/32!=0)
y=y%32;
for (i=0; i<y; i++)
{
temp=x&0x00000001;
x=x>>1;
x=(x&0x7fffffff)+(temp<<31);
}
return x;
}

void keyextend(unsigned int *s,unsigned int *l)
{
unsigned int i,j,k,a,b;
s[0]=p;
for (i=1; i<=43; i++)
s[i]=s[i-1]+q;
a=0;
b=0;
i=0;
j=0;
for (k=1; k<=132; k++)
{
s[i]=s[i]+a+b;
s[i]=moveleft(s[i],3);
a=s[i];
l[j]=l[j]+a+b;
l[j]=moveleft(l[j],(a+b));
b=l[j];
i=(i+1)%44;
j=(j+1)%8;
}
}

void encryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S)
{
int i,j,t,u,temp;
*B=*B+S[0];
*D=*D+S[1];
j=(unsigned int)(5); //log(w)/log(2)
for (i=1; i<=r; i++)
{
t=moveleft(((*B)*(2*(*B)+1)),j);
u=moveleft(((*D)*(2*(*D)+1)),j);
temp=moveleft(((*A)^t),u);
*A=temp+S[2*i];
temp=moveleft(((*C)^u), t);
*C=temp+S[2*i+1];
temp=*A;
*A=*B;
*B=*C;
*C=*D;
*D=temp;
}
*A=*A+S[2*r+2];
*C=*C+S[2*r+3];

}

void decryp(unsigned int *A,unsigned int *B,unsigned int *C,unsigned int *D,unsigned int *S)
{
unsigned int i,j,u,t,temp;
j=(unsigned int)(5); //log(w)/log(2)
*C=*C-S[2*r+3];
*A=*A-S[2*r+2];
for (i=r; i>=1; i--)
{
temp=*D;
*D=*C;
*C=*B;
*B=*A;
*A=temp;
u=moveleft(((*D)*(2*(*D)+1)),j);
t=moveleft(((*B)*(2*(*B)+1)),j);
temp=moveright(((*C)-S[2*i+1]),t);
*C=temp^u;
temp=moveright(((*A)-S[2*i]), u);
*A=temp^t;
}
*D=*D-S[1];
*B=*B-S[0];
}

int main()
{

unsigned int A,B,C,D,S[2*r+4],L[c] ={0};
unsigned char plaintxt[17] = {0};
unsigned int keylen = c*4,i,j,temp;
unsigned char key[] = {"52Mi!R_u_MiFans?DO_u_like_me?Tha"};
j = 0;
for(i=0; i<keylen;i++)
{
temp = (unsigned int)key[i];
if(i%4==3)
temp = temp<<24;
else if(i%4==2)
temp = temp<<16;
else if(i%4==1)
temp = temp<<8;
L[j] = L[j] + temp;
if(i%4==3)
j++;
}
keyextend(S,L);
A = 0x7E5705E0,B = 0x154E206D,C = 0x0B66CB9B,D = 0x059C6CAB;
decryp(&A,&B,&C,&D,S);
plaintxt[3]=((A&0xff000000)>>24)&0xff;
plaintxt[2]=((A&0xff0000)>>16)&0xff;
plaintxt[1]=((A&0xff00)>>8)&0xff;
plaintxt[0]=A&0xff;
plaintxt[7]=((B&0xff000000)>>24)&0xff;
plaintxt[6]=((B&0xff0000)>>16)&0xff;
plaintxt[5]=((B&0xff00)>>8)&0xff;
plaintxt[4]=B&0xff;
plaintxt[11]=((C&0xff000000)>>24)&0xff;
plaintxt[10]=((C&0xff0000)>>16)&0xff;
plaintxt[9]=((C&0xff00)>>8)&0xff;
plaintxt[8]=C&0xff;
plaintxt[15]=((D&0xff000000)>>24)&0xff;
plaintxt[14]=((D&0xff0000)>>16)&0xff;
plaintxt[13]=((D&0xff00)>>8)&0xff;
plaintxt[12]=D&0xff;
plaintxt[16]='\x00';
printf("%16s",plaintxt);
A = 0x2C3D3B0E,B = 0x8D33D886,C = 0x198A6D51,D = 0x25D22C40;
decryp(&A,&B,&C,&D,S);
plaintxt[3]=((A&0xff000000)>>24)&0xff;
plaintxt[2]=((A&0xff0000)>>16)&0xff;
plaintxt[1]=((A&0xff00)>>8)&0xff;
plaintxt[0]=A&0xff;
plaintxt[7]=((B&0xff000000)>>24)&0xff;
plaintxt[6]=((B&0xff0000)>>16)&0xff;
plaintxt[5]=((B&0xff00)>>8)&0xff;
plaintxt[4]=B&0xff;
plaintxt[11]=((C&0xff000000)>>24)&0xff;
plaintxt[10]=((C&0xff0000)>>16)&0xff;
plaintxt[9]=((C&0xff00)>>8)&0xff;
plaintxt[8]=C&0xff;
plaintxt[15]=((D&0xff000000)>>24)&0xff;
plaintxt[14]=((D&0xff0000)>>16)&0xff;
plaintxt[13]=((D&0xff00)>>8)&0xff;
plaintxt[12]=D&0xff;
plaintxt[16]='\x00';
printf("%16s\n",plaintxt);
system("pause");
return 0;
}
//hctf{p1ay_Wi7h_p7r4Ce_L0L_6f95e}
//52Mi!R_u_MiFans?DO_u_like_me?Tha -> L
/*cipher =
0xE0,0x05,0x57,0x7E
0x6D,0x20,0x4E,0x15
0x9B,0xCB,0x66,0x0B
0xAB,0x6C,0x9C,0x05
0x0E,0x3B,0x3D,0x2C
0x86,0xD8,0x33,0x8D
0x51,0x6D,0x8A,0x19
0x40,0x2C,0xD2,0x25
*/

嗯,就酱!后面的层数没有出来,额,还要继续努力才行QAQ!