pwnable.kr
源碼
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
int main(int argc, char* argv[]){
if(argc<2){
printf("usage : %s [passcode]\n", argv[0]);
return 0;
}
if(strlen(argv[1]) != 20){
printf("passcode length should be 20 bytes\n");
return 0;
}
if(hashcode == check_password( argv[1] )){
system("/bin/cat flag");
return 0;
}
else
printf("wrong passcode.\n");
return 0;
}
解題
從主函數(shù)入手,根據(jù)源碼可以看出,我們要運行程序的命令應為:./col + [passcode]
,而且這個passcode
的長度為20,然后這個passcode
會傳入到check_password
函數(shù)中返回出一個res
,如果這個res == hashcode(0x21DD09EC)
就能得到flag
,解題關鍵就是理解check_password
函數(shù)的運算邏輯。
在check_password
中,我們傳入了一個char
型的p
,然后使用 (int*)
進行強制轉(zhuǎn)換成int
指針,char
的存儲大小為1
字節(jié),而int
的存儲大小為4
字節(jié),也就是說我們將輸入的p
轉(zhuǎn)換成了5
個數(shù)組,而這5
個數(shù)組相加之和要等于0x21DD09EC
那我們可以簡單的想0x21DD09EC = 4 * X + Y
,簡單設一下X = 0x04040404
,則Y = 0x21DD09EC - 4 * 0x04040404 = 0x11CCF9DC
然后將他們傳回去,就可以獲得flag
,但是要注意小端問題
flag
= daddy! I just managed to create a hash collision :)