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是什么, ...
随机推荐
- dagger2的初次使用
一.使用前准备 1.打开app的build.gradle文件: 顶部停用apt插件: //添加如下代码,应用apt插件 apply plugin: 'com.neenbedankt.android-a ...
- Java Socket聊天室编程(二)之利用socket实现单聊聊天室
这篇文章主要介绍了Java Socket聊天室编程(二)之利用socket实现单聊聊天室的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在上篇文章Java Socket聊天室编程(一)之 ...
- Java原子类操作原理剖析
◆CAS的概念◆ 对于并发控制来说,使用锁是一种悲观的策略.它总是假设每次请求都会产生冲突,如果多个线程请求同一个资源,则使用锁宁可牺牲性能也要保证线程安全.而无锁则是比较乐观的看待这个问题,它会假设 ...
- #Java学习之路——基础阶段二(第五篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- 7. VIM 系列 - 程序员利器(语法检测、代码块补全、symbol管理、函数跳转)
目录 1. 语法检查利器 ale 2. 补全代码块 3. symbol 管理器 taglist.vim 4. 函数跳转 1. 语法检查利器 ale 安装 ale Plug 'w0rp/ale' 配置 ...
- Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!
Spring Cloud 的注册中心可以由 Eureka.Consul.Zookeeper.ETCD 等来实现,这里推荐使用 Spring Cloud Eureka 来实现注册中心,它基于 Netfl ...
- python的append insert extend pop del remove使用
对于 python 数组的操作,有插入和删除,下面介绍各个函数的功能: 插入 插入的函数有 append.insert .extend append append(i) 是在数组的末尾插入一个元素 i ...
- js判断参数是否为非数字
isNaN() 函数用于检查其参数是否是非数字值.
- FileSizeUtil【获取文件夹或文件的大小】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 获取文件夹或者文件的大小,可以指定单位,也可以自动计算合适的单位值. 效果图 代码分析 常用的方法: getFolderOrFile ...
- 从B站的代码泄露事件中,我们能学到些什么?
先声明一下,本文不聊ISSUE中的七七八八,也不聊代码是否写的好,更不聊是不是跟蔡徐坤有关之类的吃瓜内容.仅站在技术人的角度,从这次的代码泄露事件,聊聊在代码的安全管理上,通常都需要做哪些事来预防此类 ...