PWN学习 ---- pwnable ----input

 

 

源代码:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <arpa/inet.h>

 

int main(int argc, char* argv[], char* envp[]){

printf("Welcome to pwnable.kr ");

printf("Let's see if you know how to give input to program ");

printf("Just give me correct inputs then you will get the flag :) ");

 

// argv

if(argc != 100) return 0;

if(strcmp(argv['A'],"x00")) return 0;

if(strcmp(argv['B'],"x20x0ax0d")) return 0;

printf("Stage 1 clear! ");

 

// stdio

char buf[4];

read(0, buf, 4);

if(memcmp(buf, "x00x0ax00xff", 4)) return 0;

read(2, buf, 4);

        if(memcmp(buf, "x00x0ax02xff", 4)) return 0;

printf("Stage 2 clear! ");

 

// env

if(strcmp("xcaxfexbaxbe", getenv("xdexadxbexef"))) return 0;

printf("Stage 3 clear! ");

 

// file

FILE* fp = fopen("x0a", "r");

if(!fp) return 0;

if( fread(buf, 4, 1, fp)!=1 ) return 0;

if( memcmp(buf, "x00x00x00x00", 4) ) return 0;

fclose(fp);

printf("Stage 4 clear! ");

 

// network

int sd, cd;

struct sockaddr_in saddr, caddr;

sd = socket(AF_INET, SOCK_STREAM, 0);

if(sd == -1){

printf("socket error, tell admin ");

return 0;

}

saddr.sin_family = AF_INET;

saddr.sin_addr.s_addr = INADDR_ANY;

saddr.sin_port = htons( atoi(argv['C']) );

if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){

printf("bind error, use another port ");

     return 1;

}

listen(sd, 1);

int c = sizeof(struct sockaddr_in);

cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c);

if(cd < 0){

printf("accept error, tell admin ");

return 0;

}

if( recv(cd, buf, 4, 0) != 4 ) return 0;

if(memcmp(buf, "xdexadxbexef", 4)) return 0;

printf("Stage 5 clear! ");

 

// here's your flag

system("/bin/cat flag");

return 0;

}

 

 

这道题参考了很多网上的wp,网上很多都是用c语言

写的exp,很少是用python编写的exp

 

我这里写的exp是用python来编写的,

主要使用的模块是

Pwn  socket

 

 

Exp:

这个题目总体来说分成几部分

每个部分都有一个知识点

 

第一部分: argv

先判断argc 的参数数量为100

然后判断第65个参数为 x00

66 个参数为 x20x0ax0d

这里的 argv[‘A’] 就是 第65个参数

 

第二部分: stdin

这里的知识点是:

stdoutStandardoutput)标准输出 1  

stdinStandardinput)标准输入  0

stderrStandarderror)标准错误 2

可以看到这里有两个标准

第一个if 判断 标准输入 为  x00x0ax00xff

第二个if 判断 标准错误 为  x00x0ax02xff

 

第三部分:env

这里的知识点是 环境变量 

判断 xdexadxbexef 为变量名 内容为 xcaxfexbaxbe

 

第四部分:file

这里的知识点是:文件的内容

打开一个文件 x0a ,然后读4个字节到buf里面,然后内容是 x00x00x00x00

 

第五部分:network

这里的知识点:linux的网络编程

这里前面的部分都不用管,这是打开一个程序的,相当于是一个服务器

这里要求输入一个端口,然后接受一段数据,4位数 ,然后内容是 xdexadxbexef

这里在 agrc 里面输入了端口,然后就会自动打开一个端口,生成一个进程

这里可以用socket连接,然后发送数据

这里我使用socket连接,不用pwntools,因为我用pwntools 的时候会出现了EOF错误,不知道是什么原因

 

过了这一步,然后就到了读取flag

但是这里inputs这个文件夹没有权限写文件,然后exp要放在/tmp 文件夹里面,所以这里要先生成一个软连接,然后就可以读取了

 

这里总结一下我学这个遇到的点

Pwntools 如果要指定executable ,那么必须要用argv

Pwntools process 可以指定参数 stdin    stderr   env

然后发送过去,输入返回值

 

然后socket  连接

如果连接成功了,是没有其他信息输出的,要再一次 print s.recv() 才回输入Stage 5 clear!

在下面再一次  print s.recv() 得到flag

原文地址:https://www.cnblogs.com/nienie/p/9723873.html