secskill
  • Introduction
  • 1.web应用漏洞
    • 1.1 SQL注入漏洞
      • 1.1.1 type注入利用
      • 1.1.2 mothod注入利用
      • 1.1.3 按照效果注入利用
      • 1.1.4 order,limit和from后的注入
      • 1.10.1 sqlmap使用
    • 1.2 目录遍历漏洞
    • 1.3 跨站脚本漏洞
      • 1.3.10 flash xss
      • 1.3.11 Uxss
    • 1.4 未过滤HTML代码漏洞
    • 1.5 数据库运行出错
    • 1.6 Flash安全配置缺陷漏洞
    • 1.7 编辑器漏洞
      • 1.7.1 kindeditor编辑器漏洞
        • 1.7.1.1 kindeditor<=4.1.5文件上传漏洞
      • 1.7.2 fckeditor编辑器漏洞
        • 1.7.2.1 fckeditor<=2.6.4文件上传漏洞
    • 1.8 URL Redirect漏洞
    • 1.9 任意文件上传漏洞
    • 1.10 敏感信息泄露漏洞
    • 1.11 未加密登陆请求漏洞
    • 1.12 后台弱口令漏洞
    • 1.13 后台口令暴力破解漏洞
    • 1.14 跨站请求伪造漏洞
    • 1.15 Unicode 编码转换漏洞
    • 1.16 Possible .Net Error Message
    • 1.17 发生内部错误漏洞
    • 1.18 旁站攻击漏洞
    • 1.19 后台登录页面绕过
    • 1.20 Possible PHP Error Message
    • 1.21 UrlPath Pollution
    • 1.22 File Operation-Web.xml漏洞
    • 1.23 短文件名泄漏漏洞
    • 1.24 OS注入漏洞
    • 1.25 SOAP注入漏洞
    • 1.26 SMTP注入漏洞
    • 1.27 LDAP注入漏洞
    • 1.28 命令执行漏洞
    • 1.29 HTTP消息头注入漏洞
    • 1.30 验证机制缺陷漏洞
    • 1.31 越权漏洞
    • 1.31 服务端请求伪造漏洞
    • 1.32 xxe漏洞
    • 1.33 逻辑漏洞
    • 1.34 支付漏洞
      • 1.34.1 支付漏洞
    • 1.35 cors漏洞
      • 1.35.1 cors
    • 1.36 jsonp漏洞
    • 1.37 点击劫持漏洞
    • 1.38 框架注入漏洞
    • 1.39 文件包含漏洞
    • 1.40 CRLF注入漏洞
    • 1.41 SSTI漏洞
  • 2.中间件漏洞
    • 2.1 IIS
      • 2.1.1 CVE-2017-7269
    • 2.2 Apache
    • 2.3 Axis2
    • 2.4 lighttpd
    • 2.5 Tomcat
      • 2.5.1 CVE-2017-12615
    • 2.6 Nginx
    • 2.7 WebLogic
    • 2.8 JBoss
    • 2.9 Websphere
    • 2.10 Struct2
    • 2.11 XAMMP
    • 2.12 LAMPP
    • 2.13 FastCGI
    • 2.14 PHPCGI
    • 2.15 JOnAS
    • 2.16 Joomla
      • 2.16.1 CVE-2017-8917
    • 2.17 Padding oracle
    • 2.18 Jenkins
      • 2.18.1 CVE-2019-1003000
      • 2.18.2 CVE-2017-1000353
    • 2.18 Drupal
      • 2.18.1 CVE-2019-6340l
    • 2.19 PHPGD
      • 2.19.1 CVE-2019-6977
    • 2.20 PhpMyAdmin
      • 2.20.1 CVE-2016-5734
      • 2.20.2 反序列化漏洞
      • 2.20.3 CVE-2018-12613
    • 2.21 PHP
      • 2.21.1 extract
      • 2.21.2 strcmp
      • 2.21.3 urldecode
      • 2.21.4 md5
      • 2.21.5 strpos
      • 2.21.6 is_numeric
      • 2.21.7 sha
      • 2.21.7 ereg
      • 2.21.8 creat
  • 3.系统漏洞
    • 3.1 DNS域传送漏洞
    • 3.2 SSH Services Port 22 Enabled
    • 3.3 NetBIOS Services Port 139 Enabled
    • 3.4 OpenSSL 漏洞
    • 3.5 docker remote API漏洞
    • 3.6 Samba远程代码执行漏洞
    • 3.7 Windows系统漏洞
      • 3.7.1 ms17-010
      • 3.7.2 ms08-067
      • 3.7.3 ms16-075
      • 3.7.4 CVE-2017-0213
      • 3.7.5 ms16-135
      • 3.7.6 CVE-2018-8120
      • 3.7.7 CVE-2018-0824
    • 3.8 linux系统漏洞
      • 3.8.1 ubuntu
        • 3.8.1.1 CVE-2015-1328
        • 3.8.1.2 CVE-2017-16995
    • 3.9 openssh漏洞
      • 3.9.1 cve-2016-6515
  • 4.网络漏洞
    • 4.1 ARP欺骗嗅探漏洞
    • 4.2 反弹shell的N种姿势
    • 4.3 DNS欺骗
  • 5.cms漏洞
    • 5.1 08cms
    • 5.2 74cms
    • 5.3 Appcms
    • 5.4 Aspcms
    • 5.5 Bluecms
    • 5.6 Cscms
    • 5.7 Dedecms
    • 5.8 Discuz
      • 5.8.1 Discuz任意文件删除
    • 5.9 Dkcms
    • 5.10 Ecshop
    • 5.11 Finecms
    • 5.12 Fscms
    • 5.13 Jeecms
    • 5.14 Ibcms
    • 5.15 Maccms
    • 5.16 Php168
    • 5.17 Phpcms
    • 5.18 Phpmywind
    • 5.19 Phpwind
    • 5.20 Phpweb
    • 5.21 Qibocms
    • 5.22 Seacms
    • 5.23 Shopex
    • 5.24 Thinkphp
      • 5.24.1 SQL
      • 5.24.2 RCE
      • 5.24.3 RCE2
    • 5.25 Typecho
    • 5.26 Wordpress
      • 5.26.1 Wordpress Plugin_sql
    • 5.27 Xycms
    • 5.28 Zabbix
    • 5.29 Zblog
    • 5.30 Zzcms
