pwnable从入门到放弃第二题,
ssh [email protected] -p2222 (pw:guest)
同样是登录,然后看到了col.c、col、flag三个文件,读一下col.c
#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=;
for(i=; i<; i++){
res += ip[i];
}
return res;
} int main(int argc, char* argv[]){
if(argc<){
printf("usage : %s [passcode]\n", argv[]);
return ;
}
if(strlen(argv[]) != ){
printf("passcode length should be 20 bytes\n");
return ;
} if(hashcode == check_password( argv[] )){
system("/bin/cat flag");
return ;
}
else
printf("wrong passcode.\n");
return ;
}
发现就限定了字符串长度为20,然后做了一次check函数,函数中就是把输入参数的字符串指针当做整数指针进行解析然后把结果相加,所以碰撞还是很简单的。
没想到= = 找轮子是永远的痛,吐口血再写。
可以把hash分解成 b*4+c的形式,我先猜测了c,当c=0x01010104时,(hash-c)mod 4 = 0,因此b存在。
接下来肯定得编码然后就直接调用就好了,结果是找不到能转换的轮子。struct.pack不会用QAQ。
最后迫不得已用了pwn.p32,pwntools大法好,先膜一发。
那干脆就直接调用子线程就好了。
需要找到一个可写的目录,我用了winscp图形化界面去找,找到/tmp下程序可写可执行,恩。
把脚本放到下面,就好了
import struct
import pwn
a = 0x21DD09EC
c = 0x01010104
b = (a-c)/4 col = pwn.p32(c)+pwn.p32(b)*4
print (col) import subprocess
child = subprocess.Popen(args= ['/home/col/col',str(col)])
child.wait()
print("over")
运行一下