日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

防止sql注入和sqlmap介绍

發(fā)布時間:2023/12/29 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 防止sql注入和sqlmap介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

sql注入問題從WEB誕生到現(xiàn)在也一直沒停過,各種大小公司都出現(xiàn)過sql注入問題,導致被拖庫,然后存在社工庫撞庫等一系列影響。

防止sql注入個人理解最主要的就一點,那就是變量全部參數(shù)化,能根本的解決sql注入問題。比如代碼里寫sql或數(shù)據(jù)庫層面寫存儲過程,只要不拼接sql語句,不執(zhí)行動態(tài)sql語句,那就能防止sql注入。

但實際情況sql語句可能非常復雜。很多年前有討論很熱的話題,非常復雜的業(yè)務邏輯到底用sql語句在存儲過程里來實現(xiàn),還是在代碼service層來實現(xiàn)復雜的業(yè)務邏輯。比如電信移動很多老項目都是有非常復雜的存儲過程或函數(shù)來實現(xiàn)業(yè)務,這里不說到底放哪里好,因為和實際業(yè)務情況有關系。不管把這么復雜的業(yè)務邏輯在代碼層面service或dao里實現(xiàn)還是存儲過程實現(xiàn),都需要防止sql注入問題。

和數(shù)據(jù)庫交互的業(yè)務系統(tǒng),去掉業(yè)務邏輯層面,不管應用服務器還是數(shù)據(jù)庫服務器,就剩下sql的操作。這里說下我認為的幾種和實際情況最接近的寫sql語句的情況:

1、where里是單條件或條件個數(shù)明確的sql語句:

比如按照用戶ID查詢用戶信息;1個訂單多個產(chǎn)品,按照訂單ID,產(chǎn)品ID查詢該訂單里某個產(chǎn)品的信息,where條件是明確的。

2、where條件不明確的,不明確的原因是需要根據(jù)用戶的選擇作為條件:

比如查詢訂單,訂單有多個元素:OrderID,UserID,ProductID,ProductName,CreateTime,Status,現(xiàn)在是多條件搜索頁面,用戶可能選擇按照CreateTime和Status作為條件查詢某個時間段訂單狀態(tài)為支付完成的,where條件為:where CreateTime=.. and Status=..,如果用戶按照其他元素搜索,where寫法又不一樣。

3、where條件是一個in范圍的或like查詢的:

比如where UserID in (1,2,3,4)。

這里最簡單的是第1個情況,條件明確,直接把每個確定的條件參數(shù)化查詢sql即可。

第2個情況稍微復雜點,一般開發(fā)人員很容易拼接sql語句,尤其條件非常多的情況下,按照用戶查詢的不同條件,if else..按照條件直接拼接sql語句,這樣就造成了sql注入。實際處理時,可以在第一個if前定義一個List變量,針對每個if條件,如果符合if條件,sql語句就參數(shù)化一個占位符,List變量add一個用戶傳入的條件。下面是示例代碼:

if (null != begindate && !"".equals(begindate)) {
// 開始日期
sqlBuilder.append(" and beginDate >= ? ");
params.add(DateUtil.conversionDate6(begindate.trim() + " 00:00"));
}

sqlBuilder用于參數(shù)化拼接sql,params是參數(shù)化集合List params,后面再參數(shù)化sql查詢:

Query query = sessionFactory.getCurrentSession().createQuery(sqlBuilder.toString());

private void setQueryParamter(Query query, List params) {
if (!params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
query.setParameter(i, params.get(i));
}
}
}

第3個情況in會有一個問題,就是比如in(?)?傳入的問題,需要把?參數(shù)傳為一個數(shù)組,經(jīng)常出現(xiàn)的問題可能傳入一個字符串導致查詢不出來,比如:

String sqlStr = "select * from user i where i.id in (:ids)";

Query query = sessionFactory.getCurrentSession().createQuery(queryString);
query.setParameterList("ids", idsValue);

idsValue可能會被賦值為"'1','2','3'"的字符串,實際應該為String[] splits=...的一個數(shù)組。

like里應該如下:

sql.append("and name like ? ");
list.add("%"+param+"%");

而不應該寫為:

sql.append("and name like '%?%' ");
list.add(param);

list作為參數(shù)化傳入的參數(shù)。

