pwnable input解题记录

给了源码如下:

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "arpa/inet.h" int main(){ //stage argv
char *argv[101] = {"/home/input2/input", [1 ... 99] = "A", NULL};
argv['A'] = "\x00";
argv['B'] = "\x20\x0a\x0d";
argv['C'] = "55555"; //stage stdio
int pipe2stdin[2] = {-1, -1};
int pipe2stderr[2] = {-1, -1};
pid_t childpid; //stage file
FILE* fp = fopen("\x0a", "w");
fwrite("\x00\x00\x00\x00", 4, 1, fp);
fclose(fp); if(pipe(pipe2stdin) < 0 || pipe(pipe2stderr) < 0)
{
perror("Cannot create the pipe!");
exit(1);
}
if((childpid = fork()) < 0)
{
perror("Cannot fork!");
exit(1);
}
if(childpid == 0)
{
close(pipe2stdin[0]); //close pipes of read
close(pipe2stderr[0]); write(pipe2stdin[1], "\x00\x0a\x00\xff", 4);
write(pipe2stderr[1], "\x00\x0a\x02\xff", 4);
}
else{
close(pipe2stdin[1]); close(pipe2stderr[1]); //close pipes of write
dup2(pipe2stdin[0], 0); dup2(pipe2stderr[0], 2);
close(pipe2stdin[0]); close(pipe2stderr[0]); //stage env
char *envp[2] = {"\xde\xad\xbe\xef=\xca\xfe\xba\xbe", NULL}; execve("/home/input2/input", argv, envp);
}
sleep(2);
int sockfd;
struct sockaddr_in server;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("Socket build error!");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(55555);
if(connect(sockfd, (struct sockaddr*)&server, sizeof(server)) < 0){
perror("Connect error!");
exit(1);
}
char buf[4] = "\xde\xad\xbe\xef";
write(sockfd, buf, 4);
close(sockfd); return 0;
}

是为了让解题者满足代码中所需要满足的条件,总共5个,分别包括:参数传递、标准输入输出、环境变量、文件读写以及网络通信方面。

1.argv

  参数第'A''B'位分别为"\x00"和"\x20\x0a\x0d",也就是第65位和第66位(第0位为可执行文件的路径),但是'\x00'会截断。

  于是使用execve运行input文件,execve函数在unistd(unix standard)头文件中:

int execve(const char *path, char *const argv[], char *const envp[]);

以argv参数进行传递相应参数。

2.stdio

ssize_t read(int fildes, void *buf, size_t nbytes);

摘自 http://codewiki.wikidot.com/c:system-calls:read

Field Description
int fildes The file descriptor of where to read the input. You can either use a file descriptor obtained from the open system call, or you can use 0, 1, or 2, to refer to standard input, standard output, or standard error, respectively.
const void *buf A character array where the read content will be stored.
size_t nbytes The number of bytes to read before truncating the data. If the data to be read is smaller than nbytes, all data is saved in the buffer.
return value Returns the number of bytes that were read. If value is negative, then the system call returned an error.

  可以看到分别需要从stdinstderr读取相关的数据,但是stderr没法写,于是需要用到c中的叫做管道(pipe)的东西可用于子进程与父进程之间的通讯使用;于是子进程向缓冲区写数据,而父进程先将定义的相应缓冲区分别替换stdin和stderr,之后则可以从缓冲区进行读取。

3.env

  getenv函数获取系统中环境变量,这个同样以execve进行处理,其中的envp参数进行传递。

4.file

  常规操作,自己创建一个文件,然后写"\x00\x00\x00\x00"进去然后再读即可。

5.network

  是以传递的第C个参数作为监听端口,以及socket通信获取传来的消息,采用本地通信。socket网络编程网上一搜就出来的,其实百度百科说的还挺清楚的...中间需要sleep几秒等待接收信息的服务开启,然后传递信息。


  最后在/tmp目录下面可以创建一个文件xxx,但是由于后面还得创建一个与/home/input2/flag的软链接(因为在/tmp目录下仍然没有权限cat flag),因为在运行input2文件时路径还是相对路径:

ln -s /home/input2/flag flag

之后创建一个c文件编译运行即可。

代码整理:

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "arpa/inet.h" int main(){ //stage argv
char *argv[101] = {"/home/input2/input", [1 ... 99] = "A", NULL};
argv['A'] = "\x00";
argv['B'] = "\x20\x0a\x0d";
argv['C'] = "55555"; //stage stdio
int pipe2stdin[2] = {-1, -1};
int pipe2stderr[2] = {-1, -1};
pid_t childpid; //stage file
FILE* fp = fopen("\x0a", "w");
fwrite("\x00\x00\x00\x00", 4, 1, fp);
fclose(fp); if(pipe(pipe2stdin) < 0 || pipe(pipe2stderr) < 0)
{
perror("Cannot create the pipe!");
exit(1);
}
if((childpid = fork()) < 0)
{
perror("Cannot fork!");
exit(1);
}
if(childpid == 0) //child process
{
close(pipe2stdin[0]); //close pipes of read
close(pipe2stderr[0]); write(pipe2stdin[1], "\x00\x0a\x00\xff", 4);
write(pipe2stderr[1], "\x00\x0a\x02\xff", 4);
}
else{ //parent process
close(pipe2stdin[1]); close(pipe2stderr[1]); //close pipes of write
dup2(pipe2stdin[0], 0); dup2(pipe2stderr[0], 2); //change stdin and stderr
close(pipe2stdin[0]); close(pipe2stderr[0]); //stage env
char *envp[2] = {"\xde\xad\xbe\xef=\xca\xfe\xba\xbe", NULL}; execve("/home/input2/input", argv, envp);
}
sleep(2);
int sockfd;
struct sockaddr_in server;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("Socket build error!");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(55555);
if(connect(sockfd, (struct sockaddr*)&server, sizeof(server)) < 0){
perror("Connect error!");
exit(1);
}
char buf[4] = "\xde\xad\xbe\xef";
write(sockfd, buf, 4);
close(sockfd); return 0;
}

