第一次接触代码审计我想从几个问答开始,简单对审计有个简单的认知。

Q1:为什么做代码审计 A1:目标用了开源软件,有审计需求,不管是扫描目标获得备份源码还是拿到 WebShell 后翻到生产应用源码,通过代码发现更多漏洞做好后门储备。

Q2:代码审查和代码审计区别 A2:Code Review
更多的是关注软件整体,比如说重构,设计,风格这种,而代码审计则是只从安全角度看这段代码有没漏洞,不需要关注工程相关的内容。

Q3:审计前知识储备
A3:我的经历是先黑盒挖过些 Web 洞后,发现根据现实需要,审计是是后面做项目自然需要会的内容,这里以 Java 为例去说明学习审计需要学哪些内容,后面的PHP,JavaScript,Python,Golang 都是类似。
刚接触 JavaWeb,肯定先把 JavaSE 完整跟一遍网上培训班公开的视频,确保知识点都比较熟悉最后在跟进 JavaWeb。JavaWeb 这块相关的知识按照顺序需要学习的有 MySQL/JDBC/Mybatis/Servlet/JSP/Spring/Spring MVC/Spring Boot。
这么多内容我到底需要学习到啥成度才能开始审?这里简单聊聊 Java 代码审计学习深与浅。学习基础的 Web 应用代码审计只需要会对应框架使用,了解基本使用场景,特别深入的源码分析无需了解,如 Spring 处理请求用的是 Servlet,那 Servlet 规范在各个 Web 容器中实现就不需要分析。那什么时候才需要深入源码呢?如果是挖框架或者知名组件的漏洞,这才需要你学习设计模式和算法,去分析它们的源码,这些内容大量在框架中使用。所以在刚开始的时候不要深究源码分析,否则会学偏,最后学着学着变成学开发了。

目录

1 动态(远程)调试环境搭建

阅读代码的工具使用 JetBrains 家的 IDE。

1.1 PHP

尽量不要用 Windows 集成环境,比如 phpStudy,WampServer,使用 Linux 安装 PHP 应用进行调试可以增加在真实环境的熟练度,Linux 我是使用 WSL2 安装的 Kali,当然 Ubuntu 也可以参考,只是软件源安装方式不同,其他操作都是一样。

安装 PHP

Kali 2024.3 自带的 8.2.12 不能满足审计环境下对每个漏洞的 PHP 版本要求。

先来看看怎么安装 PHP,Kali 是 Debain 所以用 Ondřej Surý 维护的源来安装,他非常贴心,给出了 Bash 脚本

由于是在 Kali 下使用这个库,直接使用作者的脚本运行会报错是因为 https://packages.sury.org/php/dists/ 只有 bookworm 和 bullseye 两个源,bookworm 是 Debian 12,bullseye 是 Debian 11。而我们安装库源时使用的是 $(lsb_release -sc) 识别 Debain 是那个版本,在 Kali 下输出的是 kali-rolling,实际上 Debain 没有这个版本自然找不到仓库。

Ign:2 https://packages.sury.org/php kali-rolling InRelease
Err:3 https://packages.sury.org/php kali-rolling Release
  404  Not Found [IP: 143.244.50.83 443]
Reading package lists... Done
E: The repository 'https://packages.sury.org/php kali-rolling Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

Kali 是根据 Debain trixie 版本进行构建的,所以我们可以直接把 $(lsb_release -sc) 改成 bookworm 就好。

#!/bin/sh
# To add this repository please do:

if [ "$(whoami)" != "root" ]; then
    SUDO=sudo
fi

# 更新源
${SUDO} apt-get update

# lsb_release 命令是一个简单的工具,可以帮助识别所使用的Linux发行版及其与Linux标准库的一致性。这个包包含了一个基本的实现,它使用了/etc/os-release中的信息,而不是依赖于LSB包。
# 常见CA证书。包含Mozilla浏览器附带的证书颁发机构,允许基于SSL的应用程序检查SSL连接的真实性。
${SUDO} apt-get -y install lsb-release ca-certificates curl

# 下载软件包的密钥环(keyring),然后安装这个密钥环,以便在后续安装软件包时可以验证其来源。
${SUDO} curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
${SUDO} dpkg -i /tmp/debsuryorg-archive-keyring.deb

# 导入 gpg 密钥,安装 PHP 源。记得把 $(lsb_release -sc) 改成 bookworm
${SUDO} sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main" > /etc/apt/sources.list.d/php.list'

