安全漏洞之SQL注入和shell注入
SQL注入
發(fā)生部位
SQL注入安全漏洞發(fā)生于應(yīng)用程序和數(shù)據(jù)庫之間。
原理
當(dāng)攻擊者在輸入的字符串之中注入SQL指令,由于程序沒有設(shè)置相關(guān)的字符檢查,那么這些指令就會(huì)被數(shù)據(jù)服務(wù)器認(rèn)為是正常的SQL指令并執(zhí)行,因此,數(shù)據(jù)服務(wù)器就會(huì)遭到破壞或者數(shù)據(jù)被泄露出去。
示例
某個(gè)網(wǎng)站的登錄驗(yàn)證的SQL查詢代碼為
strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"惡意填入
userName = "1' OR '1'='1";與
passWord = "1' OR '1'='1";時(shí),將導(dǎo)致原本的SQL字符串被填為
strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"也就是實(shí)際上運(yùn)行的SQL命令會(huì)變成下面這樣的
strSQL = "SELECT * FROM users;"因此達(dá)到無賬號密碼,亦可登錄網(wǎng)站。所以SQL注入被俗稱為黑客的填空游戲。
SQL注入方式
-
數(shù)字型輸入
上面的示例就是一種數(shù)字型輸入。再比如,在瀏覽器地址欄輸入:learn.me/sql/article.php?id=1,這是一個(gè)get型接口,發(fā)送這個(gè)請求相當(dāng)于調(diào)用一個(gè)查詢語句:
$sql = "SELECT * FROM article WHERE id =",$id正常情況下,應(yīng)該返回一個(gè)id=1的文章信息。那么,如果在瀏覽器地址欄輸入:learn.me/sql/article.php?id=-1 OR 1 =1,這就是一個(gè)SQL注入攻擊了,可能會(huì)返回所有文章的相關(guān)信息。因?yàn)?=1一定是true,所以整個(gè)where語句永遠(yuǎn)是true,那么查詢的結(jié)果相當(dāng)于整張表的內(nèi)容。
-
字符型輸入
用戶登錄時(shí)調(diào)用接口learn.me/sql/login.html,首先連接數(shù)據(jù)庫,然后后臺對post請求參數(shù)中攜帶的用戶名、密碼進(jìn)行參數(shù)校驗(yàn),即sql的查詢過程。假設(shè)正確的用戶名和密碼為user和pwd123,輸入正確的用戶名和密碼、提交,相當(dāng)于調(diào)用了以下的SQL語句:
SELECT * FROM user WHERE username = 'user' ADN password = 'pwd123'由于用戶名和密碼都是字符串,SQL注入方法即把參數(shù)攜帶的數(shù)據(jù)變成mysql中注釋的字符串。
(1)’#’:’#'后所有的字符串都會(huì)被當(dāng)成注釋來處理
SELECT * FROM user WHERE username = 'user'#'ADN password = '111' SELECT * FROM user WHERE username = 'user'(2)’-- ’ (–后面有個(gè)空格):’-- '后面的字符串都會(huì)被當(dāng)成注釋來處理
SELECT * FROM user WHERE username = 'user'-- 'AND password = '111' SELECT * FROM user WHERE username = 'user' -
搜索型輸入
當(dāng)在搜索框搜索的時(shí)候,稱為搜索型。搜索型與數(shù)字型注入最大的區(qū)別在于:數(shù)字型不需要百分號閉合,而搜索類型一般要使用百分號來閉合。
如何防御SQL注入
- 在設(shè)計(jì)應(yīng)用程序時(shí),完全使用參數(shù)化查詢(Parameterized Query)來設(shè)計(jì)資料訪問功能。
- 在組合SQL字符串時(shí),先針對所傳入的參數(shù)加入其他字符(將單引號字符前加上轉(zhuǎn)義字符)。
- 如果使用PHP開發(fā)網(wǎng)頁程序的話,需加入轉(zhuǎn)義字符之功能(自動(dòng)將所有的網(wǎng)頁傳入?yún)?shù),將單引號字符前加上轉(zhuǎn)義字符)。
- 使用php開發(fā),可寫入html特殊函數(shù),可正確阻擋XSS攻擊。
- 其他,使用其他更安全的方式連接SQL數(shù)據(jù)庫。例如已修正過SQL注入問題的數(shù)據(jù)庫連接組件,例如ASP.NET的SqlDataSource對象或是 LINQ to SQL。
- 增強(qiáng)WAF的防御力
shell注入(OS命令注入)
發(fā)生部位
程序中調(diào)用系統(tǒng)命令的地方。
原理
通常情況下,Web應(yīng)用程序會(huì)有需要執(zhí)行shell命令的時(shí)候,有可能只是使用Unix sendmail程序發(fā)送電子郵件,或運(yùn)行指定的Perl和C + +程序。從開發(fā)的角度來看,這樣做可以減少程序的開發(fā)時(shí)間。然而,如果攻擊者以構(gòu)造特殊命令字符串的方式,把惡意代碼輸入一個(gè)編輯域(例如缺乏有效驗(yàn)證的輸入框),從而傳遞到后臺程序,惡意命令代碼一旦執(zhí)行,就會(huì)導(dǎo)致信息泄露或者正常數(shù)據(jù)的破壞,甚至可能導(dǎo)致惡意命令掌控該用戶的電腦和他們的網(wǎng)絡(luò)。
示例
String imageName = (String) params.get("imageName"); String cmd = "docker pull " + imageName; Process process = Runtime.getRuntime().exec(cmd); // ...在上面的Java代碼中,前端傳遞docker鏡像名至后端服務(wù)器,由后端服務(wù)器調(diào)用docker pull命令拉取對應(yīng)的鏡像文件。當(dāng)前端傳入的imageName參數(shù)值為正常的鏡像名稱時(shí)(如nginx),會(huì)執(zhí)行docker pull nginx命令拉取nginx鏡像。而當(dāng)前端傳入的imageName參數(shù)值為nginx; echo hacked,即帶有惡意指令echo hacked時(shí),后端程序?qū)⒃趫?zhí)行docker pull nginx成功后執(zhí)行echo hacked命令。此處為了演示方便以及避免造成誤操作,所以采用了直觀且無害的echo命令。在終端直接運(yùn)行該命令的結(jié)果如下所示:
# 示例中省略了執(zhí)行結(jié)果與本文無關(guān)的一些輸出信息 $ docker pull nginx; echo hacked Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest hacked # <- 此處為執(zhí)行惡意命令的結(jié)果shell注入方式
shell注入主要就是利用了一些符號的的特殊作用,下面介紹幾種常見的符號。
-
; 連續(xù)指令
command1; command2表示執(zhí)行完command1后繼續(xù)執(zhí)行command2,上面的示例就是采取了這種方式。
-
管道 |
command1 | command2表示先執(zhí)行command1,然后將command1的輸出作為command2的輸入,再執(zhí)行command2。例如:
$ ping -c 4 127.0.0.1 | grep loss 4 packets transmitted, 4 packets received, 0.0% packet loss # grep loss會(huì)輸出ping -c 4 127.0.0.1結(jié)果中含loss字段的行 -
& 后臺執(zhí)行
command1 & command2表示在后臺執(zhí)行command1,在前臺執(zhí)行command2。例如:
$ ping -c 4 127.0.0.1 & echo hacked [1] 2333 # <- ping命令的進(jìn)程號 hacked # <- echo hacked的執(zhí)行結(jié)果 PING 127.0.0.1 (127.0.0.1): 56 data bytes # ... ping的執(zhí)行結(jié)果注: ping命令涉及網(wǎng)絡(luò)I/O,所以輸出在echo命令之后,而非ping命令在echo之后執(zhí)行。
-
&&與||
command1 && command2或command1 || command2
二者的區(qū)別為&& command2中的command2僅在command1執(zhí)行成功后(退出碼為0)執(zhí)行,而|| command2中的command2僅在command1執(zhí)行失敗(退出碼為非0值)后執(zhí)行。
-
command與$(command)
當(dāng)命令為command1 $(command2)時(shí)(command1command2``同理),command2的輸出將作為command1的參數(shù)。例如用戶輸入的參數(shù)為$(echo hacked)時(shí),程序在執(zhí)行ping之前將會(huì)先執(zhí)行echo hacked命令。
除了上述幾種shell注入的方式以外,例如重定向(>、>>、<、<<)等也可能被攻擊者所利用。
如何防御shell注入
-
避免直接執(zhí)行用戶輸入的命令
-
對用戶輸入的參數(shù)進(jìn)行校驗(yàn)
-
過濾常見的符號
-
使用黑白名單機(jī)制
-
使用語言提供的轉(zhuǎn)碼方法
-
使用最少權(quán)限的用戶運(yùn)行程序
…
參考
維基百科
博客1
博客2
博客3
總結(jié)
以上是生活随笔為你收集整理的安全漏洞之SQL注入和shell注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 暴风魔镜 光标漂移_如何防止光标在游戏过
- 下一篇: 谁能走得更远?百度、阿里、腾讯的区块链技