본문 바로가기

4-5. 2022-2 심화 스터디/버그 헌팅과 모의 해킹

[2022.11.19] 원격코드실행(RCE)

원격 코드 실행(RCE)

 

원격 코드 실행이란?

취약한 애플리케이션이 사용자의 입력 값을 검증하지 않고 사용할 때 발생한다.

 

원격 코드 실행 공격 종류

1. 셀 명령 실행

-> 애플리케이션이 검증되지 않은 셸 명령을 실행할 때 RCE 수행 가능

 

  • www.<example>.com이 ping 명령으로 원격 서버를 사용할 수 있는지 확인이 가능하 도록 설계되어있다고 가정
  • www.<example>.com?domain=google.com 을 입력하면 사이트의 PHP코드는 다음과 같이 처리.

  • domain 변수가 검증되지 않고 그대로 shell_exec에 전달되어 명령을 실행.
  • 매개변수의 값으로 ‘google.com’을 줬을 때 우리가 예상하는 결과는 아래와 같지만, 리눅스 명령어에서는 세미콜론(;) 입력 시 여러 명령어를 동시에 실행할 수 있음.

  • google.com;id’와 같이 값을 전달한다면 두 명령어가 동시에 실행되며 아래의 1과 2가 동시에 출력됨. 이런 경우 사용자의 권한에 따라 RCE 취약점의 심각성이 결정됨.

  • 이에 대한 해결 방법으로 PHP에서 escapeshellcmd 함수를 이용해 문자열을 검증 해 필터링하는 방법이 있음
  • 특수 문자를 검증할 수 있지만, 커맨드라인 플래그를 전달할 수 없게 된다는 단점이 있음.

 

 

2. 취약한 애플리케이션이 사용하는 프로그래밍 언어로 함수 실행

 

일반적인 경우
  • www.<example>.com에서 사용자가 www.<example>.com?id=1&action=view와 같은 URL을 통해 블로그 게시물을 읽고 편집할 수 있는 경우.
  •  php 함수 중 하나인 call_user_func는 첫 번재 파라미터를 호출하고 나머지 파라미터를 해당 함수의 인수로 전달함. 아래의 경우, 애플리케이션은 action 변수에 할당된 view 함수를 호출하고, 1을 함수에 전달하며 첫 번째 게시글을 보여주게 됨.

 

해당 내용을 악의적으로 사용하는 경우
  • www.<example>.com에서 악의적인 사용자가 www.<example>.com?id=1&action=view와 같은 URL을 통해 블로그 게시물을 읽고 편집할 수 있는 경우.
  •  만약 악의적인 사용자에 의해 id의 값으로 ‘/etc/passwd’, action의 값으로 ‘file_get_contents’를 전달했다면, 해당 ‘file_get_contents’ 함수가 호출되며 지정된 파일 ‘/etc/passwd’를 읽게 됨.

  • 해당 내용은 다음과 같은 내용을 출력

  • 해당 취약점을 이용해 애플리케이션의 소스코드를 읽거나 데이터베이스 접속 정보를 얻을 수도 있으며, 이와 같은 문자열이 전혀 필터링되지 않을 경우 shell_exec, exec, system 등의 함수로 쉘 명령어를 실행할 수도 있음.

3. 원격 코드 실행 권한 상승을 위한 전략

->  해당 취약점의 파급력은 서버 사용자의 권한이나 공격자가 다른 버그를 이용해 사용자의 권한을 높일 수 있는지에 따라 잘라지는데, 이를 보통 로컬 권한 상승(Local Previlege Escalation, LPE)이라고 함.

 

  • 커널 취약점을 공격하는 경우
    공격자의 권한을 상승시키거나, 기존엔 할 수 없었던 다른 작업을 할 수 있음
  • 루트로 실행되는 서비스를 이용해 공격하는 경우
    관리자를 공격해 루트로 실행되는 서비스에 액세스 가능, 모든 명령을 루트 권한으로 실행 가능
  • SUID를 가진 프로그램을 대상으로 공격하는 경우
    지정된 사용자의 권한으로 파일 실행
    SUID는 보안을 강화하기 위한 것이지만 잘못 구성할 경 우 루트로 실행되는 서비스와 유사한 상위 권한 명령 실행 가능해짐
