Mass SQL Injection 피해 DB 복구 방안

가. 복구 방법

1) 데이터베이스 백업본을 사용한 복구

침해사고가 발생하기 이전의 백업본이 있다면 그 백업본을 이용하여 복구하는 것이 가장 빠를 것이다. 그러나 실시간으로 갱신되는 데이터베이스의 특성 상 핫 백업과 같이 백업도 실시간으로 이루어지고 있다면 다행이지만, 대부분의 경우 백 업된 시점이후의 자료 유실이 불가피 하다.

그러므로 백업본으로 복구할 때에는 반드시 자료 유실에 대한 충분한 검토가 필요하다. 예를 들어, 일일 백업이 새벽 3시에 이루어지고 있던 데이터베이스라면 침해사고가 오후 1시에 발생한 경우 10시간 동안 갱신된 자료의 유실에 대해 고려해야 한다.

2) 컬럼단위 복구 방법

지금까지 발견된 악성코드 삽입 사고는 아무리 많은 레코드에 악성코드가 삽입 됐더라도 특정 악성코드 유포지(URI)를 담고 있었기 때문에 “UPDATE” SQL 명령문을 사용해도 충분히 복구 할 수 있다. 그러나 실제 적용 전에는 반드시 시험을 거친 후 적용해야 한다.

Update [테이블명] set [컬럼명]=replace([컬럼명],
          '[삭제하고자하는 악성코드 문자열]','')
예> Update freebbs set title=replace(title,
          '<script src=hxxp://url/b.js></script>','')

만약 저장되어 있던 자료가 ntext, nvarchar와 같이 유니코드를 지원하는 등 별도의 인코딩방식으로 저장되어 있는 경우, 자료 형 변환을 통해 삽입된 악성코드를 좀 더 수월하게 찾아내고 제거할 수 있다.

다만, 자료 형 변환에서 사용하는 임시변수의 크기를 충분히 지정해야 추가적인 자료 유실을 예방 할 수 있다.

Update [테이블명] set [컬럼명] = replace(cast([컬럼명] as varchar(8000)),
          '[삭제하고자하는 악성코드 문자열]', '')

예> Update freebbs Set contents = replace(cast(contents as
      varchar(8000)), '<script src=hxxp://url/b.js></script>', '')

참고로 MS SQL 2005이상에서는 varchar(max)를 사용 할 수 있으며, 이외에도 다양한 자료 형에 대해 고려해야 하므로, SQL서버에서 사용하는 큰 값 자료 형 문서를 참고하고, “UPDATETEXT”문을 사용하는 것도 함께 고려한다.


3) 일괄복구 스크립트 사용

컬럼단위의 복구 스크립트는 복구대상 컬럼이 많은 경우, 적지 않은 시간이 필요하기 때문에 악성코드 삭제를 더 빠르게 수행하고자 한다면 일괄복구 스크립트를 참조하여 적용한다.

-- Mass SQL Injection 피해 DB 일괄 복구 스크립트, 한국마이크로소프트 제공
-- 사고의 특성 상 DB 자료값들이 varchar 또는 nvarchar 등으로 형변환 되거나 제한된 임시 공간에 저장되는 과정이 있어 자료의 유실이나 손상이 발생합니다.
-- 그러므로, 본 복구 스크립트는 이러한 전형적인 Mass SQL Injection 피해를 입은 DB의 복구에만 사용 하시기 바랍니다.
-- 본 복구 스크립트는 DB관리자와 충분히 검토하신 후 적용하셔야 하며, 이에 대한 책임은 전적으로 사용자에게 있습니다.
-- Mass SQL Injection에 대한 자료는 KrCERT/CC 홈페이지(www.KrCERT.or.kr) 보안공지 또는 기술문서를 참조하시기 바랍니다. 2008. 11 KrCERT/CC, webcheck@krcert.or.kr

declare @tab varchar(255), @col varchar(255), @owner varchar(255),
@type int

declare table_cursor cursor for select so.name, sc.name, sc.xtype, su.name from sysobjects so inner join syscolumns sc on so.id = sc.id inner join sysusers su on so.uid = su.uid where so.xtype='u' and (sc.xtype=99 or sc.xtype=35 or sc.xtype=231 or sc.xtype=167)
open table_cursor fetch next from table_cursor into @tab, @col, @type, @owner while(@@fetch_status=0)
begin

-- varchar, text 또는 nvarchar, ntext 일 경우 MS-SQL 2005 이상의 환경이라면 varchar(max) 또는 nvarchar(max) 으로 변경하여 사용
-- 악성코드 부분을 실제 삭제하려는 악성코드로 수정
    (악성코드 예: <script src=hxxp:// malcode.tld></script>)

    if (@type = 35 or @type = 167)
        exec('update ' + @owner + '.[' + @tab + '] set [' + @col + ']
        = replace(convert(varchar(8000), [' + @col + ']), '<악성코드>','''')')
    else
        exec('update ' + @owner + '.[' + @tab + '] set [' + @col + ']
        = replace(convert(nvarchar(4000), [' + @col + ']), '<악성코드>','''')')

        print '[' + @col + ']' + ' column of ' + @owner + '.' + @tab + 'has been updated.'
        fetch next from table_cursor into @tab, @col, @type, @owner
    end

close table_cursor
deallocate table_cursor

위의 일괄 복구 스크립트도 복구 대상 데이터베이스에 직접 적용하기 전에 문제가 없는지 반드시 테스트 환경에서 확인을 거쳐야 한다.


일괄 복구 스크립트에서도 강제 형 변환을 사용했기 때문에 공격 스크립트처럼 데이터의 유실이 발생 할 소지가 있다. 하지만 앞서 분석한 형태의 공격 스크립트 였다면 이미 임시변수의 크기에 맞게 데이터가 조정된 상태이므로 추가적인 데이터의 유실은 없을 것이다.

Posted by n3015m
:
BLOG main image
'네오이즘'의 보안LAB 블로그입니다........... n3oism@gmail.com by n3015m

카테고리

분류 전체보기 (228)
[ HappyDevTool ] (29)
[ HappyToolRelease ] (4)
[Book] (6)
[ Security Studies ] (0)
- CII (2)
- BigData (2)
- Web Hacking (10)
- SQL Injection (25)
- Mobile Security (9)
- Network (6)
- OperatingSystem (4)
- Malware & Reversing (4)
- Phishing (5)
- Compliance (0)
- Programming (13)
- Tools (13)
- IoT (6)
- etc (21)
[Pentration Testing] (3)
[OS X] (4)
[ Security Trends ] (16)
[ Fixing Guideline ] (7)
My Way, My Life (34)
About Me (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :