190706——【CTF】pwn:pwnable.kr 刷题之 collision

此题为 pwnable.kr 中 toddler级别的第二题
涉及小端法存储,python -c,字符处理等知识

原题链接:https://pwnable.kr/play.php

190706——【CTF】pwn:pwnable.kr 刷题之 collision_第1张图片
题目描述:
190706——【CTF】pwn:pwnable.kr 刷题之 collision_第2张图片
依照昨天的套路,登上之后看可以文件,和昨天的第一题一模一样的套路:
在这里插入图片描述
直接看源码:

#include 
#include 
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位的参数,而后,参数经过函数check_password的处理后和hashcode比较,hashcode是一个20位的十六进制数0x21DD09EC,若相等,则打印flag。

check_password函数的主要效果是,将传入的char型指针强制类型转换为int型,然后将整型的ip数组(字符串转为整型数时长度被切割)累加得到结果。

该步中的强制类型转换,其本质是将一个字符串作为整型读取,char型变量占1个字节,而int型占4字节,则转换后,将一次读取4个字节,当做一个int。

题目要求输入20位数,经过转换后,为5位int,这和check_password函数中从ip[0]到ip[4]一共累加5位是一致的。

所以解题的思路就是,输入一个20位的参数,使其转换成5个int之后累加等于0x21DD09EC

找到5个这样的数并不难:
190706——【CTF】pwn:pwnable.kr 刷题之 collision_第3张图片
难的是怎么传进去?
查了一下,用了python,使用-c参数传递,这个地方查了一下文档1

-c
执行 command 中的 Python 代码。 command 可以为一条或以换行符分隔 的多条语句,其中前导空格像在普通模块代码中一样具有作用。

190706——【CTF】pwn:pwnable.kr 刷题之 collision_第4张图片

同时,因为小端法的缘故,这个数字需要倒过来放进去

./col `python-c "print '\xe0\xfd\xd0\x15' + '\x03\x03\x03\x03' * 4 "`

注意这个命令,是用 `` 倒引号括起来的。这里试了 ’ ’ 很多次,每次都报不是20位,可能是编码的问题。

同时,使用倒引号不仅是格式的要求,它本身也是shell命令的一部分:

反引号 ``

反引号``是命令替换,命令替换是指 Shell 可以先执行`` 中的命令,将输出结果暂时保存,在适当的地方输出。语法: `command`

运行之后即可得到flag
在这里插入图片描述
参考:
1、(int* )p是什么意思
2、什么是大端法和小端法
3、linux shell 中 ‘’,""和`` 的区别


  1. python文档——命令行与环境 ↩︎

你可能感兴趣的:(pwn)