Toddler's Bottle - collision
- A constant hashcode is 0x21DD09EC.
- User is required to provide a 20 bytes passcode.
- A check_password function is applied to this passcode.
- You can get the flag if the result equals to the constant hashcode.
How your passcode is caculated by check_password ?
- int* ip = (int*)p => change char* p to int* p. int is 4 bytes, char is only 1 byte.
- passcode is 20 bytes, so now it has five parts and each parts is a int size(4bytes).
- for each part, the function adds them.
- sum_of__five__parts == hashcode???
- yes=>get flag; no=>wrong passcode.
code:
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;
}
Solution
Divide constant 0x21DD09EC into five parts. For example, 0x21DD09EC = a + b*4. Avoid using \x00 which is the NULL character to end a string.
My value: 0x21DD09EC = 0x69f6bc8+0x6cf6789*4
./col `python -c 'print "\xc8\x6b\x9f\x06"+"\x89\x67\xcf\06"*4'