# 更新源
${SUDO} apt-get update

成功更新源后可以 apt search php 对应版本是不是存在,一切没问题后可以安装 php。

apt install -y php8.3

但是还是报错,说没有依赖,这是仓库里没有,可以去 Debian 官网软件包仓库手动下载 libffi7libssl1.1 安装。

┌──(root㉿raingray)-[~/Desktop]
└─# apt install -y php8.3
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 php8.3 : Depends: libapache2-mod-php8.3 but it is not installable or
                   php8.3-fpm but it is not installable or
                   php8.3-cgi but it is not installable
 php8.3-common : Depends: libffi7 (>= 3.3~20180313) but it is not installable
                 Depends: libssl1.1 (>= 1.1.0) but it is not installable
E: Unable to correct problems, you have held broken packages.

它这个源的是只能安装最新版本,比如安装 php8.3,等同于安装主版本 8 次版本 3 的最新发布版,你想安装指定 8.3.x 的修复版就不行,人家没提供这些版本,只能去官网下载手动编译安装

安装 PHP 扩展

php 安装完成后可以安装相同版本的扩展,比如 php8.3 就安装 php8.3-fpm。安装多个可以用花括号包起来,一个则不用。

apt install -y php8.3-{fpm,cli,mysql,curl,gd,mbstring,xml,zip,imap,opcache,soap,gmp,bcmath}

其中 php8.3-fpm 安装完成后命令是 php-fpm8.3,默认配置文件是 /etc/php/8.3/fpm/pool.d/www.conf,默认监听 socket,实在不知道配置文件路径可以用 php-fpm8.3 -t 看看配置文件检查结果。

Listen =/run/php/php8.3-fpm.sock

Nginx 默认配置文件(/etc/nginx/sites-available/default)只要 fastcgi_pass 和 php-fpm 配置文件监听的路径一致就可以,剩下的都用 snippets/fastcgi-php.conf 默认配置即可解析 PHP 脚本。

location ~ \.php$ {
    # FastCGI 配置文件
    include snippets/fastcgi-php.conf;

    # 设置从 FastCGI 服务器读取请求响应最长等待时间,默认 60s
    # 避免 Debug 长时间断点,造成 Nginx 都不到 PHP-FPM 响应返回 504 Gateway Time-out,所以这里设置成三天。
    fastcgi_read_timeout 259200;

    # With php-fpm (or other unix sockets)
    fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}

跟以往 Nginx 版本不一样,不再使用 fastcgi.conf 作为默认配置文件,而是用 /etc/nginx/snippets/fastcgi-php.conf 配置怎么把 PHP 请求发送给 PHP-FPM 解析。

# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+?\.php)(/.*)$;

# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;

# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

fastcgi_index index.php;
include fastcgi.conf;

GPT 对解释如下 fastcgi-php.conf。

这段 fastcgi-php.conf 配置的内容用于处理 PHP 请求,具体解释如下:

这段 fastcgi-php.conf 配置的内容用于处理 PHP 请求,具体解释如下:

  1. fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    功能:将请求 URI 拆分为两个部分。
    $fastcgi_script_name:匹配到的 PHP 文件名(例如 example.php)。
    $fastcgi_path_info:匹配到的额外路径信息(例如 /some/path)。
    正则解释:
    ^(.+?.php):匹配以 .php 结尾的文件名。
    (/.*)$:匹配随后的路径信息。
  2. try_files $fastcgi_script_name =404;
    功能:在处理请求之前,检查指定的 PHP 文件是否存在。
    工作机制:
    如果 $fastcgi_script_name 对应的文件存在,则继续处理请求。
    如果文件不存在,则返回 404 错误。
  3. set $path_info $fastcgi_path_info;
    功能:将之前分割出的 $fastcgi_path_info 赋值给新的变量 $path_info
    目的:这是为了绕过 try_files$fastcgi_path_info 的重置(在某些情况下,try_files 会重置该变量),确保可以继续使用该路径信息。
  4. fastcgi_param PATH_INFO $path_info;
    功能:将 $path_info 变量传递给 FastCGI 作为 PATH_INFO 参数。
    目的:使 PHP 脚本能够访问额外的路径信息,通常用于处理 RESTful 请求或其他需要路径信息的场景。
  5. fastcgi_index index.php;
    功能:指定默认的 PHP 文件,当请求目录时(例如 http://example.com/),默认使用 index.php 文件。
    作用:当用户访问某个目录而不指定文件时,会自动加载 index.php。
  6. include fastcgi.conf;
    功能:包含 Nginx 的标准 FastCGI 配置文件 fastcgi.conf,通常包含了处理 FastCGI 请求所需的其他参数配置。
    作用:设置一些 FastCGI 参数,如 SCRIPT_FILENAME、QUERY_STRING、REQUEST_METHOD 等,这些是与 PHP-FPM 进行通信所必需的。

安装 Xdebug 扩展

按照官网兼容性表格去下载 Xdebug 扩展源码,手动编译获取扩展。

确定下当前 PHP 版本的默认扩展目录,可以通过命令或者 phpinfo 查看 extension_dir 的值。有了扩展目录后把刚刚的扩展复制过去。

┌──(root㉿raingray)-[~/Desktop]
└─# php8.3 -ini | grep extension_dir
extension_dir => /usr/lib/php/20230831 => /usr/lib/php/20230831

手动没试过,后续有机会再尝试。

如果图省事也可以直接搜索 php[version]-xdebug 去安装,安装前需要确认对应 xdebug 版本是多少,这里是 3.3.2。自动安装的好处是,节省编译和手动复制的过程。

┌──(root㉿raingray)-[~/Desktop]
└─# apt info php8.3-xdebug
Package: php8.3-xdebug
Version: 3.3.2-1+0~20240420.60+debian11~1.gbp3869a8
Priority: optional
Section: php
Source: xdebug
Maintainer: Debian PHP PECL Maintainers <team+php-pecl@tracker.debian.org>
Installed-Size: 2,353 kB
Provides: php-xdebug
Pre-Depends: php-common (>= 2:69~)
Depends: ucf, php8.3-common, phpapi-20230831, libc6 (>= 2.29), zlib1g (>= 1:1.2.11.dfsg)
Breaks: php-xdebug (<< 3.3.2-1+0~20240420.60+debian11~1.gbp3869a8~)
Replaces: php-xdebug (<< 3.3.2-1+0~20240420.60+debian11~1.gbp3869a8~)
Homepage: https://xdebug.org/
Download-Size: 612 kB
APT-Manual-Installed: yes
APT-Sources: https://packages.sury.org/php bullseye/main amd64 Packages
Description: Xdebug Module for PHP
 The Xdebug extension helps you debugging your script by providing a lot of
 valuable debug information. The debug information that Xdebug can provide
 includes the following:
 .
    * stack traces and function traces in error messages with:
       - full parameter display for user defined functions
       - function name, file name and line indications
       - support for member functions
    * memory allocation
    * protection for infinite recursions
 .
 Xdebug also provides:
 .
    * profiling information for PHP scripts
    * script execution analysis
    * capabilities to debug your scripts interactively with a debug client

先通过 phpinfo 确认当前用的是哪个 php.ini 配置文件(浪费了好几个小时排查配置错误,一定要检查好再编辑),编辑 php.ini 搜索 zend_extension= 启用扩展。

zend_extension=xdebug

在 php.ini 搜索 Module Settings,配置 XdeBug 扩展相关细节,需要注意 XDebug3.x 和 XDebug 2.x 配置项部分名称和值有更改,具体可以从官网 Upgrading from Xdebug 2 to 3 这篇文档搜下面配置找到原来对应 2.x 内容。其中 3.x 中的各个设置项官网也有展示,可不止下面设置的这点儿,有另外的需求需要自己查阅。

;XDebug 3 配置
[XDebug]
xdebug.client_host=172.18.80.1
xdebug.client_port=9003
xdebug.remote_log=/tmp/xdebug-log
xdebug.mode=debug
xdebug.idekey=PHPSTORM
xdebug.start_with_request=true
xdebug.discover_client_host=true

xdebug.client_host 和 xdebug.client_port 作用是收到 PHP 请求先主动向这个地址的端口进行连接。具体地址我填的是宿主机 WSL 网卡地址,这个地址呢和 WSL 虚拟机互相通信,不然连接不上就没法 Debug。

以太网适配器 vEthernet (WSL (Hyper-V firewall)):

   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . : fe80::b9aa:8af7:6749:f64%77
   IPv4 地址 . . . . . . . . . . . . : 172.18.80.1
   子网掩码  . . . . . . . . . . . . : 255.255.240.0
   默认网关. . . . . . . . . . . . . :

xdebug.idekey=PHPSTORM,是设置连接的密钥。xdebug.start_with_request=true 则是不使用浏览器插件 Xdebug helper 也能主动连接客户端。

最后重启 php-fpm 查看 phpinfo 确认 XDebug3 成功加载。

PHPINFO 中确认 XDebug3 成功加载.png

配置 PhpStorm

1.配置项目解析器

使用 PhpStorm 打开 WSL 实例 Web 项目源码路径 \\wsl.localhost\kali-linux\var\www\html

Ctrl + Alt + s 打开设置,设置好当前项目 PHP language level 用的什么版本 PHP 好做语法、特性检查

CLI 解析器是后续单独运行某个 php 脚本会用到你设置的命令行解析器。设置的时候要选 “From Docker, Vagrant VM, WSL, Remote...” 会自动识别出当前 WSL 中的实例。

PhpStorm PHP CLI 解析器.png

2.设置监听端口

PHP -> Debug -> Xdebug -> Debug port 设置 PhpStorm 要监听的 XDbug 端口,设置完成会在本地 IPV4/IPV6 上监听这两个端口,等待服务端连接。

这个值填 php.ini 中配的端口 9003,这里默认值是 9003 和 9000,可以同时监听多个端口。

PhpStorm 配置 Debug-1.png

3.配置 Web 服务器

先确认 WSL 实例对外的 IP 是多少,这里是 172.18.91.76。

┌──(root㉿raingray)-[~]
└─# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 10.255.255.254/32 brd 10.255.255.254 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:19:99:85 brd ff:ff:ff:ff:ff:ff
    inet 172.18.91.76/20 brd 172.18.95.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fe19:9985/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:64:93:33:7e brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

找到 PHP -> Servers 新建一个服务器,填写完地址和端口,把项目源码本地路径和服务器上源码绝对路径做映射就完成这步骤。

PhpStorm 配置 Web Server.png

4.测试网络连接

前面设置完监听的端口后,需要手动启动监听等待链接。

PhpStorm 启动端口监听.png

这个端口监听的状态也可以在主界面上找到。

PhpStorm 主界面启动端口监听功能位置.png

启动完成后通过网络状态发现确实开启了监听。

PS C:\Users\gbb> netstat -anp tcp | findstr 9003
  TCP    0.0.0.0:9003           0.0.0.0:0              LISTENING

验证到底服务器能不能链接到 PhpStorm 9003 端口,全绿就没问题,这个检查结果就显示了客户端相关信息。

网络连接检查结果.png

5.运行配置文件设置

创建的配置选择 PHP Remote Debug,Server 选择第三步创建好的 Web Server,对应 IDEKey 也填 php.ini 中的 key。

PhpStorm 配置 Debug 运行内容-2.png

一切填写完成需要再点 Pre-configuration 中的 Validate 验证下,确保设置没有填写错误。

之后就以 Debug 方式运行,只要下好断点访问对应页面就能拦截成功。

断点成功.png

多个 PHP 版本管理

切换的前提是你有安装好新版本 php,对应 php-fpm 和 XDebug。

1.切换 PHP

多个 PHP 版本的情况下用 update-alternatives 切换默认值。

┌──(root㉿raingray)-[/var/www/html]
└─# sudo update-alternatives --config php
There are 2 choices for the alternative php (providing /usr/bin/php).

  Selection    Path             Priority   Status
------------------------------------------------------------
  0            /usr/bin/php8.3   83        auto mode
  1            /usr/bin/php8.2   82        manual mode
* 2            /usr/bin/php8.3   83        manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/bin/php8.2 to provide /usr/bin/php (php) in manual mode

可以看到第一个 PHP Value: /usr/bin/php8.2 值就是 8.2。

┌──(root㉿raingray)-[~/Desktop]
└─# update-alternatives --query php
Name: php
Link: /usr/bin/php
Slaves:
 php.1.gz /usr/share/man/man1/php.1.gz
Status: manual
Best: /usr/bin/php8.3
Value: /usr/bin/php8.2

Alternative: /usr/bin/php8.2
Priority: 82
Slaves:
 php.1.gz /usr/share/man/man1/php8.2.1.gz

Alternative: /usr/bin/php8.3
Priority: 83
Slaves:
 php.1.gz /usr/share/man/man1/php8.3.1.gz

2.切换 PHP-FPM

先确认下 php-fpm 监听在哪,内容没有错。

┌──(root㉿raingray)-[~/Desktop]
└─# php-fpm8.2 -t
[22-Oct-2024 17:46:55] NOTICE: configuration file /etc/php/8.2/fpm/php-fpm.conf test is successful


┌──(root㉿raingray)-[~/Desktop]
└─# grep "^listen =" /etc/php/8.2/fpm/pool.d/www.conf
listen = /run/php/php8.2-fpm.sock

启动对应 php 版本的 php-fpm。

┌──(root㉿raingray)-[~/Desktop]
└─# systemctl status php8.2-fpm
○ php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php8.2-fpm.service; disabled; preset: disabled)
     Active: inactive (dead)
       Docs: man:php-fpm8.2(8)