잠재적인 RCE 취약점을 찾을 수 있는 패턴이 존재함
  • 사이트가 시스템 명령을 실행하는 경우
  • 파라미터를 통해 서버에서 기능을 수행할 수 있는 경우: 이는 파라미터에 시스템 명령을 실행시킬 수 있는 세미콜론, 백틱 등과 같은 특수문자로 테스트할 수 있음
  • 제한되지 않은 파일 업로드가 가능한 경우: php 웹사이트에서 파일을 업로드할 수 있고, 유형을 제한하지 않으면 php를 업로드할 수 있게 되며 코드를 실행할 수도 있음

사례 

 

Polyvore ImageMagick
  • ImageMagick: 이미지를 처리하고 다양한 프로그래밍 언어를 지원하는 그래픽 라이브러리
  • ImageMagick의 다양한 방식의 입력을 제대로 검증하지 않았는데, 특히 외부 라이브러리를 사용해 파일을 처리하는 위임 기능이 가장 위험했음. 입력에 정상적인 url이 아닌, 세미콜론 및 파이프라인과 함께 입력하면 추가 명령을 실행할 수 있음.

  • 위임 기능은 외부 파일 참조를 허용하는 이미지 파일 유형에 의해 익스플로잇 될 수 있음.
  • ImageMagick는 이미지를 처리할 때 확장자가 아닌 파일 내용을 기준으로 처리함. 따라서 애플리케이션에서 파일의 확장자를 문자열 끝을 통해 필터링해도, ImageMagick에선 올바르게 해당 파일을 인식함.
  • 예를 들어, 애플리케이션에서 jpg만 허용한다고 가정하면 공격자는 mvgjpg로 우회해 애플리케이션을 통과하고, ImageMagick는 이를 올바르게 mvg로 인식해 버림.
  • 사데기 푸어(공격자)가 작성한 SVG 익스플로잇 파일은 아래와 같음.

  • 이 파일은 1번의 행에 악성 입력을 포함하는데, 백틱을 통해 페이로드가 즉시 실행됨. 이로 인해 id의 실행 결과가 cURL의 인풋으로 전달됨. cURL 라이브러리는 원격 HTTP 요청을 하며 예제의 8080번 포트에서 대기 중인 사데기 푸어의 IP로 접속하고, 이 출력이 처리 없이 POST 본문으로 cURL에 전달됨. 마지막으로 ‘>/dev/null’을 통해 아무것도 출력하지 않음으로써 공격 흔적을 발견하기 어려움.
  • 실제로 사데기 푸어가 페이로드를 테스트한 결과, 사이트에서 파일로 이미지를 업로드한 이후 아래와 같은 POST 요청을 수신했음. 이 요청에는 id 명령의 결과가 포함되어 있었으며, 이는 공격이 성공적으로 이루어졌음을 의미함.

 

SSH를 통한 RCE
  • 랜드리는 사용자가 템플리 파일을 업데이트 할 수 있는 API를 발견
  • 경로:
 /api/i/services/site/write-configuration. json?path=/config/sites/test/pa ge/rcst / config.xrnl
  • post body 를 통해 XML를 받아들임.
  • 어디서나 파일을 쓸 수 있고 애플리케이션이 파일로 해석하게 할 수 있다면 서버에서 원하는 코드를 실행하고 시스템 콜을 호출할 수 있었기 때문에 해당 공격을 위한 테스트 시작
  • 경로:
../../../ ../../../../../../../../../tmp/test.txt  

