pwnable.krToddler‘s Bottle-[fd]
Posted KUSIA_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pwnable.krToddler‘s Bottle-[fd]相关的知识,希望对你有一定的参考价值。
打开题目审题
Mommy! what is a file descriptor in Linux?
* try to play the wargame your self but if you are ABSOLUTE beginner, follow this tutorial link:
https://youtu.be/971eZhMHQQw
ssh fd@pwnable.kr -p2222 (pw:guest)
Linux中的文件描述符是什么。如果你是完全的初学者,可以去youtube链接看视频。
解释下 SSH:
ssh fd@pwnable.kr -p2222 (pw:guest)
SSH 是Linux系统的登录工具,现广泛用于服务器登录和各种加密通信。其实在这里就是一个终端连接工具。
所以,打开CMD
输入命令回车,输入密码:guest 。即可登录服务器。
登录上就可以开始找flag了。
找到突破口
照例先 ls -la
fd@pwnable:~$ ls -la
total 40
drwxr-x--- 5 root fd 4096 Oct 26 2016 .
drwxr-xr-x 115 root root 4096 Dec 22 2020 ..
d--------- 2 root root 4096 Jun 12 2014 .bash_history
-r-sr-x--- 1 fd_pwn fd 7322 Jun 11 2014 fd
-rw-r--r-- 1 root root 418 Jun 11 2014 fd.c
-r--r----- 1 fd_pwn root 50 Jun 11 2014 flag
-rw------- 1 root root 128 Oct 26 2016 .gdb_history
dr-xr-xr-x 2 root root 4096 Dec 19 2016 .irssi
drwxr-xr-x 2 root root 4096 Oct 23 2016 .pwntools-cache
发现flag文件,尝试查看(肯定看不了
fd@pwnable:~$ cat flag
cat: flag: Permission denied
fd@pwnable:~$
果然不能看。
看下别的,文件flag肯定是最后的答案,所以需要看看其他文件找寻突破口。
还有一个c语言源文件fd.c
和可执行文件fd
。
那没什么说的,看看fd.c。
fd@pwnable:~$ cat 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;
}
找到重点 system("/bin/cat flag");
看到源码大概已经明白了,我们没有查看文件的权限,但是fd有,所以只要分析如何让代码执行system("/bin/cat flag");
即可。
相关c语言知识
int main( int argc , char * argv[ ] ,char * envp[ ])
main函数的参数列表保存了输入参数的信息:
第一个参数argc记录了输入参数的个数。且argc是包括程序本身在内的参数个数。如本题目,直接./fd运行,该参数实际上是1,而不是0。
第二个参数是字符串数组的,字符串数组的每个单元是char*类型的,指向一个c风格字符串,arg[ ]指向的数组中至少有一个字符指针,即arg[0].他通常指向程序中的可执行文件的文件名。
第三个参数是用来取得系统的环境变量,如:在DOS下,有一个PATH变量。当你在DOS提示符下输入一个命令的时候,DOS会首先在当前目录下找这个命令的执行文件。如果找不到,则到PATH定义的路径下去找,找到则执行,找不到返回Bad command or file name 。在DOS命令提示符下键入set可查看系统的环境变量。
int atoi(const char * str)
**函数说明:**C 库函数 int atoi(const char *str) 把参数 str 所指向的字符串转换为一个整数(类型为 int 型)。
ssize_t read(int fd, void * buf, size_t count);
函数说明:read()会把参数fd 所指的文件传送count 个字节到buf 指针所指的内存中. 若参数count 为0, 则read()不会有作用并返回0. 返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。
fd所指文件指的是什么
每一个进程在进程控制块中都保存着一分文件描述符表,文件描述符就是这个表的索引,文件描述符表中每个表项都有一个指向已打开文件的指针。
fd: 为打开文件的文件描述符,而每个进程都有一张文件描述符表,fd文件描述符就是这张表的索引。
Linux下 文件描述符(fd)与 文件指针(FILE*) 想了解更多可以看该链接。
简言之,在linux中,值为0、1、2的fd,分别代表标准输入
、标准输出
、标准错误输出
。
源代码分析
char buf[32];
int main(int argc, char* argv[], char* envp[]){
// 输入参数不能少于2 接一个参数就可以
if(argc<2){
printf("pass argv[1] a number\\n");
return 0;
}
// 将 argv[1] - 0x1234 赋值给fd
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
// 读取32字节到buf中,那么fd 必须为标准输入 即为0
len = read(fd, buf, 32);
// buf 中32字节一定是 LETMEWIN 这样就能得到flag
if(!strcmp("LETMEWIN\\n", buf)){
printf("good job :)\\n");
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\\n");
return 0;
}
代码看完了,想必如何做出来也都心里有数了。
参数一定要满足 fd=0
那么 参数 argv[1] = 0x1234 = 4660。
最后在输入“LETMEWIN” 即可。
找到FLAG
执行可执行文件fd。./fd 4660
回车。
fd@pwnable:~$ ./fd 4660
此时开始执行len = read(fd, buf, 32);
输入“LETMEWIN” 回车即可得到flag。
fd@pwnable:~$ ./fd 4660
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!
flag:mommy! I think I know what a file descriptor is!!
输入验证即可。
参考:
https://www.cnblogs.com/ftl1012/p/ssh.html
https://blog.csdn.net/qq_40657299/article/details/78332875
以上是关于pwnable.krToddler‘s Bottle-[fd]的主要内容,如果未能解决你的问题,请参考以下文章
pwnable.krToddler‘s Bottle-[fd]
pwnable.krToddler‘s Bottle-[random]