File Vulnerability Advanced for linux


소스코드 분석

def file():

  • /file 경로로 GET 요청을 보내면 ./files/{path} 경로에 있는 데이터가 출력됩니다.
  • 별도의 입력 값 검증은 존재하지 않기 때문에 이 부분을 활용하면 공개된 경로에 있는 파일 출력이 가능합니다.

  • /etc/passwd 경로로 요청을 보내면 서버로부터 해당 파일 정보가 출력됨을 확인했습니다.
    • root, nginx, user 등의 유저가 존재하네요.


def admin():

  • admin() 함수가 호출되면, 데코레이터에 의해 key_required 함수가 호출됩니다.
  • 이 때, key_required 함수에서는 /admin 경로로 GET 요청이 들어올 때 API_KEY 파라미터 값을 apikey 변수에 저장하는데요. 이 값을 운영체제에 저장된 환경변수(API_KEY) 값과 비교해서 동일한 경우에만 /admin 경로로 접속할 수 있도록 하고 있습니다.
    • 따라서, /admin 경로로 접근하기 위해서는 OS 환경변수에 저장된 API_KEY 값을 알아내야 합니다.
  • 대상 호스트의 운영체제는 리눅스/유닉스 환경으로 보이는데요. /etc/passwd 파일로부터 “root, nginx, user” 등의 계정정보를 획득한 상태입니다. 보통 환경변수는 유저의 홈 디렉토리의 “.bash_history” 파일에 저장된 경우가 많기 때문에 이를 확인해 보아야 합니다.

  • 아래 경로로 요청을 보내 “user” 계정의 .bash_history 파일에 저장된 API_KEY 값을 획득했습니다.

  • /admin 경로 접근 시 “API_KEY” 값을 포함하면 더 이상 “Access Denied!” 메시지가 발생하지 않습니다.

  • 다시 admin() 함수 내부를 살펴보니 subprocess.getoutput(cmd) 코드가 있습니다.
    • 위 함수는 cmd 인자 값이 쉘에서 실행된 결과를 반환한다고 합니다.

  • cmd 파라미터에 임의의 명령어를 추가한 후 서버로 전달하면 RCE가 가능합니다.

  • 플래그 파일은 루트 폴더 경로에서 확인되었는데요. 실행 파일로 확인 됐습니다.

strings 바이너리로 flag 파일에 저장된 플래그 문자열을 추출했습니다. ()



번외 1.

  • 리눅스 환경에서 현재 프로세스에서 사용중인 환경변수 값은 /proc/self/environ 경로에 저장된다고 합니다.
  • 운이 좋게 사용자 계정의 .bash_history 파일에 환경변수 값이 저장되어 있었지만, 히스토리가 삭제된 경우에는 위 파일에 저장된 값을 확인해 보아야 할 것 같네요. (REFERENCE 2.)

번외 2.

  • 루트 경로까지 접근해서 파일들을 확인할 수 있었던 이유는 확보한 계정이 root 이기 때문입니다.

🐛.. 🐛.. 🐛..


REFERENCE

  1. https://docs.python.org/3/library/subprocess.html
  2. https://medium.com/@zoningxtr/from-lfi-to-rce-via-proc-self-environ-shell-access-via-headers-1f22e18c65db