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的博文中介绍过应用场景为:

如果一个应用程序是这样操作的:

  1. 准备了一个密文和一些数据构造成一个字符串里,并且使用了MD5之类的哈希函数生成了一个哈希值(也就是所谓的signature/签名)

  2. 让攻击者可以提交数据以及哈希值,虽然攻击者不知道密文

  3. 服务器把提交的数据跟密文构造成字符串,并经过哈希后判断是否等同于提交上来的哈希值

这个时候,该应用程序就易受长度扩展攻击

另外,只有盐值在前,原文在后,才可以用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://skysec.top/2017/08/16/jarvisoj-web/#flag%E5%9C%A8%E7%AE%A1%E7%90%86%E5%91%98%E6%89%8B%E9%87%8C

http://yulige.top/?p=271

https://blog.cindemor.com/post/ctf-web-19.html

PHP代码审计分段讲解(12)的更多相关文章

  1. PHP代码审计分段讲解(14)

    30题利用提交数组绕过逻辑 本篇博客是PHP代码审计分段讲解系列题解的最后一篇,对于我这个懒癌患者来说,很多事情知易行难,坚持下去,继续学习和提高自己. 源码如下: <?php $role = ...

  2. PHP代码审计分段讲解(13)

    代码审计分段讲解之29题,代码如下: <?php require("config.php"); $table = $_GET['table']?$_GET['table']: ...

  3. PHP代码审计分段讲解(11)

    后面的题目相对于之前的题目难度稍微提升了一些,所以对每道题进行单独的分析 27题 <?php if(!$_GET['id']) { header('Location: index.php?id= ...

  4. PHP代码审计分段讲解(9)

    22 弱类型整数大小比较绕过 <?php error_reporting(0); $flag = "flag{test}"; $temp = $_GET['password' ...

  5. PHP代码审计分段讲解(8)

    20 十六进制与数字比较 源代码为: <?php error_reporting(0); function noother_says_correct($temp) { $flag = 'flag ...

  6. PHP代码审计分段讲解(5)

    11 sql闭合绕过 源代码为 <?php if($_POST[user] && $_POST[pass]) { $conn = mysql_connect("**** ...

  7. PHP代码审计分段讲解(1)

    PHP源码来自:https://github.com/bowu678/php_bugs 快乐的暑期学习生活+1 01 extract变量覆盖 <?php $flag='xxx'; extract ...

  8. PHP代码审计分段讲解(10)

    26 unserialize()序列化 <!-- 题目:http://web.jarvisoj.com:32768 --> <!-- index.php --> <?ph ...

  9. PHP代码审计分段讲解(7)

    17 密码md5比较绕过 <?php if($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ': ...

随机推荐

  1. JavaScript ES 模块:现代化前端编程必备技能

    自从 ES 模块被添加到规范中后,JavaScript 中的模块就更加简单了.模块按文件分开,异步加载.导出是用 export 关键字定义的:值可以用 import 关键字导入. 虽然导入和导出单个值 ...

  2. kudu集群:kudu_master、kudu_tserver服务及数据的迁移(根据官网总结)

    是不是都需要一个声明,来一个: 声明: 本文只是总结本人本地模拟环境测试,并没有经过严格的线上测试.请自己在本地严格测试之后慎重使用在生产环境! kudu_master.kudu_tserver服务迁 ...

  3. 论文阅读:Learning Attention-based Embeddings for Relation Prediction in Knowledge Graphs(2019 ACL)

    基于Attention的知识图谱关系预测 论文地址 Abstract 关于知识库完成的研究(也称为关系预测)的任务越来越受关注.多项最新研究表明,基于卷积神经网络(CNN)的模型会生成更丰富,更具表达 ...

  4. 预训练模型——开创NLP新纪元

    预训练模型--开创NLP新纪元 论文地址 BERT相关论文列表 清华整理-预训练语言模型 awesome-bert-nlp BERT Lang Street huggingface models 论文 ...

  5. Selective Acknowledgment 选项 浅析 2

    来自:http://abcdxyzk.github.io/blog/2013/09/06/kernel-net-sack/ static int tcp_sacktag_write_queue(str ...

  6. Android状态栏与布局重叠解决方案

    问题起因: 同组的同事将项目全局设置成了沉浸式,对于我这个半路过来开发的人 可真是头疼呵~ 没办法,那就我自己添加一个头吧.也可以在布局中取消沉浸式,不过我这个是在fragment中,为了不修改之前的 ...

  7. Python生成csv中文乱码解决办法

    前言 在Linux下面用python进行数据处理,然后输出为csv格式,如果没有中文一切正常,但是如果有中文,就会出现乱码的问题,本篇将讲述怎么处理这个问题 处理过程 原始代码 #!/usr/bin/ ...

  8. Python_俄罗斯方块

    网上资料,仅供学习,希望以后自己也能看懂再改进下... """ 俄罗斯方块 author: wolfstar last edited: 2018年1月 "&qu ...

  9. ISITDTU CTF 2020 部分Web题目Writeup

    周末,跟着m3w师傅打ISITDTUCTF,m3w师傅带弟弟上分,Tql! Web1 给了源码: <?php class Read{ public $flag; public function ...

  10. 7、Spring Boot检索

    1.ElasticSearch简介 Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard(分片)的方式保证数据安全,并且提供自动resha ...