Zasfe
Zasfe's memory
Zasfe
전체 방문자
558,240
오늘
3
어제
22
  • 분류 전체보기 (143)
    • 이야기 (50)
    • 뜻알기 (1)
    • 컴퓨터 (91)

인기 글

  • 리눅스에서 오라클 실행하기
    2014.07.04
  • 이벤트로그에 10016 Distribute⋯
    2014.10.07
    이벤트로그에 10016 Distribute⋯
  • 신뢰할수 있는 사이트 등록하기
    2009.05.22
  • [ASP] Session.Timeout 최대값⋯
    2009.12.08
    [ASP] Session.Timeout 최대값⋯
  • CentOS 5.x 설치후 X Window 설⋯
    2014.06.24

최근 글

  • 워나크라이(WannaCry) 대란
    2017.05.15
  • 이벤트로그에 10016 Distribute⋯
    2014.10.07
    이벤트로그에 10016 Distribute⋯
  • 리눅스에서 오라클 실행하기
    2014.07.04
  • CentOS 5.x 설치후 X Window 설⋯
    2014.06.24
  • CentOS 4.x Yum repo 재설정 방법
    2014.06.20

태그

  • webknight 2.2
  • Function
  • ASP
  • 저장프로시저
  • VBScript
  • Autoit
  • 배치파일
  • webhacking
  • MSSQL2K
  • error
  • webknight
  • nslookup
  • backup
  • webknight2.2
  • Security
  • IIS
  • IIS7
  • rsync
  • web.config
  • cmd
  • webknight2.1
  • MSSQL
  • 생각
  • 캐슬
  • webshell
  • Castle
  • Microsoft Windows 2000 Scripting Guide
  • 보안
  • Skin
  • 홈페이지 보안 강화도구
hELLO · Designed By 정상우.
Zasfe

Zasfe's memory

컴퓨터

Mass SQL Injection 일괄 삭제하기 - VBScript

2008. 10. 31. 18:11

요즘 많은 분들이 MASS SQL Injection 으로 피해를 보고 있는것 같습니다. 필자도 물론 예외는 아니였습니다.
지금에야 '쿠키를 이용한 인젝션공격이였습니다' 라고 이야기를 하지만 얼마전까지만해도 스크립트가 추가된 구문을 볼때마다 필자가 관리하는 서버를 사용하는 분들에게 송구스러운 마음이 참 많았습니다.

예전부터 심심치 않게 SQL Injection 을 이용한 스크립트 삽입공격은 있었습니다.
쿼리스트링에 추가하여서 공격하는 수준이였기때문에 웹나이트(Webknight) 문법으로 전부 막아내는 쿼거(?)도 이루었던 적도 있습니다.

이렇게 자만하다 큰코다친겁니다.  제가 관리하는 몇개의 사이트가 스크립트가 추가되는 사례가 발견되더니 잊을만 하면 한번씩 스크립트가 추가되는 현상을 발견하게 되었고, 쇼핑몰같은 경우는 데이터베이스를 복구할수도 없는 그런 상황까지 겪게 되었습니다.

"목마른 사람이 우물을 판다"고 했던가요..
일단 삽입이 되도록 하는 구문을 분석하여서 이를 바탕으로 스크립트만 삭제하는 구문을 작성하려고 하였습니다. char, nchar, varchar, nvarchar 는 너무 쉽게 변경이 가능했지만 문제는 text, ntext 같은 대용량의 유니코드 형식의 데이터에서 스크립트를 삭제하는 부분이였습니다.

몇몇 다른 분들의 경우 text 타입을 varchar(8000) 으로 변환하고 이를 수정하는 방법을 선택하셨습니다.
이 방법도 좋은 방법입니다. 쿼리만으로 작업을 진행할수도 있고, 일단 SQL 쿼리를 구하기가 쉬웠습니다. ( SQL 쿼리를 공개해주신 분들 감사합니다.)

그래도 문제는 발생하였습니다. 문자열을 신문을 집어 넣은건지 상당히 큰 text 타입의 데이터를 만나버리고 말았던 것이였습니다.
결국 VBScript 를 이용해서 다시 작업을 하도록 변경하였습니다. (사실 SQL 쿼리 수정보다 VBScript가 더 쉽게 생각되었습니다.;)

이래서 탄생한 Replace_string_in_mssql.vbs 입니다.

' ***************************************************************************************
'  디비 변조데이터 복구 스크립트 
'  버 젼    : v1.0                                                                   
' ***************************************************************************************
Option Explicit
'On Error Resume Next

