pwnable学习----fd
# pwnable学习----fd
[website](http://pwnable.kr/play.php)
首先贴出来题目。。。

嗯就是这个,按照题目描述,ssh远程连接目标主机
<ssh fd@pwnable.kr -p2222>
密码是 guest
OK,打开后是这个样子

那么先来看看这里有什么吧
<ls>
一共显示有3个文件
二进制文件 (fd)、c代码 (fd.c)、还有个(flag)
好的接下来每个文件试一下吧。
(fd.c)编译以后就是(fd)二进制文件运行了
(flag)没有权限打开了
好的那先来看看(fd.c)里面是什么吧
<less fd.c>
或者<cat fd.c>
可以看出来,运行二进制文件,带参数输入后,根据你的参数来判断,条件符合输出相应语句。
嗯这个是有两个提示的:
pass argc[1] a number -----提示一
learn about Linux file IO\n -----提示二
刚开始就没管这个提示--_--,导致走了很多弯路。。。
根据提示,必须要输入一个参数才能进入if下面的语句,否则就 return 0 了。
那么,代码里面的 argc,argv,envp又是什么意思呢?好吧,百度了一下找到了
[这是百度的网址](http://blog.csdn.net/tinide/article/details/8205841)
我自己照着上面敲了代码跑了一下
<#include<iostream>
using namespace std;
int main(int argc, char* argv[], char* env[])
{
cout<<"------argc-------"<<endl;
cout<<argc<<endl;
cout<<"------argc-------"<<endl;
int i;
cout<<"sdcssc"<<argv[0]<<endl;
for (i=0; i<argc; i++)
cout<<argv[i]<<endl;
cout<<"__--------env-------"<<endl;
for(i=0; env[i]!=NULL; i++)
cout<<env[i]<<endl;
return 0;
}>
<./fd hongshulin 123>

好吧从 env 我就不懂了...
现在明白了,运行程序后的第一个参数为 argv[1] 就是解题的关键了。
接下来是 atoi 函数了,找出字符串中的数字并输出
[atoi 函数](https://baike.baidu.com/item/atoi/10931331?fr=aladdin)
那么第一个参数要输入什么呢?随便输入一个,提示为“[learn about Linux file IO](https://segmentfault.com/a/1190000008179453)”。OK,看来要学习一下 Linux 的输入输出了。
这里面说的很清楚,“当需要读写文件时,也需要将相应的文件描述符作为参数传给读写函数。”
这里面也有关于 read() 函数的描述如下:
read()函数的使用方法:
原型定义:ssize_t read[1] (int fd, void *buf, size_t count);
使用的头文件:#include <unistd.h>
fd 是文件指针,读上来的数据保存在缓冲区 buf 中, count 为请求读取的字节数。
那么接下来只要传进去一个参数使得 fd==0 即可,嗯应该是因为穿进去的参数当作字符串,而且相对于人来说是 十进制 ,故换算 0x1234 == (4660)10 ,接着手动输入 LETMEWIN\0
得到这个了就

顺便查到的与之无关的一些命令:
grep 命令:使用 grep 查找一个二进制文件,输出匹配字符串的偏移量。
[网址](https://www.v2ex.com/t/155823)
grep -oba 'some string' binary.file (输出十进制偏移量)
gdb 命令:用gdb查看指定地址的内存内容
格式: x /nfu <addr>
[网址](https://www.cnblogs.com/super119/archive/2011/03/26/1996125.html)
网上找到的 pwnable.kr 的 writeup
[❤️❤️❤️](http://blog.csdn.net/u012763794/article/details/51992512)
[website](http://pwnable.kr/play.php)
首先贴出来题目。。。
嗯就是这个,按照题目描述,ssh远程连接目标主机
<ssh fd@pwnable.kr -p2222>
密码是 guest
OK,打开后是这个样子
那么先来看看这里有什么吧
<ls>
一共显示有3个文件
二进制文件 (fd)、c代码 (fd.c)、还有个(flag)
好的接下来每个文件试一下吧。
(fd.c)编译以后就是(fd)二进制文件运行了
(flag)没有权限打开了
好的那先来看看(fd.c)里面是什么吧
<less fd.c>
或者<cat fd.c>
可以看出来,运行二进制文件,带参数输入后,根据你的参数来判断,条件符合输出相应语句。
嗯这个是有两个提示的:
pass argc[1] a number -----提示一
learn about Linux file IO\n -----提示二
刚开始就没管这个提示--_--,导致走了很多弯路。。。
根据提示,必须要输入一个参数才能进入if下面的语句,否则就 return 0 了。
那么,代码里面的 argc,argv,envp又是什么意思呢?好吧,百度了一下找到了
[这是百度的网址](http://blog.csdn.net/tinide/article/details/8205841)
我自己照着上面敲了代码跑了一下
<#include<iostream>
using namespace std;
int main(int argc, char* argv[], char* env[])
{
cout<<"------argc-------"<<endl;
cout<<argc<<endl;
cout<<"------argc-------"<<endl;
int i;
cout<<"sdcssc"<<argv[0]<<endl;
for (i=0; i<argc; i++)
cout<<argv[i]<<endl;
cout<<"__--------env-------"<<endl;
for(i=0; env[i]!=NULL; i++)
cout<<env[i]<<endl;
return 0;
}>
<./fd hongshulin 123>
好吧从 env 我就不懂了...
现在明白了,运行程序后的第一个参数为 argv[1] 就是解题的关键了。
接下来是 atoi 函数了,找出字符串中的数字并输出
[atoi 函数](https://baike.baidu.com/item/atoi/10931331?fr=aladdin)
那么第一个参数要输入什么呢?随便输入一个,提示为“[learn about Linux file IO](https://segmentfault.com/a/1190000008179453)”。OK,看来要学习一下 Linux 的输入输出了。
这里面说的很清楚,“当需要读写文件时,也需要将相应的文件描述符作为参数传给读写函数。”
这里面也有关于 read() 函数的描述如下:
read()函数的使用方法:
原型定义:ssize_t read[1] (int fd, void *buf, size_t count);
使用的头文件:#include <unistd.h>
fd 是文件指针,读上来的数据保存在缓冲区 buf 中, count 为请求读取的字节数。
那么接下来只要传进去一个参数使得 fd==0 即可,嗯应该是因为穿进去的参数当作字符串,而且相对于人来说是 十进制 ,故换算 0x1234 == (4660)10 ,接着手动输入 LETMEWIN\0
得到这个了就
顺便查到的与之无关的一些命令:
grep 命令:使用 grep 查找一个二进制文件,输出匹配字符串的偏移量。
[网址](https://www.v2ex.com/t/155823)
grep -oba 'some string' binary.file (输出十进制偏移量)
gdb 命令:用gdb查看指定地址的内存内容
格式: x /nfu <addr>
[网址](https://www.cnblogs.com/super119/archive/2011/03/26/1996125.html)
网上找到的 pwnable.kr 的 writeup
[❤️❤️❤️](http://blog.csdn.net/u012763794/article/details/51992512)