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. 解决Dynamics 365使用JS调用Web API时报no property value was found in the payload 错误。

    摘要: 微软动态CRM专家罗勇 ,回复323或者20190421可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 碰到如下报错: message: "An er ...

  2. 解决小米手机USB安装apk时AS报错:INSTALL_FAILED_USER_RESTRICTED

    今天,直接用AS在小米手机上运行安装的时候总是报错:INSTALL_FAILED_USER_RESTRICTED,于是乎,通过以下方式解决: 在开发者选项将USB安装打开,然后,哈,解决了.记录一下.

  3. Windows-删除Windows Server backup卷影副本

    现有环境中有一台Windows Server做过定期备份计划,时间太久未做清理操作,收到磁盘报警邮件后需要及时释放该空间,具体操作步骤如下: 当前备份计划信息如下: 清理步骤如下: 1.以管理身份运行 ...

  4. mysql建数据库的字符集与排序规则

    1.字符集说明: 一般选择utf8.下面介绍一下utf8与utfmb4的区别. utf8mb4兼容utf8,且比utf8能表示更多的字符.至于什么时候用,看你的做什么项目了,到http://blog. ...

  5. 源码安装Nginx加TCP反向代理模块

    说明: 安装方式是源码编译安装,因此先安装相关依赖,否则报错. yum -y install gcc* patch openssl openssl-devel 安装步骤: 下载nginx源码包: wg ...

  6. 使用C#+XPath+HtmlAgilityPack轻松搞一个资源下载器

    HtmlAgilityPack简介 HtmlAgilityPack是一个开源的解析HTML元素的类库,最大的特点是可以通过XPath来解析HMTL,如果您以前用C#操作过XML,那么使用起HtmlAg ...

  7. Ubuntu16.04 部署配置GO语言开发环境 & 注意事项

    1. 安装GO 安装go语言包: $ curl -O https://storage.googleapis.com/golang/go1.10.1.linux-amd64.tar.gz   下载完成后 ...

  8. [翻译] 介绍EF Core

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  9. Spring Boot(四):Thymeleaf 使用详解

    在上篇文章Spring Boot (二):Web 综合开发中简单介绍了一下 Thymeleaf,这篇文章将更加全面详细的介绍 Thymeleaf 的使用.Thymeleaf 是新一代的模板引擎,在 S ...

  10. WebApiClient的JsonPatch局部更新

    1. 文章目的 随着WebApiClient的不断完善,越来越多开发者选择WebApiClient替换原生的HttpClient,本文将介绍使用WebApiClient来完成JsonPatch提交的新 ...