LoginSignup
0
0

More than 3 years have passed since last update.

Pwnable.kr-[input] writeup

Posted at

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

ssh input2@pwnable.kr -p2222 (pw:guest)

input2@pwnable:~$ 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
input2@pwnable:~$ cat 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;
}

STAGE1,STAGE5に従ってargvを入力します。
argv['A'] = '\x00' (STAGE1)
argv['B'] = '\x20\x0a\x0d'
argv['C'] = 4444 (STAGE5,接続するポート番号を指定する。)

STAGE2では標準入力と標準エラー出力に入力を渡す必要があるため、パイプを別々に作ってprocess()に渡します。ちなみにこれをssh接続からしようとするとpty等を意識する必要が出てきて一気に面倒になります。

STAGE3に従って環境変数をprocess()に渡し、STAGE5に従って先にファイルに'\x00\x00\x00\x00'を書き込んでおきます。

from pwn import *
import os

args = ['A']*100
args[65] = '\x00'
args[66] = '\x20\x0a\x0d'
args[67] = '4444'

r1, w1 = os.pipe()
r2, w2 = os.pipe()
os.write(w1, '\x00\x0a\x00\xff')
os.write(w2, '\x00\x0a\x02\xff')

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

p = process(executable='/home/input2/input', 
        argv=args, 
        stdin=r1, stderr=r2, 
        env={'\xde\xad\xbe\xef' :'\xca\xfe\xba\xbe'})

net = remote('localhost', 4444)
net.sendline('\xde\xad\xbe\xef')

p.interactive()
[*] Closed connection to localhost port 4444
input2@pwnable:/tmp/input212$ ln -s /home/input2/flag flag
input2@pwnable:/tmp/input212$ python input212.py
[+] Starting local process '/home/input2/input': pid 108561
[+] Opening connection to localhost on port 4444: 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 clear!
Stage 3 clear!
Stage 4 clear!
Stage 5 clear!
Mommy! I learned how to pass various input in Linux :)
[*] Process '/home/input2/input' stopped with exit code 0 (
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0