' 삭제할 자바스크립트 구문
' 다중입력이 가능하며, 다중입력시 | 로 입력하시기 바랍니다.
Const strReplace = "<script src=http://ojkqn.cn></script>|<script src=http://wefd4.cn>|" 
Const strDBServerIP = "127.0.0.1"    ' 접속할 데이터베이스 서버 IP
Const strSQLuser = "sa"                ' 접속할 데이터베이스 아이디
Const strSQLpass = "1230"              ' 접속할 데이터베이스 패스워드
Const strSQLBD = "pubs"                 ' 접속할 데이터베이스 이름

Dim CRLF, TAB :TAB  = CHR( 9 ):CRLF = CHR( 13 ) & CHR( 10 )
Dim AdCn,connectionstring,SQL,DBdata,arrDBData, arrDBData2

Dim SQL_Tables, SQL_Tables_Exists_Javascript, ColumnsArrDBdata, ColumnsTotal, TableArrDBdata, TableTotal, SQL_tmp
Dim i, j, db_table, db_column, db_xtype, db_type, db_owner, db_len
Dim TablecolumnCheck, SQL_Tables_Replace_Javascript
Dim KeyName, Key_code, Key_entry, arr_Replacetxt, Replacetxt

arr_Replacetxt = split(strReplace,"|")

SQL_Tables = "select o.name, c.name, c.xtype, type = (select t.name from systypes t where t.name <> 'sysname' and t.xtype=c.xtype ) , owner = user_name(uid) " & _
            " ,Len = (select  case when t.name in (N'nchar', N'nvarchar') then c.length/2 else c.length end from systypes t where t.name <> 'sysname' and t.xtype=c.xtype ) " & _
            " from dbo.syscolumns c " & _
            " Left Join (select name,id,uid from dbo.sysobjects where xtype='U' " & _
            " and (case when (OBJECTPROPERTY(id, N'IsMSShipped')=1) then 1 else OBJECTPROPERTY(id, N'IsSystemTable') end)=0 ) o " & _
            " on c.id=o.id where o.name is not null and c.xtype in (35, 99, 167, 175, 231, 239) " & _
            " order by o.name, c.name "

' 35  -- text
' 99  -- ntext
' 167 -- varchar
' 175 -- char
' 231 -- nvarchar
' 239 -- nchar

connectionstring = "Provider=SQLOLEDB.1;Data Source= "&strDBServerIP&";Initial Catalog="&strSQLBD&";user id = '"&strSQLuser&"';password='"&strSQLpass&"' "


SQL = SQL_Tables
Set AdCn = CreateObject("ADODB.Connection")
AdCn.open = connectionstring
set DBdata = AdCn.Execute(SQL)
IF Not DBdata.Eof then
  ColumnsArrDBdata = DBdata.GetRows()
  ColumnsTotal = UBound(ColumnsArrDBdata, 2)+1
else
  ColumnsTotal = 0
end if
DBdata.Close
Set DBdata = Nothing

wscript.echo "컬럼갯수 : "&ColumnsTotal
If ColumnsTotal>0 then
  For i=1 to ColumnsTotal
      db_table = ColumnsArrDBdata(0,i-1)
      db_column = ColumnsArrDBdata(1,i-1)
      db_xtype = ColumnsArrDBdata(2,i-1)
      db_type = ColumnsArrDBdata(3,i-1)
      db_owner = ColumnsArrDBdata(4,i-1)
      db_len = ColumnsArrDBdata(5,i-1)
      
      SQL = "select count(*) From ["&db_owner&"].["&db_table&"] where CHARINDEX('<script',"&db_column&") > 0 "

      set DBdata = AdCn.Execute(SQL)
      IF Not DBdata.Eof then
          arrDBData = DBdata.GetRows()
          TablecolumnCheck = arrDBData(0,0)
      else
          TablecolumnCheck = 0
      end if
      DBdata.Close
      Set DBdata = Nothing
      
      if TablecolumnCheck > 0 then
        If db_xtype <> 35 and db_xtype <> 99 then
          For each Replacetxt in arr_Replacetxt
            wscript.echo "["&db_owner&"].["&db_table&"] 에서 "&db_column&" 컬럼에 대한 "&Replacetxt&" 삭제중..."
            SQL = "Update ["&db_owner&"].["&db_table&"] Set "&db_column&" = replace("&db_column&",'"&Replacetxt&"','')"
            AdCn.Execute(SQL)
          Next
        Else
          SQL = "select name from syscolumns  where id in (select id from sysobjects where name = '"&db_table&"') "
          SQL = SQL&"and colid in (select sik.colid from sysindexkeys sik join sysobjects so on sik.id = so.id where sik.indid = 1 and so.name = '"&db_table&"')"
          set DBdata = AdCn.Execute(SQL)
          IF Not DBdata.Eof then
            arrDBData2 = DBdata.GetRows()
            KeyName = arrDBData2(0,0)
          else
            KeyName = ""
          end if
          DBdata.Close
          Set DBdata = Nothing

          If Len(KeyName) > 0 then
            SQL = "select "&KeyName&","&db_column&" From ["&db_owner&"].["&db_table&"] "
            set DBdata = AdCn.Execute(SQL)
            IF Not DBdata.Eof then
              TableArrDBdata = DBdata.GetRows()
              TableTotal = UBound(TableArrDBdata, 2)+1
            else
              TableTotal = 0
            end if
            DBdata.Close
            Set DBdata = Nothing

            If TableTotal > 0 then
              for j=1 to TableTotal
                Key_code = TableArrDBdata(0,j-1)
                Key_entry = TableArrDBdata(1,j-1)
                Key_entry = Replace(Key_entry,"'","''")
                For each Replacetxt in arr_Replacetxt
                  Key_entry = Replace(Key_entry,Replacetxt,"")
                Next
                wscript.echo "["&db_owner&"].["&db_table&"] 에서 "&db_column&" 컬럼에 대한 삭제중..."
                SQL = "update ["&db_owner&"].["&db_table&"] Set "&db_column&" = '"&Key_entry&"' where "&KeyName&"="&Key_code
                AdCn.Execute(SQL)
              Next
            End if
          End if
        End if
        
      End if
  next
