次のようにcol.cコードは次のとおりです。
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
|
#含める <string.hの>
符号なしの
長い
ハッシュコード=
0x21DD09EC
。
符号なしの ロング (CONST のchar *のP)
{
int型
* IP =(
int型
*)のp;
int型
私は、
int型の
A =
0
;
用
(i =
0
; iは<
5
; iは++){
RES + = IP [i]は、
}
リターン
のres;
}
INT メイン(int型 ARGC、チャー *のARGV [])
{
もし
(ARGC <
2
){
printf
(
"用法:%S [パスコード] n"は
、ARGV [
0
])。
リターン
0
;
}
もし
(
strlenを
(ARGV [
1
])!=
20
){
printf
(
「パスコード長は20 bytesnなければなりません」
)。
リターン
0
;
}
if(hashcode == check_password( argv[
1] )){
system(
"/bin/cat flag");
}
else
printf(
"wrong passcode.n");
return
0;
}
|
观察代码,可知代码逻辑过程是:
1.先输入一个不少于20字节长度的值
2.对输入的前五位整数求和(int类型,一个int等于4字节,5位int类型,恰好20字节)
3.求得的和与0x21DD09EC比较,若相等则通过
重点1:
这里将输入的char类型的指针强制转换为了int指针,从而ip指针一次能够指向4个字节大小的内存区域。画个图模拟一下内存布局:
思路1:将0x21DD09EC除以5变为4字节为一组,分别输入,最后以4字节为一组进行求和即可。
比如:
1
2
3
4
|
>>>
0x21DD09EC/
5
113626824
>>> hex(
0x21DD09EC/
5)
'0x6c5cec8'
|
哦,稍等。好像不能被5整除哦。换个方式:4 x 0x01010101 + 0x1dd905e8
1
2
3
|
>>> hex(
0x21DD09EC
-4*
0x01010101)
'0x1dd905e8'
>>>
|
接下我们把刚刚的值输入:
1
2
3
|
col@ubuntu:~$ ./col `python -c
"print 16*'x01'+'xe8x05xd9x1d'"`
daddy! I just managed to create a
hash collision :)
col@ubuntu:~$
|
YES,GET FLAG!