当前位置: 首页 > news >正文

详细介绍:代码世界的“数字刑侦”:深入解析代码审计实战

摘要:每一个安全漏洞,在被利用之前,都曾是一行静静躺在代码库中的普通代码。代码审计,正是那门在漏洞“行凶”之前,就将其从源代码中“缉拿归案”的终极艺术。本文将深入代码审计的核心方法论,系统性地介绍如何通过“危险函数定位”找到潜在的“犯罪现场”,如何通过“数据流跟踪分析”绘制出攻击者的完整行动路线,以及如何审查“过滤函数”并发现其绕过方式。本文旨在为你构建一套从“怀疑”到“验证”的、可落地的代码审计思维框架。

关键词: 代码审计, 安全编码, 静态分析, SAST, 数据流分析, 危险函数, 漏洞挖掘


⚠️ 严正声明与道德准则:以审计之心,行守护之责

本文所有技术、方法和示例,均以防御和教育为唯一目的,旨在帮助开发者和安全工程师识别并修复自己代码中的安全漏洞。代码审计是一项授权行为。严禁将本文内容用于任何形式的非法活动。


引言:从“黑盒”到“白盒”的上帝视角

在之前的文章中,我们探讨的大多是“黑盒测试”——我们不看应用的内部代码,只通过外部的输入输出来猜测其是否存在漏洞。

代码审计,则是“白盒测试”。我们拥有了应用的完整源代码,这给了我们“上帝视角”。我们可以清晰地看到:

  • 数据是如何流入的?

  • 途经了哪些处理逻辑?

  • 最终流向了何方?

这使得我们能够发现那些极其隐蔽的、黑盒测试难以触及的深层次漏洞。

第一章:审计的“思维模式”——从“正向”到“反向”

  1. 正向追踪 (Forward Tracking):

    • 思路: 从“入口”开始,跟着用户的输入数据“走”。

    • 流程: 找到一个接收用户输入的“源头”(Source),如PHP的$_GET, $_POST,然后一步步地跟踪这个变量,看它流经了哪些函数,最终是否进入了一个危险的“终点”(Sink)。

    • 优点: 符合直觉。

    • 缺点: 在大型项目中,一个输入变量可能经过几十个函数的传递,容易“跟丢”。

  2. 反向追踪 (Backward Tracking) —— 专业审计者的首选:

    • 思路: 从“终点”开始,逆流而上,寻找它的“源头”。

    • 流程: 首先,在代码库中全局搜索所有已知的“危险函数”(Sink),将它们标记为潜在的“犯罪现场”。然后,对每一个“现场”,逆向分析传入其中的变量,看其是否最终可以被用户的输入所控制。

    • 优点:目标明确,效率极高。

第二章:“犯罪现场”定位——危险函数(Sink)的识别

这是反向追踪的第一步。你需要有一份针对你所审计语言的“危险函数清单”。