Oct 22 15:24:01 raingray systemd[1]: Starting php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager...
Oct 22 15:24:01 raingray systemd[1]: Started php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager.
Oct 22 15:55:08 raingray systemd[1]: Stopping php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager...
Oct 22 15:55:08 raingray systemd[1]: php8.2-fpm.service: Deactivated successfully.
Oct 22 15:55:08 raingray systemd[1]: Stopped php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager.

┌──(root㉿raingray)-[~/Desktop]
└─# systemctl start php8.2-fpm

3.修改 Nginx 中 PHP-FPM 配置

将 fastcgi_pass 中的版本号进行修改成 php-fpm 监听位置,重新加载配置文件。

┌──(root㉿raingray)-[~/Desktop]
└─# nginx -s reload
2024/10/22 17:48:55 [notice] 26372#26372: signal process started

嫌麻烦也可以建立虚拟环境,给确保给每一个 PHP 应用都启动他们需要的 PHP-FPM 版本独立的,在配置中也使用对应版本 PHP-FPM。

PHP 启用错误展示

编辑 php.ini 启用错误信息展示,方便调试代码异常。

copy /etc/php/7.4/fpm/php.ini /etc/php/7.4/fpm/php.ini.back
sed -i 's/^display_errors = Off/display_errors = On/' /etc/php/7.4/fpm/php.ini
grep ^display_errors /etc/php/7.4/fpm/php.ini

