제리의 블로그

pwnable.kr input 본문

Wargame/pwnable.kr

pwnable.kr input

j3rrry 2018. 9. 2. 12:55

input - 4 pt


Mom? how can I pass my input to a computer program?

ssh input2@pwnable.kr -p2222 (pw:guest)
뭔가 입력할 것이 많아보이는 문제입니다.




input2@ubuntu:~$ ls -l
total 24
-r--r----- 1 input2_pwn root      55 Jun 30  2014 flag
-r-sr-x--- 1 input2_pwn input2 13250 Jun 30  2014 input
-rw-r--r-- 1 root       root    1754 Jun 30  2014 input.c
이번 문제도 소스코드가 주어졌습니다.



Stage 1

        // 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");
인자 100개인데
argv 의 'A' 번째와 'B' 번째의 데이터가 지정되어 있습니다.
'A' 번째란 ascii code 로 변환했을 때의 값으로 0x41 이고
'B' 번째란 ascii code 로 변환했을 때의 값으로 0x42 입니다.




$ ./input `python -c 'print "1 "*0x40+"\x00 "+"\x20\x0a\x0d "+"2 "*(99-0x42)'`
그러나 위와같이 해보니
쉘에서 "\x00" 은 EOF이므로 페이로드가 끊깁니다.
그렇기 때문에 스크립트를 실행하는 방식으로 하게 되는데요



from pwn import *

p = ['/home/input2/input'] + ['\0'] * 0x41 + ['\x20\x0a\x0d'] + ['1'] * (99 - 0x42)
p = process(p)
p.interactive()




$ python a.py
[+] Starting local process '/home/input2/input': Done
[*] Switching to interactive mode
Welcome to pwnable.kr
Let's see if you know how to give input to program
Just give me correct inputs then you will get the flag :)
Stage 1 clear!


stage 2

    // 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");
file descriptor 에는 stdin - 0, stdout - 1, stderr - 2 가 있습니다.
pipe() 를 통해서 입력했습니다.



# Stage 2
fd1 = os.pipe()
fd2 = os.pipe()
os.write(fd1[1], "\x00\x0a\x00\xff")
os.write(fd2[1], "\x00\x0a\x02\xff")

p = process(p, stdin=fd1[0], stderr=fd2[0])

for i in range(2):
    os.close(fd1[i])
    os.close(fd2[i])

print p.recvuntil('Stage 2 clear!')
stdin 은 p.send('\x00\x0a\x00\xff') 로 대체 가능합니다.



Stage 3

        // env
        if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
        printf("Stage 3 clear!\n");
변수명 "\xde\xad\xbe\xef" 의 데이터는 "\xca\xfe\xba\xbe" 여야 한다.
$ export `echo -e "\xde\xad\xbe\xef=\xca\xfe\xba\xbe"`
bash: export: `ޭ��=����': not a valid identifier
export 하는 법을 모르겠다.



그래서 python 코드에 넣어보았다.
e = {"\xde\xad\xbe\xef":"\xca\xfe\xba\xbe"}
p = process(p, stdin=fd1[0], stderr=fd2[0], env=e)


$ python a.py
[+] Starting local process './input': pid 1026
[*] Process './input' stopped with exit code 0 (pid 1026)
[*] Switching to interactive mode

Stage 3 clear!
Exception in thread Thread-2:
...



Stage 4

    // 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");
이번엔 파일 "\x0a" 를 읽어는데 내용이 "\x00\x00\x00\x00" 이어야 한다.
# Stage 4
with open('\x0a', 'w') as f:
    f.write("\x00\x00\x00\x00")



$ python a.py
[+] Starting local process './input': pid 1096
[*] Switching to interactive mode
Stage 4 clear!
$



Stage 5

    // 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");
Stage 5 는 socket 을 열어서 4 bytes 의 데이터를 받습니다.
48번째 줄에 의하면 argv[67] 이 포트 번호가 됩니다.
그리고 입력되는 데이터는 "\xde\xad\xbe\xef" 입니다.



# Stage 5
r = remote('localhost', int(arg[67]))
r.send("\xde\xad\xbe\xef")
r.close()


$ python a.py
[+] Starting local process './input': pid 1323
[+] Opening connection to localhost on port 7000: Done
[*] Closed connection to localhost port 7000
[*] Switching to interactive mode

[*] Process './input' stopped with exit code 0 (pid 1323)
Stage 5 clear!
Exception in thread Thread-3:
...
AttributeError: 'NoneType' object has no attribute 'closed'
$



Hiden Stage?

    // here's your flag
    system("/bin/cat flag");
    return 0;
fopen("","w") 파일 작성하는것도 있고 해서
작업하는 디렉토리가 /tmp/*/ 입니다.
그런데 flag 파일이 상대주소입니다.
그래서 심볼릭 링크를 사용합니다.


$ ln -s /home/input2/flag flag


 
input2@ubuntu:/tmp/1710201420$ python a.py
[+] Starting local process '/home/input2/input': Done
[+] Opening connection to localhost on port 7000: Done
[*] Closed connection to localhost port 7000
Stage 5 clear!
[*] Switching to interactive mode
Mommy! I learned how to pass various input in Linux :)
...
$


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

pwnable.kr syscall  (0) 2018.09.04
pwnable.kr fix  (0) 2018.09.03
pwnable.kr random  (0) 2018.08.30
pwnable.kr passcode  (0) 2018.08.29
pwnable.kr flag  (0) 2018.08.29
Comments