EZ_command_injection

소스코드
app.py
- 주어진 소스코드 중 중요파일은 “app.py” 파일입니다.
- 사용자로부터
/ping?host={사용자 입력 값}경로로 GET 요청을 전달받으면, 서버는 아래 코드를 순차적으로 실행합니다.ipaddress.ip_address(host)값이 유효한 값이라면 24라인에서 실행되는 OS 명령어의 인자로 사용되고- 유효하지 않은 값이라면
ValueError예외 처리가 발생합니다.
- 서버 측에 공격자가 원하는 운영체제 명령어를 실행시키기 위해서는 “host” 파라미터에 악성 페이로드를 삽입해야 하는데요.
ipaddress.ip_address함수가 받아들일 수 없는 값이 인자로 전달되는 경우 반드시 예외 처리(ValueError)가 발생하기 때문에 이를 우회할 수 있는 방안을 찾아야 합니다.

- 먼저, 주어진 소스코드의
Dockerfile에는 서버에서 사용중인 파이썬 버전(3.10)이 노출되고 있었습니다.

-
파이썬 공식문서를 통해 파이썬 3.10 버전의 ipaddress 모듈 사용법을 확인해보았습니다.
-
ipaddress.ip_address(인자)는 인자로 전달된 IP 주소에 따라 IPv4/IPv6 객체를 반환한다고 합니다.

-
ipaddress.ip_address(address)의 반환 값(IPv6 객체)에 대해 다시 IPv6(address)의 인자 값을 검증하는데요. -
이 때 인자 값을
%scope_id로 표시되는 스코프 존 ID를 설정하는게 가능했습니다.- (ipaddress.ip_address(address) 이 때부터 인자 값에 ScopeID를 설정할 수 있었던 것입니다.)

- (ipaddress.ip_address(address) 이 때부터 인자 값에 ScopeID를 설정할 수 있었던 것입니다.)
- 위 정보를 토대로, 파이썬 3.10 버전에서 테스트를 진행해보겠습니다.
ipaddress.ip_address({사용자 입력 값})구조에서 사용자의 입력 값(host)을 아래와 같이 설정하면- 오류가 발생하지 않고 삽입된 문자열을 모두 정상적으로 인식하여 반환해주고 있습니다. (“ff02::5678%1;whoami”)
- Baaaaam. 오류가 발생하지 않으니 공격자가 이 구간에 악성 페이로드를 삽입할 수 있겠죠?

- Baaaaam. 오류가 발생하지 않으니 공격자가 이 구간에 악성 페이로드를 삽입할 수 있겠죠?
- 먼저, RCE 테스트를 위해
whoami명령어를 실행해봤는데요. 대상 호스트의 계정정보(root)를 확인할 수 있었습니다.

- 플래그는 앱 루트 디렉토리에 존재하므로 바로 출력해보면? 쨘! 하고 플래그가 출력됩니다. GG

번외
ipaddress.ip_address(host)에서host인자 값으로 “ff02::5678%1;whoami” 가 설정되었을 때 왜 오류가 발생하지 않는지 궁금했는데요.- 깃허브에서 Python 3.10 버전
ipaddress모듈을 살펴 보니, 인자 값을 검증하는 로직이 아래와 같이 설정되어 있었습니다.- 1892 라인을 보면
ip_str.partition('%')함수를 통해%문자를 기준으로 문자열을 나눠 튜플로 만들고 이 값을 각각 (addr, sep, scope_id) 에 할당하고 있었습니다. (따라서, % 뒤에 임의의 문자열(공격 페이로드)을 삽입해도 오류가 발생하지 않았던 것이죠.)

- 1892 라인을 보면
🐛.. 🐛.. 🐛..