<commit_before>---
layout:     post
title:      "2016-Hctf题解 -- 就是干"
subtitle:   "fast-bin内存机制的探究利用"
date:       2016-12-01 16:55:25
author:     "Carter"
header-img: "img/post-bg-2015.jpg"
tags:
    - Linux
    - pwn
    - UAF
---



### 一. 知识点：
**1. 代码段开了随机化怎么调试：**

需要两个文件，其一是debug，通过peda获取每次程序加载代码段基址，内容如下：

```javascript
python
code_addr = peda.get_vmmap('binary')[0][0]
peda.execute('set $code='+hex(code_addr))
end
source aa
```

另一个是断点文件aa，通过source指令链接到debug文件中，内容如下：

```python
break * $code + 0xe93
break * $code + 0xd65
```

在exp中只需要加入一句话就可以挂载gdb，并在启动gdb后自动加载断点信息

```python
gdb.attach(pidof('pwn1')[-1],open('debug'))
```

### 二. 题目描述：
该题主要有两个功能：

 - 一是开辟内存输入字符串
 - 二是删除字符串并释放该内存块

明显就是考察申请释放堆块的相关姿势。首先来看**输入字符串函数**：

每个字符串都会分配一个长度为32的堆块A「实际分配长度为48，包括16字节堆块头」。接着判断输入字符串长度，如果长度小于15，则直接把字符串存储在该堆块A中；如果大于15，则另外开辟一块内存B存储字符串，堆块A中仅仅存储堆块B的地址。

**长度小于15的字符串堆块：**

布局如下：
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/10.png)
对应内存如下：
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/1.png)

**长度大于15的字符串堆块：**
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/2.png)
内存中还有一个堆块总管理地址，对每个字符串有两个变量来标志它：1.该字符串是否被删除的标志位; 2.为字符串分配的堆块地址
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/3.png)

再来看看**删除字符串函数**:首先判断字符串对应的堆管理结构的第二个位置是否为0[**漏洞所在：第二个位置是函数地址永远不可能为0,判断无效**]，然后调用堆块中存储的'处理删除字符串函数'。如果我们可以覆盖此函数地址为其他地址，再释放该堆块，那么就可以任意函数执行了
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/4.png)

### 三. 漏洞利用：<commit_msg>hello<commit_after>---
layout:     post
title:      "2016-Hctf题解 -- 就是干"
subtitle:   "fast-bin内存机制的探究利用"
date:       2016-12-01 16:55:25
author:     "Carter"
header-img: "img/post-bg-2015.jpg"
tags:
    - Linux
    - pwn
    - UAF
---



### 一. 知识点：
**1. 代码段开了随机化怎么调试：**

需要两个文件，其一是debug，通过peda获取每次程序加载代码段基址，内容如下：

```javascript
python
code_addr = peda.get_vmmap('binary')[0][0]
peda.execute('set $code='+hex(code_addr))
end
source aa
```

另一个是断点文件aa，通过source指令链接到debug文件中，内容如下：

```python
break * $code + 0xe93
break * $code + 0xd65
```

在exp中只需要加入一句话就可以挂载gdb，并在启动gdb后自动加载断点信息

```python
gdb.attach(pidof('pwn1')[-1],open('debug'))
```

### 二. 题目描述：
该题主要有两个功能：

 - 一是开辟内存输入字符串
 - 二是删除字符串并释放该内存块

明显就是考察申请释放堆块的相关姿势。首先来看**输入字符串函数**：

每个字符串都会分配一个长度为32的堆块A「实际分配长度为48，包括16字节堆块头」。接着判断输入字符串长度，如果长度小于15，则直接把字符串存储在该堆块A中；如果大于15，则另外开辟一块内存B存储字符串，堆块A中仅仅存储堆块B的地址。

**长度小于15的字符串堆块：**

布局如下：
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/10.png)
对应内存如下：
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/1.png)

**长度大于15的字符串堆块：**
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/2.png)
内存中还有一个堆块总管理地址，对每个字符串有两个变量来标志它：1.该字符串是否被删除的标志位; 2.为字符串分配的堆块地址
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/3.png)

再来看看**删除字符串函数**:首先判断字符串对应的堆管理结构的第二个位置是否为0[**漏洞所在：第二个位置是函数地址永远不可能为0,判断无效**]，然后调用堆块中存储的'处理删除字符串函数'。如果我们可以覆盖此函数地址为其他地址，再释放该堆块，那么就可以任意函数执行了
![图片](https://raw.githubusercontent.com/carterMgj/blog_img/master/2016-12-01-Hctf-jiushigan/4.png)


### 三. 漏洞利用：

{'fraction_non_alphanumeric': 0.17501546072974644, 'fraction_numerical': 0.05998763141620284, 'mean_word_length': 5.781970649895178, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3819856', 'n_tokens_mistral': 2181, 'n_tokens_neox': 2371, 'n_words': 129}