当前位置: 首页 > 工具软件 > UAF > 使用案例 >

初次定位UAF(内存释放后再次使用)问题

冀弘厚
2023-12-01

记第一次定位UAF

       某某打开KASAN的版本报过来我们的一个业务出现必现UAF(USE after free)踩内存问题,正常版本没有想过堆栈信息异常,第一次遇到这问题,简单记录下定位过程。

       了解KASAN概念下:

The Kernel Address Sanitizer (KASAN) — The Linux Kernel documentation

KernelAddressSANitizerKASAN)是一个动态检测内存错误的工具。它为找到use-after-freeout-of-bounds问题提供了一个快速和全面的解决方案

通过gdb和调用栈信息调试追踪到一个对象的成员变量释放后再次出现赋值,以下代码是抽象出来和问题场景相似的代码:

#include <deque>

class Action {

public:

    void a() {

        if (true) {

            delegate_->Complete();

        }

    }

    void b() {

        ;;;;; // more function call

        a();

        time = XXX:ss();   // UAF 问题出现的地方

    }

private:

    int time;

    ActionManager *delegate_;

}

class ActionManager {

public:

    std::deque<std::unique_ptr<Action>> actions_;

    std::unique_ptr<Action> current_;

    void Complete() {

        current_.reset();

        StartNextAction();

    }

    void StartNextAction() {

       

    }

}

         一般这种问题应该看下原生安卓二进制有没有,或者看下是否有自己的修改,但是我们的代码已经改了很多东西,调用的so等也不一样了,直接替换原生的有可能混淆问题,第一次见到UAF问题,其实有些不知道怎么搞,就想着是内存释放再次被用,简单的看了下类Aciton的b()函数,没感觉有什么异常,调用栈信息就是报B异常导致异常,也看下了组内同事初步定为的原因,和同事交流了,按照他的方向去定位怎么也找不到上下文应该出现的log,找测试同学问了下背景和版本路径,发现当天有此类型版本。下下来自测试一下没发现有此问题,当天先搁置,第二天感觉还是需要再看下,因为15号的版本必现,17号没有,又是我们自己的代码,没人合入代码,需要找到原因,当天18号看有当天构建的版本,下下来更新,logcat 一看必现!

      看了下17号配置相关信息,发现是17的不是天网版本,并没有使能kasan。就直接想着上GDB吧,设置入参,设置断点等操作,一层层调用和监控,发现在B函数调用完A函数还没有异常,再走一步出现段错误的提示,一开始以为是调用的函数的原因,查看是原生基础函数,再走读A函数上下文调用,管理类的Complete 把对象释放了,程序继续向下走,Action相关成员变量已经被释放,出现了踩内存问题!!!

事后回顾,发现是我们自己改的代码,经过这次UAF问题,知道这类问题调试手法以及优先查看上下文,要细读代码,内存UAF 肯定是某个对象被释放了,要找到位置。

相关代码细节就不在次贴出来了(大家懂得),C++各层类相互之间的调用,要注意呀~~以后设计开发多层嵌套的时候可得注意哈~

 类似资料: