[PWN] pwntools - fmstr_payload (-> fmtstr_payload)
[*] 정리...
pwntools에는 FSB를 할때 페이로드를 엄청 편하게 작성하는 것을 도와주는 fmstr_payload 메소드가 있다.
검색해보면 많이 나오지만 옛날 글이라 그런지 아니면 내가 못본건지 대부분 32bit 환경 위주의 글이고 64bit 환경에 대한 내용이 있다 하더라도 context.bits를 설정해야한다는 중요한 내용이 빠져있는 것 같아서 간단히 정리해봤다.
(참고로 python2.7의 pwntools 기준이다.)
[*] 사용법
사용법은 아래와 같이 매우 간단하다.
- x86 (32bit)
from pwn import *
...
payload = ''
Writes = {
[덮을 대상의 주소1]:[덮을 값],
[덮을 대상의 주소2]:[덮을 값],
}
payload += fmstr_payload(FSB_Offset, Writes)
# 또는
payload += fmtstr_payload(FSB_Offset, Writes)
...
- x64 (64bit)
from pwn import *
...
payload = ''
Writes = {
[덮을 대상의 주소1]:[덮을 값],
[덮을 대상의 주소2]:[덮을 값],
}
context.bits = 64
payload += fmstr_payload(FSB_Offset, Writes)
# 또는
payload += fmtstr_payload(FSB_Offset, Writes)
...
[*] 차이(이번 글의 핵심)
위 두개의 코드의 차이는 context.bits의 값을 설정하는 것에 있다. (대부분 내용이 빠져있었다)
fmstr_payload는 기본적으로 x86 환경에 맞게 페이로드를 작성하기에 x64에서 그냥 사용하면 아래와 같이 패킹 중에 에러가 난다.
ValueError: pack(): number does not fit within word_size [0, 139868650402880, 4294967296]
word_size가 맞지 않아서 그런데 (이건 뇌피셜이지만) 해당 코드에서 x86 (32bit)가 디폴트 환경올 설정이 되어 있어 1 word를 32bit 단위로 구분하기 때문에 context.bits 설정 없이 32bit 이상의 값을 덮을 대상의 주소나 덮을 값으로 넣는다면 packer에서 패킹하는 사이즈보다 값이 더 커서 에러가 나게 되는 것(일것)이다.
[*] 결론
fmstr_payload를 쓸때 x64에 대한 페이로드를 작성하는 경우에는 context.bits = 64 코드를 넣어주면 에러없이 잘 실행된다.
[*] 참고
https://docs.pwntools.com/en/stable/fmtstr.html#pwnlib.fmtstr.fmtstr_payload
pwnlib.fmtstr — Format string bug exploitation tools — pwntools 4.7.0 documentation
A tuple (score, value, mask) where score equals the number of matching bytes between the returned value and target.
docs.pwntools.com
[*] 업데이트
정확히 몇버전 부터인지는 모르겠지만 pwntools 4.6.0 버전 이상부터는 fmstr_payload 함수의 이름이 fmtstr_payload로 변경됨.