CTF Blind pwn题型学习笔记

概述

  所谓Blind pwn,即是在无法获得二进制程序文件的情况下对题目进行漏洞利用。这篇博客主要是将见到过的盲打pwn题做一个总结,大概可以分为以下几类盲打pwn题:逻辑漏洞盲打、格式化字符串盲打、栈溢出盲打、堆盲打。

如何辨别漏洞类型

  对于盲打题,首先第一步应该是判断属于哪种类型的盲打,判断的步骤也很简单,nc连上后,直接看程序提供的菜单功能。
  一般来说,需要逻辑漏洞利用的题,菜单功能会比较复杂,这个下面单独的小节会讲解。而对于格式化字符串漏洞、栈溢出漏洞,题目提供的功能就非常简单了,一般会直接提示我们进行输入,然后就是打印输出。因此鉴别是否是格式化字符串漏洞可以利用常用的招数,比如输入%p等格式化符号;而对于栈溢出就输入超长的字符串即可,看程序是否崩溃。
  当然对于盲打的题目,还有一个重要的提示就是要看题目,有些时候题目本身就是提示,暗示了利用的类型。

逻辑漏洞盲打

  首先,我们来看下逻辑漏洞利用的题目,这里以2021年heroctf的一道比赛题目为例。这里我就无法提供二进制程序和远程环境了,只能凭记忆讲解一下这道题目。
  在做这道题的时候,我也是刚入门pwn题,对于盲打的题目更是知之甚少,不过当时也是听说过BROP的,这是一种利用栈溢出来实现盲打的,后面会介绍。所以当时一度差点放弃这道题目,不过好在后面仔细看了下,其实是一道非常简单的逻辑漏洞利用题目。
  题目的逻辑大概如下:这是一个模拟赌场游戏的程序,首先我们会有初始的金币,随便举个数目,就1000$吧,然后程序提供赌钱,买运气,买flag,退出等几个选项。买运气会花费100$,然后没有其它任何作用;买flag的话需要2000$。最后就是赌钱,每次赌钱,有50个赌桌可供选择,要求我们先下注,即输入赌桌的号数,同时下注的钱也是我们可以控制的,下注的钱越多,赢的也就越多,输的话就是全没,然后程序会随机返回一个数(一定在1-50之间,这是多次运行程序看到的结果,确认是随机的),如果返回的数和我们输入的赌桌数一样,就是我们赢,不一样就是输。
  程序逻辑到这里也就差不多完了,想要达到的目标也很明确,就是我们需要去赌钱赚够2000$来买到flag。当然直接赌钱是不可能赌的,无法是课本还是现实的经验告诉我们,赌钱这个东西永远都不可能有赢家,你也许会小赚,但终究是亏的。因此,这里利用了程序实现时的逻辑漏洞,或者也不叫漏洞,毕竟现实中也有很多操作是这样搞的。程序的实现方式是让我们自己选择赌桌号数,自己决定每个赌桌的钱数,而且可以多次下注,因此答案就来了,我们在每个赌桌上都下注一样的钱,这样我们每次赌钱都可以在某个赌桌上赢。至于下注多少钱就看赔率,保证即使49个赌桌输的情况下,一个赌桌赢也是赚的。这样我们多赌几次就可以赢够买flag的钱,当然最终还是用脚本来实现交互的,毕竟手动操作太繁琐。
  做完这道题,我不仅想到了鸡蛋不要放到一个笼子里的名言,以及联想到了股票市场上对冲基金操作的原理,总而言之,只要我全都买,就一定会赢😏。

格式化字符串盲打

原理阐述

  这里先总结一下格式化字符串漏洞盲打的一般操作步骤,简而言之的话就是先找到一个代码段的地址,然后从该地址出发尽可能的泄露出二进制程序本身,之后将泄露出来的内容保存在一个文件中。这样就相当于获得了二进制程序文件本身,再用IDA进行分析,之后的步骤就和普通的pwn题一样了。
  因此这里关键的步骤就是如何找到一个地址进而泄露二进制程序。这里可以分为两种情况进行讨论,第一种是针对没有开PIE保护的程序,这样程序代码基址是固定的,32位程序为0x8048000, 64位程序为0x400000,我们直接从这些地址开始泄露即可。那么如何判断程序是否开启了PIE保护,可以直接先用%p尝试泄露一些栈上的地址,如果有和上述基址偏移不大的值存在的话,说明程序是没有开启PIE保护的。
  接下来讨论第二种情况,就是简单尝试后无法确定程序是否开了PIE,那么我们直接泄露400bytes的栈上内容来看看情况,一般可以从上面找到.start函数的地址,也就是.text代码段的起始地址。大家可以参考一下这篇中的demo – pwn 盲打,它也是以没有开PIE保护的程序为例,这样可以方便的识别出.start函数,但开了PIE的话识别起来有点难度。将上面的操作简单总结为如下流程:leak stack & find .text --> dump .text。
  当然之所以格式化字符串漏洞的题可以这样做,也是利用了其泄露信息的便捷性,常用的泄露方式总结如下。

%n$p   # 打印printf第n个参数的值
%n$s   # 以printf第n个参数的值为地址打印其指向的值

例题讲解

axb_2019_fmt32

  这道题在buuoj上有复现,并且是给了二进制文件的,如果直接看二进制文件的话,题目非常简单。这里我们只把提供的二进制文件和最后dump出来的程序做对比,而不是直接利用它解题。
  通过题目命名和nc连接后操作可以判断其为格式化字符串漏洞,程序存在alarm,非常短的时间后程序会自动停止。通过题目名字和泄露出的栈数据,可以初步判断其为32位程序,并且没有开启PIE保护。
  dump脚本如下,主要分为leak和dump两个函数。leak函数的功能是利用fmt的offset加上给定的地址来泄露二进制程序本身,注意这里使用的是%s。dump函数,根据程序的逻辑来不断执行leak函数,尽可能的泄露出二进制程序。

from pwn import *


p = remote(
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值