해당 문제는 Article 메뉴에서 게시글 조회 시 File Download 취약점이 터진다.
http://web2.tendollar.kr:10101/?p=view&f=../../../../../var/www/html/index.php
해당 취약점을 통해 소스코드를 쭉 보다보면 login 시 admin으로 로그인 가능한 조건이 나온다.
loginchk.php
<?php
$id = $_POST['id'];
$pw = $_POST['pw'];
if($id!='' && $pw!=''){
if(preg_match('/kou/i',$id)){
die('<script>alert("Don\'t login at kou.");history.back();</script>');
}
if(login($id,$pw)){
$_SESSION['is_login'] = 1;
$_SESSION['admin'] = 1;
echo '<script>alert("Login Success.");location.href="?p=home";</script>';
}else{
echo '<script>alert("Login Fail.");history.back();</script>';
}
}else{
echo '<script>alert("Login Fail.");history.back();</script>';
}
?>
위 코드를 보면 id가 kou인 계정으로 로그인을 해야하는데 정규식으로 필터하는 구문을 보면 일반적인 방법으로는 절대 로그인이 불가능해 보인다.
이를 우회할 방법이 있나 보기위해 login함수를 찾아보면 모든 php 파일 내 login 함수가 없다. 이럴 경우 해당 함수가 so 파일 내에 존재할 것이기 때문에 php.ini를 내 로드하는 모듈을 보면 되지만, view.php 소스코드 내 해당 모듈 경로가 존재하길래 이 경로로 해당 파일을 다운받아 ida로 까봤다.
view.php
<?php
$f = $_GET['f'];
if(!is_array($f) && !is_null($f) && $f!=''){
// $f = str_replace('../','', $f);
if($f[strlen($f)-1]=='/'){
$f[strlen($f)-1]=='\0';
}
if(preg_match('/Secret Data/i',$f) && $_SESSION['admin']==1){
?>
<div class="description">
<p style="font-size: 20px;">Secret Data</p>
<br><br>
<pre><?php loadFile($f); ?></pre>
</div>
<?php
}else if(preg_match('/Secret Data/i',$f) && $_SESSION['admin']==0){
?>
<div class="description">
<p style="font-size: 20px;">Secret Data</p>
<br><br>
<pre>You're not admin.</pre>
</div>
<?php
}else{
?>
<div class="description">
<p style="font-size: 20px;"><?=$f;?></p>
<br><br>
<?php
if(preg_match('/kou\.so/i',$f)){
echo 'Okay Here<br><div>'.file_get_contents('/var/www/modules/kou.so').'</div>';
}
?>
<pre><?php loadFile($f); ?></pre>
</div>
<?php
}
}else{
echo '<script>alert("No found.");history.back();</script>';
}
?>
so path = /var/www/modules/kou.so
해당 모듈내에서 로그인 시 호출되는 함수들을 보면 다음과 같다.
대충 보면 일단 id값이 kou인지 체크하고 pw와 같은 경우 1e0c6abede7ff7184c3cefe606f9760a 값과 동일하면 admin으로 로그인이 가능한 구조이다. 일반적으로 id=kou&pw=1e0c6abede7ff7184c3cefe606f9760a 넣게되면 통과할 수가 없는 구조인데 zlf_login 함수에서 파라미터로 넘어온 id,pw값을 지역변수에 담을 때 strcpy를 사용하고 있고 id변수가 pw보다 먼저 선언되어 있어 pw 값을 통해 id 변수를 덮을 수 있다.
pw를 1e0c6abede7ff7184c3cefe606f9760akou이런식으로 넣어주면 id 지역 변수 값이 kou로 덮여서 위의 모든 조건을 통과하여 admin으로 로그인이 가능해진다.
id=1&pw=1e0c6abede7ff7184c3cefe606f9760akou
admin 로그인 후 Article 메뉴의 Secret Data를 확인해보면 플래그가 나온다.
'CTF > Writeup' 카테고리의 다른 글
hwp CTF 2018 unpack0r (0) | 2018.12.10 |
---|---|
TenDollar CTF 2018 Cat-Proxy (0) | 2018.12.02 |
TenDollar CTF 2018 XSS (0) | 2018.12.01 |
TenDollar CTF 2018 LinkedList - 1,2 (0) | 2018.12.01 |
TenDollar CTF 2018 Ninja (0) | 2018.12.01 |