1.2 Python🔨

使用虚拟环境来隔离不同应用对包的要求

PyCharm

1.3 Java🔨

运行时添加下面选项开启 JVM 调试。

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

Tomcat 调试 https://wx.zsxq.com/group/2212251881/topic/215258288444481
https://wx.zsxq.com/group/2212251881/topic/588481244848244

IDEA 插件 MurphySec 辅助源码审计。

2 源码获取方式

  1. 根据应用特征找到供应链或者互联网上其他相同版本的系统,打下打下拿源码。目标是 Windows 可用 makecab 打包站点源码进行审计
  2. 申请试用或者购买使用权拿到源码,这种商业产品有可能在云市场存在线上版本,通常以 ISO 镜像或者 Docker 部署的容器的方式来提供服务
  3. 找找有没泄露或公开过源码,github、tg、网盘、淘宝、闲鱼

3 审计策略

1.全局通览

代码量一大,费时,对要求快速出成果的项目 ROI 低,另一个缺点是不好关注各个功能之间的关联。对于公司内部审计,去排除安全风险是可行的。

2.自顶向下

从用户使用角度,审指定功能,逐层追溯调用了哪些方法,将这些方法全部审一遍。

3.自底向上

找到你感兴趣的方法,逐层往上追溯谁在调用,一直审到用户入口。

4.关键字匹配

有些方法使用不当会产生漏洞,通过关键字匹配快速找到这些方法,去看谁在调用。缺点是覆盖不全,对于需要快速审计的应用比较适合使用。

工具:
Seay、RIPS、Tomm 闪电文件搜索、grep(或者使用 ack 替代)
Fortify、CodeQL

具体审计方式有两种:一种是纯静态看代码 SAST(Static Application Security Testing),简称静态分析,另一种就是静态查看结合动态调试下断点具体分析数据流向。

4 审计根本原则

原则只有一个,只看输入的数据流是否可控,最终改变控制流。数据流就是用户输入的数据,控制流是整个代码或者业务逻辑。

  1. 代码逻辑有没安全问题,调用的 API 是否安全
  2. 参数是否可控
  3. 观察数据输入输出 Filtering/Escaping 情况,有过滤能绕过并且能够通过 URL 访问,就是 Vulnerability 漏洞,没有过滤也是漏洞,不然就是风险 weakness。需要画流程图

