N1CTF 2021

Write for fun!!!!

signin

<?php 
//flag is /flag
$path=$_POST['path'];
$time=(isset($_GET['time'])) ? urldecode(date(file_get_contents('php://input'))) : date("Y/m/d H:i:s");
$name="/var/www/tmp/".time().rand().'.txt';
$black="f|ht|ba|z|ro|;|,|=|c|g|da|_";
$blist=explode("|",$black);
foreach($blist as $b){
    if(strpos($path,$b) !== false){
        die('111');
    }
}
if(file_put_contents($name, $time)){
	echo "<pre class='language-html'><code class='language-html'>logpath:$name</code></pre>";
}
$check=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($path));
if(is_file($check)){
	echo "<pre class='language-html'><code class='language-html'>".file_get_contents($check)."</code></pre>";
}

Ý tưởng của bài này chúng ta sẽ thực hiện truyền giá trị /flag vào một file. Vì tên file được tạo này sẽ luôn luôn được in ra nên dù tên file là random thì chúng ta vẫn luôn biết được tên file mà chúng ta truyền vào là bao nhiêu.

Nhưng làm sao để truyền được flag vào mới là vấn đề, cũng chính là vấn đề cần phải giải quyết ở bài này.

Vì bài này dùng hàm date() lên giá trị được lấy từ file_get_contents('php://input')

file_get_contents('php://input') sẽ lấy dữ liệu raw post.

Vậy nên nếu giá trị chúng ta sử dụng là /flag thì kết quả sẽ luôn luôn bị thay đổi:

Do kiến thức gà mờ nên mình thật sự mất khá nhiều thời gian để suy nghĩ chỗ này, hoặc do mình quá lười đọc kĩ docs. Người ta đã chỉ rõ ràng cách để escaping characters trong hàm date():

Theo hướng dẫn chúng ta chỉ cần truyền \/\f\l\a\g qua POST method là có thể lấy có được chuỗi /flag:

File chứa chuỗi "/flag" hiện đang ở /var/www/tmp/1637652075892996841.txt. Giờ chúng ta chỉ cần truyền parameter path vào sử dụng giá trị trên và gửi request dưới method POST thì sẽ có thể read được /flag:

Last updated