Powered by GitBook
On this page
  • md5()
  • Raw MD5 Hash引发的注入
  • 实例
  • md5 碰撞相关问题
  • 修复建议

Was this helpful?

  1. 2.中间件漏洞
  2. 2.21 PHP

2.21.4 md5

md5()

md5()函数使用参考

md5 — 计算字符串的 MD5 散列值

string md5( string $str[, bool $raw_output = false] )


参数 

str
原始字符串。 
raw_output
如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。 


返回值 

以 32 字符十六进制数字形式返回散列值。

示例代码:

<?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';
}
?>

代码审计需要满足两个条件:1. username和password的值不能相同

2. username和password的MD5值相同 利用MD5函数不能处理数组进行构造payload

Raw MD5 Hash引发的注入

根据描述

如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。

先来看下效果:

class LoginManager {
  private $em;
  private $user;
  private $password;

  public function __construct($user, $password) {
    $this->em = DoctrineManager::getEntityManager();
    $this->user = $user;
    $this->password = $password;
  }

  public function isValid() {
    $user = $this->sanitizeInput($this->user);
    $pass = $this->sanitizeInput($this->password);

    $queryBuilder = $this->em->createQueryBuilder()
      ->select("COUNT(p)")
      ->from("User", "u")
      ->where("user = '$user' AND password = '$pass'");
    $query = $queryBuilder->getQuery();
    return boolval($query->getSingleScalarResult());
  }

  public function sanitizeInput($input, $length = 20) {
    $input = addslashes($input);
    if (strlen($input) > $length) {
      $input = substr($input, 0, $length);
    }
    return $input;
  }
}

