关于SHCTF一些题目的思考

web

MD5的事就拜托了

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['SHCTF'])){
extract(parse_url($_POST['SHCTF']));
if($$$scheme==='SHCTF'){
echo(md5($flag));
echo("</br>");
}
if(isset($_GET['length'])){
$num=$_GET['length'];
if($num*100!=intval($num*100)){
echo(strlen($flag));
echo("</br>");
}
}
}
if($_POST['SHCTF']!=md5($flag)){
if($_POST['SHCTF']===md5($flag.urldecode($num))){
echo("flag is".$flag);
}
}

extract

首先是关于extract函数,extract函数是将关联数组的键值作为变量名,将键值的值作为变量的值,如下:

这里可以看到,extract函数将键值xiaoming转换成了变量,而变量对应的值就是键值对应的值

parse_url

再来看parse_url函数,parse_url — 解析 URL,返回其组成部分:

其返回值:

当然,我们也可以自己构造一个url,例如:

这里我们构造一个user的协议,此时开始的索引即schema就是user,然后一级一级索引,值得注意的是,此函数只会将最后一个@后面的值解析为host,例如:

这里可以看到最后一个@前的内容都被解析为了pass的值,如果host不指定值,即@后面不接任何值或没有@且没有多余的值赋给host或在协议中多添加,如:user:///www.baidu.com,这时会直接返回false.

间接引用构建变量名,形成变量覆盖

通过上面的分析,我们知道只需要通过两次间接引用schema变量后的值要等于'SHCTF'就行,什么是间接引用,如下:

所以在schema索引的第三个值应该为SHCTF,所以可以构造url通过parse_url函数和extract函数解析后,满足这个要求,payload:

1
user://pass:SHCTF@任意值

这里通过解析后可以得到:

1
2
3
$schema="user"
$user="pass"
$pass="SHCTF"

那么$$$schema="SHCTF",这时会给到flag的md5值

哈希扩展攻击

我们知道第二个if会给到flag的长度,最后是比较传入的值要等于flag和传入num值url解码的字符串的md5值,由于知道了flag中的部分字符(固定最后一位为})以及flag的md5值和长度,这时候就可以进行哈希扩展攻击,