奇怪的pwn入门(第n+1天)

奇怪的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: 要转换为整数的字符串

    返回值

    成功: 返回转换后的长整数
    失败:返回0

    PS:文件描述符:

    在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())##接收服务器传回的消息

参考资源:

write函数的详解与read函数的详解

pwn学习笔记汇总

原文地址:https://www.cnblogs.com/Ziggy29/p/13258638.html