'sql injection'에 해당되는 글 1건
- 2008.10.17 SQL Injection 공격 확인 및 메일 발송 스크립트
SQL Injection 공격 확인 및 메일 발송 스크립트
공부하자 공부~/Web 보안 2008. 10. 17. 14:46
SQL Injection 공격 방어에 대한 작업을 하던 중..
http://blog.daum.net/_blog/BlogView.do?blogid=0KYRA&articleno=6787162
위의 홈페이지에서 해당 소스를 받아서 SQL Injection 의심사례 발생시 메일로 전달되게 하였습니다.
매번 XML 페이지를 보기도 뭣하고 해서리..
또 다른 방법으로는 XML 파싱 부분을 좀 수정 해서 RSS 구독설정 해 놓는것도 좋은 방법이 될거라 생각 됩니다.
<%
' ===========================
' injection 처리
' ===========================
' SQL Injection 필터 정의 ( www.krcert.or.kr 및 기타 참조 )
injection_filter = ""
injection_filter = injection_filter & "having|syscomments|xp_displayqueuemesgs|xp_printstatements|table|raiserror|xp_dsinfo|xp_peekqueue|--|"
injection_filter = injection_filter & "shutdown|exec|xp_mergelineages|xp_proxiedmetadata|select|kill|xp_|xp_readpkfromqueue|"
injection_filter = injection_filter & "xp_displayparamstmt|insert|declare|sp_|xp_readpkfromvarbin|xp_availablemedia|update|openrowset|"
injection_filter = injection_filter & "xp_cmdshell|xp_repl_encrypt|xp_enumdsn|delete|opendatasource|xp_reg|xp_resetqueue|xp_filelist|"
injection_filter = injection_filter & "drop|pwdencrypt|xp_servicecontrol|xp_sqlinventory|sp_password|alter|msdasql|xp_setsqlsecurity|"
injection_filter = injection_filter & "xp_unpackcab|sp_adduser|create|sqloledb|xp_readerrorlog|xp_sprintf|sp_addextendedproc|inner|join|"
injection_filter = injection_filter & "char(|xp_controlqueueservice|xp_displayparamstmt|sp_dropextendedproc|from|syslogins|"
injection_filter = injection_filter & "xp_createprivatequeue|xp_enumresult|sp_add_job|where|sysxlogins|xp_decodequeuecommand|xp_showcolv|"
injection_filter = injection_filter & "sp_start_job|union|sysdatabases|xp_deleteprivatequeue|xp_updatecolvbm|sp_delete_alert|group|by|"
injection_filter = injection_filter & "sysobjects|xp_deletequeue|xp_execresultset|sp_msrepl_startup|"
injection_filter = injection_filter & "%20and%20|isMember|administrators /add|xp_dirtree|--|2=2|3=3|a=a|b=b|c=c|…|;’|’;"
Function objXML_Log(BAD_WORD,QUERY_STRING)
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
'IP,시간등 XML파일로 기록한다.
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
On Error Resume Next
Set objXML = server.CreateObject("Microsoft.XMLDOM")
objXML.async = False
'-----파일명칭- 결과 XML 화일이 저장될 공간을 지정 ( 권한 확인 필요 )
xml_file_name = "/FileHome/injection.xml"
'-----파일이 존재하는지 체크
blnFileExist = objXML.load(server.MapPath(xml_file_name))
If blnFileExist = False Then
objXML.appendChild(objXML.createProcessingInstruction("xml","version=""1.0"""))
objXML.appendChild(objXML.createElement("IP_LOGS"))
intID = 1
Else
intID = objXML.documentElement.childNodes(objXML.documentElement.childNodes.length - 1).childNodes(0).text + 1
End If
'-----프로세스 시작
Set objXMLv = objXML.createElement("IP_LOG")
objXMLv.appendChild(objXML.createElement("ID"))
objXMLv.appendChild(objXML.createElement("USER_ID"))
objXMLv.appendChild(objXML.createElement("BAD_WORD"))
objXMLv.appendChild(objXML.createElement("QUERY_STRING"))
objXMLv.appendChild(objXML.createElement("HTTP_REFERER"))
objXMLv.appendChild(objXML.createElement("REMOTE_ADDR"))
objXMLv.appendChild(objXML.createElement("LOCAL_ADDR"))
objXMLv.appendChild(objXML.createElement("DATE"))
objXMLv.childNodes(0).text = intID
objXMLv.childNodes(1).text = session("USER_ID") ' 회원 가입 페이지라면 회원 아이디도 넣을 수 있도록..
objXMLv.childNodes(2).text = BAD_WORD
objXMLv.childNodes(3).text = Request.ServerVariables("SCRIPT_NAME") &"?"& QUERY_STRING
objXMLv.childNodes(4).text = Request.ServerVariables("HTTP_REFERER")
objXMLv.childNodes(5).text = Request.ServerVariables("REMOTE_ADDR")
objXMLv.childNodes(6).text = Request.ServerVariables("LOCAL_ADDR")
objXMLv.childNodes(7).text = Now()
' 오류내용을 보고할 메일 본문 작성
MainCont = ""
MainCont = MainCont & "<table width=""700"" cellspacing=""0"" cellpadding=""0"" border=""1"" style=""font-size:9pt;"">"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">번호</td><td width=""500""> "&intID&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">아이디</td><td width=""500""> "&session("USER_ID")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">금지단어</td><td width=""500""> "&BAD_WORD&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">넘어온 값</td><td width=""500""> "&Request.ServerVariables("SCRIPT_NAME") &"?"& QUERY_STRING
objXMLv.childNodes(4).text = Request.ServerVariables("HTTP_REFERER")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">이전 페이지</td><td width=""500""> "&Request.ServerVariables("HTTP_REFERER")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">클라이언트 아이피</td><td width=""500""> "&Request.ServerVariables("REMOTE_ADDR")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">서버 아이피</td><td width=""500""> "&Request.ServerVariables("LOCAL_ADDR")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">날짜</td><td width=""500""> "&Now()&"</td></tr></table>"
' Injection 의심내용 메일로 전달
Call objXML_Email(발신자 메일 주소 임의로 입력,관리자 이메일 주소,"SQL 오류가 발생 되었습니다.",MainCont)
'-----파일 저장
objXML.documentElement.appendChild(objXMLv.cloneNode(True))
objXML.save(server.MapPath(xml_file_name))
'-----객체 해제
Set objXMLv = Nothing
Set objXML = Nothing
End Function
'------ 메일 발송 함수. SMTP 가 설정되어 있어야 함.
Function objXML_Email(FromMail,ToMail,strTitle,MainCont)
sch = "http://schemas.microsoft.com/cdo/configuration/"
Set cdoConfig = CreateObject("CDO.Configuration")
With cdoConfig.Fields
.Item(sch & "sendusing") = 1 'cdoSendUsingPort 1=내부, 2=외부
.Item(sch & "smtpserverport") = 25 'SMTP Port
.Item(sch & "smtpserver") = "localhost" 'Mail Server Address or Domain or "localhost"
.update
End With
Set cdoMessage = CreateObject("CDO.Message")
With cdoMessage
Set .Configuration = cdoConfig
.From = FromMail '보내는이 메일주소
.To = ToMail '받는이 메일주소
.Subject = strTitle '메일제목
.HtmlBody = MainCont '메일형식지정 : HtmlBody or TextBody
.Send
End With
Set cdoMessage = Nothing
Set cdoConfig = Nothing
End Function
Function f_injection(query_string)
f_injection = false
injection_filter_arr = split(injection_filter,"|")
injection_filter_cnt = Ubound(injection_filter_arr)
for injection_j = 0 to injection_filter_cnt
if InStr(1,query_string,injection_filter_arr(injection_j),1) > 0 Then
f_injection = true
' 오류 메시지 후 페이지 로딩을 중단 하려면 아래의 주석을 제거 합니다.
' Response.Write "특수문자 또는 명령어는 서버에 전달할 수 없습니다. (필터링된 문자 : <font color=blue>"& injection_filter_arr(injection_j) &"</font>)<br>"
Call objXML_Log(injection_filter_arr(injection_j),query_string)
' Response.End
exit for
end if
next
End function
'post체크
For each injection_item in REQUEST.FORM
For i=1 to REQUEST.FORM(injection_item).Count
If REQUEST.FORM(injection_item)(i) <> "" Then
If f_injection(REQUEST.FORM(injection_item)(i)) = true then
post_check = true
exit for
End if
End if
Next
Next
'get체크
inj_qs = Request.ServerVariables("QUERY_STRING")
If inj_qs <> "" Then
get_check = f_injection(unescape(inj_qs))
End if
if post_check = true or get_check = true then
Response.End
End if
%>
http://blog.daum.net/_blog/BlogView.do?blogid=0KYRA&articleno=6787162
위의 홈페이지에서 해당 소스를 받아서 SQL Injection 의심사례 발생시 메일로 전달되게 하였습니다.
매번 XML 페이지를 보기도 뭣하고 해서리..
또 다른 방법으로는 XML 파싱 부분을 좀 수정 해서 RSS 구독설정 해 놓는것도 좋은 방법이 될거라 생각 됩니다.
<%
' ===========================
' injection 처리
' ===========================
' SQL Injection 필터 정의 ( www.krcert.or.kr 및 기타 참조 )
injection_filter = ""
injection_filter = injection_filter & "having|syscomments|xp_displayqueuemesgs|xp_printstatements|table|raiserror|xp_dsinfo|xp_peekqueue|--|"
injection_filter = injection_filter & "shutdown|exec|xp_mergelineages|xp_proxiedmetadata|select|kill|xp_|xp_readpkfromqueue|"
injection_filter = injection_filter & "xp_displayparamstmt|insert|declare|sp_|xp_readpkfromvarbin|xp_availablemedia|update|openrowset|"
injection_filter = injection_filter & "xp_cmdshell|xp_repl_encrypt|xp_enumdsn|delete|opendatasource|xp_reg|xp_resetqueue|xp_filelist|"
injection_filter = injection_filter & "drop|pwdencrypt|xp_servicecontrol|xp_sqlinventory|sp_password|alter|msdasql|xp_setsqlsecurity|"
injection_filter = injection_filter & "xp_unpackcab|sp_adduser|create|sqloledb|xp_readerrorlog|xp_sprintf|sp_addextendedproc|inner|join|"
injection_filter = injection_filter & "char(|xp_controlqueueservice|xp_displayparamstmt|sp_dropextendedproc|from|syslogins|"
injection_filter = injection_filter & "xp_createprivatequeue|xp_enumresult|sp_add_job|where|sysxlogins|xp_decodequeuecommand|xp_showcolv|"
injection_filter = injection_filter & "sp_start_job|union|sysdatabases|xp_deleteprivatequeue|xp_updatecolvbm|sp_delete_alert|group|by|"
injection_filter = injection_filter & "sysobjects|xp_deletequeue|xp_execresultset|sp_msrepl_startup|"
injection_filter = injection_filter & "%20and%20|isMember|administrators /add|xp_dirtree|--|2=2|3=3|a=a|b=b|c=c|…|;’|’;"
Function objXML_Log(BAD_WORD,QUERY_STRING)
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
'IP,시간등 XML파일로 기록한다.
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
On Error Resume Next
Set objXML = server.CreateObject("Microsoft.XMLDOM")
objXML.async = False
'-----파일명칭- 결과 XML 화일이 저장될 공간을 지정 ( 권한 확인 필요 )
xml_file_name = "/FileHome/injection.xml"
'-----파일이 존재하는지 체크
blnFileExist = objXML.load(server.MapPath(xml_file_name))
If blnFileExist = False Then
objXML.appendChild(objXML.createProcessingInstruction("xml","version=""1.0"""))
objXML.appendChild(objXML.createElement("IP_LOGS"))
intID = 1
Else
intID = objXML.documentElement.childNodes(objXML.documentElement.childNodes.length - 1).childNodes(0).text + 1
End If
'-----프로세스 시작
Set objXMLv = objXML.createElement("IP_LOG")
objXMLv.appendChild(objXML.createElement("ID"))
objXMLv.appendChild(objXML.createElement("USER_ID"))
objXMLv.appendChild(objXML.createElement("BAD_WORD"))
objXMLv.appendChild(objXML.createElement("QUERY_STRING"))
objXMLv.appendChild(objXML.createElement("HTTP_REFERER"))
objXMLv.appendChild(objXML.createElement("REMOTE_ADDR"))
objXMLv.appendChild(objXML.createElement("LOCAL_ADDR"))
objXMLv.appendChild(objXML.createElement("DATE"))
objXMLv.childNodes(0).text = intID
objXMLv.childNodes(1).text = session("USER_ID") ' 회원 가입 페이지라면 회원 아이디도 넣을 수 있도록..
objXMLv.childNodes(2).text = BAD_WORD
objXMLv.childNodes(3).text = Request.ServerVariables("SCRIPT_NAME") &"?"& QUERY_STRING
objXMLv.childNodes(4).text = Request.ServerVariables("HTTP_REFERER")
objXMLv.childNodes(5).text = Request.ServerVariables("REMOTE_ADDR")
objXMLv.childNodes(6).text = Request.ServerVariables("LOCAL_ADDR")
objXMLv.childNodes(7).text = Now()
' 오류내용을 보고할 메일 본문 작성
MainCont = ""
MainCont = MainCont & "<table width=""700"" cellspacing=""0"" cellpadding=""0"" border=""1"" style=""font-size:9pt;"">"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">번호</td><td width=""500""> "&intID&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">아이디</td><td width=""500""> "&session("USER_ID")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">금지단어</td><td width=""500""> "&BAD_WORD&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">넘어온 값</td><td width=""500""> "&Request.ServerVariables("SCRIPT_NAME") &"?"& QUERY_STRING
objXMLv.childNodes(4).text = Request.ServerVariables("HTTP_REFERER")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">이전 페이지</td><td width=""500""> "&Request.ServerVariables("HTTP_REFERER")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">클라이언트 아이피</td><td width=""500""> "&Request.ServerVariables("REMOTE_ADDR")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">서버 아이피</td><td width=""500""> "&Request.ServerVariables("LOCAL_ADDR")&"</td></tr>"
MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">날짜</td><td width=""500""> "&Now()&"</td></tr></table>"
' Injection 의심내용 메일로 전달
Call objXML_Email(발신자 메일 주소 임의로 입력,관리자 이메일 주소,"SQL 오류가 발생 되었습니다.",MainCont)
'-----파일 저장
objXML.documentElement.appendChild(objXMLv.cloneNode(True))
objXML.save(server.MapPath(xml_file_name))
'-----객체 해제
Set objXMLv = Nothing
Set objXML = Nothing
End Function
'------ 메일 발송 함수. SMTP 가 설정되어 있어야 함.
Function objXML_Email(FromMail,ToMail,strTitle,MainCont)
sch = "http://schemas.microsoft.com/cdo/configuration/"
Set cdoConfig = CreateObject("CDO.Configuration")
With cdoConfig.Fields
.Item(sch & "sendusing") = 1 'cdoSendUsingPort 1=내부, 2=외부
.Item(sch & "smtpserverport") = 25 'SMTP Port
.Item(sch & "smtpserver") = "localhost" 'Mail Server Address or Domain or "localhost"
.update
End With
Set cdoMessage = CreateObject("CDO.Message")
With cdoMessage
Set .Configuration = cdoConfig
.From = FromMail '보내는이 메일주소
.To = ToMail '받는이 메일주소
.Subject = strTitle '메일제목
.HtmlBody = MainCont '메일형식지정 : HtmlBody or TextBody
.Send
End With
Set cdoMessage = Nothing
Set cdoConfig = Nothing
End Function
Function f_injection(query_string)
f_injection = false
injection_filter_arr = split(injection_filter,"|")
injection_filter_cnt = Ubound(injection_filter_arr)
for injection_j = 0 to injection_filter_cnt
if InStr(1,query_string,injection_filter_arr(injection_j),1) > 0 Then
f_injection = true
' 오류 메시지 후 페이지 로딩을 중단 하려면 아래의 주석을 제거 합니다.
' Response.Write "특수문자 또는 명령어는 서버에 전달할 수 없습니다. (필터링된 문자 : <font color=blue>"& injection_filter_arr(injection_j) &"</font>)<br>"
Call objXML_Log(injection_filter_arr(injection_j),query_string)
' Response.End
exit for
end if
next
End function
'post체크
For each injection_item in REQUEST.FORM
For i=1 to REQUEST.FORM(injection_item).Count
If REQUEST.FORM(injection_item)(i) <> "" Then
If f_injection(REQUEST.FORM(injection_item)(i)) = true then
post_check = true
exit for
End if
End if
Next
Next
'get체크
inj_qs = Request.ServerVariables("QUERY_STRING")
If inj_qs <> "" Then
get_check = f_injection(unescape(inj_qs))
End if
if post_check = true or get_check = true then
Response.End
End if
%>