感觉自己什么都不会,各种东西都开始学了。这个假期看看自己能把pwn学到什么程度~~
www.pwnable.kr.com come on
题目:fd
补一点知识:
linux文件权限:分为所有者、用户组、其他用户,在这里,flag明显是root创建的,只有root和与root在同一个用户组中的用户具有可读权限,而其他用户是没有读权限的,但是fd.c是有read的权限的。
函数解释:
1 int argc 表示的是命令行中输入的参数
2 char* argv[]表示的是包括文件名在内的参数,文件名是argv[0]
3 char* envp[]是环境变量,比如path=c:\windows之类的东西。它没有一个整数来为它记数是通过最后一个evnp[i]==NULL来表示结尾的。
4 atoi:
【函数说明】atoi() 函数会扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。
【返回值】返回转换后的整型数;如果 str 不能转换成 int 或者 str 为空字符串,那么将返回 0。
温馨提示:ANSI C 规范定义了 stof()、atoi()、atol()、strtod()、strtol()、strtoul() 共6个可以将字符串转换为数字的函数,大家可以对比学习。另外在 C99 / C++11 规范中又新增了5个函数,分别是 atoll()、strtof()、strtold()、strtoll()、strtoull()
5 read()
read()会把参数fd所指的文件传送nbyte个字节到buf指针所指的内存中。若参数nbyte为0,则read()不会有作用并返回0。返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或无可读取的数据。错误返回-1,并将根据不同的错误原因适当的设置错误码。
在这里是从fd指向的文件中读取32个字节写到Buf中。len是表示都回来的字节数。
6 strcmp
设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1>str2,则返回正数;
若str1<str2,则返回负数。
这样再去看代码就清楚多了,就是输入命令行参数,如果小于2就打印一句话退出,否则用读取一个文件,从中读32个字节,写到buf中,对比字符串,若相等就输出flag。
进一步细看
我的想法是atoi(argv[1])-0x1234会不会是一个文件句柄,这个文件的开头正好是对应的字符串?可是这个文件是什么呢?很快就否定了这个无知的想法。
后来查了查资料,是read函数有个特定:
fd == 0为从标准输入读取
fd == 1为从标准输出读取
fd == 2为从标准错误输出 读取
那么如果fd==0,不就可以从标准输入中读取存储到buf了么?
那么接下来就是让fd=0 à atoi(argv[1]) = 0x1234 à 0x1234=4660(十进制)。
fd=0的时候,从标准输入中输入:LETMEWIN,来满足这个:
OK!!!
本题总结与收获
对linux的函数特性要深入理解,尤其是一些容易产生漏洞的函数