-
-
[原创]迷失丛林 Writeup by or4nge
-
发表于: 2021-11-17 02:07 11819
-
很容易定位到程序的输入
输入长度为32,需要通过 sub_4014A0
, sub_401580
的验证
4014A0
较为简单,是个经典的hexstr转成char存到 4041F0
这个地址,最后的16是计算转换后的长度,所以输入就是 [0-9A-F]{32}
随后将输入的前八字节存入 404000
中,剩下的部分传参进 sub_401580
要想让该函数返回1,需要先通过一组if验证
看一下使用的变量,应该是对前八字节的输入进行的验证
结合动调发现大概就是根据404000数组,构成一个 <value, index>
的结构,两两存放到404420当中
分析了一下404000数组的作用和特征,发现这个数组应该是构成一个环状的结构(以当前数值作为索引寻找下一个数),猜测不能有重复的数字,否则可能会构成小循环之类的,用脚本验证了一下发现后面248个数字果然没有重复,于是将前八字节的取值可能锁定到了 0x1e, 0x28, 0x4b, 0x6d, 0x8c, 0xa3, 0xd2, 0xfb
中,总共有 $8!=40320$ 种可能,完全可以爆破
把ida代码复制下来改一改
转换一下得到前八字节 B4D682C8BF2DE13A
确定前八字节后,只需要关注和参数(后八字节)有关的部分了,中间全部动调跳过
这一部分程序相较来说就简单了不少,主要是根据404000开头的八个字节作为初始值,每个字节单独与输入的八个字节进行运算,根据末尾bit决定是+1还是找索引,最终目的是凑成 GoodJob~
这个字符串(sub_4024C0
是个字符串比较)
可以使用搜索算法求解,但考虑到每个字节是单独运算的,常规爆破也只需要 0x800
的运算量,所以还是直接爆破了
最后得到下半段验证码 D9B6AEF24A80CB22
if
( v21
=
=
(char)
169
&& v22
=
=
(char)
0xAC
&& v23
=
=
(char)
0xA7
&& v24 >
0xC8u
)
if
( v21
=
=
(char)
169
&& v22
=
=
(char)
0xAC
&& v23
=
=
(char)
0xA7
&& v24 >
0xC8u
)
#include <stdio.h>
#include <stdint.h>
#include <algorithm>
#include <cstring>
unsigned char byte_404000[]
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0xA2
,
0x9B
,
0xF4
,
0xDF
,
0xAC
,
0x7C
,
0xA1
,
0xC6
,
0x16
,
0xD0
,
0x0F
,
0xDD
,
0xDC
,
0x73
,
0xC5
,
0x6B
,
0xD1
,
0x96
,
0x47
,
0xC2
,
0x26
,
0x67
,
0x4E
,
0x41
,
0x82
,
0x20
,
0x56
,
0x9A
,
0x6E
,
0x33
,
0x92
,
0x88
,
0x29
,
0xB5
,
0xB4
,
0x71
,
0xA9
,
0xCE
,
0xC3
,
0x34
,
0x50
,
0x59
,
0xBF
,
0x2D
,
0x57
,
0x22
,
0xA6
,
0x30
,
0x04
,
0xB2
,
0xCD
,
0x36
,
0xD5
,
0x68
,
0x4D
,
0x5B
,
0x45
,
0x9E
,
0x85
,
0xCF
,
0x9D
,
0xCC
,
0x61
,
0x78
,
0x32
,
0x76
,
0x31
,
0xE3
,
0x80
,
0xAD
,
0x39
,
0x4F
,
0xFA
,
0x72
,
0x83
,
0x4C
,
0x86
,
0x60
,
0xB7
,
0xD7
,
0x63
,
0x0C
,
0x44
,
0x35
,
0xB3
,
0x7B
,
0x19
,
0xD4
,
0x69
,
0x08
,
0x0B
,
0x1F
,
0x3D
,
0x11
,
0x79
,
0xD3
,
0xEE
,
0x93
,
0x42
,
0xDE
,
0x23
,
0x3B
,
0x5D
,
0x8D
,
0xA5
,
0x77
,
0x5F
,
0x58
,
0xDB
,
0x97
,
0xF6
,
0x7A
,
0x18
,
0x52
,
0x15
,
0x74
,
0x25
,
0x62
,
0x2C
,
0x05
,
0xE8
,
0x0D
,
0x98
,
0x2A
,
0x43
,
0xE2
,
0xEF
,
0x48
,
0x87
,
0x49
,
0x1C
,
0xCA
,
0x2B
,
0xA7
,
0x8A
,
0x09
,
0x81
,
0xE7
,
0x53
,
0xAA
,
0xFF
,
0x6F
,
0x8E
,
0x91
,
0xF1
,
0xF0
,
0xA4
,
0x46
,
0x3A
,
0x7D
,
0x54
,
0xEB
,
0x2F
,
0xC1
,
0xC0
,
0x0E
,
0xBD
,
0xE1
,
0x6C
,
0x64
,
0xBE
,
0xE4
,
0x02
,
0x3C
,
0x5A
,
0xA8
,
0x9F
,
0x37
,
0xAF
,
0xA0
,
0x13
,
0xED
,
0x1B
,
0xEC
,
0x8B
,
0x3E
,
0x7E
,
0x27
,
0x99
,
0x75
,
0xAB
,
0xFE
,
0xD9
,
0x3F
,
0xF3
,
0xEA
,
0x70
,
0xF7
,
0x95
,
0xBA
,
0x1D
,
0x40
,
0xB0
,
0xF9
,
0xE5
,
0xF8
,
0x06
,
0xBC
,
0xB6
,
0x03
,
0xC9
,
0x10
,
0x9C
,
0x2E
,
0x89
,
0x5C
,
0x7F
,
0xB1
,
0x1A
,
0xD6
,
0x90
,
0xAE
,
0xDA
,
0xE6
,
0x5E
,
0xB9
,
0x84
,
0xE9
,
0x55
,
0xBB
,
0xC7
,
0x0A
,
0xE0
,
0x66
,
0xF2
,
0xD8
,
0xCB
,
0x00
,
0x12
,
0xB8
,
0x17
,
0x94
,
0x6A
,
0x4A
,
0x01
,
0x24
,
0x14
,
0x51
,
0x07
,
0x65
,
0x21
,
0xC8
,
0x38
,
0xFD
,
0x8F
,
0xC4
,
0xF5
,
0xFC
};
unsigned char byte_404220[
520
];
unsigned char byte_404420[
65537
];
int
dword_404100[]
=
{
2
,
4
,
8
,
0x10
,
0x20
,
0x40
,
0x80
,
0
};
using namespace std;
int
sub_401580(unsigned char
*
a2) {
int
v2;
/
/
ebp
unsigned char
*
v3;
/
/
eax
int
*
v4;
/
/
esi
unsigned char
*
v5;
/
/
ecx
int
v6;
/
/
edi
unsigned char
*
v7;
/
/
ecx
int
v8;
/
/
edx
unsigned char
*
v9;
/
/
eax
int
v10;
/
/
ecx
int
v11;
/
/
esi
int
v12;
/
/
eax
unsigned char v13;
/
/
dl
int
v14;
/
/
edi
int
v15;
/
/
eax
int
v16;
/
/
ecx
int
v17;
/
/
esi
int
i;
/
/
eax
char v19;
/
/
dl
unsigned char v21;
/
/
[esp
+
10h
] [ebp
-
Ch]
unsigned char v22;
/
/
[esp
+
11h
] [ebp
-
Bh]
unsigned char v23;
/
/
[esp
+
12h
] [ebp
-
Ah]
unsigned char v24;
/
/
[esp
+
13h
] [ebp
-
9h
]
unsigned char
*
v25;
/
/
[esp
+
14h
] [ebp
-
8h
]
v21
=
0
;
v22
=
0
;
v23
=
0
;
v24
=
0
;
v2
=
1
;
v25
=
byte_404420;
for
(i
=
0
; i <
8
; i
+
+
)
byte_404000[i]
=
a2[i];
do
{
byte_404220[
0
]
=
byte_404000[v2
-
1
];
byte_404220[
1
]
=
v2;
v3
=
byte_404220;
v4
=
dword_404100;
v5
=
&byte_404220[dword_404100[
0
]];
do
{
v6
=
*
v4;
/
/
2
,
4
,
8
,
10h
,
20h
,
40h
,
80h
if
(
*
v4 >
0
)
{
do
{
v7
=
v5
+
1
;
*
(v7
-
1
)
=
byte_404000[
*
v3];
*
v7
=
*
v3
+
1
;
v5
=
v7
+
1
;
+
+
v3;
-
-
v6;
}
while
( v6 );
}
+
+
v4;
}
while
( v4 < &(dword_404100[
7
]) );
v8
=
256
;
do
{
+
+
v25[
*
v3
+
+
];
-
-
v8;
}
while
( v8 );
+
+
v2;
v25
+
=
256
;
}
while
( v2
-
1
<
256
);
v9
=
&byte_404420[
0x28
];
v10
=
256
;
do
{
if
(
*
(v9
-
40
) )
+
+
v21;
if
(
*
(v9
-
26
) )
+
+
v22;
if
(
*
v9 )
+
+
v23;
if
( v9[
39
] )
+
+
v24;
v9
+
=
256
;
-
-
v10;
}
while
( v10 );
if
( v21
=
=
0xA9
&& v22
=
=
0xAC
&& v23
=
=
0xA7
&& v24 >
0xC8u
){
for
(i
=
0
; i <
8
; i
+
+
){
printf(
"%hhX"
, a2[i]);
}
}
return
0
;
}
int
main(){
unsigned char flag[]
=
{
0x1e
,
0x28
,
0x4b
,
0x6d
,
0x8c
,
0xa3
,
0xd2
,
0xfb
};
do{
memset(byte_404420,
0
,
65536
);
sub_401580(flag);
}
while
(next_permutation(flag, flag
+
8
));
return
0
;
}
#include <stdio.h>
#include <stdint.h>
#include <algorithm>
#include <cstring>
unsigned char byte_404000[]
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0xA2
,
0x9B
,
0xF4
,
0xDF
,
0xAC
,
0x7C
,
0xA1
,
0xC6
,
0x16
,
0xD0
,
0x0F
,
0xDD
,
0xDC
,
0x73
,
0xC5
,
0x6B
,
0xD1
,
0x96
,
0x47
,
0xC2
,
0x26
,
0x67
,
0x4E
,
0x41
,
0x82
,
0x20
,
0x56
,
0x9A
,
0x6E
,
0x33
,
0x92
,
0x88
,
0x29
,
0xB5
,
0xB4
,
0x71
,
0xA9
,
0xCE
,
0xC3
,
0x34
,
0x50
,
0x59
,
0xBF
,
0x2D
,
0x57
,
0x22
,
0xA6
,
0x30
,
0x04
,
0xB2
,
0xCD
,
0x36
,
0xD5
,
0x68
,
0x4D
,
0x5B
,
0x45
,
0x9E
,
0x85
,
0xCF
,
0x9D
,
0xCC
,
0x61
,
0x78
,
0x32
,
0x76
,
0x31
,
0xE3
,
0x80
,
0xAD
,
0x39
,
0x4F
,
0xFA
,
0x72
,
0x83
,
0x4C
,
0x86
,
0x60
,
0xB7
,
0xD7
,
0x63
,
0x0C
,
0x44
,
0x35
,
0xB3
,
0x7B
,
0x19
,
0xD4
,
0x69
,
0x08
,
0x0B
,
0x1F
,
0x3D
,
0x11
,
0x79
,
0xD3
,
0xEE
,
0x93
,
0x42
,
0xDE
,
0x23
,
0x3B
,
0x5D
,
0x8D
,
0xA5
,
0x77
,
0x5F
,
0x58
,
0xDB
,
0x97
,
0xF6
,
0x7A
,
0x18
,
0x52
,
0x15
,
0x74
,
0x25
,
0x62
,
0x2C
,
0x05
,
0xE8
,
0x0D
,
0x98
,
0x2A
,
0x43
,
0xE2
,
0xEF
,
0x48
,
0x87
,
0x49
,
0x1C
,
0xCA
,
0x2B
,
0xA7
,
0x8A
,
0x09
,
0x81
,
0xE7
,
0x53
,
0xAA
,
0xFF
,
0x6F
,
0x8E
,
0x91
,
0xF1
,
0xF0
,
0xA4
,
0x46
,
0x3A
,
0x7D
,
0x54
,
0xEB
,
0x2F
,
0xC1
,
0xC0
,
0x0E
,
0xBD
,
0xE1
,
0x6C
,
0x64
,
0xBE
,
0xE4
,
0x02
,
0x3C
,
0x5A
,
0xA8
,
0x9F
,
0x37
,
0xAF
,
0xA0
,
0x13
,
0xED
,
0x1B
,
0xEC
,
0x8B
,
0x3E
,
0x7E
,
0x27
,
0x99
,
0x75
,
0xAB
,
0xFE
,
0xD9
,
0x3F
,
0xF3
,
0xEA
,
0x70
,
0xF7
,
0x95
,
0xBA
,
0x1D
,
0x40
,
0xB0
,
0xF9
,
0xE5
,
0xF8
,
0x06
,
0xBC
,
0xB6
,
0x03
,
0xC9
,
0x10
,
0x9C
,
0x2E
,
0x89
,
0x5C
,
0x7F
,
0xB1
,
0x1A
,
0xD6
,
0x90
,
0xAE
,
0xDA
,
0xE6
,
0x5E
,
0xB9
,
0x84
,
0xE9
,
0x55
,
0xBB
,
0xC7
,
0x0A
,
0xE0
,
0x66
,
0xF2
,
0xD8
,
0xCB
,
0x00
,
0x12
,
0xB8
,
0x17
,
0x94
,
0x6A
,
0x4A
,
0x01
,
0x24
,
0x14
,
0x51
,
0x07
,
0x65
,
0x21
,
0xC8
,
0x38
,
0xFD
,
0x8F
,
0xC4
,
0xF5
,
0xFC
};
unsigned char byte_404220[
520
];
unsigned char byte_404420[
65537
];
int
dword_404100[]
=
{
2
,
4
,
8
,
0x10
,
0x20
,
0x40
,
0x80
,
0
};
using namespace std;
int
sub_401580(unsigned char
*
a2) {
int
v2;
/
/
ebp
unsigned char
*
v3;
/
/
eax
int
*
v4;
/
/
esi
unsigned char
*
v5;
/
/
ecx
int
v6;
/
/
edi
unsigned char
*
v7;
/
/
ecx
int
v8;
/
/
edx
unsigned char
*
v9;
/
/
eax
int
v10;
/
/
ecx
int
v11;
/
/
esi
int
v12;
/
/
eax
unsigned char v13;
/
/
dl
int
v14;
/
/
edi
int
v15;
/
/
eax
int
v16;
/
/
ecx
int
v17;
/
/
esi
int
i;
/
/
eax
char v19;
/
/
dl
unsigned char v21;
/
/
[esp
+
10h
] [ebp
-
Ch]
unsigned char v22;
/
/
[esp
+
11h
] [ebp
-
Bh]
unsigned char v23;
/
/
[esp
+
12h
] [ebp
-
Ah]
unsigned char v24;
/
/
[esp
+
13h
] [ebp
-
9h
]
unsigned char
*
v25;
/
/
[esp
+
14h
] [ebp
-
8h
]
v21
=
0
;
v22
=
0
;
v23
=
0
;
v24
=
0
;
v2
=
1
;
v25
=
byte_404420;
for
(i
=
0
; i <
8
; i
+
+
)
byte_404000[i]
=
a2[i];
do
{
byte_404220[
0
]
=
byte_404000[v2
-
1
];
byte_404220[
1
]
=
v2;
v3
=
byte_404220;
v4
=
dword_404100;
v5
=
&byte_404220[dword_404100[
0
]];
do
{
v6
=
*
v4;
/
/
2
,
4
,
8
,
10h
,
20h
,
40h
,
80h
if
(
*
v4 >
0
)
{
do
{
v7
=
v5
+
1
;
*
(v7
-
1
)
=
byte_404000[
*
v3];
*
v7
=
*
v3
+
1
;
v5
=
v7
+
1
;
+
+
v3;
-
-
v6;
}
while
( v6 );
}
+
+
v4;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课