“零基础”PHP代码审计入门

news2025/2/25 12:11:07

目录

一、代码审计目的

二、代码审计基础

三、 代码审计思路

四、PHP核心配置

五、 代码审计环境

六、手动调试代码

七、PHP的弱类型

八、学习漏洞函数

九、审计入门总结

推荐一些demo:


一、代码审计目的

代码审计指的是对源代码进行检查,寻找代码中的bug以及安全缺陷(漏洞)。代码审计这是一个需要多方面技能的技术,也是需要一定的知识储备。我们需要掌握编程,安全工具的使用、漏洞原理、漏洞的修复方式、函数的缺陷等等,如果再高级一些,我们需要学习不同的设计模式,编程思想、MVC框架以及常见的框架。

那么对于小白应该是需要一个路线,一个流程。

先记住一句话"一切存在用户输入的地方都有可能存在漏洞"戳一戳免费获取网络安全资料腾讯文档-在线文档icon-default.png?t=N7T8https://docs.qq.com/doc/DYmVETWlZemh0Ymdv

二、代码审计基础

代码审计入门基础:html/js基础语法、PHP基础语法 ,面向对象思想,PHP小项目开发(Blog、注册登录、表单、文件上传、留言板等),Web漏洞挖掘及利用,Web安全工具基本使用(burpsuite、sqlmap等),代码审计工具(seay审计系统、zend studio+xdebug等)

代码审计两种基本方式:

  • 通读全文源码:通读全文发作为一种最麻烦的方法也是最全面的审计方法。特别是针对大型程序,源码成千上万行。当然了解整个Web应用的业务逻辑,才能挖掘到更多更有价值的漏洞。
  • 功能点审计:根据漏洞对应发生函数进行功能行审计,常会用到逆向溯源数据流方法进行审计。

代码审计两种基本方法:

  • 正向追踪数据流:跟踪用户输入参数 -> 来到代码逻辑 -> 最后审计代码逻辑缺陷 -> 尝试构造payload
  • 逆向溯源数据流:字符串搜索指定操作函数 -> 跟踪函数可控参数 -> 审计代码逻辑缺陷 -> 尝试构造payload

现cms可分大体两类:

  • 单入口cms:不管访问哪个模块都使用同一个入口文件,常见的MVC框架采用这种模式。
  • 多入口cms:每个模块都有一个入口文件(可以前端设置一个入口文件 index.php,后端创建一个入口文件admin.php,前后端的入口文件是独立的)。

三、 代码审计思路

从个人角度出发,如果环境允许的话,可以先选择做一个”程序员“再来做代码审计。

因为从开发者的位置去思考问题,可以快速定位问题。学习面向对象编程以及面向过程编程,编写一些项目提升对代码的理解能力,再是对各种漏洞可以独立挖掘利用并能理解漏洞的危害,这里我们主要针对PHP源码做审计

接下来我们从三个层次开始我们的源码审计思路

  1. 确定要审计的源码是什么语言
  2. 确定该源码是单入口还是多入口
  3. 确定该语言的各种漏洞诞生的函数

四、PHP核心配置

一个漏洞在不同环境造成的结果也是不一样的。

由于关于php.ini配置的内容过于多,这里推荐浏览官方文档 https://www.php.net/manual/zh/ini.php,我们在这里主要列下php.ini 主要使用的安全配置。

  • safe_mode = off
用来限制文档的存取,限制环境变量的存取,控制外部程序的执行. PHP5.4.0移除。
  • 限制环境变量存取safe_mode_allowed_env_vars = string
指定php程序可以改变的环境变量的前缀,当这个选项的值为空时,那么php可以改变任何环境变量,如果 如:safe_mode_allowed_env_vars = PHP_,当这个选项的值为空时,那么php可以改变任何环境变量。
  • 外部程序执行目录safe_mode_exec_dir = "/usr/local/bin"
当安全模式被激活,safe_mode_exec_dir参数限制通过exec()函数执行的可执行文件到指定的目录。举例来说,如果你想限制在/usr/local/bin目录执行功能,你可以使用这个指令:
safe_mode_exec_dir = "/usr/local/bin"
  • 禁用函数
    disable_functions
为了更安全的运行PHP,可以用此指令来禁止一些敏感函数的使用,当你想用本指令禁止一些危险函数时,切记把dl()函数也加到禁止列表,攻击者可以利用dl()函数加载自定义的php扩展突破disable_functions.配置禁止函数时可以使用逗号分隔函数名。
  • COM组件com.allow_dcom = false
