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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL注入(二)

發布時間:2024/4/17 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL注入(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

5.限制輸入長度??

  如果在Web頁面上使用文本框收集用戶輸入的數據,使用文本框的MaxLength屬性來限制用戶輸入過長的字符也是一個很好的方法,因為用戶的輸入不夠長,也就減少了貼入大量腳本的可能性。程序員可以針對需要收集的數據類型作出一個相應的限制策略。

6.URL重寫技術

????????我們利用URL重寫技術過濾一些SQL注入字符,從而達到防御SQL注入。因為許多SQL注入是從URL輸入發生的。

7.傳遞參數盡量不是字符

  假設我們顯示一篇新聞的頁面,從URL傳遞參數中獲得newid我們可能會隨手寫下下面的代碼:???

  string?newsid?=?Request.QueryString["newsid"];
  string?newssql?=?"select?*?from?news?where?newsid="?+?newsid;

?

?

  如果傳遞過來的參數是數字字符就沒有問題。但是如果傳遞過來的newsid是“1 delete from table ”的話,那么sql的值就變成了“select * from table where newsid=1 delete from news”。發生注入成功。但是這里改為

??????? int newsid=int.Parse(Request.QueryString["newsid"].ToString());

????????string?newssql?=?"select?*?from?news?where?newsid="?+?newsid.Tostring();

????????這里如果還是上面"1 delete from table "會發生錯誤,因為在轉換時候出現了錯誤

????????從上面的一個小例子,我們得出在傳遞參數時候盡量不要用字符,免得被注入。?

?

  最后是我想擴展下利用URL重寫技術來過濾一些SQL注入字符,首先這里有一篇關于URL重寫的文章,我的基本思想是可以利用它,屏蔽一些危險的SQL注入字符串,這些字符串我們可以人為的設定,畢竟我們還是根據特定的環境設定我們防御措施。首先我們在ModuleRewriter類中的Rewrite函數得到絕對的URL判斷其中是否有危險字符,如果有我們就將它鏈接到一個提示用戶您輸入危險的URL地址。如果不是我們繼續判斷是否觸發了其他的URL重寫的規則,觸發了就重寫。這樣就大致上能在URL上防御危險字符

代碼

?

上面是要在web.config配置文件加上的內容,這里我加上了兩個重寫規則,第一個規則是專門針對滿足這個正則表達式的頁面URL查看是否有危險字符,有危險字符就會發送到Default_sql_error.aspx頁面,來示警。這里我假定會發生危險字符注入的頁面時以"d"字符開頭并加上數字的頁面(這里我們可以根據實際情況自己定義,看哪些頁面URL容易發生我們就制定這些頁面的正則表達式),第二個是一般URL重寫。因為這里我采用的是HTTP模塊執行URL重寫,所以加上<httpModules></httpModules>這一塊。

?????????第二步就是要在重寫Rewrite函數了

?

protected override void Rewrite(string requestedPath, System.Web.HttpApplication app)
{
// 獲得配置規則
RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;

Uri url = app.Request.Url;

// 判斷url 中是否含有SQL 注入攻擊敏感的字符或字符串,如果存在,sqlatFlag = 1 ;
string urlstr = url.AbsoluteUri;
int sqlatFlag = 0;
string words = "exec ,xp ,sp ,declare ,cmd ,Union ,--";

// 如果還有其他敏感的字符或者符號,可以加入上面這行字符串中
string[] split = words.Split(',');
foreach (string s in split)
{
if (urlstr.IndexOf(s.ToUpper()) > 0)
{
sqlatFlag = 1;
break;
}
}
if (sqlatFlag == 1)
{
// 創建regex
Regex re = new Regex(rules[0].SendTo, RegexOptions.IgnoreCase);
// 找到匹配的規則,進行必要的替換
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.ToString());
// 重寫URL
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
//RewriterUtils.RewriteUrl(app.Context, rules[0].SendTo);
}
else
{
// 遍歷除rules[0 ]以外的其他URL 重寫規則
for (int i = 1; i < rules.Count; i++)
{
// 獲得要查找的模式,并且解析URL (轉換為相應的目錄)
string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";
// 創建regex
Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
// 查看是否找到了匹配的規則
if (re.IsMatch(requestedPath))
{
// 找到了匹配的規則, 進行必要的替換
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
// 重寫URL
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
break;
// 退出For 循環
}
}
}
}

