多次比赛在pwn上面被花式吊打了,最近来学习点pwn的相关知识吧,以外得到一个网站pwnable.kr.提供了各式各样的环境让我们去练习,我自己也将练习的过程和心得体会在博客上一一记录吧.以下是入门题目,考的是linux下的文件描述符.(小菜心得,大牛勿笑,如有错误,还请指正)
得到程序的源代码如下
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 char buf[32]; 5 int main(int argc, char* argv[], char* envp[]){ 6 if(argc<2){ 7 printf("pass argv[1] a number\n"); 8 return 0; 9 } 10 int fd = atoi( argv[1] ) - 0x1234; 11 int len = 0; 12 len = read(fd, buf, 32); 13 if(!strcmp("LETMEWIN\n", buf)){ 14 printf("good job :)\n"); 15 system("/bin/cat flag"); 16 exit(0); 17 } 18 printf("learn about Linux file IO\n"); 19 return 0; 20 21 }
因为初次接触linuxC,对代码"int main(int argc, char* argv[], char* envp[])"中的参数百度了一下,int argc指的执行程序时命令行的参数个数,之后的数组argv[]用来存放命令行中参数的具体值.所以这道题如果只键入了一个参数的话程序就会输出"pass argv[1] a number\n"让我们给第二个参数一个具体的数值.
在第10行代码中fd被赋值为第二个参数通过atoi()函数转化为整型之后的值减去0x1234(十进制的4660)之后的值。在linuxC下read()函数是涉及到了文件描述的函数,通过fd的取值的不同来完成向buf中输入32个字符或者是从buf中输出32个字符.(关于文件描述符可以看看这个大牛的解释http://blog.csdn.net/cywosp/article/details/38965239)因为程序在之后将buf与字符串"LETMEWIN\n"做了对比,我们可以知道,这个时候需要文件描述符fd==0来进行对buf做输入操作.而通过这上面对fd的定义我们就可以知道argv[1]==0x1234.所以构造语句
echo "LETMEWIN"|./fd 4660 (此处echo"LETMEWIN"是将字符串LETMEWIN作为echo的参数传入buf中,后一句的./fd 4660是为了构造第二个参数大小刚刚好等于0x1234来使fd等于0从而通过read函数来完成字符串对比过程)