Else
  wscript.echo "컬럼이 없습니다."
end if
      
AdCn.Close
set AdCn=Nothing


내용은 무척 간단합니다. 컬럼중에 text, ntext, varchar, char, nvarchar, nchar 에 해당하는 것들에 대해서 "<script" 라는 구문이 포함되어 있으면 삭제작업을 하는 것으로 text, ntext 타입에 대해서만 특별히 ado를 이용해서 처리하였습니다.

Replace_string_081117.vbs

PS) 덕분에 웹방화벽인 웹나이트(webknight) 버젼업그레이드와 룰셋의 추가 작업에 매진(?) 하는 기간이 되었습니다. 계속되고 있습니다.

수정1. 컬럼명이 [컬럼명] 과 같은형식의 컬럼도 처리하도록 수정.
수정2. 내용이 없는 항목에 대한 구문오류 우회토록 수정.

'컴퓨터' 카테고리의 다른 글

내 웹사이트가 있는 서버 관리자는 보안을 모른다?  (4) 2008.11.04
Filezilla Server 한글깨짐패치 사용하기  (2) 2008.11.04
Mass SQL Injection 일괄 삭제하기 - VBScript  (21) 2008.10.31
웹나이트가 2.2 로 업데이트 되었습니다.  (0) 2008.10.22
IIS 와 vbscript  (0) 2008.10.17
nslookup 의 사용 방법  (0) 2008.09.29
    '컴퓨터' 카테고리의 다른 글
    • 내 웹사이트가 있는 서버 관리자는 보안을 모른다?
    • Filezilla Server 한글깨짐패치 사용하기
    • 웹나이트가 2.2 로 업데이트 되었습니다.
    • IIS 와 vbscript
    Mass SQL Injection, sql injection, webknight
    Zasfe
    Zasfe
    느낌. 기억
    댓글쓰기
    1. 안광해
      2008.11.05 15:10
      공개해줘서 고마워요. 항상 수고하고 ^^
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2008.11.05 16:03
        도움이 되셨다니 다행이네요 잘지내고 계시죠.? ^^
        수정/삭제
    2. Favicon of http://www.hyungs.net BlogIcon 김도형
      2008.11.17 15:37
      역쉬~ 윈도우스페셜리스트~ ㅋ
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2008.11.18 09:18
        감사합니다만 글을 몽땅 퍼가시는건 좀 자제를..;;
        수정/삭제
    3. Favicon of http://ienfant.tistory.com BlogIcon ienfant
      2008.11.19 16:34
      ㅎㅎ 덕분에 업무처리 시간이 줄어들었습니다. 그런데! 엄청나게 많이 삽입된 경우는 뭐 어쩔수 없이 노가다..ㅋ
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2008.11.20 14:25
        도움이 되었다니 다행입니다.
        중복구문도 처리를 하도록 했는데 아직 몇가지 오류가 더 있는가보군요.
        오류내용을 알려주시면 바로 처리하여 드리도록 하겠습니다.
        수정/삭제
    4. Favicon of http://www.hyungs.net BlogIcon 김도형
      2008.12.05 23:24
      오늘 웹어플리케이션 보안 교육을 다녀왔는데..
      강사가 그러더군요. 백업만이 살길이다. ㅋㅋ
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2008.12.08 01:26
        막으려고 애쓰는게 먼저 아닐까요..;;
        수정/삭제
    5. 일지선생
      2008.12.15 17:45
      감사합니다.

      잘쓰겠습니다

      그런데 대용량 디비를 복구 하던중

      행 : 124
      문자 : 19
      varchar 값 '20031030001'을 변화하는 중 int 열이 오버플로되었습니다. 최대 정수 값을 초과했습니다.

      이런 오류가 나오는데 어떻게 수정하면 될까요?;;
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2008.12.16 09:07
        제가 올려드린것과 다른것인가요.?

        최신본인 081117자 파일로 해보시기 바랍니다.

        그래도 문제가 발생할경우, 오류가 나는 부분을 올려주시기바랍니다.
        수정/삭제
    6. 한지성
      2008.12.22 12:16
      이거 vbs인데 어떻게 실행하나요?
      ASP 웹페이지에서 돌려야하는건지.. 제가 VBS를 안돌려봐서요..
      허접한 질문 죄송합니다. ㅠㅠ

      그리고 혹시 char(8000) 으로 스크립트문 제거하는 SQL문 있으시면 좀 올려주시면 감사히 잘 사용하겠습니다.

      감사합니다.
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2008.12.22 16:22
        vbs 는 VBScript 라는 윈도우용 스크립트 파일입니다.
        사용하시는 방법은 커맨드라인창에 [ cscript Replace_string_in_mssql.vbs ] 이런 식으로 실행을 하시면 됩니다.

        Mass SQL Injection 복구 쿼리는 다음 사이트에도 예제가 있으니
        사용해보시기 바랍니다.

        http://twooks.tistory.com/21
        수정/삭제
    7. 한지성
      2008.12.24 13:59
      감사합니다. ^^
      수정/삭제댓글쓰기댓글보기
    8. Favicon of http://hi79.pe.kr BlogIcon 밥띵이
      2009.01.12 11:35
      용도는 SQL Injection 으로 올려주셨는데요,
      전 Text 필드 Update를 해야하는데(특정문구 제거), 제대로 되지 않아..
      zasfe님의 vbs에서 제가 원하는 문구 삭제하도록 변경하고 ^^; 돌렸습니다.

      감사합니다~
      수정/삭제댓글쓰기댓글보기
      1. zasfe
        2009.01.12 14:13
        도움이 되셨다니 다행입니다.

        저도 이걸 공개하기전에 사용하던 원본 스크립트의 용도가 Text 필드의 데이터 변경이였습니다.

        시간이 좀 걸리더라도(할줄씩 처리하기때문에) 확실하게 원본에서 원하는 작업만 가능하기때문에 이것만한것도 없더라구요 ^^
        수정/삭제
    9. Favicon of http://jaehun.org BlogIcon Jaehun
      2009.04.06 11:52
      트래백 다시 고쳤습니다. 확인 부탁드릴께요 ^^;
      수정/삭제댓글쓰기댓글보기
      1. Favicon of http://zasfe.com BlogIcon Zasfe
        2009.04.06 13:05
        지금보니 등록이 되어 있네요.
        방문해주셔서 감사합니다. ^^
        수정/삭제
    10. yunseok
      2009.05.26 22:35
      죄송한데...계속 어느부분에서만

      Replace_string_081117.vbs(69, 7) OLE DB Provider For SQL SERVER 시간제한이 만료되었습니다.

      라고 나오는데 왜그런걸까요??

      분명 서버에서 스크립트시간제한을 모두 (0)무한으로 설정했는데요...
      수정/삭제댓글쓰기댓글보기
      1. Favicon of http://zasfe.com BlogIcon Zasfe
        2009.05.27 08:50
        메시지 내용만 보면 지금 스크립트를 실행하는 PC에서 데이터베이스 서버로 연결이 안되거나, 데이터베이스의 로드율이 높아서 60초내에 접속이 불가능한 문제 같습니다.

        그리고 서버내의 스크립트시간제한은 서버내로 접속한 이후 쿼리에서 소요되는 시간을 나타내는 것이므로 지금같은 현상에는 적용되지 않습니다.


        원본 소스에서 다음 부분을 수정하시기 바랍니다.

        변경전
        Set AdCn = CreateObject("ADODB.Connection";)
        AdCn.open = connectionstring
        set DBdata = AdCn.Execute(SQL)

        변경후
        Set AdCn = CreateObject("ADODB.Connection";)
        AdCn.open = connectionstring
        AdCn.CommandTimeout = 600 ' 10분
        set DBdata = AdCn.Execute(SQL)
        수정/삭제
    11. marlboroguy
      2009.08.13 11:05
      검색엔진에서 타고 들어왔습니다.

      좋은 글 잘보고 갑니다.
      수정/삭제댓글쓰기댓글보기
      1. Zasfe
        2009.08.13 12:55
        감사합니다.
        수정/삭제
    다음 글
    Filezilla Server 한글깨짐패치 사용하기
    이전 글
    방귀의 특효약?
    • 이전
    • 1
    • ···
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • ···
    • 143
    • 다음

    티스토리툴바