$auth = new LoginManager($_POST['user'], $_POST['passwd']);
if (!$auth->isValid()) {
  exit;
}

从 第17行-20行 代码中明显存在SQL语句拼接的形式,而 $pass 变量和 $user 变量是在 第30-31行 中通过 POST 方式由用户进行控制。这里很明显存在SQL注入漏洞

程序代码 第14行 调用 sanitizeInput 函数针对用户输入的 $user 变量进行了处理,跟进一下 sanitizeInput 函数,在 第25行 找到这个函数,这个函数的作用就是调用 addslashes 函数针对输入数据进行处理。

所以按照这种情况下这个地方,似乎不存在注入点了,先别急,我们继续往下看,我们看到 第13行 代码针对用户输入 password 的值调用 md5 函数进行相关处理

我们知道我可以控制的点有两个变量,一个是 $user ,一个是 $pass ,$pass 经过了 md5 的处理,但是返回字段不是标准的md5值,$user 经过了 addslashes 函数的处理,无法引入特殊符号去闭合。这里做个假设,如果我们经过 $pass = md5($this->password, true); 处理之后的值逃逸出一个反斜杆,那么实际上带入到数据库的值就如下所示:

select count(p) from user s where password='xxxxxx\' and user='xxx#'

如果这种情况发生,实际上也存在了SQL注入。我们尝试fuzz一下,看看会不会存在某个值经过了 md5(xxx, true) 处理之后,最后一位是反斜杠。

我们针对1-1000进行一下fuzz,发现 md5(128, true) 最后的结果带有反斜杠。因此这题最后的payload如下:

user= OR 1=1#&passwd=128

带入到数据库查询的语句如下:

select count(p) from user s where password='v�an���l���q��\' and user=' OR 1=1#'

实例

$password=$_POST['password'];
    $sql = "SELECT * FROM admin WHERE username = 'admin' and password = '".md5($password,true)."'";
    $result=mysqli_query($link,$sql);
        if(mysqli_num_rows($result)>0){
            echo 'flag is :'.$flag;
        }
        else{
            echo '密码错误!';
        }

从上图中的代码中的 第5行 可以看到,当查询结果返回大于0的时候,就会输出 flag ,我们前面分析过当 md5 函数的 $raw_output 设置会true的时候, md5 函数返回前16字节长度的原始二进制,然后再将二进制转换成字符串,这种情况下可能会引入单引号等特殊字符。

有人尝试过破解这个类型的字符,目前已知两个是 ffifdyop 和129581926211651571912466741651878684928 ,我们来看看实际效果。

原先:SELECT * FROM admin WHERE username = 'admin' and password = 'md5($password,true)'
变成:SELECT * FROM admin WHERE username = 'admin' and password = ''or'6\xc9]\x99'

由于 and 运算符优先级比 or 高,所以前面的:id=1000 and password = '' 会先执行,然后将执行结果与后面的 '6\xc9]\x99' 进行 or 运算。在布尔运算中,除了 0、'0'、false、null ,其余结果都为真。所以整个 SQL 语句的 where 条件判断部分为真,这样可定就能查出数据。

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";}
?>

思路很明确,a的值不能等于QNKCDZO但是a经过md5后的值必须与QNKCDZO的值相等

因为php 0e开头的字符串都是==的,不是===

如:

var_dump("0e462097431906854"=="0e83040041");

上面这个返回true,如果题目的md5是0e开头的,

如

md5('240610708') 的结果是:0e462097431906509019562988736854 
md5('QNKCDZO') 的结果是:0e830400451993494058024219903391

还有240610708、QNKCDZO、aabg7XSs、aabC9RqS

所以我们传递任意一个进去即可(当为===时不可以)

===时可以参考

修复建议

建议在使用 md5 函数的时候,不要将 $raw_output 字段设置为true 。

Previous2.21.3 urldecodeNext2.21.5 strpos

Last updated 6 years ago

Was this helpful?

http://123.206.87.240:9009/18.php?username[]=6&password[]=2
https://xz.aliyun.com/t/2232