PHP代码审计分段讲解(12)
28题
<!DOCTYPE html>
<html>
<head>
<title>Web 350</title>
<style type="text/css">
body {
background:gray;
text-align:center;
}
</style>
</head> <body>
<?php
$auth = false;
$role = "guest";
$salt =
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"])))
// strrev返回 string 反转后的字符串。
{
$auth = true;
} else {
$auth = false;
}
} else {
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
if ($auth) {
echo "<h3>Welcome Admin. Your flag is
} else {
echo "<h3>Only Admin can see the flag!!</h3>";
}
?> </body>
这个题目出处应该是Jarvis OJ中的flag在管理员手里,题目地址在:http://web.jarvisoj.com:32778/
简单分析一下代码:
$auth = false;
$role = "guest";
$salt =
首先给三个变量赋值,$auth和$role的值是我们可见的,$salt应该是后端赋值而我们不可见。
接着在COOKIE中传输role,并且将其反序列化的值赋给role
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
接着是给hsh赋值
$hsh = $_COOKIE["hsh"];
然后是一个判断,进而给auth赋值
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"])))
// strrev返回 string 反转后的字符串。
{
$auth = true;
} else {
$auth = false;
}
我们看到最后想要获取flag需要 $auth为真
if ($auth) {
echo "<h3>Welcome Admin. Your flag is xxx"
} else {
echo "<h3>Only Admin can see the flag!!</h3>";
}
即我们需要满足这个条件
$role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))
如果COOKIE中没有role的话,就进入else,使用代码最开始赋值的auth和role进行以下操作
else {
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
但else里面的操作正常来说是不能拿到flag的
所以我们需要突破的是:
$role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))
先看后面的一个比较:
$hsh === md5($salt.strrev($_COOKIE["role"]))
左边的$hsh是我们COOKIE中传递过去的$hsh 哈希值
右边是使用盐值和反转后的传过去的role值连接后,并进行md5加密的结果,需要与$hsh相等
这里看上去是无懈可击的,虽然我们可以传递hsh和role的值,但是因为我们不知道盐值,所以得到的md5很难凭猜或者爆破来令其与hsh相等。
但是如MD5,SHA1, SHA2等,都是基于Merkle–Damgård结构,而这类算法的问题在于:如果你知道加密前的原文,和加密后的密文,只需要再知道盐值的长度,就能在原文后面添加信息并计算出相应的密文。
在pcat的博文中介绍过应用场景为:
如果一个应用程序是这样操作的:
准备了一个密文和一些数据构造成一个字符串里,并且使用了MD5之类的哈希函数生成了一个哈希值(也就是所谓的signature/签名)
让攻击者可以提交数据以及哈希值,虽然攻击者不知道密文
服务器把提交的数据跟密文构造成字符串,并经过哈希后判断是否等同于提交上来的哈希值
这个时候,该应用程序就易受长度扩展攻击
另外,只有盐值在前,原文在后,才可以用hash长度扩展攻击。
预测得到的是:
md5(盐+原文+填充+恶意扩充)
算法原理在这篇文章中非常详细了,具体可移步:
https://www.freebuf.com/articles/web/31756.html
哈希长度扩展攻击我们通常使用HashPump进行利用
HashPump是一个借助于OpenSSL实现了针对多种散列函数的攻击的工具,支持针对MD5、CRC32、SHA1、SHA256和SHA512等长度扩展攻击。而MD2、SHA224和SHA384算法不受此攻击的影响,因其部分避免了对状态变量的输出,并不输出全部的状态变量。
其安装过程为:
git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install
对于该题,我们先进行抓包,获取初始哈希值

role进行url解码后为:
s:5:"guest";
hsh为
3a4727d57463f122833d9e732f94e4e0
这里还利用了PHP反序列化unserialize的一个特性,即
unserialize()会忽略多余的字符
举例代码为:
<?php
$s = 's:5:"admin"; s:5:"guest";';
echo unserialize($s);
?>
输出结果为:

可以看出后面的
s:5:"guest";
并没有进行反序列化,而是被忽略了,这也是我们使用填充字符进行哈希长度扩展攻击的关键。
另外我们虽然不知道盐值的长度,但是我们可以进行逐个尝试

将获得的结果反序后重放