PHP设置在安全模式下(safe_mode),仍允许攻击者使用COM()函数来创建系统组件来还行任意命令,推荐关闭这个函数。 使用COM()函数需要在PHP.ini中配置 extension=php_com_dotnet.dll,如果PHPversion<5.4.5则不需要。
  • 全局变量注册开关register_globals = off
php.ini的register_globals选项的默认值为OFF,在4.2版本之前是默认开启的,当设定为On时,程序可以接收来自服务器的各种环境变量,包括表单提交的变量,这是对服务器分厂不安全的, register_globals = off时,服务器端获取数据的时候用$_GET['name']来获取数据。 register_globals = on时,服务端使用POST或GET提交的变量,豆浆自动使用全局变量的值来接受。
  • 魔术引号自动过滤magic_quotes_gpc = on
PHP5.4.0被移除 magic_quotes_gpc = off 在php.ini中默认是关闭的,如果打开它,将自动把用户提交对sql的查询的语句进行转换,如果设置成ON,php会把所有的单引号,双引号,和反斜杠和空字符(NULL)加上反斜杠()进行转义 它会影响HTTP请求的数据(GET,POST.COOKIE),开启它会提高网站的安全性。
  • 是否允许包含远程文件allow_url_include = off
该配置为ON的情况下,可以直接包含远程文件,若包含的变量为可控的情况下,可以直接控制变量来执行PHP代码。
  • 是否允许打开远程文件allow_url_open = on
允许本地PHP文件通过调用url重写来打开或者关闭写权限,默认的封装协议提供的ftp和http协议来访问文件。
  • HTTP头部版本信息expose_php = off
防止通过http头泄漏php版本信息。
  • 文件上传临时目录upload_tmp_dir =
上传文件临时保存的目录,如果不设置的话,则采用系统的临时目录。
  • 用户可访问目录open_basedir = D:\WWW
能够控制PHP脚本只能访问指定的目录,这样能够避免PHP脚本访问不应该访问的文件,一定程度上限制了。webshell的危害
  • 内部错误选项display_errors = on
表明实现PHP脚本的内部错误,网站发布后建议关不PHP的错误回显。
  • 错误报告级别error_reporting(E_ALL & ~Enotice)
具体列表推荐: https://www.runoob.com/php/func-error-reporting.html
这里设置的作用是将错误级别调到最高,显示所有问题,方便环境部署时候排错

五、 代码审计环境

PHP源码部署环境:Phpstudy 2018

集成开发环境:Zend Studio/Phpstorm

数据库管理工具:Navicat for MySQL 12

MySQL实时监控工具:MySQLMonitor

文本编辑工具:Sublime_Text3

代码审计辅助工具:Seay源代码审计系统、Search and Replace、Rips 0.55

代码审计辅助安全工具:渗透版火狐、BurpSuite、Sqlmap

六、手动调试代码

echo
exit();
print_r
var_dump();
debug_zval_dump();
debug_print_backtrace();
echo "<script>alert($estr);</script>"";
die("<script>alert($estr);</script>");

七、PHP的弱类型

1.比较符号 == 与 ===

  • == 在进行比较的时候,会先将字符串类型转化成相同,如果整型跟字符型比较字符或从左往右提取整型直到遇到字符结束,再比较。
  • === 在进行比较的时候,会先判断两种字符串的类型是否相等,当等号两边类型不同时,会先转换为相同的类型,再对转换后的值进行比较,如果比较一个数字和字符串或者涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照常数值进行比较.。
//字符串和数字比较
var_dump(0=="admin");   //true
echo '<br>';
var_dump(1=="1admin");  //true
echo '<br>';
var_dump(1=="admin1");  //false
echo '<br>';
var_dump(0=="admin1");  //true
echo '<br>';
//数字和数组
$arr = array();
var_dump(0==$arr);  //false
echo '<br>';
//字符串和数组
$arr = array();
var_dump("0"==$arr);    //false
echo '<br>';
//"合法数字+e+合法数字"类型的字符串
var_dump("0e123456"=="0e4456789");  //true
echo '<br>';
var_dump("1e1"=="10");  //true

2.array_search 与 is_array

  • is_array:判断传入的是不是一个数组。
  • array_search(x,$数组):在数组中寻找与指定值(x)相等的值,array_search函数 类似于"==",会进行类型的转换。
if(!is_array($_GET['test'])){
exit();
}
​
$test = $_GET['test'];
​
for($i = 0;$i<count($test) ;$i++ ){
if($test[$i] === "admin"){
echo "error";
exit();
}
$test[$i] = intval($test[$i]);
}
​
if(array_search("admin",$test) === 0){
echo "flag";
}else{
echo "false";
}

