# 1. save_the_world

```python
from flask import Flask, send_file, request, render_template
import os
from urllib.parse import unquote
import secrets
import config
from middleware import PathTraversalMiddleware
app = Flask(__name__,template_folder="templates")
app.wsgi_app = PathTraversalMiddleware(app.wsgi_app)
@app.route('/')
def hello_world():
return render_template('index.html')
@app.route('/upload', methods=['POST','GET'])
def handleUpload():
if request.method == 'POST':
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
extension = file.filename.split('.')[-1]
if extension not in config.ALLOW_EXTENSION:
return 'Invalid file extension'
new_name = '%s.%s' % (secrets.token_hex(16), extension)
if file:
file.save('%s/%s' % (config.UPLOAD_FOLDER,new_name))
return render_template('upload.html', success_message='File uploaded successfully: %s' % new_name)
else:
return render_template('upload.html')
@app.route('/viewfile/<filepath>')
def handleFile(filepath):
target_file = os.path.abspath('%s/%s' % (config.UPLOAD_FOLDER,unquote(filepath)))
if os.path.isfile(target_file):
return send_file(target_file)
else:
return '', 404
if __name__ == '__main__':
app.run(host="0.0.0.0",port=5000)
```
## Phân tích
App này có 2 chức năng chính đó là `upload file` và `viewfile`
Do ở challenge này đã bị `filter whitelist` rồi nên ta sẽ không thể upload file to rce được
```python
#config.py
UPLOAD_FOLDER = "/app/uploads"
ALLOW_EXTENSION = ["jpg","png","gif"]
```
Next sang hàm tiếp theo
```python
@app.route('/viewfile/<filepath>')
def handleFile(filepath):
target_file = os.path.abspath('%s/%s' % (config.UPLOAD_FOLDER,unquote(filepath)))
if os.path.isfile(target_file):
return send_file(target_file)
else:
return '', 404
```
Ở đây có xuất hiện hàm `send_file` dẫn đến `Path Traversal`

## Exploit
Ở đây có 1 class chống path travelsal được import ở `app.py`
```python
class PathTraversalMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
# Extract the path from the request
path = environ.get('PATH_INFO', '')
# Check if the path contains ".."
if ".." in path:
# Block the request if it contains ".."
return self.block_request(start_response)
# If the path is safe, proceed with the request
return self.app(environ, start_response)
def block_request(self, start_response):
# Return a 403 Forbidden response
start_response('403 Forbidden', [('Content-Type', 'text/plain')])
return [b'Forbidden: Path traversal not allowed.']
```
Bypass được bằng url decode
Nhưng bị dính hàm `unquote(filepath)`
```bash
$ cat test.py
from urllib.parse import unquote
filepath = '%2e%2e%2f%2e%2e%2f%2e%2e%2f'
print(unquote(filepath))
$ python3 test.py
../../../
```
Hàm này sẽ url decode ra nên khi ta truyền thằng trên url như kia sẽ bị dính `..` trong path
-> ez bypass bằng `double encode`

Flag được lưu ở biến env



# 2. WarmupPHP
Bài này có 3 flag với mỗi vuln 1 flag

## Flag1

Có thể thấy đây là [smarty ssti](https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#smarty-php)
Tưởng dễ ăn nhưng lại chỉ sử dụng được hàm `{$smarty.version}`

Bế tắc nên mình chuyển sang dirsearch và có được source
```
$ curl http://103.162.14.116:10007/robots.txt
User-agent: *
Disallow: /?source
```
```php
<?php
include('flagl.php');
include('flag2.php');
include_once('/app/vendor/autoload.php');
define(FLAG1', $flag1);
if (!isset($_GET['name'])) {
header (Location: /?name=guest');
}
if (isset($_GET['source'])) {
show_source(__FILE__);
}
$smarty = new Smarty();
$policy = new Smarty_Security ($smarty);
if(str_starts_with ($_GET['name'], 'kcsc')) {
$policy->php_functions = $allow_php_func;
}
$smarty->enableSecurity ($policy);
$smarty->display('string: KCSC hello fen, '.$_GET['name']);
```
ez flag1

## Flag2
### Phân tích
```php
<?php
function debug($input) {
if (str_contains($input, '/') || str_contains($input, '.')) {
die('invalid filepath');
}
if (strlen(readlink($input)) >= 128) {
echo file_get_contents($input);
}
}
$allow_php_func = [
'debug',
'symlink'
];
?>
```
Nhìn lại file source có:
```php
if(str_starts_with ($_GET['name'], 'kcsc')) {
$policy->php_functions = $allow_php_func;
}
```
khi chuỗi bắt đầu bằng `kcsc` sẽ kích hoạt `$policy` cho phép sử dụng 2 hàm `debug` và `symlink`
```
$allow_php_func = [
'debug',
'symlink'
];
```
Đầu tiền với hàm `debug`
```php
function debug($input) {
if (str_contains($input, '/') || str_contains($input, '.')) {
die('invalid filepath');
}
if (strlen(readlink($input)) >= 128) {
echo file_get_contents($input);
}
}
```
Đầu tiên hàm này sẽ kiểm tra xem symlink có chứa `.` hay `/` không thì sẽ `die()`
Thứ 2, sẽ kiểm tra độ dài của symlink khi được link lúc đầu nếu lớn hơn 128 sẽ in ra file được link ấy
### Exploit
Luồng exploit sẽ như sau:
- Tạo 1 symlink có độ dài > 128 đến file `flag2.php` bằng hàm `symlink()`

- Đọc file bằng hàm `debug()`

#