# CTF : SQLi 2

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FpmKoYOzsTaj6MZq8jTSt%2Fimage.png?alt=media&#x26;token=4f1587bc-5291-479e-8d0c-9e27093bc5ab" alt=""><figcaption></figcaption></figure>

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

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FOTIM0zo7Am5V5GdPjKIP%2Fimage.png?alt=media&#x26;token=c6760064-7dd5-4b32-b575-b1b8e4d4afcb" alt=""><figcaption></figcaption></figure>

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

이 결과를 바탕으로 추측해보면&#x20;

```
SELECT * FROM member WHERE id='___'
```

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

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2Fg6xHovmMk1c2af4soJ4z%2Fimage.png?alt=media&#x26;token=e213a710-3085-4ca1-84c2-6ee503447920" alt=""><figcaption></figcaption></figure>

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

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FADwWcXz3bXdAZJoivRMi%2Fimage.png?alt=media&#x26;token=a4393554-d3a2-4752-aa04-30ed07d4a4c3" alt=""><figcaption></figcaption></figure>

UNION으로 COLUMN이 한 개인 경우

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FEgm9koicHwUf8DcaeI56%2Fimage.png?alt=media&#x26;token=4d620b2e-42e9-4cad-882e-0c72dcb9a83e" alt=""><figcaption></figcaption></figure>

COLUMN이 두 개인 경우.. 쭉 늘려 나가면&#x20;

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FNtmrODqPVPZO7X2YlHxd%2Fimage.png?alt=media&#x26;token=b18f6fda-e2eb-4fbe-9ec5-30d3809ebda5" alt=""><figcaption></figcaption></figure>

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

이 말은 즉, UNION 앞에 작성된 SELECT문이 <mark style="background-color:blue;">**6개의 COLUMN**</mark>을 반환한다는 의미이다.&#x20;

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

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

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

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

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

확인할 수 있었다.&#x20;

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

이용해야 할 거 같다는 판단을 내렸다.&#x20;

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

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

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

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

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

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

이 사이트는 아마도 <mark style="background-color:blue;">**결과가 여러 개일 때, 맨 첫 번째 ROW만**</mark> 보여주고 있는 듯하다.&#x20;

그렇다면 [doldol](https://hh-rys-log.gitbook.io/normaltic/6-11-29/assignment/doldol "mention")에서 알아본 [<mark style="color:blue;">**LIMIT**</mark>](https://hh-rys-log.gitbook.io/normaltic/v/6-11-29/)를 활용해볼 수 있지 않을까?

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

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

두 번째 ROW로 들어가게 될 것이다.&#x20;

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FkCc6rXElxTSKN3WJSy22%2Fimage.png?alt=media&#x26;token=d00dda7c-dca4-4b38-a891-1e5d737b8933" alt=""><figcaption></figcaption></figure>

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

즉 INFO에 들어가는 값은 <mark style="background-color:blue;">**6번째 column**</mark> 값이며, 우리가 UNION으로 주입한 값을 확인하기 위해서는&#x20;

<mark style="background-color:blue;">**LIMIT**</mark>로 두 번째 ROW를 가져올 필요가 있다는 걸 확인한 것!

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FgN1lstdlNsOvRHFmh08A%2Fimage.png?alt=media&#x26;token=e42aa453-38e2-4b7f-8e50-ef0302c8b177" alt=""><figcaption></figcaption></figure>

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

LIMIT 1,1로 두 번째 ROW 값을 가져와 보면&#x20;

결과는 <mark style="color:blue;">**database : sqli\_5**</mark>

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FgL5rEPH1c4rsHCsC21h0%2Fimage.png?alt=media&#x26;token=408feb01-9dc2-44f6-acf0-987c016b14e8" alt=""><figcaption></figcaption></figure>

information\_schema.tables에서 table\_name을 조회해보면 결과는! <mark style="color:blue;">**flag\_honey**</mark>

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2F90VHW3mevoVjzQXSdr6w%2Fimage.png?alt=media&#x26;token=76a08778-f31d-427f-9e82-b83a83633b94" alt=""><figcaption></figcaption></figure>

information\_schema.columns 에게 column\_name을 알려 달라했더니 <mark style="color:blue;">**flag**</mark>라는 column이 있다고 한다.

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FtzPkSSR0AyxgiCpF4ppu%2Fimage.png?alt=media&#x26;token=c9c9ea8f-6cc5-44f9-b8b6-5016fdb98fb7" alt=""><figcaption></figcaption></figure>

Query를 딱 주입했더니! 결과는 **kkkkkkkk\_Not Here! (kill.. kill.. kill...)**

아무래도 flag가 어디엔 없는 거 같다.&#x20;

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

```
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 안에 있는 테이블을 알려줘! 라고 한 뒤,&#x20;

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

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FoUY8Ns3L1beE5W6L0pem%2Fimage.png?alt=media&#x26;token=7a0f6e91-c136-4931-a71e-632ba7572a54" alt=""><figcaption></figcaption></figure>

DB sqli\_5에 들어있는 테이블은 flag\_honey에 이어 <mark style="color:blue;">**game\_user**</mark>와&#x20;

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2F0CgnqHeMncvmMYiKnGla%2Fimage.png?alt=media&#x26;token=8477fd4f-90bf-478d-a9b8-39e55f3ec2df" alt=""><figcaption></figcaption></figure>

<mark style="color:blue;">**secret**</mark>으로 확인되었다.&#x20;

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2F8pmwuUwoUDFeHYHC1seH%2Fimage.png?alt=media&#x26;token=03ec95a1-39dd-405d-89df-3efd9ff97115" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://2312435576-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOzogQ2aBWvTUNLb9AodP%2Fuploads%2FWcmFx192yBWXkfiZaBL3%2Fimage.png?alt=media&#x26;token=272bd3ab-7960-4c06-9f63-6879876d5b51" alt=""><figcaption></figcaption></figure>

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

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

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

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

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

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