pwnable.kr-fd
误入一个游戏网站。。。(真的像是在打游戏)
贴一下他的等级,我才刚刚开始,感觉挺有意思,和大家分享下
幼儿瓶:非常简单的挑战,都是一些简单的错误。
Rookiss:新手需要掌握的典型漏洞利用。
怪诞:这些挑战是怪诞的,解决起来很痛苦,但获得Flag后,成就感满满。
黑客的秘密:针对这些挑战的预期解决方案涉及特殊的黑客技术。

题目是fd,一下想到文件描述符(file descriptor)

连上看看,下面有flag和fd、fd.c,只有fd.c有访问权限

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
argc 保存 命令行总的参数个数(程序文件名也算在内,所以 argc 至少值应该大于等于 1))
argv 是一个指针数组,其元素个数是 argc,存放的是指向每一个参数的指针,所以 argv[1] 就表示程序运行的第二个命令参数(第一个命令参数是 argv[0],也就是程序名)。envp 是一个指针数组,指向系统的环境变量字符串,这里没有用到。
从源代码中,我们可以看到关键一句在于通过第 2 个 if 语句的检查,如果 buf 变量的值为 LETMEWIN 字符串,那么就可以顺利打开 flag 文件。buf 是从哪里来呢?
len = read(fd, buf, 32);
向上溯源,可以看到,buf 的值来源于 read 函数读进来的内容。
C 语言中 read 函数的原型是:ssize_t read(int fd, void*buf, size_t count)。其中 fd 代表文件描述符,buf 为读出数据的缓冲区,count 是读取的字节数。
Linux 标准文件描述符是这样规定的:
数字 0 表示 STDIN,即标准输入,也就是我们通过运行程序之后,在命令行输入的数据。
数字 1 表示 STDOUT,即标准输出,也就是程序运行过程中,在终端显示的数据。
数字 2 表示 STDERR,即标准错误输入,也就是程序运行时如果发生错误,导致不能正常退出时,终端上会显示的信息。
所以,我们只需要让程序运行的第一个命令参数等于 0x1234 即可,转换成 10 进制的值是 4660。然后再写入LETMEWIN,就可以拿到flag了
输入
./fd 4660
LETMIWIN
即可

浙公网安备 33010602011771号