前一段時間安全部門測出某個程序存在sql注入漏洞叫榕,在我原來潛意識中一直認為構(gòu)造危險的 sql 語句是相對較難的,所以沒有繃緊神經(jīng)堆巧,總認為就算存在漏洞虚婿,也很難被實際攻擊赋铝,總抱有僥幸心理插勤,但這次事件卻給了我很大一個教訓(xùn)。
sql 注入如何產(chǎn)生的
某個程序?qū)?URL id 參數(shù)沒有做嚴格的限制柬甥,正常的情況下饮六,會這樣執(zhí)行:
update table set id = {id} where name = 'login'
如果攻擊者傳遞 id 參數(shù)是 1 and sleep(5) --,則會構(gòu)成一條危險的 SQL 語句:
update table set id = 1 and sleep(5) -- where name = 'login'
開始我倒沒太在意(只能說太不敏感了)苛蒲,雖然注入了卤橄,但僅僅對我們不重要的一個表進行了全表替換。第二個傷害我認為是 sql 執(zhí)行 延遲了 5 秒而已臂外。
后來發(fā)生的事情(下面會說)才讓我猜測到這條語句耗時很久窟扑,假設(shè) table 表有 10 條記錄,那么整個 sql 語句會執(zhí)行 50 秒漏健,全表鎖定了 table 表的 update 操作嚎货。
當(dāng)然這個sleep 耗時如此之長是我后面發(fā)現(xiàn)的,怎么發(fā)現(xiàn)的呢蔫浆?看下面殖属。
全表鎖定
注入發(fā)生的第二天,同事說某個功能總是不成功瓦盛,頁面總是超時洗显,我排查了下,發(fā)現(xiàn)該功能執(zhí)行的一個關(guān)鍵 sql (在同一個庫)居然超時報錯了:
update table2 set tb =2 where id=3
我在 mysql 終端執(zhí)行了下 show full processlist
87 | db | ip:port | Query | 93724 | User sleep | update table set id = 1 and sleep(5) -- where name = 'login' |
居然發(fā)現(xiàn) sql 注入語句還在執(zhí)行原环,而其他的 update 操作由于 table 表被全表鎖定了挠唆,一直在等待,積累了很多的 update 操作嘱吗。
同時執(zhí)行 show global status:
| Innodb_row_lock_current_waits | 77 |
確實顯示 77 個操作被鎖了玄组。
立刻反饋給了 DBA 同時,他們執(zhí)行了 information_schema 庫的相關(guān)操作:
SELECT r.trx_id waiting_trx_id,r.trx_mysql_thread_id waiting_thread,r.trx_query waiting_query,b.trx_id blocking_trx_id,b.trx_mysql_thread_id blocking_thread,b.trx_query blocking_query FROM innodb_lock_waits w INNER JOIN innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN innodb_trx r ON r.trx_id = w.requesting_trx_id ;
也顯示被鎖定了,立刻在 mysqld 端 kill 了這條語句俄讹,服務(wù)正常運行了哆致。
這個時候我才意識到 sql 注入的危害比我想象的大多了。
沉思
對于我們開發(fā)者來說患膛,知道 sql 注入是危險的沽瞭,但如何構(gòu)造危險 sql 可能是很難的,可怕的是現(xiàn)在居然有這樣的工具(比如 sqlmap)剩瓶,那么危險的 sql 會產(chǎn)生什么后果:
- 偷窺:導(dǎo)出全表數(shù)據(jù)
- 破壞:更新、刪除記錄
sqlmap
sqlmap 是一個滲透測試工具:
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers.
我完全不會使用該工具城丧,總感覺什么白帽子延曙、紅帽子、黑帽子都不是啥好東西...亡哄,他們帶來好處的同時也帶來極大的危害枝缔。
同事使用了下這個工具,我在旁邊看了一會蚊惯,感覺功能太強大了愿卸,雖然不知道它的實現(xiàn)原理,但很想搞明白截型,經(jīng)過同事的測試趴荸,發(fā)現(xiàn)幾個原理:
- 要完整注入,被注入程序必須要打印結(jié)果宦焦,否則很多 sqlmap 功能(比如導(dǎo)出表結(jié)構(gòu))會失效发钝。
- information_schema 被極大的利用了,沒有特殊需求波闹,要關(guān)閉它的操作權(quán)限酝豪。
- sqlmap 有 session data,比如它將整個庫表結(jié)構(gòu) dump 到 session data精堕。
上面幾個原理都是我通過觀察 mysql 日志發(fā)現(xiàn)的孵淘,要開啟 mysql 日志,打開 my.cnf :
general_log_file = /var/log/mysql/mysql.log
然后一邊運行 sqlmap歹篓,一邊觀察 general_log_file 日志瘫证。
接下去講解 sqlmap 的幾個操作:
sqlmap.py -u "http://localhost/test/db.php?id=1" --batch --schema
sqlmap.py -u "http://localhost/test/db.php?id=1" --batch --tables
其中讓我驚嘆它功能強大的是能執(zhí)行 shell:
sqlmap.py -u "http://localhost/test/db.php?id=1" --batch --sql-shell
實現(xiàn) shell 原理其實也不復(fù)雜,就是它內(nèi)部又調(diào)用了下 db.php滋捶,然后將結(jié)果輸出痛悯,本質(zhì)上并沒有啥區(qū)別。
本文發(fā)表于【2018-12-20】重窟,地址是https://mp.weixin.qq.com/s/89t2vW--z4ElaKklQwYuCQ载萌,歡迎大家關(guān)注,我的公眾號(ID:yudadanwx,虞大膽的嘰嘰喳喳)