[BJDCTF2020]Easy MD5-学习笔记

发布时间:2026/8/2 4:33:38
[BJDCTF2020]Easy MD5-学习笔记 前置知识1、PHP 松散比较 vs 2、 0e 绕过正文一、代码审计md5函数知识点讲解二、构造请求参数三、PHP 松散比较四、构造数组实现MD5 绕过五、PHP 严格比较1、为什么 0e 绕过在这里失效2、为什么数组绕过仍然有效六、构造数组实现MD5 绕过前置知识1、PHP 松散比较vsPHP 有两种比较运算符松散比较只比较值会进行类型转换严格比较同时比较值和类型不会进行类型转换2、0e绕过当一个字符串的 MD5 哈希值形如0eXXXXXXXXX即0e开头后面全是数字PHP 的会把它当作科学计数法处理0e123在科学计数法中等于0 × 10¹²³0因此两个不同的0e开头的 MD5 值用比较结果都为true因为0 0经典0e碰撞对字符串MD5 值QNKCDZO0e830400451993494058024219903391s878926199a0e545993274517709034328855841020s155964671a0e342768416822451524974117254469s214587387a0e848240448830537924465865611904更简单的解法数组绕过:除了0e绕过还有更通用的数组绕过方法在 PHP 中md5(数组)→ 返回NULL因为md5()期望字符串参数传入数组会报错但返回NULLNULL NULL→true松散比较不同数组$a ! $b→true所以只需要传a[]1b[]2即可绕过。正文一、代码审计访问目标首页http://ceb7428be7b64f06d52ca0af.http-ctf2.dasctf.com:80/页面自动跳转到./leveldo4.php。访问./leveldo4.php响应头中包含一个提示Hint: select * from admin where passwordmd5($pass,true)页面是一个密码输入框提交的密码会经过md5($pass, true)处理后拼接到 SQL 查询中。md5函数知识点讲解md5($string, $raw_output)函数的第二个参数$raw_output默认false返回32 字符的十六进制字符串如d41d8cd98f00b204e9800998ecf8427e设为true返回16 字节的原始二进制数据可能包含不可见字符当md5($pass, true)的输出直接拼接到 SQL 查询时如果原始二进制数据中包含单引号等 SQL 特殊字符就可能造成 SQL 注入。因此我们需要找一个字符串它的 MD5 原始二进制值恰好构成 SQL 注入语句。经过前人验证字符串ffifdyop的 MD5 原始二进制值为 or 6É]é®ãR^ìÿ在 SQL 中解析后等效于select*fromadminwherepasswordor6É...由于6É...不为假 or 6É...结果为真从而绕过密码验证。其他可用字符串129581926211651571912466741651878684928→ MD5 raw:06da5430449f8f6f23dfc1276f722738但ffifdyop是最经典、最简洁的 payload。二、构造请求参数向./leveldo4.php发送 GET 请求参数为passwordffifdyopGET /leveldo4.php?passwordffifdyop HTTP/1.1 Host: ceb7428be7b64f06d52ca0af.http-ctf2.dasctf.com响应成功页面底部出现 JavaScript 重定向scriptwindow.location.replace(./levels91.php)/script三、PHP 松散比较访问./levels91.php页面 HTML 注释中泄露了 PHP 源码$a$_GET[a];$b$_GET[b];if($a!$bmd5($a)md5($b)){// wow, glzjin wants a girl friend.条件要求$a ! $b两个值不相等松散比较md5($a) md5($b)两个值的 MD5 哈希松散相等四、构造数组实现MD5 绕过向./levels91.php发送 GET 请求使用数组绕过GET /levels91.php?a[]1b[]2 HTTP/1.1 Host: ceb7428be7b64f06d52ca0af.http-ctf2.dasctf.com响应中出现 JavaScript 重定向scriptwindow.location.replace(./levell14.php)/script五、PHP 严格比较访问./levell14.php页面直接显示了 PHP 源码?phperror_reporting(0);includeflag.php;highlight_file(__FILE__);if($_POST[param1]!$_POST[param2]md5($_POST[param1])md5($_POST[param2])){echo$flag;}条件要求$_POST[param1] ! $_POST[param2]严格不相等类型和值都不同md5($_POST[param1]) md5($_POST[param2])MD5 哈希严格相等1、为什么0e绕过在这里失效严格比较要求类型和值都相等0e830400451993494058024219903391 0e545993274517709034328855841020→false即使它们数值上都是 0但字符串内容不同严格比较会直接返回false2、为什么数组绕过仍然有效当 PHP 的md5()函数接收到数组参数时PHP 会抛出警告Warning但仍然返回NULLmd5($_POST[param1])→NULLmd5($_POST[param2])→NULLNULL NULL→true类型相同NULL值相同NULL同时$_POST[param1] ! $_POST[param2]→true两个不同的数组因为$a array(0 1)和$b array(0 2)是两个不同的数组对象因此数组绕过对同样有效六、构造数组实现MD5 绕过向./levell14.php发送 POST 请求使用数组绕过POST /levell14.php HTTP/1.1 Host: ceb7428be7b64f06d52ca0af.http-ctf2.dasctf.com Content-Type: application/x-www-form-urlencoded Content-Length: 21 param1[]1param2[]2响应体中成功输出 Flag。

相关新闻