ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • |Lord Of Bufferoverflow| #11 skeleton - golem
    Wargame Site/BOF 2019. 6. 16. 11:49

     

     

     

     

    자, 이 문제에서는 vampire > skeleton 에서 사용했던 방법은 통하지 않는다.

    memset 의 범위에 들어가기 때문이다.

     

    결국, RET 만으로 overflow 를 이용해야한다.

     

     

     

     

    RET 하나만으로 어떻게 문제를 해결할 수 있을까?

    우선 라이브러리에 접근하는 방법에 대한 이해가 필요했다.

     

     


     

    오늘도 어김없이 구글링을 하다가 좋은 정리글을 발견했다.  출처 : https://jiafei427.wordpress.com/2016/11/15/

     

    - 정적 라이브러리는 .a 로 끝나는 파일이며, 빌드 시에 실행 파일에 포함된다.

    - 공유 라이브러리는 .so 로 끝나는 파일이며, 여러 프로그램에서 공유된다. 디스크 공간이 절약되며 메모리 사용량 또한 절약된다.

    - 공유 라이브러리는 파일이 실행되는 시점에서 프로그램 링커 로더가 /lib, /usr/lib, LD_LIBRARY_PATH 등에서 해당 파일의 존재유무를 확인하고 이를 사용하게된다.

    - 동적 적재 라이브러리는 해당 라이브러리에 포함된 함수가 사용되는 시점에 불려와 사용된다.

     

    공유 라이브러리를 컴파일하기 위해서는 fPIC 라는 옵션이 필요하다. 리눅스에서는 일반 공유 라이브러리를 동적으로 적재가 가능해서 공유 라이브러리와 동적 적재 라이브러리가 같다고 할 수 있다.

     


     

     

    정적 라이브러리 보다 동적 라이브러리가 우선된다는 점을 챙기고, 하단의 코드를 작성했다. 

     

    출처 : https://turtle1000.tistory.com/46

     

    fPIC 옵션으로 동적 라이브러리 파일을 만들었다.

    그 뒤, LD_PRELOAD 환경변수에 printf.so 공유 라이브러리를 설정해주었다.

     

     

     

    다음과 같이 printf.so 의 printf 함수가 실행되는 것을 볼 수 있다.

    하지만, golem 을 실행하면 다음과 같이 printf.so 가 예상대로 작동되지 않은 것을 확인할 수 있다.

     

    여러차례 질의를 통해 알아낸 결과,

    Setuid 가 걸린 파일에 모두 똑같이 적용된다면 so injection 공격에 취약해진다.

    따라서 LD_PRELOAD 의 적용범위가 한정되어있다는 점을 알게되었다.

    그.렇.다.면

    LD_PRELOAD 를 Setuid 가 없는 부분을 이용해서 적용해주면 적용이 된다는 말이된다.

     

     

    결국 우리가 필요한건 패스워드(my-pass) 이기 때문에, setuid 가 걸려있지 않은 my-pass 를 가지고 활용할 수 있지 않을까?

     

    우선, my-pass 의 원리를 파악하는게 중요하다

     

     

     

     

    UID, EUID

     

    우선, UID 는 현재 프로세스에서 실제 유저의 ID 값을 말한다.

    EUID 는 setuid 와 같은 권한이 변경되었을 때 바뀌는 값으로, 실행되는 동안 설정되는 일시적인 ID 값을 말한다.

     

    my-pass 는 이러한 EUID 를 가져와서 해당 Password 를 가져오는 방식을 사용한다.

    이때 사용되는 함수가 geteuid 라는 함수이다. 반환값은 int 형이며, euid 를 불러와 해당 euid 의 패스워드를 출력해주는 방식이다.

     

    다음과 같은 코드를 작성해준 뒤, 위와 같은 방법으로 fPIC 컴파일을 하며, 환경변수 설정을 해준다.

     

    우선, darkelf 계정으로 테스트해보았다.

     

    gcc my-pass.c -shared -fPIC -o my-pass

    export LD_PRELOAD = my-pass

     

    짜잔! geteuid 를 읽어와서 해당 계정의 비밀번호를 가져오는 것을 알 수 있었다!!!!!

    모든 계정을 가져올 수 있게되는 것이다.

     

    지금까지의 풀이를 통해 단계가 올라갈수록 계정의 UID 가 1씩 증가하는 걸 알 수 있었다.

    따라서 golem 은 511 이며, 위의 return 값을 511 로 바꿔주면, golem 의 패스워드를 알 수 있다.

     

     

    댓글

Designed by Tistory.