上面的示例代碼是java的示例代碼,其他.NET和PHP也可以參考。不同數(shù)據(jù)庫參數(shù)化的占位符號不一樣,比如msql是@,oracle是:,mysql是?,mysql里用名字取名的占位符是":名字",比如前面的:ids。

上面說了如何防止sql注入,下面簡單介紹下神器sqlmap,它是一個典型的sql注入檢測和利用工具。

sqlmap支持5種sql注入模式:

1、基于布爾的盲注(Boolean-based blind SQL injection),即可以根據(jù)返回頁面判斷條件真假的注入。

比如對參數(shù)加一個' and '1'='1和' and '1'='2,如果第一個能查詢出來,第二個不行,則說明可以注入,后面可以根據(jù)字段and exist(...)不斷猜測。

2、基于時間的盲注(Time-based blind SQL injection),即不能根據(jù)頁面返回內容判斷任何信息,用條件語句查看時間延遲語句是否執(zhí)行(即頁面返回時間是否增加)來判斷。

比如直接把某個參數(shù)的值刪除,改為if((ascii(mid(user(),1,1))=103 and sleep(3))如果ascii(mid(user(),1,1))=103條件為真,則會等待3秒才返回結果,如果ascii(mid(user(),1,1))=103為假,則直接返回頁面,這樣不斷猜測user()的第1,2,3個字符。

3、基于報錯注入(Error-based SQL injection),即頁面會返回錯誤信息,或者把注入的語句的結果直接返回在頁面中。

比如在條件后面增加+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a),通過報錯把user()顯示出來,這個方法是最快的。

這里報錯注入的sql很不好理解,首先它實現(xiàn)的前提是如果sql報錯了,后臺配置的按照sql怎么出錯怎么拋出異常到頁面(即非友好頁面),然后比如這里報錯主要依靠floor(rand(0)*2),rand(0)是mysql的一個函數(shù),他會返回0到1之間的隨機浮點數(shù),rand(0)*2為1到2之間的隨機浮點數(shù),floor是往下取整的函數(shù),比如floor(0.2)=0,floor(1.2)=1。這里group by x就非常重要了,比如我們查詢select 1 from information_schema.tables group by rand(0) limit 0,30;將會查詢30個1出來,原因是group by 一個隨機數(shù),每次都將查詢不同的數(shù)據(jù)出來,limit限制30就顯示30條。所以剛才試的sql語句,因為group by x,x的值是隨機的,比如x值為~root@127.0.0.1~0,也可能為~root@127.0.0.1~1,group by 這個數(shù)據(jù)如果遇到兩個相同的group key,則就報錯了,如果頁面吧錯誤拋出到頁面,則可以通過正則匹配~和~符號之間的為user()的值,比如報錯:Duplicate entry '~root@127.0.0.1~1' for key 'group_key'。

4、聯(lián)合查詢注入(UNION query SQL injection),可以使用union的情況下的注入。

這個很好理解,就是在select后union把數(shù)據(jù)查詢出來,比如先在查詢條件后輸入order by 3,order by 4..到order by 8的時候報錯了,說明select了7條記錄。然后條件后輸入 and 1=2 union select 1,user(),database()...查詢7個數(shù)據(jù)出來,由于第一個select后有了1=2條件不成i,因此只會查詢我們寫的select語句,這樣覆蓋之前的查詢記錄返回出我們需要的數(shù)據(jù),這個速度也非常快。

5、堆查詢注入(Stacked queries SQL injection),可以同時執(zhí)行多條語句的執(zhí)行時的注入。

比如用;分隔后執(zhí)行其他sql語句,一般用于更新數(shù)據(jù)或執(zhí)行系統(tǒng)相關命令,比如在參數(shù)后面增加; update sysuser set password='' where username='admin',或比如sqlserver執(zhí)行exec master..xp_cmdshell,執(zhí)行cmd命令創(chuàng)建遠程登錄用戶等。

sqlmap非常強大,可以get,post,httpheader的值變化識別是否存在注入,它可以自動識別MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase和SAP MaxDB數(shù)據(jù)庫,還有一些常用的繞過防止sql注入的替換符號,也可以自己擴展python腳本繞過WAF之類的防注入程序,常用參數(shù)和常用檢測命令后續(xù)單獨再寫一個blog文章。

如需轉載,請注明來自:http://lawson.cnblogs.com

總結

以上是生活随笔為你收集整理的防止sql注入和sqlmap介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。