CTF : SQLi 2

DATE : 2023/12/03

이번에도 숨겨진 flag를 찾아보자!

사이트를 들어가면 이번에 아무런 정보도 나와 있지 않다.

다만 검색 창에 placeholder 값으로 "normaltic"이 들어가 있으니 왠지 입력해봐야 할 거 같았다.

normaltic이라 입력해보면 위와 같이 id, level, rank point, info 값이 출력된다.

이 결과를 바탕으로 추측해보면

SELECT * FROM member WHERE id='___'

사용자가 입력한 값을 id 자리에 넣어서 Query를 실행하는 거라 생각해볼 수 있다.

그럼 SQL injection이 가능한 지 확인해봐야 한다.

이번에도 항등원인 조건을 넣어봤더니 결과는 문제 없이 잘 나온다!

그렇다면 과연 서버에 준비되어 있는 구문은 몇 개의 COLUMN을 꺼내오는 지 확인해보자.

UNION으로 COLUMN이 한 개인 경우

COLUMN이 두 개인 경우.. 쭉 늘려 나가면

6까지 입력했을 때 비로소 결과가 나오는 걸 확인할 수 있을 것이다.

이 말은 즉, UNION 앞에 작성된 SELECT문이 6개의 COLUMN을 반환한다는 의미이다.

그렇다면 여기서, 과연 몇 번째 COLUMN 값이 어느 위치에 출력 되고 있는 것인지 알아야 한다.

화면에 보여지는 값은 총 4개인데 이런 저런 값을 입력하다 보니

(1) 검색 바에 입력한 내용이 그대로 ID에 출력

(2) level, rank point 값은 안 변함

(3) SQL이 문제 없이 실행된 경우에만 INFO에 My name in normaltic 문구가 나온다는 걸

확인할 수 있었다.

그래서, 그나마 화면을 통해 Query의 결과를 얻고자 한다면 INFO 자리를

이용해야 할 거 같다는 판단을 내렸다.

그.렇.다.면 우리가 알아내야 하는 건 :

(1) info가 몇 번째 column인가!

(2) UNION으로 주입한 값은 어떻게 확인할 수 있는가! 이다.

위에서 우리는 UNION으로 1,2,3,4,5,6을 선행된 SELECT문 결과에 이어 붙였는데

주입한 값(1,2,3,4,5,6)은 어디서도 찾아볼 수가 없었다.

화면에 나오지 않으니 UNION이 제대로 실행이 되지 않은 것일까?? 정답은 NO!

이 사이트는 아마도 결과가 여러 개일 때, 맨 첫 번째 ROW만 보여주고 있는 듯하다.

그렇다면 DolDol 계정만 출력에서 알아본 LIMIT를 활용해볼 수 있지 않을까?

normaltic' union select 1,2,3,4,5,6 limit 1,1 #

UNION을 사용해 두 SELECT문의 결과를 합친 경우, UNION 뒤에 작성한 Query의 값은

두 번째 ROW로 들어가게 될 것이다.

따라서 LIMIT 1,1로 두 번째 ROW의 값이 나오도록 Query를 작성해보면

INFO 부분의 값이 6으로 변경된 걸 확인할 수 있다.

즉 INFO에 들어가는 값은 6번째 column 값이며, 우리가 UNION으로 주입한 값을 확인하기 위해서는

LIMIT로 두 번째 ROW를 가져올 필요가 있다는 걸 확인한 것!

그럼 이제 DB, TABLE, COLUMN 정보를 얻어낼 수 있게 된다!

ID 부분에 보이는 값을 입력한 경우, database() 결과를 6번째 COLUMN에 넣고

LIMIT 1,1로 두 번째 ROW 값을 가져와 보면

결과는 database : sqli_5

DB 이름을 알아냈으니 안에 어떤 table이 들어있는 지 확인해보자.

information_schema.tables에서 table_name을 조회해보면 결과는! flag_honey

바-로flag_honey table에는 어떤 column이 있을 지 확인해보자.

information_schema.columns 에게 column_name을 알려 달라했더니 flag라는 column이 있다고 한다.

그럼 이제 flag_honey table에 있는 flag column 값을 추출해보자.

Query를 딱 주입했더니! 결과는 kkkkkkkk_Not Here! (kill.. kill.. kill...)

아무래도 flag가 어디엔 없는 거 같다.

그럼 미련 없이 재끼고(?) 다른 테이블을 탐색하러 가보자.

normaltic' union select 1,1,1,1,1,table_name from information_schema.tables where table_schema='sqli_5' limit 1,1 #

위에서는 sqli_5 DB 안에 있는 테이블을 알려줘! 라고 한 뒤,

결과의 첫 번째 테이블 이름만 확인했음을 알아야 한다. (LIMIT 1,1)

그래서 이번엔 다른 테이블도 있는 지 확인해보려 한다.

DB sqli_5에 들어있는 테이블은 flag_honey에 이어 game_user

secret으로 확인되었다.

바-로 secret table로 달려가 column name을 확인하고 ( flag_honey와 동일하게 flag column 존재)

첫 번째 값부터 확인해보았다. 첫 번째 ROW에는 FLAG가 없는 모양이다.

LIMIT 값을 바꾸고 두 번째 ROW를 확인해보면! 마침내 FLAG를 확인할 수 있다!!

이렇게 해서 두 번째 SQLi 문제도 해결이다. 🎉

이번 문제는 Query의 결과가 화면에 보여지지만, 일부 column으로 그 범위가 제한되다 보니

그에 맞게 SQL도 조금씩 바꿔줄 필요가 있었다.

조금은 번거로울 수 있었겠지만, 이번 문제를 통해서 데이터를 추출 과정에 확실히 익숙해졌고

그 과정에서 상황에 맞게 조금씩 Query를 변경할 줄 아는! 능력이 조금은 생긴 거 같다! 🤗

Last updated