Pwn

pwnable.kr(collision)

Posted on 2020-01-02,2 min read

ssh连接服务器,查看下目录


和上一题差不多。直接查看源码

#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=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;
}

分析下:这段程序主要是让我输入20个字符。将20个字符传入check_password函数强制转换为int类型,循环赋值给res,最后与0x21DD09EC比较
这里。我们用Visual Studio调试下。更明显

可以看到,在栈中。我们看到了数据,
4141414142424242434343434444444445454545
A A A A B B B B C C C C D D D D E E E E
由于是字符,存入的时候只占了1字节,但是,for循环读取的时候p[i],i是4字节的int类型,所以,读取的时候就会四字节读取一次,第一次读取AAAA,第二次读取BBBB,而不是第一次A,第二次A

接下来,程序就会把0x41414141+0x42424242+0x43434343+0x44444444+0x45454545,加在一起与目标数值比较

构造PAYLOAD,只要不为\x00,程序不会结束,就行了

./1 `python -c 'print "\x02"*16+"\xE4\x01\xD5\x19"'
33686018
0x2020202
33686018
0x2020202
33686018
0x2020202
33686018
0x2020202
433390052
0x19d501e4

下一篇: pwnable.kr(fd)→