'sql'에 해당되는 글 1건

  1. 2015.10.13 SQL Injection 확인 팁

반응형


어느순간 홈페이지를 보면 이상한 문자들이 잔뜩 보여지며 홈페이지가 정상 동작을 하지 않음을 발견하게 됩니다.

DB에서 쿼리를 날려보면 이런 문자열이 잔뜩 들어가있습니다.


SQL Injection공격에 당한 상황입니다.


SQL Injection에 당하는 이유는 주로 웹프로그램 개발을 안일한 생각으로 동적쿼리를 사용하여 개발하였기 때문입니다.

동적쿼리라 함은 쿼리를 날릴때 스토어드 프로시저나 정적쿼리(Parameter)가 아닌 문자열을 연결하여 쿼리를 완성하는 쉽지만 위험한 개발 방식으로 다음과 같습니다.

strSqr = "select * from member_tbl where userid = '" & testid & "'"



SQL Injection 해킹(사실 해킹 수준급도 아님)을 받게 되면 첫째로 복구할 데이터를 확인해야 합니다.

그러기 위해선 어떤 테이블이 해킹 당했는지 알아내야 하므로 이때 사용되는 쿼리입니다.

단순 확인과 함께 임시 테이블에 넣어 보다 편리하게 확인이 가능합니다.


먼저 테이블부터 생성합니다.

CREATE TABLE [dbo].[totallog_table](

[db_name] [varchar](50) NOT NULL,

[table_name] [varchar](1000) NOT NULL,

[field_name] [varchar](1000) NOT NULL,

[log_data] [text] NULL

) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


그럼 아래와 같은 테이블이 생성됩니다.


log_data만 널 허용필드입니다.



다음은 해킹된 테이블을 찾는 스크립트입니다.

sysobject와 syscolumns테이블을 이용해 해당 데이터베이스에 존재하는 모든 필드들을 검사하는 스크릅트입니다.

dbname만 자신이 사용중인 db의 이름으로 바꿔주면 됩니다.


DECLARE @TABLENAME varchar(255), @COLUMNNAME 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 @TABLENAME, @COLUMNNAME;

WHILE (@@FETCH_STATUS = 0) BEGIN


print 'insert into dbo.INJECTIONLOG_TABLE (db_name, table_name, column_name, log_data) values (''dbname'', ''dbname.'+ @TABLENAME +''', '''+ @COLUMNNAME +''', (select top 1 ['+@COLUMNNAME+'] from '+'dbname.dbo.'+@TABLENAME+' where ['+@COLUMNNAME+'] like ''%<div style="display"%''))'


FETCH NEXT FROM Table_Cursor INTO @TABLENAME, @COLUMNNAME;

END;


CLOSE Table_Cursor;

DEALLOCATE Table_Cursor;




쿼리분석기에서 실행하고 아래 쿼리를 날리면 훼손된 레코드들을 보유한 테이블의 필드들을 확인할 수 있습니다.
select * from TotalLog_Tbl where log_data is not null



예방법
1. 쿼리는 동적 쿼리가 아닌 정적 쿼리를 사용하거나 스토어드 프로시저를 사용해야 함 (개발할때 조금 힘들어짐)
2. 웹방화벽 설치 (돈나감)
3. ASP기준 웹페이지 상단에 아래 함수를 공통 파일로 만들어 include (개편함)
For Each strRequest In Request.QueryString
  For nCnt = 1 To Request.QueryString(strRequest).Count
 Call isHack(Request.QueryString(strRequest)(nCnt))
  Next
Next


For Each strRequest In Request.Form
  For nCnt = 1 To Request.Form(strRequest).Count
 Call isHack(Request.Form(strRequest)(nCnt))
  Next
Next


Function isHack(byVal strValue)
Dim strHackDefine, strResult, nCnt 
strHackDefine = Split("insert,update,select,delete,drop,create,--, or , and ,char,script,iframe,',having,embed,object,cast,sysdatabases", ",")
strResult = trim(Lcase(strValue))
For nCnt = LBound(strHackDefine) To UBound(strHackDefine)
If InStr(strResult, strHackDefine(nCnt)) > 0 Then
If strHackDefine(nCnt) = "'" Then
strValue = Replace(strValue, "'", "`")
Elseif strResult = "kr-aed-ilovecharacter" Then

Else
Response.End
End If
End if
Next
End Function 
4. 1+2+3


반응형
Posted by Hippalus
,