抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

64位无壳

1
2
3
4
5
6
BOOL VirtualProtect(
LPVOID lpAddress, // 目标地址起始位置
DWORD dwSize, // 大小
DWORD flNewProtect, // 请求的保护方式
PDWORD lpflOldProtect // 保存老的保护方式
);

VirtualProtectEx函数可以改变在特定进程中内存区域的保护属性。

独立了一个新的虚拟内存,权限可读可写可执行,作为后面新程序的一个引导,根据后面给的内存地址,将被引导的程序dump下来

无法正常运行,文件头存在问题。(主程序是64位但是文件头

这里修改文件头和可选头的值

主要逻辑为

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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
int sub_BF2850()
{
FILE *v0; // rax
__int64 v1; // rax
_QWORD *v2; // rsi
__int64 v3; // rdi
__int64 v4; // rdx
__int64 v5; // rbx
__m128i *v6; // rax
__m128i *v7; // rdi
__m128i *v8; // rax
unsigned __int64 *v10; // rsi
__int64 v11; // rbx
__int64 v12; // rcx
__m128i *input_1; // rbp
__int64 v14; // rdx
unsigned __int64 v15; // rdi
__int64 v16; // rbx
unsigned __int64 *len; // rbp
__m128i *v18; // rax
__int64 v19; // rcx
__m128i *input_2; // rdi
__int64 v21; // rdx
unsigned __int64 v22; // rsi
__int64 v23; // rdi
__int64 v24; // rdx
unsigned __int64 v25; // rcx
__m128i v26; // xmm4
__int64 v27; // rdi
__int64 v28; // rdx
unsigned __int64 v29; // rcx
__m128i v30; // [rsp+20h] [rbp-78h] BYREF
__m128i v31; // [rsp+30h] [rbp-68h] BYREF
__int64 v32; // [rsp+40h] [rbp-58h] BYREF
__int64 v33; // [rsp+48h] [rbp-50h]
__m128i v34; // [rsp+50h] [rbp-48h] BYREF
__int64 v35; // [rsp+60h] [rbp-38h] BYREF
__int64 v36; // [rsp+68h] [rbp-30h]

nimRegisterGlobalMarker(sub_BF27A0);
nimRegisterGlobalMarker(sub_BF2790);
nimRegisterGlobalMarker(sub_BF2780);
nimRegisterGlobalMarker(sub_BF2770);
nimRegisterGlobalMarker(sub_BF2760);
nimRegisterGlobalMarker(sub_BF2750);
nimRegisterGlobalMarker(sub_BF2740);
nimRegisterGlobalMarker(sub_BF2730);
nimRegisterGlobalMarker(sub_BF2720);
printf_0(off_BF6DC8, 1i64);
v0 = (FILE *)off_BF50C0(0i64);
v1 = scanf(v0);
v2 = (_QWORD *)v1;
if ( v1 )
*(_QWORD *)(v1 - 16) += 8i64;
if ( input )
{
v3 = *(_QWORD *)(input - 16);
v4 = input - 16;
*(_QWORD *)(input - 16) = v3 - 8;
if ( (unsigned __int64)(v3 - 8) <= 7 )
addZCT__Y66tOYFjgwJ0k4aLz4bc0Q(&qword_C01F80 + 3, v4);
}
input = (__int64)v2;
v5 = 0i64;
v6 = sub_BE8FC0(5i64);
v7 = v6;
if ( !v6 )
{
if ( v2 )
sub_BEC420(0i64, -1i64);
sub_BEC420(0i64, -1i64);
}
if ( !v2 )
{
if ( !v6->m128i_i64[0] )
sub_BEC420(0i64, -1i64);
sub_BEC420(0i64, -1i64);
}
do
{
if ( v6->m128i_i64[0] <= (unsigned __int64)v5 )
sub_BEC420(v5, v6->m128i_i64[0] - 1);
if ( *v2 <= (unsigned __int64)v5 )
sub_BEC420(v5, *v2 - 1i64);
v6[1].m128i_i8[v5] = *((_BYTE *)v2 + v5 + 16);
++v5;
}
while ( v5 <= 4 );
if ( v6->m128i_i64[0] != 5 )
goto error;
v8 = v6 + 1;
if ( v7[1].m128i_i32[0] != 'galf' ) //判断输入是否为flag
goto error;
if ( v8->m128i_i8[4] != '{' )
goto error;
v10 = (unsigned __int64 *)input;
if ( !input || *(_QWORD *)input != 42i64 || *(_BYTE *)(input + 57) != '}' )// 判断长度为42位 并且最后一位是}
goto error;
v11 = 0i64;
input_1 = sub_BE8FC0(18i64);
if ( !input_1 )
sub_BEC420(0i64, -1i64);
do
{
v14 = input_1->m128i_i64[0];
if ( input_1->m128i_i64[0] <= (unsigned __int64)v11 )
sub_BEC420(v11, v14 - 1); // 跳过
v15 = v11 + 5;
if ( v11 + 5 < 0 || v15 < v11 )
sub_BE7F70(v12, v14); // 跳过
if ( *v10 <= v15 )
sub_BEC420(v11 + 5, *v10 - 1); // 跳过
input_1[1].m128i_i8[v11++] = *((_BYTE *)v10 + v15 + 16);// 保存我们输入后去除flag{的后18位
}
while ( v11 <= 17 );
v16 = 0i64;
str2int(input_1, 10i64, &ll_input_1); //将我们的输入转换为了无符号的long long类型的一个数据
len = (unsigned __int64 *)input;
v18 = sub_BE8FC0(18i64);
input_2 = v18;
if ( !v18 )
{
if ( len )
sub_BEC420(0i64, -1i64);
sub_BEC420(0i64, -1i64);
}
if ( !len )
{
if ( !v18->m128i_i64[0] )
sub_BEC420(0i64, -1i64);
sub_BEC420(23i64, -1i64);
}
do
{
v21 = input_2->m128i_i64[0];
if ( input_2->m128i_i64[0] <= (unsigned __int64)v16 )
sub_BEC420(v16, v21 - 1);
v22 = v16 + 23;
if ( v16 + 23 < 0 || v22 < v16 )
sub_BE7F70(v19, v21);
if ( *len <= v22 )
sub_BEC420(v16 + 23, *len - 1);
input_2[1].m128i_i8[v16++] = *((_BYTE *)len + v22 + 16);// 保存后18位
}
while ( v16 <= 17 );
str2int(input_2, 10i64, &ll_input_2);
str2int(qword_BF6D80, 10i64, &xmmword_C0C150);
str2int(qword_BF6D40, 10i64, &max_num);
v31 = _mm_loadu_si128((const __m128i *)&xmmword_C0C150); //大致可以猜测_mm_lodau_si128是将后面的偏移地址处的数据进行加载,那么可以猜测在这个前后应该会有加密部分
v30 = _mm_loadu_si128((const __m128i *)&ll_input_1);
if ( !(unsigned __int8)check(&v31, &v30) )
goto error;
v31 = _mm_loadu_si128((const __m128i *)&ll_input_1);
v30 = _mm_loadu_si128((const __m128i *)&max_num);
if ( !(unsigned __int8)check(&v31, &v30) )
goto error;
v32 = 0i64;
v33 = 0i64;
v31 = (__m128i)ll_input_1;
v30 = (__m128i)ll_input_1;
func_sqr(&v31, &v30, &v32);
v23 = v32;
if ( v32 )
*(_QWORD *)(v32 - 16) += 8i64;
if ( (_QWORD)xmmword_C0C190 )
{
v24 = xmmword_C0C190 - 16;
v25 = *(_QWORD *)(xmmword_C0C190 - 16) - 8i64;
*(_QWORD *)(xmmword_C0C190 - 16) = v25;
if ( v25 <= 7 )
addZCT__Y66tOYFjgwJ0k4aLz4bc0Q(&qword_C01F80 + 3, v24);
}
*(_QWORD *)&xmmword_C0C190 = v23;
v34 = 0ui64;
BYTE8(xmmword_C0C190) = v33;
v31 = (__m128i)ll_input_2;
v30 = (__m128i)ll_input_2;
func_sqr(&v31, &v30, &v34);
v26 = _mm_load_si128(&v34);
v35 = 0i64;
v36 = 0i64;
v31 = v26;
func_mul(&v31, 11i64, &v35);
v27 = v35;
if ( v35 )
*(_QWORD *)(v35 - 16) += 8i64;
if ( (_QWORD)xmmword_C0C120 )
{
v28 = xmmword_C0C120 - 16;
v29 = *(_QWORD *)(xmmword_C0C120 - 16) - 8i64;
*(_QWORD *)(xmmword_C0C120 - 16) = v29;
if ( v29 <= 7 )
addZCT__Y66tOYFjgwJ0k4aLz4bc0Q(&qword_C01F80 + 3, v28);
}
*(_QWORD *)&xmmword_C0C120 = v27;
v31 = _mm_loadu_si128((const __m128i *)&xmmword_C0C190);
BYTE8(xmmword_C0C120) = v36;
v30 = _mm_loadu_si128((const __m128i *)&xmmword_C0C120);
sub_BF23C0(&v31, &v30, &num_9);
str2int(qword_BF6D10, 10i64, &xmmword_C0C180);
v31 = _mm_loadu_si128((const __m128i *)&num_9);
v30 = _mm_loadu_si128((const __m128i *)&xmmword_C0C180);
if ( (unsigned __int8)sub_BF2500(&v31, &v30) )
{
qword_BFA660 = 1i64;
}
else
{
error:
if ( qword_BFA660 != 1 )
return printf_0(off_BF6CC0, 1i64);
}
return printf_0(win, 1i64);
}

$$
input1^2-11*(input^2)=9
$$

大致流程为输入42位的flag。去除flag{}后分为两个18位的数进行上述运算

采用:www.wolframalpha.com/ 进行求解

y是17位前面补上0得到

1
flag{118936021352508390035860559716724409}

评论