(*../ 기호는 현재 경로의 상위 디렉터리를 나타냄)

  • 이것을 통해 랜드리는 원하는 폴더에 파일을 쓸 수 있었음
  • 파일을 업로드 할 수 있었지만 애플리케이션 구성으로 인해 코드를 실행할 수 없었기 때문에 SSH를 이용.
    (*ssh는 공개 ssh 키를 사용해 사용자를 인증)

 

  1. 원격 호스트의 .ssh/authorized_keys 디렉터리에 있는 공개키를 확인하고 보안 연결을 통해 커맨드라인에 로그인 함
  2. 해당 디렉터리에 자신의 ssh 공개키를 업로드
  3. 사이트에서는 공격자를 서버 ssh 액세스와 전체 권한을 가진 루트 사용자로 인증

 

결과

  • ../../../ ../../../../../../../../../root/.ssh/authorized_keys에 파일을 쓸 수 있게 됨
  • ssh 서버 로그인에 성공했고, id 명령을 실행해 noot uid=0( root ) gid=0( root ) groups=0( root )를 확인

시사점

  • 광범위한 프로그램에서 버그를 찾을 때 서브도메인을 나열해 테스트 영역을 식별하는 것이 중요
facebooksearch.algolia.com의 Algolia RCE

 

<배경>

Michiel Prins의 Gitrob 도구를 이용한 algolia.com 조사

  • Gitrob: 초기 깃허브 저장소, 개인이나 조직을 이용해 연관된 사람들로부터 찾을 수 있 는 모든 저장소를 수집하고 그 안에서 비밀번호, DB 등과 같은 키워드를 기반으로 민감 한 파일을 찾음.

이때 Algolia가 공개 저장소에 루비 온 레일즈 secret_key_base 값을 공개적으로 커밋한 것 발견.
*결코 공개되면 안됨.

  • secret_key_base: 레일즈가 서명된 쿠키를 조작하는 것을 막을 수 있도록 도와주는 것. 
  • 루비 온 레일즈: Ruby를 사용하는 웹 프레임워크.
    • 쿠키에 서명함. → 서명을 확인하여 쿠키의 시작부분 변경 여부 확인.
    • 쿠키와 서명을 이용해 웹 사이트 세션을 관리
      • 세션: 클라이언트 별로 서버에 저장되는 정보
        • 웹 클라이어느가 서버측에 요청을 보내면, 서버는 클라이언트를 식별하는 session id를 생성
        • 서버는 session id를 이용해서 key와 value 를 이용한 저장소의 httpSession을 실행
        • 서버는 session id를 저장하고 있는 쿠키를 생성하여 클라이언트에 접속
        • 클라이언트는 서버측에 요청을 보낼 때, session id를 가지고 있는 쿠키를 전송
        • 서버는 쿠키에 있는 session id 를 이용해서 그 전 요청에서 생성한 httpSession을 찾고 사용
  • 레일즈 쿠키 저장소
    • 쿠키에 저장된 정보를 직렬화하고 역직렬화함.
      • 직렬화: 객체나 데이터를 전송하고 재구성할 수 있는 상태로 변환
        → 레일즈는 세션 정보를 쿠키에 저장하고 사용자가 다음 HTTP를 요청할 때 쿠키를 다시 읽을 수 있는 형식으로 변환
  • 레일즈의 비밀 값을 알면 유효한 직렬화 객체를 만들어 쿠키를 통해 사이트로 전송
  • 프린스는 메타스플로잇 프레임워크에 포함된 레일즈 시크릿 역직렬화 익스플로잇을 사 용해서 해당 취약점을 RCE로 연결.
    • 메타스플로잇 프레임워크: 역직렬화가 성공하면 리버스셸 호출

⇒ 유효한 직렬화 객체를 만들어 공개된 secret_key_base를 통해 쿠키를 통해 전송 (악성 쿠 키 전송) → 역직렬화할 때 서버의 셸을 획득.