PWNABLE学习笔记【updating】
PWNABLE学习笔记 [updating]
这是我学习system exploit时, 在pwnable上做题的一个记录, 感谢这个平台提供的练习, 帮助我入门学习。
PWNABLE:Link
WriteUp(14 challenges): Link
Challenge 1: [fd]
题目文件:文件fd.c , 文件fd(fd.c编译后的可执行二进制文件), 文件flag
1 |
|
题目要点
作为第一个题目,主要的知识点是让我们掌握C语言的文件IO标识符,open和read(题目中)。
关注题目中的以下几个要点:
主函数中的参数
- argc 保存的是命令行中总的参数个数,并且包含程序名。 e.g.
./test 1 2 3 4
,那么,argc的值即为 5 - agrv[] 数组中保存传入的参数,参数可以是多个的,e.g.
./test 1 2 3
,那个argv[0] == 1, argv[1] == 2, argv[2] == 3 - envp[] 数组中保存系统的环境变量,操作系统运行程序时,通过envp参数将系统环境变量传递给程序
- argc 保存的是命令行中总的参数个数,并且包含程序名。 e.g.
atoi() 函数
- 该函数(atoi, ascii to integer)会将字符串转化为整数
- 函数会扫描输入的参数,跳过空白字符(空格、tab缩进等),将数字的字符转为整型,如果无法有效转换(字符串以英文字母开头),则会返回0
- 注意,函数会保留+-符号,但会舍弃小数点及后面的数字
read() 函数
ssize_t read (int fd, void *buf, size_t count);
功能:用于从文件描述符(fd, file description)对应的文件读取数据(从打开的设备或文件中读取数据,也可以为终端上的数据)
在UNIX/Linux平台上,fd有三个(fd = 0, fd = 1; fd = 2),分别对应控制台(Console)的标准输入,标准输出,标准错误输出
e.g. 在
read(0,buf,32)
中,fd=0,表示进行标准输入(控制台,键盘输入),读取最多32个字节到buf中常规的用途是配合open()函数,实现文件的读取
1 | int fp = open("./test.txt", O_RDONLY); //只读模式打开文件 |
strcmp() 函数
int strcmp(const char *s1, const char *s2);
- 功能:比较字符串s1与字符串s2,区分大小写,相同返回0,不同则返回s1与s2的差值
system() 函数
int system(char *command);
- 功能:发出一个terminal命令
补充:open() 函数
int open(const char *path, int oflags,mode_t mode);
功能:用于建立了一条到文件或设备的访问路径,配合read()等函数,实现文件的读写和设备的操作
重要补充:文件权限
在题目中,我们以fd的用户身份登入,我们的操作都是受身份限制的,因此我们需要对题目中的文件进行权限的识别。使用groups fd
判断fd用户所属的组为fd。使用命令ls -l
可以查看当年目录下的所有文件的权限:
1 | -r-sr-x--- 1 fd_pwn fd 7322 Jun 11 2014 fd |
依次分析:
权限:前面由连字符和字母组成的部分,例如
-r-sr-x---
, 该部分由四个部分组成,共占10位(1 + 3 + 3 + 3)类型 所有者权限 所属组权限 其他人权限 - r - s r - x - - - 类型部分
-
代表文件d
代表目录l
代表链接c
代表字符型设备b
代表块设备n
代表网络设备权限部分
-
权限为空r
可读w
可写x
可执行s
当执行该文件时将具有该文件所有者的权限,注意这个,比较特殊
所有者:例如fd_pwn,表示fd文件的所有者是fd_pwn
- 分析第一条,可以发现fd和目标文件flag是同一个所有者
所属组:例如fd, 表示fd文件所属组是fd,同一个组中的有不同的用户/角色
- 继续分析第一条,可以发现fd和flag是不是同一个组,flag属于root组
文件大小
创建事件
文件名称
综合以上的条件,我们分析目标文件flag,可以得出:
- flag是文件
- flag的权限为:所有者可读;所属组可读;其他人无权限
- flag的所有者为:fd_pwn
- flag的所属组为:root
分析我们可以利用的二进制可执行文件fd可以发现:
fd是文件
fd的权限为:所有者可读,并且当执行该文件时将具有该文件所有者的权限;所属组可读可执行;其他人无权限
fd的所有者为fd_pwn
fd的所有组为fd,注意,这里很重要, 可以发现我们登入使用的用户fd属于用户组fd,与该文件相同。结合文件权限中表明的,所属组可以执行该文件,并且执行该文件时可以获取该文件所有者的权限,而文件fd与文件flag属于同一个所有者fd_pwn, 文件flag的所有者可以读取文件flag。
那么,我们的用户fd就可以执行文件fd,暂时获取所有者fd_pwn的权限,进而可以读取文件flag
总结一下,在Linux/Unix中一切皆文件,弄清楚文件的权限,我们的角色,才可以明确我们想进行的操作,一切从实际出发,而思维又要高于实际。
题目总结
这是第一道题目,主要考察文件IO的知识点。在分析过程中,我们不经要去看程序代码,更要注意理清文件权限和我们的角色,这样才能更加明确总体的思路。
在做题或者分析的过程中,我们的第一步不是直接去分析程序文件,而是要查看当前用户角色和文件权限,明确自己可以做什么,不可以做什么,这会更好地帮助我们组织后面的操作。