5 快速审计方法

历史漏洞

确认当前组件依赖来看看不能不能打历史漏洞。

时间不着急的情况下还可以 diff 两个版本找差异来确认漏洞点。

入口分析

文件定位,可以通过文件调用里面具体方法。

路由映射,通过配置文件定义访问路径,通过配置文件来指定这个路径访问的是哪个功能的哪个方法。简称路由定位代码。

常用框架就这些,不懂的快速去官网学学路由怎么配置。

知道路由就能快速了解这个 URL 对应着具体代码位置。

自动化工具:常见的框架或者 Web 应用路由设置就是些固定用法,可以写个小工具自动化手机路由请求 URL,请求方法和参数。

实战问题:
拿到 SpringBoot 应用编译后的 Jar 包,用 IDEA 怎么搜索对应获取请求参数的注解?没法搜索字节码中的内容。最好统一反编译成 Java 再搜索。下面是 Java 快速反编译两种方式:

1.使用 IntelliJ IDEA 的插件 java-decompiler.jar,将目标 jar 反编译输出到指定目录下,

java -cp java-decompiler.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true 目标.jar 输出目录

java -jar java-decompiler.jar -dgs=true 目标.jar 输出目录

2.使用 jadx

Spring 注解快速查看接口

@(.*?)Mapping(

1.查配置文件
Servlet:WEB-INF/web.xml
SpringBoot
Struts2
pom.xml 可以看到依赖信息

2.分析第三方组件
通过上述配置文件查框架、组件版本有 Nday 打 Nday。

3.查过滤器和拦截器
过滤器和拦截器会先处理请求再进入代码逻辑。这一步很可能做了过滤。

<filter> 引入过滤器 </filter>
<filter-mapping> 作用在哪些请求上

4.审计具体功能

https://github.com/0e0w/HackJava

业务功能

优先检查鉴权,寻找未授权。

垃圾洞攒着,组合成高危洞。

审计检查清单🔨

不同审计项目要求不同,有的是要拿 Shell,有的是需要发现系统所有安全风险点。

1.认证

应用程序用户是否经过身份验证,还是都被视为匿名用户?

哪些因素用于身份验证 (,例如密码、令牌和证书) ?

如果正在使用密码,是否有任何关于复杂性或年龄的政策?

2.授权

是否可以根据应用程序的功能为用户提供不同的角色?

是否检查了每个传入请求的缓存授权数据?

Web 根目录中是否存储了任何未授权普通用户的私有敏感数据文件?

3.数据验证

用户提交的数据是否经过验证?

数据是用户输入后立即验证,还是代码使用数据?

数据验证是如何完成的(白名单、黑名单、最小/最大等)?

您是否正在使用数据库?如果是这样,您是否使用准备好的语句?

4.异常/错误处理

正在使用哪些方法进行错误处理?

向用户显示有关错误的哪些详细信息?

错误跟踪是否曾发送回给用户?还是仅发送到日志?

敏感数据是否错误地记录到日志文件中?

如果数据库引发错误,错误消息是发送给用户,还是传递给日志?

5.会话管理

应用程序是否有任何方法可以管理或存储会话状态,如果有,如何管理或存储?

会话 ID 是如何生成的?

当用户登录站点并创建新会话时,是否会删除上一个会话?

令牌是否用于会话管理?如果是,使用什么算法?

会话是否有任何超时?

如果使用 Cookie,Cookie 中是否存在路径和域限制?

6.日志

代码中是否使用了任何类型的日志记录?

生成的日志消息会发送到哪里?

不应有权访问日志文件的用户(任何或所有员工)是否能够访问它们?

您是否记录了任何未首先验证的输入或验证失败的数据?

日志消息是否带有时间戳?

是否有任何敏感数据写入日志(例如,密码、API 密钥等)?

7.加密

代码中是否使用了任何加密算法?(SSL、TLS、RSA?

您从哪里获得该库的实现,它使用什么版本?

如果使用 3DES 或 AES(任何分组密码),则使用哪种加密模式?

代码中是否有处理加密的中心函数?它在哪里?

参考链接

最近更新:

发布时间:

摆哈儿龙门阵