漏洞类型PHPJavaPython
命令执行system, exec, shell_exec, `Runtime.exec, ProcessBuilderos.system, subprocess.run(shell=True)
代码执行eval, assert, preg_replace /eSpEL, OGNL, 不安全的反序列化eval, exec, pickle.loads
SQL注入mysqli_query, mysql_queryStatement.executeQuerycursor.execute (配合字符串格式化)
文件包含include, require, file_get_contents--
文件上传move_uploaded_file--
SSRFcurl_exec, file_get_contentsURL.openConnectionrequests.get, urllib.request.urlopen
XSSecho, print, printfout.printlnrender_template (不自动转义时)

实战操作: 使用你的IDE(如VS Code, PhpStorm, IntelliJ)的全局搜索功能(Global Search),将这些关键字作为你的第一批目标,创建一个“高风险代码清单”。


第三章:“嫌疑人”追踪——数据流分析

现在,我们对一个“犯罪现场”进行深入调查。

  • 场景: 我们在审计一个PHP应用,通过全局搜索,发现了一处危险的“Sink”:

    PHP

    // file: /user/profile.php
    ...
    $sql = "SELECT * FROM users WHERE id = $user_id";
    $result = mysqli_query($conn, $sql); // <-- 我们的Sink!
    ...
  • 反向追踪开始:

    1. 第一步:分析Sink的直接输入。

      • mysqli_query的第二个参数是$sql。我们需要知道$sql从哪里来。

    2. 第二步:向上追溯变量$sql

      • 就在上一行,我们看到$sql是由字符串和变量$user_id拼接而成的。这是一个强烈的危险信号!

    3. 第三步:继续向上追溯变量$user_id

      • 使用IDE的“查找所有引用”(Find Usages)功能,或继续向上读代码。我们可能发现:

      PHP

      ...
      $user_id = $_GET['id']; // <-- 源头(Source)找到了!
      ...
      $sql = "SELECT * FROM users WHERE id = $user_id";
      $result = mysqli_query($conn, $sql);
      ...
  • 结论: 我们成功地构建了一条完整的数据流链:$_GET['id'] (Source) -> $user_id -> $sql -> mysqli_query (Sink)。在这条链路上,没有任何的过滤或处理。这是一个典型的数字型SQL注入漏洞


第四章:“安保系统”审查——寻找过滤函数及其绕过

并非所有的数据流都是“裸奔”的。在数据从Source流向Sink的过程中,常会经过一个或多个“安保检查站”——过滤/净化函数(Sanitization Functions)

  • 场景: 我们在追踪另一个漏洞时,发现了这样的代码:

    PHP

    // file: /search.php
    ...
    $keyword = $_GET['q'];
    $safe_keyword = sanitize_input($keyword); // <-- 发现一个过滤函数!
    echo "
    您搜索了: " . $safe_keyword . "
    "; // <-- Sink (XSS) ...
  • 审查流程:

    1. 定位过滤函数: 我们找到了一个自定义的过滤函数sanitize_input()

    2. 深入其内部逻辑(最关键的一步):

      • 使用IDE的“跳转到定义”(Go to Definition)功能,我们查看sanitize_input()的源码:

      PHP

      // file: /lib/security.php
      function sanitize_input($data) {// 开发者试图通过一个简单的黑名单来防御XSS$data = str_replace("<script>", "", $data);$data = str_replace("onerror", "", $data);return $data;
      }
    3. 寻找绕过方式:

      • 分析: 这是一个典型的、极其脆弱的黑名单过滤。它只过滤了小写的<script>onerror

      • 构造Bypass Payload:

        • 大小写绕过:<sCrIpT>alert(1)</ScRiPt>

        • 利用其他标签/事件:<img src=x ONERROR=alert(1)> (大写的ONERROR)

        • 双写绕过:<sc<script>ript>alert(1)</script> (如果使用的是str_replace而非str_ireplace)

  • 结论: 过滤函数存在,但其逻辑过于简单,可以被轻松绕过。存储型XSS漏洞依然存在。

审查过滤函数的“心法”:

  • 黑名单 vs. 白名单: 任何基于黑名单的过滤,都应被高度怀疑。健壮的防御永远是白名单。

  • “一次性”过滤: 过滤函数是否只执行了一次?攻击者可能通过双重编码等方式绕过。

  • 上下文错误: 过滤函数是否用错了地方?例如,用htmlspecialchars()(防御XSS)去尝试防御SQL注入,这是无效的。

结论:从“代码阅读者”到“逻辑审查官”

代码审计的本质,不是简单地寻找代码中的“错别字”,而是要成为一名逻辑的“审查官”。它要求我们:

  1. 建立“危险意识”: 熟知各类危险函数,能够快速定位潜在的风险点。

  2. 具备“追踪能力”: 能够像侦探一样,耐心、细致地追踪数据在复杂代码中的完整流转路径。

  3. 拥有“批判性思维”: 绝不轻信任何一个所谓的“安全函数”,而是要深入其内部,审视其逻辑是否严谨,是否存在被绕过的可能。

将这种“反向追踪、深入分析、批判性思考”的思维模式,融入到你的每一次代码审查中,你就能在漏洞被利用之前,将其“捉拿归案”,从而构建出真正坚不可摧的软件系统。

http://www.hskmm.com/?act=detail&tid=23797

相关文章:

  • 三霍尔BLDC如何测量Hall同步角度(需要示波器)
  • QBXT2025S刷题 Day2
  • PyCharm中搭建PyTorch和YOLOv10开发环境 - 实践
  • 基于PCIe(XDMA)的多路(1-32路)信号采集与回放子系统, 多路视频、AD、光纤等信号,支持PR over PCIe
  • Spring事务管理:@Transactional注解
  • AI元人文的未来:软硬件协同发展研究报告——声明Ai研究
  • 个人主页网址
  • 10.3考试t3(similarity)solution
  • 安卓渗透测试流
  • 日志|寻找旋转排序数组中的最小值|寻找两个正序数组的中位数|二分查找
  • 有关三角剖分的性质
  • 西门子通信-自制示意
  • Vue之刷新页面会触发的生命周期函数
  • 傅里叶的一生
  • Dos命令学习(新手)
  • 吴恩达深度学习课程一:神经网络和深度学习 第一周:深度学习简介
  • 实用指南:AI Agent开发平台如何设计?核心架构与工作流实战案例详解
  • Numercial result of HAA-DRSM
  • 防重复提交的实现
  • Day25错误(error)与异常(exception)的简单认识
  • 算法课第一次作业
  • 1. 对拍板子
  • Luogu P14122 [SCCPC 2021] Direction Setting题解 最小费用流
  • MySQL_基础
  • 5 qoj14553 序列与整数对 题解
  • AT_arc064_d [ARC064F] Rotated Palindromes
  • vscode代码块格式转换器
  • 二分模板
  • 如何控制事务?
  • C语言速成秘籍——跳转语句(goto) - 实践