奇怪的pwn入门(第n+1天)
先从比较基础的 pwnable 开始做起吧
C语言函数
-
write()
原型:
write(int fd,const void*buf,size_t count);
参数说明:
fd: 是文件描述符(write所对应的是写,即就是1)
buf: 通常是一个字符串,需要写入的字符串
count:是每次写入的字节数返回值:
成功:返回写入的字节数
失败:返回-1并设置errno -
read()
原型:
read(int fd,void*buf,size_t count)
参数说明:
fd: 是文件描述符
buf: 为读出数据的缓冲区;
count: 为每次读取的字节数(是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移)返回值:
成功:返回读出的字节数
失败:返回-1,并设置errno,如果在调用read之前到达文件末尾,则这次read返回0 -
atoi()[类似数字串强转数字]
原型:
int atoi(const char *str)
参数说明:
str: 要转换为整数的字符串返回值:
成功: 返回转换后的长整数
失败:返回0PS:文件描述符:
在linux中,进程是通过文件描述符(file descriptors 简称fd)来访问文件的,文件描述符实际上是一个整数。在程序刚启动的时候,默认有三个文件描述符,分别是:0(代表标准输入),1(代表标准输出),2(代表标准错误)。再打开一个新的文件的话,它的文件描述符就是3。
1.fd
1.根据题目信息ssh fd@pwnable.kr -p2222 (pw:guest)
大意是ssh通过2222端口连接远程服务器pwnable.kr,fd为用户名,guest为密码
然后ls -l查看都有啥
2.vim打开fd.c康一下
先判断参数是否小于2,若小于2就输出"传给argv[1]一个数字"然后结束。这里的参数应该是包括我们运行的文件名,所以我们只用额外传入一串数字即可继续运行。
之后是把输入的数(argv[1])与0x1234相减作为文件描述符,再将文件描述符对应的源读入32字节到buf中。将buf与LETMEWIN字符串相比较,若相同则输出flag中的内容。
这里fd:0(代表标准输入),1(代表标准输出),2(代表标准错误)。再打开一个新的文件的话,它的文件描述符就是3。应该没有打开文件这种操作,所以我们使得fd为0应该就可以进行将“LETMEWIN”读入buf的操作。
这里运行fd并传入0x1234的十进制4660,并输入LETMEWIN,得到flag(我第一遍做的时候并不知道那就是flag55555555)
事实上是以后要用python写exp才行
from pwn import *
pwn_ssh=ssh(host='pwnable.kr',user='fd',password='guest',port=2222)
print (pwn_ssh.connected())
sh=pwn_ssh.process(argv=['fd','4660'],executable='./fd')##打开一个进程,传入参数,其中argv[ ]数组的第一个参数是程序名,第二个参数是输入程序的参数,executable是指要运行的可执行文件;
sh.sendline("LETMEWIN")##传入字符串
print (sh.recvall())##接收服务器传回的消息
参考资源: