'SQL 인젝션'에 해당되는 글 1건

  1. 2008.10.17 SQL Injection 공격 확인 및 메일 발송 스크립트

SQL Injection 공격 확인 및 메일 발송 스크립트

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"">&nbsp;"&intID&"</td></tr>"
  MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">아이디</td><td width=""500"">&nbsp;"&session("USER_ID")&"</td></tr>"
  MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">금지단어</td><td width=""500"">&nbsp;"&BAD_WORD&"</td></tr>"
  MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">넘어온 값</td><td width=""500"">&nbsp;"&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"">&nbsp;"&Request.ServerVariables("HTTP_REFERER")&"</td></tr>"
  MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">클라이언트 아이피</td><td width=""500"">&nbsp;"&Request.ServerVariables("REMOTE_ADDR")&"</td></tr>"
  MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">서버 아이피</td><td width=""500"">&nbsp;"&Request.ServerVariables("LOCAL_ADDR")&"</td></tr>"
  MainCont = MainCont & "<tr bgcolor=""#FFFFFF""><td height=""26"" width=""200"" align=""center"">날짜</td><td width=""500"">&nbsp;"&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


 %>
prev 1 next