[CTF][WP]4.29 友谊赛

Web

Rce

一百年没写web题了)
exec_shell没有回显则rce读flag到可见的地方

?cmd=cat /fla* >a.txt
/a.txt

flag game

js逆向题,F12可以看到

比较关键的是后面的内容

结合定义的u和d函数可以知道后面flag的判断标准是0-x位的子串的哈希匹配
由于我们已知flag开头为xujc{ 所以可以进行爆破

import hashlib
import itertools

checkers='''sha224 8 a99265
sha224 10 035052
sha256 12 c7c3c8
sha256 14 a9db92
sha256 16 6ae31d
sha256 18 bb1eaa
sha256 20 33f4bb
sha224 22 8ac593
sha256 24 cb5892
sha256 26 f380c2
sha224 28 b5fa69
sha224 30 b4f950
sha256 32 b1c3fc
sha224 34 bacfd2
sha256 36 40272c
sha256 38 16138c
sha224 40 31a24d
sha256 42 16138c''' # 从题目给出的js代码中提取处理之后的格式


checkers = checkers.strip().split("\n")
checkers = [i.split() for i in checkers]

def sha256(s):
    return hashlib.sha256(s.encode()).hexdigest()

def sha224(s):
    return hashlib.sha224(s.encode()).hexdigest()

def check_flag(initial_flag, hash_type, length, expected_hash):
    # 遍历所有可能的字符填充到指定长度
    possible = "0123456789abcdefghijklmnopqrstuvwxyz_/-`~:;[]'?.>,<+{@#!$%^&*()}" # 其中一个Rule提到没有大写字母,所以这里没有大写字母
    needed_length = length - len(initial_flag)
    # 找出所有可能的扩展字符组合
    for combination in itertools.product(possible, repeat=needed_length):
        print(f"trying {initial_flag + ''.join(combination)}") # 这里的print省略可以跑快很多(单纯喜欢看hz的flag一点一点暴露出来呢)
        candidate_flag = initial_flag + ''.join(combination)
        if hash_type == 'sha256' and sha256(candidate_flag)[:len(expected_hash)] == expected_hash:
            return candidate_flag
        elif hash_type == 'sha224' and sha224(candidate_flag)[:len(expected_hash)] == expected_hash:
            return candidate_flag
    return None  # 如果没有找到匹配的,返回None

flag = 'xujc{'
for i in checkers:
    # 将flag更新为新发现的匹配flag,如果找到的话
    # 如果长度足够了,就不再继续搜索
    if len(flag) >= int(i[1]):
        continue
    new_flag = check_flag(flag, i[0], int(i[1]), i[2])
    if new_flag:
        print(f"new flag: {new_flag}")
        flag = new_flag
    else:
        print(f"no match {i[1]} with hash {i[2]}")
        break  # 如果在某一步没找到匹配的,终止搜索

print(flag)

Misc

维多利亚的密码

png宽高修改+base64转文件+doc文档隐写

新型终端

题目给了一个wasm的二进制模块,花了半天时间琢磨怎么构建,最后github上找到wasmtime这个项目

运行之后真的是个终端。。。
可以看到用户是没有权限cat flag的,刚好看到有python,经典提权

print(open('flag','rb').read())

直接’r’打开会爆编码错误所以这里rb读二进制,可以看到以1f8b开头,gzip压缩的标志

导包之后解gzip得到flag

顺便贴一下主办方的网页构建终端的预期解项目工具
https://drive.google.com/file/d/1kLew5VmrCjWUrOTxIBOca6n_Z99h6fmf/view

压缩包

出于出题人对长城杯弱密码的疏忽而出的鸟题,没有什么学习意义
大概流程是伪加密+wim解压+长明文密码+弱密码的套娃

你是懂二维码的

一道考验py代码审计和二维码结构的题,之前写过了所以这次就不交flag了(不是因为真的很麻烦)
先贴一个我觉得对二维码结构讲的不错的博客QRCode – 鹤翔万里的笔记本 (tonycrane.cc)

访问链接后会给一个扫不出来的二维码,打开附件的py可以知道给的二维码是没有经过掩码处理的二维码(具体手法就是把qrcode库里的mask_func函数给重定义了)

这里可以手动读到是纠错等级H 像素57×57 版本9 掩码5 的二维码(具体怎么读的参考开头提到的博客)
这里根据题目的代码改写来获得一个有掩码和无掩码的二维码(前半部分代码和后半部分需要分开执行)

import hashlib
import qrcode
import random
import sys
import numpy as np
from PIL import Image

PIXEL_SIZE = 13  # 像素大小
BORDER_SIZE = 2  # 边框大小
MASK_NUM = 5  # 掩码

def xor_images(img1, img2):
    """将两个二维码图片进行异或操作"""
    arr1 = np.array(img1)
    arr2 = np.array(img2)
    xor_arr = np.bitwise_xor(arr1, arr2)
    xor_img = Image.fromarray(xor_arr.astype('uint8') * 255)
    return xor_img

########################################################################################
# 生成原始二维码
# qr = qrcode.QRCode( version=9, 
#                     error_correction=qrcode.constants.ERROR_CORRECT_H,
#                     box_size=PIXEL_SIZE,
#                     mask_pattern=MASK_NUM,
#                     border=BORDER_SIZE)
# qr.add_data('test')
# qr.make(fit=True)
# qr_img = qr.make_image(fill_color="black", back_color="white").convert('L')
# qr_img.save('qrcode.png')

########################################################################################
# 生成带掩码的二维码

# try:
#     original_mask_func # 如果已经定义了,就不再定义
# except NameError:
#     original_mask_func = qrcode.util.mask_func # 保存原来的mask函数

# def mask_func(pattern): # mask函数
#     if pattern == MASK_NUM:  # 如果mask和随机mask相同,就返回False
#         print(f"Hack: Mask {MASK_NUM} is means no mask") # 输出hack信息
#         return lambda i, j: False # 返回lambda函数
#     return original_mask_func(pattern) # 否则返回原来的mask函数

# if qrcode.util.mask_func is not mask_func: # 如果mask函数不是新定义的mask函数
#     qrcode.util.mask_func = mask_func

# qr_with_mask = qrcode.QRCode(   version=9,
#                                 error_correction=qrcode.constants.ERROR_CORRECT_H,
#                                 box_size=PIXEL_SIZE,
#                                 mask_pattern=MASK_NUM,
#                                 border=BORDER_SIZE)
# qr_with_mask.add_data('test')
# qr_with_mask.make(fit=True)
# img_with_mask = qr_with_mask.make_image(fill_color="black", back_color="white").convert('L')
# img_with_mask.save('qrcode_with_mask.png')


丢进ps里图层选择相差(xor)来得到掩码(不知道为什么PIL异或出来结果,急眼了用ps了)

再用掩码和题目给的异或处理

就可以读到数据了(万恶的出题人还加了盐不让手读数据出来)

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