?

?

那么下一步就是檢驗例子了

首先我們輸入http://localhost:4563/web/Default.aspx?id=1;--?

這樣http://localhost:4563/web/Default.aspx?id=1;--?沒有改變,就會顯示Default_sql_error.aspx里內容“您輸入了危險字符”。?
再輸入http://localhost:4563/web/D11.aspx就會顯示?Default2.aspx內容,因為這里觸發了第二個重寫規則

?試驗成功。

  當然用URL防SQL只是我想到一種怪癖思路,大家如果有什么特別方法可以共同考論一下,還是引用前輩們話“見招拆招”遇到實際的問題我們就根據實際情況解決,選用那個最實用的方法。

?

?

?

一個客戶對我們請求說,請我們來檢查一下他的內部網絡,這個網絡被公司的職員以及客戶們來使用。這是一個較大的安全評估的一部分,而且,雖然我們以前從沒 有真正的使用過SQL注入來破解一個網絡,但是我們對于其一般的概念相當的熟悉。在此次“戰斗”中,我們是完全成功的,而且想要通過把這個過程的每一個步驟重新記錄下來,并作為一個“生動的例子”。

“SQL注入”是特定的一種未被確認或未明確身份的用戶輸入漏洞的一個子集(“緩沖溢出”是一個不同的子集),而這個想法的目標是,讓應用程序確信從而去 運行SQL代碼,而這些代碼并不在其目的之內。如果一個應用程序是在本地通過即時的方式來創建一個SQL字符串,結果很直接,會造成一些真正的出人意料的結果。

我們要明確說明的是,這是一個有些曲折的過程,并且其中會有多次的錯誤的轉折,而其余的更有經驗的人當然會有著不同的-甚至更好的-方法。而事實上,我們成功的實現了建議,并沒有被完全的誤導。

還有一些不同的論文討論SQL注入問題,包括一些更加詳細的文章,不過此文所展示的,與破解的過程同樣份量的是發現了SQL注入的原因。

目標內網

這顯然是一個完全自主開發的應用程序,而我們對于它沒有預先的了解,或者訪問源代碼的權限:這已是一個“blind”攻擊。若干次偵測之后,我們了解到服 務器運行的是微軟的IIS6,并使用ASP.NET框架,從這其中得到的,似乎可以假定數據庫是微軟的SQL服務器:我們相信這些技術可以應用于幾乎任何 一種web應用,而此應用可能為任何一種SQL服務器所支持。

登陸頁面是一個傳統的用戶名-密碼表單,帶有一個用電子郵件給我傳送密碼的鏈接;而后者被證實是整個系統的敗筆。

當輸入一個電子郵件地址的時候,系統會假定次郵件存在的方式,再用戶數據庫里面尋找這個電子郵件地址,并且會郵寄一些內容到這個地址。由于我的電子郵件地址沒有被找到,所以它不會給我發送任何內容。

所以,第一個測試,對于任何SQL化的表單而言,是輸入一個帶有單引號構成的數據:這樣做的目標是查看是否他們在構建SQL字符串的時候根本沒有使用數據 的清理機制。當為此表單提交了一個有單引號的電子郵件之后,我們得到了一個500錯誤(服務器失敗),這就是說,這個“被破壞了的”的輸入實際上被真實的 分析過。中!