尝试得到盐值的长度为12,获得flag
这里其实可以写一个脚本进行尝试,这样可以快很多,减少体力劳动
参考链接:
https://www.freebuf.com/articles/web/31756.html
https://www.cnblogs.com/pcat/p/5478509.html
https://blog.csdn.net/zpy1998zpy/article/details/80858080
https://www.jianshu.com/p/af6c0bb5ae3a
https://blog.cindemor.com/post/ctf-web-19.html
PHP代码审计分段讲解(12)的更多相关文章
- PHP代码审计分段讲解(14)
30题利用提交数组绕过逻辑 本篇博客是PHP代码审计分段讲解系列题解的最后一篇,对于我这个懒癌患者来说,很多事情知易行难,坚持下去,继续学习和提高自己. 源码如下: <?php $role = ...
- PHP代码审计分段讲解(13)
代码审计分段讲解之29题,代码如下: <?php require("config.php"); $table = $_GET['table']?$_GET['table']: ...
- PHP代码审计分段讲解(11)
后面的题目相对于之前的题目难度稍微提升了一些,所以对每道题进行单独的分析 27题 <?php if(!$_GET['id']) { header('Location: index.php?id= ...
- PHP代码审计分段讲解(9)
22 弱类型整数大小比较绕过 <?php error_reporting(0); $flag = "flag{test}"; $temp = $_GET['password' ...
- PHP代码审计分段讲解(8)
20 十六进制与数字比较 源代码为: <?php error_reporting(0); function noother_says_correct($temp) { $flag = 'flag ...
- PHP代码审计分段讲解(5)
11 sql闭合绕过 源代码为 <?php if($_POST[user] && $_POST[pass]) { $conn = mysql_connect("**** ...
- PHP代码审计分段讲解(1)
PHP源码来自:https://github.com/bowu678/php_bugs 快乐的暑期学习生活+1 01 extract变量覆盖 <?php $flag='xxx'; extract ...
- PHP代码审计分段讲解(10)
26 unserialize()序列化 <!-- 题目:http://web.jarvisoj.com:32768 --> <!-- index.php --> <?ph ...
- PHP代码审计分段讲解(7)
17 密码md5比较绕过 <?php if($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ': ...
随机推荐
- char和signed char不同编译器下的使用反思
遇到一个问题,在使用一个算法的时候出现了仿真正常,但是在使用时出现函数的返回数据只有正值的异常. 在定位算法问题的时候,由算法函数最后的返回值由后向前推,最后发现问题在与char类型的值在不同编译器下 ...
- leetcode Reverse Nodes in k-Group翻转链表K个一组
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. k ...
- 查找数组中第k大的数
问题: 查找出一给定数组中第k大的数.例如[3,2,7,1,8,9,6,5,4],第1大的数是9,第2大的数是8-- 思考:1. 直接从大到小排序,排好序后,第k大的数就是arr[k-1]. 2. ...
- cephfs元数据池故障的恢复
前言 cephfs 在L版本已经比较稳定了,这个稳定的意义个人觉得是在其故障恢复方面的成熟,一个文件系统可恢复是其稳定必须具备的属性,本篇就是根据官网的文档来实践下这个恢复的过程 实践过程 部署一个c ...
- JS简单介绍与简单的基本语法
1.JavaScirpt是一门编程语言,是为前端服务的一门语言. (1)基础语法 (2)数据类型 (3)函数 (4)面向对象 2.还涉及到BOM和DOM (1)BOM(操作浏览器的一些功能) (2)D ...
- 08 . Vue脚手架安装,使用,自定义配置和Element-UI导入使用
Vue脚手架 Vue脚手架可以快速生成Vue项目基础的架构. 安装3.x版本的Vue脚手架 /* npm install -g @vue/cli@3.3 */ 基于3.3版本的脚手架命令创建Vue项目 ...
- web安全原理分析-SQL注入漏洞全解
简介 靶场:榆林学院信息安全协会--入侵榆大实验靶场 数字型注入 1 字符型注入 1 布尔注入 1.布尔注入简介 mysql bool注入是盲注的一种.与报错注入不同,bool注入没有任何报错信息输出 ...
- Python:利用Entrez库筛选下载PubMed文献摘要
一个不是学生物的孩子来搞生物,当真是变成了一块废铁啊,但也是让我体会到了一把生物信息的力量. 废话不多说,开整! 任务:快速高效从PubMed上下载满足条件的文献PMID.标题(TI).摘要(AB). ...
- 不想错过网课?不妨用Camtasia录制下来!
2020年突发的这场疫情给我们的日常生活与学习带来了一些不便,却也意外的让网课走红了起来.小学.中学.大学都开始通过媒体工具或直播平台开始授课,但网络授课与实际课堂上课还是有区别的,学生们受到环境影响 ...
- 用Camtasia设计微课视频封面,让课程更加高大上
在网络时代,尤其现在疫情影响只能线上学习,微课的应用前景已经越来越广了.但是想把微课做好,只有内容与录制精细是不够的,还需要一个精美的封面来吸引学生.接下来,小编就用微课制作软件Camtasia 20 ...