我们可以传入test[]=0来进行绕过,首先test是一个数组,符合is_array的判断,然后test=0;在array_search中0==admin为true,绕过了array_search

3.in_array()函数

  • array_search()与in_array()也是一样的问题。
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true

4.is_number()函数

  • 检测变量是否为数字或数字字符串,如果var是数字和数字字符串则返回TRUE,否则返回FALSE
$temp = $_GET['password'];
is_numeric($temp) ? die("no numeric") : NULL;
if($temp>9999){
echo '我giao';
}

在这里我们的payload需要的是一个大于9999的数字后面加上字符就可以了 这里构造的是10000+ 。

5.strcmp()函数

  • 比较函数如果两者相等返回0,string1>string2返回>0 反之小于0。在5.3及以后的php版本中,当strcmp()括号内是一个数组与字符串比较时,也会返回0。
$pd = "6666";
if(strcmp($_GET['pwd'],$pd) == 0){
echo "giao";
}else{
echo "?";
}

函数接受到了不符合的类型,发生了错误,但是还是判断其相等。

6.switch()语句

  • 如果switch是数字类型的case的判断时,switch会将参数转换为int类型
$pwd = "1ad";
switch($pwd){
case 1:
echo "giao";
break;
case 2:
echo "?";
break;
}

7.md5()函数

  • 0e开头的全部相等(绕过==判断),两个字符串转换成MD5值时都是0e开头,0e 纯数字这种格式的字符串在判断相等的时候会被认为是科学计数法的数字,先做字符串到数字的转换。
  • md5()中的需要是一个string类型的参数。但是当你传递一个array时,md5()`不会报错,只是会无法正确地求出array的md5值,返回false,这样就会导致任意2个array的md5值都会相等。
var_dump(md5('240610708') == md5('QNKCDZO'));//true
​
$array1=[1,2,3];
$array2=[4,5,6];
var_dump(md5($array1)===md5($array2)) //true

8.sha1()函数

  • sha1函数和md5函数一样不能判断数组的值。
$array1=[1,2,3];
$array2=[4,5,6];
​
var_dump(sha1($array1)===sha1($array2)); //true

9.empty与isset

  • 变量为:0,"0",null,'',false,array()时,使用empty函数,返回的都是true
  • 变量未定义或者为null时,isset函数返回的为false,其他都为true
$a = null;
$b = 0;
$c = "";
var_dump(empty($a));
var_dump(empty($b));
var_dump(empty($c));
var_dump(isset($a));
var_dump(isset($b));
var_dump(isset($c));

10.类型比较问题以及类型转换问题

此处推荐文章:https://www.jb51.net/article/93447.htm

八、学习漏洞函数

1.全局变量/超全局变量

全局变量:

  • 定义在函数外部的就是全局变量,它的作用域从定义处一直到文件结尾。
  • 函数内定义的变量就是局部变量,它的作用域为函数定义范围内。
  • 函数之间存在作用域互不影响。
  • 函数内访问全局变量需要 global关键字或者使用 $GLOBALS[index]数组。

超全局变量:

  • 超全局变量 在 PHP 4.1.0 中引入,是在全部作用域中始终可用的内置变量。
  • PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们。

常用的超全局变量有9个:

  • $GLOBALS
  • $_SERVER
  • $_REQUEST
  • $_POST
  • $_GET
  • $_FILES
  • $_ENV
  • $_COOKIE
  • $_SESSION

此处推荐文章:https://blog.csdn.net/zhichaosong/article/details/80507516

2.SQL注入

select
update
insert into
delete

注:此处非函数,主要找常用的SQL语句

3.代码执行

eval()
usort()
uasort()
assert()
array_map()
preg_replace()
array_filter()
call_user_func()
create_function()
call_user_func_array()
文件操作函数:
fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>'); 
动态函数:$_GET['a']($_GET['b'])

4. 命令执行

system()
exec()
passthru()
shell_exec()

5. XSS跨站脚本攻击

print
print_r
echo
printf
die
var_dump
var_export

6.文件上传漏洞

move_uploaded_file()

7.文件包含漏洞

include()
include_once()
require()
require_once()

伪协议

file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流

此处推荐文章:https://segmentfault.com/a/1190000018991087

8.任意文件下载

fopen()
readfile()
file_get_contents()

9.任意文件删除

unlink()

10.任意文件读取

file()
fgets()
fgetss()
fopen()
readfile()
fpassthru()
parse_ini_file()
file_get_contents()

11.变量覆盖

$$
extract()
parse_str()
import_request_variables()//此函数只能用于PHP4.1 ~ PHP5.4

12.反序列化漏洞

unserialize()

魔术方法

  • __construct()//每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作
  • __destruct()//某个对象的所有引用都被删除或者当对象被显式销毁时执行
  • __call() //在对象上下文中调用不可访问的方法时触发
  • __callStatic() //在静态上下文中调用不可访问的方法时触发
  • __get() //用于从不可访问的属性读取数据
  • __set() //用于将数据写入不可访问的属性
  • __isset() //在不可访问的属性上调用isset()或empty()触发
  • __unset() //在不可访问的属性上使用unset()时触发
  • __sellp() //使用serialize时触发
  • __wakeup() //使用unserialize时触发
  • __toString() //把类当作字符串使用时触发
  • __invoke() //当脚本尝试将对象调用为函数时触发
  • __set_state()//当调用 var_export() 导出类时,此静态方法会被自动调用。
  • __clone()//当使用 clone 复制一个对象时自动调用
  • __debuginfo()//使用 var_dump() 打印对象信息时自动调用

九、审计入门总结

先从Web漏洞原理开始理解再到漏洞的挖掘以及利用,我们就来到了PHP代码审计这个方向进行进修。这里我们开始学习PHP开发,以及熟悉下开发者的开发思想,站在开发者角度去思索代码。再是掌握漏洞对应发生函数使用,再是学习正则表达式。

审计路线:Demo->综合漏洞靶场->网上审计过的CMS->多入口CMS->单入口CMS->框架->函数缺陷

推荐一些demo:

  • https://github.com/bowu678/php_bugs
  • https://github.com/hongriSec/PHP-Audit-Labs
  • https://github.com/Xyntax/1000php
  • https://github.com/SukaraLin/php_code_audit_project‘

文章转载自:Saint Michael

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1158857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧校园地下管线三维可视化管控平台减少人力和物力资源的浪费

随着科技的不断发展&#xff0c;三维可视化管理平台在各个领域得到了广泛的应用。三维可视化管理平台通过将数据以三维形式呈现&#xff0c;使得用户能够更直观地理解和分析数据&#xff0c;从而提高工作效率和决策质量。 VR数字孪生园区系统是通过将实际园区的各种数据和信息进…

开关电源老化试验和性能检测系统软件

开关电源自动测试系统由PC(工控机)、测试工装、可编程直流电源、数字示波器、可编程直流电子负载、继电器模块等部分组成&#xff0c;并通过RS232/LAN通讯总线、测试夹具以及其它线缆等进行连接&#xff0c;为系统组成结构。PC与可编程直流电源、数字示波器、可编程直流电子负载…

c++装饰器模式

前言 装饰器模式&#xff0c;就是可以对一个对象无限装饰一些东西&#xff0c;而且可以没有顺序。比如一个人可能只会说出他的名字&#xff0c;但是可以让他再说哈哈&#xff0c;可以说完哈哈之后再说哇哇。如何后面又不想装饰了&#xff0c;不需要改类原来的代码&#xff0c;…

什么是数字展览馆,数字展览馆有什么应用前景

引言&#xff1a; 数字展览馆作为一种新兴的文化艺术展示形式&#xff0c;以数字化技术和虚拟现实为基础&#xff0c;正在逐渐改变传统展览的方式。 一、什么是数字展览馆&#xff1f; 1.定义 数字展览馆是利用数字技术和虚拟现实技术打造的一种线上文化艺术展示平台。通过虚…

基于springboot实现疫情防控期间外出务工人员信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot疫情防控期间外出务工人员信息管理系统 摘要 网络的广泛应用给生活带来了十分的便利。所以把疫情防控期间某村外出务工人员信息管理与现在网络相结合&#xff0c;利用java技术建设疫情防控期间某村外出务工人员信息管理系统&#xff0c;实现疫情防控期间某村外出…

《完蛋!我被美女包围了》突然火了!世界首个开源贡献榜出炉丨 RTE 开发者日报 Vol.75

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

我的天!阿里云服务器居然比腾讯云优惠1元!

2023阿里云服务器优惠活动来了&#xff0c;以前一直是腾讯云比阿里云优惠&#xff0c;阿里云绝地反击&#xff0c;放开老用户购买资格&#xff0c;99元服务器老用户可以买&#xff0c;并且享受99元续费&#xff0c;阿腾云亲测可行&#xff0c;大家抓紧吧&#xff0c;数量不多&a…

Mac上的iTerm2和Oh My Zsh 的安装(安装过程和失败详解)

前言&#xff08;无重点&#xff0c;安装往后看&#xff09; 由于在很多人的安利下&#xff0c;说很好用&#xff0c;作者今天花费了4个小时用血的教训总结出来的安装教程&#xff0c;我在安装过程中遇到的最大的问题就是 1. curl: (7) Failed to connect to raw.githubusercon…

电影《河边的错误》观后感

上周看了电影《河边的错误》&#xff0c;整部电影看介绍&#xff0c;是改编余华的小说&#xff0c;并且获得多种奖项&#xff0c;一般来说&#xff0c;差不了&#xff0c;看完之后&#xff0c;只能说&#xff0c;看得有些云里雾里的&#xff0c;看似最后主角抓到了罪犯&#xf…

STM32循迹小车原理介绍和代码示例

目录 1. 循迹模块介绍 2. 循迹小车原理 3. 循迹小车核心代码 4. 循迹小车解决转弯平滑问题 1. 循迹模块介绍 TCRT5000传感器的红外发射二极管不断发射红外线当发射出的红外线没有被反射回来或被反射回来但强度不够大时红外接收管一直处于关断状态&#xff0c;此时模块的输出…

被这7款在线涂鸦画板惊艳到,手残也能画出涂鸦大片!

作为一名涂鸦爱好者或者手帐达人&#xff0c;你是否在寻找好用的在线涂鸦画板软件呢&#xff1f;涂鸦画板软件释放了创造性的无限可能&#xff0c;让你能够将想法转化为令人惊叹的视觉效果&#xff0c;并轻松地与客户、同行和全球观众分享你的作品。 在这篇文章中&#xff0c;…

Redis之 redis.config配置文件

文章目录 前言一、基本配置1.单位2.包含3.网络配置4.通用5.快照6.安全7.限制8.仅追加模式 二、总体主要介绍总结 前言 行家一出手&#xff0c;就知有没有&#xff0c;让一起学习redis.config配置文件。 一、基本配置 Redis 的配置文件位于 Redis 安装目录下&#xff0c;文件名…

android 13 write javaBean error at *** 错误

报错代码&#xff1a;红框处。 注意&#xff1a;android10 不会报错&#xff0c;运行正常。android13就报错 错误原因&#xff1a;对象中VerifyDownloadEntity&#xff0c;有个Bitmap成员变量 public class VerifyDownloadEntity {private Bitmap bitmap;private String cooki…

SpringBoot 及 配置文件

一、什么是 SpringBoot&#xff1f; Spring 是包含了众多工具的IoC容器&#xff0c;Spring Boot 是 Spring 的脚手架&#xff0c;是为了快速开发 Spring 而创建的一个框架。 二、Spring Boot 优点 快速集成框架&#xff0c;Spring Boot 提供了启动添加依赖的功能&#xff0c…

centos7安装oxidized备份软件

首先需要提前下载ruby&#xff0c;因为默认yum安装的版本太低 https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.gz 1、yum remove ruby ruby-devel&#xff08;有就卸载&#xff0c;没有则忽略&#xff09; 2、将下载好的ruby包解压到/opt下 [rootoxidized ruby-…

Cesium:CGCS2000坐标系的xyz坐标转换成WGS84坐标系的经纬高度,再转换到笛卡尔坐标系的xyz坐标

作者:CSDN @ _乐多_ 本文将介绍使用 Vue 、cesium、proj4 框架,实现将CGCS2000坐标系的xyz坐标转换成WGS84坐标系的经纬高度,再将WGS84坐标系的经纬高度转换到笛卡尔坐标系的xyz坐标的代码。并将输入和输出使用 Vue 前端框架展示了出来。代码即插即用。 网页效果如下图所示…

Boris FX Silhouette 2023.0.3(影视后期)

Silhouette mac是一种视觉表现形式&#xff0c;通常用于描绘物体或人物的轮廓。它可以通过填充与背景形成鲜明的对比&#xff0c;从而使轮廓更加清晰明了。Silhouette 是一种简约而又具有艺术感的表现方式&#xff0c;常用于绘画、摄影和设计领域。 在绘画中&#xff0c;Silho…

springboot之拦截器、servlet过滤器

一 使用maven新建Spring Boot项目 1. File --> New --> Project... --> Maven &#xff0c;如下图所示 Project SDK下拉列表框中选择前面安装的 Java1.8&#xff0c;如果下拉列表框中不存在Java 1.8&#xff0c;可以单击New按钮&#xff0c;找到安装Java的位置&…

第22期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

激光雷达标定板提高自主驾驶功能的感知精度

激光雷达&#xff08;LiDAR&#xff09;是一种通过发射激光束并测量反射回来的时间来测量目标距离和形状的传感器。为了提高激光雷达的感知精度和稳定性&#xff0c;需要进行激光雷达标定&#xff0c;以确定其激光束的准确性和稳定性。 如果没有激光雷达&#xff0c;自动驾驶的…