垃圾代码渗透历险记

First Post:
Last Update:
Word Count: 2.3k
Read Time: 8min

探寻屎山

这里有几个大项目代码接手的心得,一般来说很少有后来的人会做这种而且有些时候上一代人也不会主动来说 甚至代码的文档乃至是注释都不一定有。导致你上线去看代码的时候非常的哈人,代码扭曲又恶心。完全不知道从何做起。

那么我们身为前端后端 哪怕是渗透测试人员 日穿了网站准备审计代码漏洞挖掘的) debug 与 代码审计的能力就显得非常的重要了。

暴论:没文档的屎山代码搭配不规律全是痕迹的服务器的条件下 维护与渗透几乎无异

这里我们先不论代码混淆和代码加密这种在生产环境可能出现的极端情况 还有 GO 写的后端 WebAPI 直接编译成二进制运行的高级东西。

首先我们假设环境是你整下来开发机测试调试机器 亦或是就是动态的脚本语言后端 (如 PHP) 等。此外你需要两个东西,一个是优秀的 IDE (喷气脑子真的是太棒啦!) 其实并不推荐使用编辑器 (如 VSC 一般牛逼的除外),当然主要是需要一个能在大项目里跨目录跨文件的强力搜索工具。
Jetbrains 一般为 Ctrl+Shift+f <C-F>。当然本文写作的时候 Github 的新玩具 代码搜索工具已经在测试了。

TL;DR

长话短说 这里采用的方法是 从外部信息开始收集,跟踪代码逻辑的执行流程 进入内部后再反过来理解周围每一个部件的处理逻辑和边界,再下放 探寻 中间件构造。整个过程讲究的是一个读代码的能力和理解的能力。

deploy & run part

首先当然是进行一个[编译(如果你真的需要编译的话),]部署和尝试运行这里需要亿点知识。一般来说 作为前端或者后端乃至运维乃至是渗透测试人员,需要关注这样几个文件。

  • Makefile
    • 一个 make 指令就能进行一个编译 其中定义了各个组件对应依赖的情况
  • CMakeList.txt
    • 这玩意用来生成 make 文件,你可以理解为 make 的 make
  • Dockerfile
    • 一般是单个基础的小部件环境配置 例如特殊的测试环境之类的
  • Docker-compose.yml
    • 一个 Docker 构建的配置 方便构建对应应用程序的服务 这样可以部署一个小网络之间的相互依赖的关系
  • config
    • 一般来说就是配置的相关 这个一般取决于具体的框架 例如 wp-config.phpconfig.py这种
  • *.yml *.yaml *.toml *.json
    • 这些就是一些服务会调用的玩意,但是要注意可能是什么 k8s 的部署文件
  • .*
    • 以 .开头的隐藏文件 很可能也是配置文件之一

如果说上面这些比较阳间(常见),来点阴间的玩意。我们会主要关注以下两几点 版本控制 和 CI-CD 这些是部署一个

  • .git / .svn
    • 这里可以参考 git 目录源码泄露
  • .github/workflow/*
    • 一般是 Github Actions 所在的地方可能会暴露一些信息,提示一些自动化部署的步骤 在你不知道上一代究竟怎么润起来代码的时候可以进行一个读。

这些都会对你理解项目各个组件之间的关系具有一定的帮助。

如果跑不起来先一般看错误信息或者提示,其实可以盲猜一手多半是配置和环境寄了,跟踪 StackPrint 这些回去定位寄掉了的部分。然后尝试从新润起来这个项目。

一般如果能够跑起来的话其实可以进行一个代码的全局搜索。接下来就是我们的第二部份

运行调试 流程跟踪

这里需要进行一个调试服务器的开 一般性 IDE 都具有类似的调试器启动方法,有的还会有测试方法。然后进行一个模拟访问和接入, 可能需要记录下一个(你不觉得麻烦也可以多个)入口位置和实现功能之类的信息。

一般性同时在 IDE 这端需要一个搜索 去寻找你记录下来的入口例如 需要访问的入口地址 /path/to/example 那么就需要在代码的部分中进行查找 定位出来具体的路由相关信息 比如说具体的注册函数和对应的业务逻辑的函数

可能在业务处理的时候具有一些 BUG 那么看情况使用 打log print 断点 这些地方的关键执行逻辑位置。

流程逻辑分析

经过多个上一步的检查或者说测试,基本能构建起一套框架处理的逻辑。

之后返回到具体业务层看到平级其他业务。主要可以看看周围其他的函数和辅助的函数之间的关系。可能会牵扯到周围很多函数和大量的库函数,这时候就可能需要一个一个搞明白。但是无论如何 不要相信的他的代码 (尤其是 Java) 你以为她是做这个的,但其实和名字说明的东西完全不一样,你可以先行信任,但是一定要记得回去检查某些东西在你的执行流程里究竟做了什么。

Wrap up

到业务分析完毕之后可以回去看看一些关键性的函数,例如数据库调度和数据库表单设计,这是一种检查,还有就是检查中间件,例如多个路由特殊的构造函数,类,对象,结构体。之后我们来到了最后的部分。一定注意要检查每一个函数/对象的安全性边界,

例如有些特殊的函数用法 在特殊构造情况下具有特殊用法 例如 Ruby的open 是具有命令执行风险的

参考文章: PHP 反序列化漏洞代码审计

渗透测试方法论

类似于黑盒的情况,我认为最为主要的有以下这么几个方面

信息收集和理解程度

所有的渗透测试都是基于信息的,所有的攻击一开始都是从信息收集开始的。只有拥有了一定程度的了解才能正确的实施攻击,乱打 EXP 和 POC 更有可能导致对方提高警惕,加强戒备,也有可能守株待兔反向打击一波,哪怕是原来具有漏洞的也有可能因为对方检查之后而被修复或打上补丁。

攻击是需要很多条件的,什么意思呢?攻击利用成功一次通常需要多个风险点(具体可以体现在利用的步骤当中)的联合利用,或者是多个漏洞联合的结果。而且进攻之中任何一步的缺失都有可能导致利用失败,乃至可能会导致整个渗透的失败。

更多的信息会为我们渗透过程铺平道路,知己知彼,百战不殆,以至于,我们甚至可能需要对于系统的了解程度超过系统本身的开发人员和系统的运行维护人员。

枚举和检查

黑盒的情况是很常见,也是很极端的。因为你完全不知道对方的代码,这会导致两个问题。一个是你对对方的执行方法不了解,可能有些地方程序员偷懒,那你就完全看不到。第二个是逻辑看不到,这里反应的有不少是代码执行的顺序,某些操作和某些操作分别看似无害但是一旦放在一起变成了危害了。这里的典型例子就有 PMA 未授权访问。 Quick Link 宝塔 PMA 未授权访问漏洞是否是一个低价错误=>

简单的枚举一些危险的弱密码,检查服务以及其版本,枚举下子域名 端口 目录。枚举资产。检查一些敏感点,例如 CI-CD 服务 Jenkins 版本管理 Gitlab FTP 文件服务 等等 这些是及其容易被穿透的。

滥用的思想

一旦你获得了一些关于目标的信息,就可以想想如何好好利用它 比如说 你偷到了一个用户名密码的组合,你只知道它可以用来登陆服务器的邮件,但是为什么不试试在 SSH 登陆里使用呢?亦或者你发现了一个数据库注入,尝试获取更多的信息,包括但不限于数据库 RCE ,敏感信息用户名密码及其复用 等。哪怕只是一个小小的 API 或许也可以为你带来一些什么。