我們猜測底層的SQL代碼可能類似于如此:

  • SELECT?fieldlist?FROM?table?WHERE?field?=?'$EMAIL';?
  • 這里,$EMAIL是由用戶通過表單提交的電子郵件地址,而這段較長的查詢提供的應用符號,是為了使得這個$EMAIL成為一個真正的字符串。我們不知道 這個數據域的確切的名字或者是于此相關的數據表的名字,但是我們卻了解他們的特性,而此后我們將會得到一些很好的猜測結果。

    當我們輸入steve@unixwiz.net' - 留意那個結尾的引號 - 這將產生出一個如下構建的SQL:

  • SELECT?fieldlist?FROM?table?WHERE?field?=?'steve@unixwiz.net'';?
  • 當這個SQL被執行的時候,SQL分析器發現了多余的引號,從而中止了工作,并給出一個語法錯誤。而這個錯誤如何表述給用戶,取決于應用程序內部錯誤修復 的過程,但是這通常不同于“電子郵件地址不存在”的錯誤提示。這個錯誤的響應是致命的第一通道,既用戶的輸入沒有被正確的清理,而因此應用程序成為了破解 的美食。

    由于我們輸入的數據顯然位于WHERE子語句中,讓我們用合法的SQL方式改變一下這個子句的本貌并看看會發生什么。通過輸入任何一種‘OR ’x‘=x語句,結果SQL成為:

  • SELECT?fieldlist?FROM?table?WHERE?field?=?'anything'?OR?'x'='x';?
  • 因為應用程序沒有真正的對這樣的查詢有所考慮,而僅僅是構建一個字符串,以致于我們使用的引號使得一個單元素的WHERE子句,變成了一個雙元素的子句, 而且’x'=x字句是確定為真的,無論第一個字句是什么。(有一種更好的方式來確保“始終為真”,這部分我們后面會談及)

    不過與“真實”的查詢不同,本應當一次返回一個單獨的項,這個版本必然會返回成員數據庫里面的每一個項。唯一的可以發現應用程序在這種情況下會做什么的方式,就是嘗試。不斷嘗試,我們留意到以下結果:

    你的登錄信息已經發送到 random.person@example.com.

    我們一般都會把查詢返回的第一行作為作為猜測的主要入口。這哥們確實從E-mail里拿回了他的密碼,同樣這個郵件可能會讓他感到吃驚并且會引起懷疑。

    現在我們知道怎么在本地玩這條查詢了,雖然目前我們還不知道我們看不到的那部分SQL結構是怎么拼起來的。但是我們通過逆向工程看到了三個不同的查詢結果:

    • 您的登陸信息已經以Email形式發送給您
    • 我們無法識別您的Email地址
    • 服務端錯誤

    頭兩個響應是有效的查詢的結果,最后一個是無效SQL造成的。 類似這樣的響應結果會幫助我們更好的逆推服務端用來查詢的SQL語句結構。

    預設字段映射

    我們要干的第一步就是猜字段名,首先我們合理的推測查詢帶了“email address” 和 “password”,所以可能的字段名選擇會有“US Mail Address”? 或者 “userid” 亦或者“phone number”? 。當然最好能執行 show table,但是我們又不知道表名,貌似目前沒什么明顯的方法能讓我們拿到表名。

    那就分步走吧。在每個例子里,我們會用我們已知的SQL加上我們自己的特殊“段”。我們已知的這條SQL的結尾是個Email地址的比對,那就猜下email是這個字段名吧

  • SELECT?fieldlist?FROM?table?WHERE?field?=?'x'?AND?email?IS?NULL;?--';?
  • 如果服務器響應是報錯,那基本上可以說明我們的SQL拼錯了。但是如果我們得到任何正常的返回,例如“未知的郵件地址” 或 “密碼已發送”? ,說明我們的字段名蒙對了。

    要注意的是,我們的“And” 關鍵字而沒用“OR” 關鍵字,這么做是有目地滴。在上一步中,我們不關心到底是哪一個Email,而且我們不想因為蒙中某人的Email然后給他發了重置密碼的郵件。這么搞那 哥們兒一定會懷疑有人對他的帳號搞三搞四。所以用“And”關鍵字拼上一個不合法的Email地址,這樣服務端總是返回空結果集,也就不會給任何人發郵 件。

    提交上面的SQL代碼段確實返回了“未知的郵件地址” 這么一個響應。現在我們確認了email地址的字段名是email。如果不是這么個響應,那我就再蒙“email_adress”或者“mail”亦或者 其他類似的。這個環節總是靠蒙的,但是蒙也得講技巧和方法方式。

    這段SQL的用意是我們假設預設的SQL查詢中的字段名是 email ,跑一下看看是不是有效。我不會管你到底有沒有匹配的Email,所以用了個偽名“x” , “--” 這個標示是表示SQL的起始。這樣SQL解析到這就會把它直接當成一條命令,而“--”后面的會是一個新的命令,這樣就屏蔽掉了后面的那些不知道的玩意 兒。

    下一步,我們來猜下其他比較明顯的字段名: "password","userid","name" 和類似的。每次我們只蒙一個名字,當返回結果不是“服務端錯誤” , 那就說明我們蒙對了。

  • SELECT?fieldlist?FROM?table?WHERE?email?=?'x'?AND?userid?IS?NULL;?--';?
  • 通過這一步,我們蒙出來了下面幾個字段名:

    • email
    • passwd
    • login_id
    • full_name

    肯定還有更多其他的(把HTML頁面表單的 <Input?? name="XXXXX"> 拿來做參考是個非常不錯的選擇)后來我又挖了一下但是沒挖出來更多的字段名。 到目前為止,我們還是不知道這些字段所屬的表的表名--咋個弄呢?

    搜尋表名

    應用內建的query已經把表名放在語句中,但我們不知道表的名字。有幾種方法可以找到這些插入在語句中表名(以及其他的表名)。我們用的是一種依賴于subselect的方法。

    下面這個單獨的query

  • SELECT?COUNT(*)?FROM?<i>tabname</i>?
  • 返回表中記錄的數量,當然,若表名是無效的,則查詢失敗。我們可以把這個查詢放入我們的查詢語句中來探查表名。

  • SELECT?email,?passwd,?login_id,?full_name?
  • ??FROM?<i>table</i>?WHERE?<b>email</b>?=?'<span>x'?AND?1=(SELECT?COUNT(*)?FROM?<i>tabname</i>);?--'</span>;?
  • 我們實際上并不關心表中有多少記錄,我們關心的是表名是否有效。通過試探不同的猜測,我們最終確定members是數據庫中的有效表名。但是,這是這個查 詢中所用的表名嗎?為此,我們需要另一個使用table.field的查詢:這只在表名的確是查詢中的表名時才工作,而不僅僅當表存在時工作。

  • SELECT?email,?passwd,?login_id,?full_name?
  • ??FROM?members?
  • ?WHERE?email?=?'<span>x'?AND?members.email?IS?NULL;?--</span>';?
  • 當這個語句返回 "Email unknown"時,可以確認我們的SQL正確執行了,并且我們成功的猜出了表名。這對后面的工作很重要,但我們先臨時使用一下另一種方法。

    弄幾個帳號先

    目前我們搞到了members表結構的部分信息,但是我們只知道一個用戶名,就是之前我們蒙中的那個發了郵件通知的那個用戶名。當時我們只得到了郵件地址,但是拿不到郵件內容。所以我們得再弄幾個有效得用戶名,高端洋氣上檔次的最好。

    我們的從公司的網站開始人肉,找到那些人物介紹的頁面,一般都是介紹公司內部人員的。這些介紹里大多都有這些人的Email地址和名字。就算沒有這些信息也沒啥,咱兜里還有貨。

    思路是這樣的,提交一個帶有“Like” 關鍵字的SQL,這樣我們可以對Email地址或者用戶名做些模糊匹配,每次提交如果返回“我們已發送您的密碼至郵箱”那也就是說我們的模糊查詢有效了,而且郵件也真的發了!!!。這么干雖然我們能拿到郵件地址,也意味著對方會收到郵件并引起警覺,所以? 慎用!!

    我們能做email、full_name(或者其他字段)的查詢,每次放入%這個通配符執行如下的查詢:

  • SELECT?email,?passwd,?login_id,?full_name?
  • ??FROM?members?
  • ?WHERE?email?=?'x'?OR?full_name?LIKE?'%Bob%';?
  • 暴力破解密碼

    我們肯定可以在登陸頁面嘗試暴力破解密碼,但是大多的應用都做了相應的防護手段。可能的防護會有操作日志,帳號鎖定或者其他能大大降低我們效率的手段或設備,但是因為輸入沒有被過濾所以給我們繞過這些防護多了一些可能。

    我們將把密碼和郵件名稱的代碼段加到我們已知的SQL里。在這個例子里我們會用一個倒霉催的哥們的郵箱,bob@example.com 然后試試我們準備的一些密碼。

  • SELECT?email,?passwd,?login_id,?full_name?
  • ??FROM?members?
  • ?WHERE?email?=?'bob@example.com'?AND?passwd?=?'hello123';?
  • 這條SQL是完整有效的,所以服務器鐵定不能夠報錯,所以我們知道當服務器響應是“您的密碼已經發送至您的郵箱” 這么個結果是我們就知道剛提交的那個密碼就是我們要的密碼。雖然倒霉催的Bob也收到了郵件并且一定會警覺,但是我們在他警覺之前就干完我們想干的了。

    這個過程可以在Perl下用腳本自動化完成,所以我們就去搞了搞Perl的腳本,結果寫腳本的時候發現了另外一種方法來干這事。

    數據庫不是只讀的

    迄今為止,我們對數據庫除了進行查詢外,沒做其他事。盡管SELECT是只讀的,但不意味SQL就只能這樣。SQL使用分號來中斷一個語句, 如果對輸入沒有做正確的處理, 它就不能阻止我們在查詢語句后面添加不相關的字符串。

    最恰當的一個例子就是這樣:

  • SELECT?email,?passwd,?login_id,?full_name???
  • ??FROM?members???
  • ?WHERE?email?=?'x';?DROP?TABLE?members;?--';??--?Boom!???
  • 第一部分提供了一個假的郵件地址 --?'x'?-- 我們并不關系這個查詢的返回,我們僅僅是給出了一個我們能夠使用無關SQL指令的方式,一個嘗試刪除整個members表而真的是無任何關系的操作.

    這表明我們不僅僅可以切分SQL指令,我們還可以修改數據庫,這完全是被允許的。

    加入一個新成員

    由上所得,我們獲知了members表的部分的結構,嘗試添加一個新的記錄到這個表里面似乎是一個可拊掌稱慶的方法:如果這能成功,我們就能夠通過我們新插入的帳戶來直接登陸了。

    這里,毫不驚奇的是,這只需要稍微加些SQL,我們把它放在不同的行從而讓我們的展示更易理解,不過從頭到尾這一部分其實仍然是一個字符串:

    SELECT?email,?passwd,?login_id,?full_name?

    ??FROM?members?

    ?WHERE?email?=?'x';?INSERT?INTO?members?('email','passwd','login_id','full_name')??VALUES?('steve@unixwiz.net','hello','steve','Steve?Friedl');--';?

    即便是我們真的確定了表的名字以及使用的字段都是正確的,在成功的實施攻擊之前,仍然有一些障礙:

  • 可能,在表單上,我們并沒有足夠的空間來直接輸入這些文本(盡管,可以使用腳本來解決這個問題,而這并不是很簡便的事情)
  • ?web應用程序的用戶可能并沒有在members表上的插入權限。
  • ?毫無疑問,members表里面有一些別的字段,有一些可能需要初始化的數據,而這可能導致插入失敗。
  • ?即便是可以達到插入一個新的記錄,應用程序可能會出現不當的行為,因為自動插入的時候有一些字段使用的是NULL。
  • ?一個有效的“成員”可能不僅僅需要在members表里面的一個記錄,而是和別的表有著數據上的關聯,(如,“訪問權限”),所以添加一個數據到一個表中,可能并不充分有效。
  • 對于手頭的案例而言,我們遇到了#4或者是#5上面的障礙 - 我們無法真正確定是哪一個 - 因為在主登陸界面上,輸入上面的用戶名+密碼的時候,返回了一個服務器上的錯誤。這就是說,那些我們沒有用到的字段可能是必要的字段,而盡管如此,它們仍 然沒有被正確的處理。

    這里,一個可行的方法,就是猜測別的字段,但是這可以保證是一個長時間而且耗費勞力的過程:雖然你可能可以猜測出來那些“顯而易見”的字段,但是卻很難構建出整個應用程序的組織圖像。

    所以,最后我們選擇走另一條不同的路。

    轉載于:https://www.cnblogs.com/barrywxx/p/4483621.html

    總結

    以上是生活随笔為你收集整理的SQL注入(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

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