pwnable.kr input解题记录
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. |
可以看到分别需要从stdin和stderr读取相关的数据,但是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解题记录的更多相关文章
- 【pwnable.kr】input
这道题是一道一遍一遍满足程序需求的题. 网上其他的题解都是用了C语言或者python语言的本地调用,我想联系一下pwntools的远程调用就写了下面的脚本, 执行效果可以通过1~4的检测,到最后soc ...
- pwnable.kr之input
连接到远程服务器:ssh input2@pwnable.kr -p2222 查看题目所给的代码,根据题目的要求我们要给出所有符合条件的输入才能拿到flag,本来想在输入上动点歪脑筋,结果输入有字节数的 ...
- 【pwnable.kr】fb
这是pwnable.kr的签到题,记录pwn入门到放弃的第一篇. ssh fd@pwnable.kr -p2222 (pw:guest) 题目很简单,登录上了ssh后,发现了3个文件:fd,fd.c, ...
- pwnable.kr详细通关秘籍(二)
i春秋作家:W1ngs 原文来自:pwnable.kr详细通关秘籍(二) 0x00 input 首先看一下代码: 可以看到程序总共有五步,全部都满足了才可以得到flag,那我们就一步一步来看 这道题考 ...
- pwnable.kr的passcode
前段时间找到一个练习pwn的网站,pwnable.kr 这里记录其中的passcode的做题过程,给自己加深印象. 废话不多说了,看一下题目, 看到题目,就ssh连接进去,就看到三个文件如下 看了一下 ...
- pwnable.kr brainfuck之write up
I made a simple brain-fuck language emulation program written in C. The [ ] commands are not impleme ...
- 【pwnable.kr】 [simple login]
Download : http://pwnable.kr/bin/login Running at : nc pwnable.kr 9003 先看看ida里面的逻辑. 比较重要的信息时input变量再 ...
- 【pwnable.kr】 mistake
又一道pwnable,我还没放弃.. ssh mistake@pwnable.kr -p2222 (pw:guest) 源代码如下: #include <stdio.h> #include ...
- 黑客练手入门| pwnable.kr—幼儿瓶—01:fd
目录 前言 pwnable.kr介绍 该怎么玩 幼儿瓶第一道题:fd 0x00 问题描述 0x01 源码分析 0x02 解题方法 0x03 知识点总结 前言 担心有人不知道pwnable.kr是什么, ...
随机推荐
- Android新手引导库推荐
本文同步至http://javaexception.com/archives/31 介绍一波新手引导层的库.都是star数挺高的一些库. 1.NewbieGuide(国内开发者开发) Android ...
- oppo设备怎么样无需root激活XPOSED框架的教程
在非常多部门的引流或业务操作中,基本上都需要使用安卓的强大XPOSED框架,近期,我们部门购来了一批新的oppo设备,基本上都都是基于7.0以上版本,基本上都不能够获得root的su超级权限,即使一部 ...
- Java实现文本编辑时基于拼音输入的补全原型
续前文Java实现"命令式"简易文本编辑器原型. 效果如下: 所在源码库同上文, 尚未和上文的编辑器右侧的命令区集成. 代码由How to show autocomplete as ...
- Flink源码分析 - 源码构建
原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483692&idx=1&sn=18cddc1ee ...
- sqlserver—数据完整性(理论篇)
数据完整性主要指的是数据的精确性和可靠性,目的就是为了防止数据库中存放的数值,以及字符具有合法性(即按照管理员定义的规则进行存放) 分为以下四类: 实体完整性 实体完整性要求每一个表中的主键字段都不能 ...
- equals方法和==的区别--用实例简单说明
首先我们创建一个类 public class People { private String name; private String address; public String getName() ...
- Java线程监控及中断
我们系统中经常有耗费时间长的任务,但客户端往往需要马上得到回应.这时我们就可以如下步骤实现: 1.客户端发起请求执行任务(选定条件,下载报表): 2.首先将任务ID及开始时间,起始状态记录到数据库表中 ...
- sklearn中的Pipeline
在将sklearn中的模型持久化时,使用sklearn.pipeline.Pipeline(steps, memory=None)将各个步骤串联起来可以很方便地保存模型. 例如,首先对数据进行了PCA ...
- 【Netty】(6) ---源码ServerBootstrap
[Netty]6 ---源码ServerBootstrap 之前写了两篇与Bootstrap相关的文章,一篇是ServerBootstrap的父类,一篇是客户端Bootstrap类,博客地址: [Ne ...
- spring里的三大拦截器
Filter 新建 TimeFilter @Component public class TimeFilter implements Filter { @Override public void in ...