源代码:
#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
这里的知识点是:
stdout(Standardoutput)标准输出 1
stdin(Standardinput)标准输入 0
stderr(Standarderror)标准错误 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