参考链接:https://werewblog.wordpress.com/2016/01/11/pwnable-kr-input/

pwnable.kr input解题记录的更多相关文章

  1. 【pwnable.kr】input

    这道题是一道一遍一遍满足程序需求的题. 网上其他的题解都是用了C语言或者python语言的本地调用,我想联系一下pwntools的远程调用就写了下面的脚本, 执行效果可以通过1~4的检测,到最后soc ...

  2. pwnable.kr之input

    连接到远程服务器:ssh input2@pwnable.kr -p2222 查看题目所给的代码,根据题目的要求我们要给出所有符合条件的输入才能拿到flag,本来想在输入上动点歪脑筋,结果输入有字节数的 ...

  3. 【pwnable.kr】fb

    这是pwnable.kr的签到题,记录pwn入门到放弃的第一篇. ssh fd@pwnable.kr -p2222 (pw:guest) 题目很简单,登录上了ssh后,发现了3个文件:fd,fd.c, ...

  4. pwnable.kr详细通关秘籍(二)

    i春秋作家:W1ngs 原文来自:pwnable.kr详细通关秘籍(二) 0x00 input 首先看一下代码: 可以看到程序总共有五步,全部都满足了才可以得到flag,那我们就一步一步来看 这道题考 ...

  5. pwnable.kr的passcode

    前段时间找到一个练习pwn的网站,pwnable.kr 这里记录其中的passcode的做题过程,给自己加深印象. 废话不多说了,看一下题目, 看到题目,就ssh连接进去,就看到三个文件如下 看了一下 ...

  6. pwnable.kr brainfuck之write up

    I made a simple brain-fuck language emulation program written in C. The [ ] commands are not impleme ...

  7. 【pwnable.kr】 [simple login]

    Download : http://pwnable.kr/bin/login Running at : nc pwnable.kr 9003 先看看ida里面的逻辑. 比较重要的信息时input变量再 ...

  8. 【pwnable.kr】 mistake

    又一道pwnable,我还没放弃.. ssh mistake@pwnable.kr -p2222 (pw:guest) 源代码如下: #include <stdio.h> #include ...

  9. 黑客练手入门| pwnable.kr—幼儿瓶—01:fd

    目录 前言 pwnable.kr介绍 该怎么玩 幼儿瓶第一道题:fd 0x00 问题描述 0x01 源码分析 0x02 解题方法 0x03 知识点总结 前言 担心有人不知道pwnable.kr是什么, ...

随机推荐

  1. 好看又能打的CRM系统大比拼:Salesforce, SugarCRM, Odoo等

    介绍 今天的CRM市场提供了大量的解决方案和软件替代品.有些适合大型企业(通常需要内部托管),而其他企业则更多地应用于SME的需求(通常使用云托管解决方案). 在CRM解决方案方面,提供商必须调整其产 ...

  2. ubuntu下svn的命令使用

    Subversion的官方网站是:http://subversion.tigris.org/ SVN简介 SVN(Subversion)是一个自由.开源的项目源代码版本控制工具.目前,绝大多数开源软件 ...

  3. crontab常用

    --crontab检查是否安装[oracle@rac1 ~]$ rpm -qa | grep crontabcrontabs-1.10-8启动与关闭[oracle@rac1 ~]$ /etc/init ...

  4. 20170319 - pycurl 提示 libcurl link-time version is older than compile-time version

    使用 conda update anaconda 升级后,运行程序得到如下提示: ImportError: pycurl: libcurl link-time version (7.45.0) is ...

  5. 禁止WPS2019开机自启动

    最近开机发现WPS总是自己启动,导致开机速度会慢5s左右,从网上找了很多办法都没用,包括运行+msconfig,启动项里面没有WPS:杀毒软件自启动管理里面也没有找到WPS,百度了一圈也没有找到任何有 ...

  6. IoC和AOP的理解

    spring 的优点?1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实 ...

  7. spring boot 2.0 集成 shiro 和 pac4j cas单点登录

    新开的项目,果断使用  spring boot  最新版本  2.0.3 ,免得后期升级坑太多,前期把雷先排了. 由于对 shiro 比较熟,故使用 shiro 来做权限控制.同时已经存在了 cas  ...

  8. Vue(day3)

    一.Vue中的ajax:vue-resource和axios vue-resource是Vue实现异步加载的官方库,即Vue中的ajax.在Vue2.js之后vue-resource将不再更新维护,所 ...

  9. python --- 冒泡排序算法

    别想太多了,这个冒泡排序就是我们脑海中想到的那个冒泡,就好像是气泡一样,较小的元素比较轻,从而要往上浮出来, 冒泡排序算法. 要对‘气泡’序列处理若干遍.所谓一遍处理,就是自底向上检查一遍这个序列,并 ...

  10. Asp.Net Core 轻松学-HttpClient的演进和避坑

    前言     在 Asp.Net Core 1.0 时代,由于设计上的问题, HttpClient 给开发者带来了无尽的困扰,用 Asp.Net Core 开发团队的话来说就是:我们注意到,HttpC ...