Pwnable kr input
复制本地路径 | 在线编辑
就是考察对C的掌握,很有用。
处理参数
源代码如下
if(argc != 100) return 0;
if(strcmp(argv['A'],"\x00")) return 0;
if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
Python 处理
python使用popen / system,代码如下。主要是\x00那么就是空字符串,其他没什么,比较自然。
args = list("A" * 99)
args[ord("A")-1] = ""
args[ord("B")-1] = "\x20\x0a\x0d"
pro = subprocess.Popen(["./input"]+args, stdin = stdinr, stderr = stderrr, env=env)
C 处理
需要注意:
结尾必须赋值为NULL!!
argv[0] = "/home/input2/input";
for(int i=1; i<100; i++) argv[i] = "a";
argv['A'] = "\x00";
argv['B'] = "\x20\x0a\x0d";
argv[100] = NULL;
execve("/home/input2/input", argv, envp);
注意点
- 没什么好说的,但是在
tiny_easy (pwnable kr)中,算是学到一个:
argv[0] 是可以不为程序名!
标准输入输出
源代码如下,注意一个是read(0),一个是read(2)
char buf[4];
read(0, buf, 4);
if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0;
read(2, buf, 4);
if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0;
Python 处理
stdinr, stdinw = os.pipe()
stderrr, stderrw = os.pipe()
os.write(stdinw, "\x00\x0a\x00\xff")
os.write(stderrw, "\x00\x0a\x02\xff")
C 处理
int pipe_stdin[2] = {-1,-1}, pipe_stderr[2] = {-1, -1};
if(pipe(pipe_stdin) < 0 || pipe(pipe_stderr) < 0) {
perror("Cannot create pipe!");
exit(-1);
}
if((pid_child = fork()) < 0) {
perror("Cannot create child process!");
exit(-1);
}
if(pid_child == 0) {
// 子进程先等待父进程重定向,然后关闭不使用的pipe read
sleep(1);
close(pipe_stdin[0]);
close(pipe_stderr[0]);
// 父进程此时已经把pipe read 重定向到stdin 和 stderr
write(pipe_stdin[1], "\x00\x0a\x00\xff", 4);
write(pipe_stderr[1], "\x00\x0a\x02\xff", 4);
}
else
{
// 父进程无需pipe write操作,首先close掉,然后把pipe read重定向到0和2
close(pipe_stdin[1]);
close(pipe_stderr[1]);
dup2(pipe_stdin[0], 0);
dup2(pipe_stderr[0], 2);
execve("/home/input2/input", argv, envp);
}
环境变量
源代码如下,关键是要知道下面这句话什么意思,什么意思呢,看处理方案就知道了。
if( strcmp( "\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef") ) ) return 0;
Python 处理
env = {"\xde\xad\xbe\xef" : "\xca\xfe\xba\xbe"}
C 处理
char *envp[2] = {"\xde\xad\xbe\xef=\xca\xfe\xba\xbe", NULL};
文件交互
源代码如下,意思是从文件名\x0a读取前4个字节,看是否是\x00\x00\x00\x00。
FILE* fp = fopen("\x0a", "r");
if(!fp) return 0;
if( fread(buf, 4, 1, fp)!=1 ) return 0;
if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0;
fclose(fp);
Python 处理
with open("\x0a","wb") as f:
f.write("\x00"*4)
C 处理
fp = fopen("\x0a","wb");
if(!fp) {
perror("Cannot open file.");
exit(-1);
}
fwrite("\x00\x00\x00\x00",4,1,fp);
fclose(fp);
fp = NULL;
网络编程
源代码如下,建议先搞懂什么意思。
int sd, cd;
struct sockaddr_in saddr, caddr;
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd == -1){
printf("socket error, tell admin\n");
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\n");
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\n");
return 0;
}
if( recv(cd, buf, 4, 0) != 4 ) return 0;
if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0;
Python 处理
time.sleep(2)
args[ord('C')-1] = "9988" # port
s = socket.socket()
s.connect(("127.0.0.1",9988))
s.send("\xde\xad\xbe\xef")
C 处理
argv['C'] = "55555";
sleep(5);
int sockfd;
struct sockaddr_in saddr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1) {
perror("Cannot create socket!");
exit(-1);
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
saddr.sin_port = htons(55555);
if(connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) {
perror("Cannot connect to server!");
exit(-1);
}
write(sockfd, "\xde\xad\xbe\xef", 4);
close(sockfd);