나혼자 공부장

[pwnable.kr] input write-up 본문

pwnable/pwnable.kr

[pwnable.kr] input write-up

라부송 2019. 12. 4. 01:02
/* input.c */

#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\n");
	printf("Let's see if you know how to give input to program\n");
	printf("Just give me correct inputs then you will get the flag :)\n");

	// argv
	if(argc != 100) return 0;
	if(strcmp(argv['A'],"\x00")) return 0;
	if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
	printf("Stage 1 clear!\n");	

	// stdio
	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;
	printf("Stage 2 clear!\n");
	
	// env
	if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
	printf("Stage 3 clear!\n");

	// file
	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);
	printf("Stage 4 clear!\n");	

	// network
	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;
	printf("Stage 5 clear!\n");

	// here's your flag
	system("/bin/cat flag");	
	return 0;
}

 

이번 문제는 특이하게도 stage가 나뉘어져 있다.

각 stage 마다 있는 if문들을 우회하는 input을 넣어주면 풀리는 문제이다.

 

 


 

Stage 1

if(argc != 100) return 0;
	if(strcmp(argv['A'],"\x00")) return 0;
	if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
	printf("Stage 1 clear!\n");	

argv[65] = "\x00"

argv[66] = "\x20\x0a\x0d" 

 

 

 


Stage 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;
	printf("Stage 2 clear!\n");

buf = 

 

dddd

#test.py

from pwn import *

argvs = [str(0) for i in range(100)]
argvs[65] = "\x00"
argvs[66] = "\x20\x0a\x0d"
argvs[67] = '8888'

envd = {"\xde\xad\xbe\xef" : "\xca\xfe\xba\xbe"}

with open("\x0a", 'w') as f :
        f.write("\x00\x00\x00\x00")

p = process(argv=argvs, stderr=open("./stderr"), executable="/home/input2/input", env=envd)
p.sendline("\x00\x0a\x00\xff")

con = remote("localhost", 8888)
con.send("\xde\xad\xbe\xef")

p.interactive()

test.py

 

ln -s /home/input2/flag flag

 

더보기

flag : Mommy! I learned how to pass various input in Linux :)

 

'pwnable > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] shellshock write-up  (0) 2019.12.04
[pwnable.kr] random write-up  (0) 2019.12.03
[pwnable.kr] passcode write-up  (0) 2019.12.02
Comments