Whitehat Contest - Pybox

Games/CTF 2013. 9. 23. 17:35

파이썬 샌드박싱기능을 제공하는 파이썬으로 만들어진 웹사이트가 주어진다. (PyBox)



Simulator 메뉴에 파이썬 스크립트를 입력하면 아래와 같은 메소드로 스크립트가 전달되어 실행되고 그 결과가 나타난다.


def myExec(data) :

    tmp = '/tmp/%s' % randStr(20)

    pid = os.fork()


    if pid == 0 :

        sys.stdout = open(tmp, 'wb')

        sys.stderr = sys.stdout

        

        print 'Running...'

        prctl.set_seccomp(True)

        try :

            exec data

        except :

            pass


        sys.stdout.flush()

        sys.exit(0)

    

    try :

        time.sleep(1.5)

        os.kill(pid, 9)

        time.sleep(0.5)

    except :

        pass


    data = readFile(tmp)


    try :

        os.remove(tmp)

    except :

        pass


    return data


입력 스크립트를 필터링 하지는 않지만 prctl 모듈의 set_seccomp 로 인해서 read, write 를 제외한 모든 시스템콜의 호출이 차단된다.


그러나 파이썬 reflection 기능을 이용해서 인터프리터 스택프레임을 뒤지다보면 웹애플리케이션을 돌리기위한 SessionManager

라는 객체를 발견할 수 있고, 그러한 타입의 'sm' 이라는 지역변수가 getframe(3) 의 f_locals 지역변수중에 존재한다.

이 객체는 클라이언트에 대한 세션을 처리하기 위한것으로 보이는데, 클라이언트 세션이 users 디렉토리 및의 해시값으로 된 파일로

존재하고, 해당 파일에 대한 file descriptor 를 세션객체가 내부적으로 open 해서 가지고 있다.


세션파일 내부에는 여러가지 클라이언트측 세션 정보들이 들어있는데, 이중에서 userdata 라는 변수의 값이 'MyScripts' 메뉴에서 출력될

파일의 리스팅을 할 디렉토리 경로를 나타내고 있었다.


따라서 추가적인 파일 open 은 할수없지만 SessionManager 가 이미 open 해놓은 세션파일에 read/write 를 할 수 있으므로

세션파일속의 디렉토리 경로를 변경하면 MyScripts 메뉴에서 리스팅할 파일 컨텐츠들을 임의의 디렉토리로 조작할 수 있다.


1. 상위 3번째 스택프레임객체를 sys._getframe(3) 으로 가져옴

2. 프레임 객체의 f_locals 속성을 통해서 지역변수들에 대한 dictionary 객체를 가져옴

3. dictionary 객체로부터 sm(SessionManager) 객체에 접근

4. sm 객체에서 fp 객체에 접근

5. fp 는 open 된 세션파일에 대한 파일객체. 이것을 임의로 read/write 하면됨


아래와 같은 스크립트를 통해서 세션파일을 덮어썻다



그랫더니 세션파일의 내용이 아래처럼 변했고



이제 이상태에서 My Scripts 메뉴에 들어가보면, 내가 지정한 경로의 파일들이 리스팅된다.



이제 key 파일을 클릭하면 PyBox 가 이것이 파이썬스크립트를 저장해놓았던 파일인줄알고 아래처럼 내용을 보여준다.



이 문제는 혼자 해결하지 못했고, '최재승' 군이 풀이법을 알려줬다.


아직 궁금한점은


1. PyBox 코드에서 prctl 부분을 아예 없애버리면 제한이 풀리는것이 아니라 아예 동작을 안하는데 원인불명.

2. 인터프리터 스택을 조사해서 얻은 file 객체에 대해서 read(100) 이런것은 잘 되는데, read() 를 호출하면 멈춰버림.

3. 다른 파이썬 exception 들은 catch 가 되는데 seek(0) 를 호출한다거나 특정한 행위들을 하면 프로세스가 아예 무반응임... 원인불명



'Games > CTF' 카테고리의 다른 글

Whitehat RSA Signing  (0) 2014.01.07
HDCON2013 final cft2  (10) 2013.10.31
Whitehat Contest - Pybox  (5) 2013.09.23
DEFCON 2013 penser writeup  (0) 2013.06.18
HDCON 2013 level5  (8) 2013.06.11
HDCON 2013 level4  (0) 2013.06.11
Posted by daehee87

댓글을 달아 주세요

  1. 2013.09.29 01:20  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • daehee87 2013.09.30 19:21 신고  댓글주소  수정/삭제

      안녕하세요~ 방문해주셔서 감사합니다
      reversing.kr 운영자님의 허락없이 모든 풀이를 공개할수는 없을것 같구요, 어떤 문제가 어떻게 막힌 상황인지 알려주시면 힌트를 드릴수는 있습니다

  2. 2013.10.01 11:59  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • daehee87 2013.10.02 18:27 신고  댓글주소  수정/삭제

      아, CRC는 상당히 어렵지만 재미있는 문제입니다 --; 일단 기본적으로 CRC 가 역연산이 된다는것을 이해하셔야 하구요. 문제는 input 8 바이트가 흩어져버리는 바람에 간단히 역연산이 안되는건데... 힌트는 4바이트씩 쪼개서 처리하면 현실시간 내에 brute forcing 이 가능해진다는 것입니다. 정방향 연산과 역방향 연산을 연결하는 divisor 값을 생각해보세요.

  3. 키흐 2016.01.25 17:50 신고  댓글주소  수정/삭제  댓글쓰기

    와 .. 윗댓글 힌트 감사합니다. 역연산, 연산 소스코드 다 짜고 도대체 어떻게 해야 하는가만 몇일째 고민했는데 조금만 알고리즘 쪽으로 생각하면 되었을것을;; 정말 감사합니다.