XYCTF2024-wp
能说什么呢,这题。。。难以言喻
RE
week1
DebugMe
这个是安卓动态调试,之前遇到过一个类似的,但是不同的是,那个直接在模拟器里面调就可以,这次这个好像没有被jadx识别到。
然后学到了另外一种方法:
在jadx调试界面直接点击启动ADB服务,然后打开模拟器,点击刷新,就能看到所有进程,然后就可以调试了
这个时候点击按钮,出flag
1 | XYCTF{d3bugg3r_15_v3ry_u53ful} |
你真的是大学生吗?
这个是一个16位dos程序,ida打开看汇编还原程序
加密逻辑:
相当于每次和下一位xor
之前没怎么搞懂mov si ,2F,然后发现是把它当地址。。没看明白add si,cx有什么用,可能add si,cx是创建一个空缓冲区存输入的。
加密逻辑确实是从最后开始向前异或,
1 | a = *p2; |
那直接逆向
1 | from prism import * |
喵喵的flag碎了一地
这个不用多说,直接跟着提示走就好
1 | flag{My_fl@g_h4s_br0ken_4parT_Bu7_Y0u_c@n_f1x_1t!} |
聪明的信使
一眼凯撒加密,拿去爆破
1 | flag{Y0u_KnOw_Crypt0_14_v3ry_Imp0rt@nt!} |
偏移是9
Trustme
解包之后感觉哪里不对,好像什么都没有,但是assets里面有一个mydb的文件,打开看看,全是0xff,异或一下试试,出来了QAQ
查一下知道这个是SQLite文件,用在线工具分析文件得到flag
1 | XYCTF{And0r1d_15_V3ryEasy} |
Baby Unity / ez Unity
这两个的做法一模一样,唯一的区别是ez里面的dat文件头被修改了,先放flag,然后记录一下第一次遇到li2cpp的题
1 | XYCTF{389f6900-e12d-4c54-a85d-64a54af9f84c} |
1 | XYCTF{IL2CPP_1s_intere5t1ng} |
原理大概是这样:
unity的游戏输出有两种一种是mono的c#(一般逆的),这种一般在managed文件夹里有Assembly-CShap.dll文件,然后这个东西可以直接被dnspy之类的直接反编译。这次这种叫li2cpp(中间代码 to cpp),通过失去动态编译特性来换取cpp的多平台,速度快等优势,对逆向来说:最恶心的就是文件变成了GameAssembly.dll,这是个PE文件(在移动端是so文件),也就是说符号表完全不必要有,这样就不好逆了(如果有佬可以直接逆的话,只能说NB),不过这个文件也没有常量表之类的东西所以肯定在一个地方存了它的数据来读入。
根据检索网络得知:符号表位于\il2cpp_data\Metadata\global-metadata.dat
现在的目的就是把这个文件导入进去了。
有一个工具叫做licppdumper可以做到这一点:
下载后双击exe,提示选择li2cpp二进制文件,选择GameAssembly.dll,又提示选择dat文件选择dat文件(baby那道题可以直接导入,ez那道题做了加密)
发现导入不了,去010看看结构:
把第一排改成AF 1B B1 FA 1D 00 00 00 00 01 00 00,删几个字符,让后面接着C0 B2
然后把下面的内容对齐
直接dumper导入,导入成功!
然后打开ida,导入脚本文件,然后选择刚刚用dumper生成的两个json文件:
script.json和stringliteral.json文件,两个选择完之后,符号表就恢复了,然后在ida里面直接找加密函数,应该很好看,一个是RC4,一个是AES直接放到在线网站上解就好了,其中用到的数被还原成注释了,不要看错了QAQ
week2
ez_cube
用ida反编译分析,找到打乱方式
百度搜索cfop pll可得公式
1 | R U' R U R U R U' R' U' R2 |
ez_rand
这个题就是考rand函数在不同环境下效果不同这个知识点,刚好我一开始就用的cpp,直接写脚本爆破出rand然后用就好了,还有注意传入初始化的值在al寄存器里面,所以要&0xffff
1 |
|
今夕是何年
架构题,是龙芯架构,配好虚拟机,然后直接输出
何须相思煮余年
居然是一个txt文件,开头是push ebp,那没事了,直接ida32打开
1 | from prism import * |
砸核桃
查一下壳是nspack,直接找个工具脱了
然后打开。又是很简单的逻辑,直接写脚本
1 | from prism import * |
week3
ez_enc
打开main,是一个简单的带mod的加密,既然是前一个数据和后一个数据有关系,还不大,直接z3
1 | from prism import * |
what’s this
是lua的字节码,放到在线解码里面解码,接出来就是正常的lua代码,
前面是一堆混淆的函数,最后是真的代码,大概是这个
1 | function Xor(num1, num2) |
分析一下是base64加换字加一些奇怪的加密,那丢给chatgpt
1 | import base64 |
ez_math
是python的混淆,还没有工具,用美化工具美化一下,还是可以理解,大概就是把a*b sum了一下,最后再化简一手
1 | if len(flag) == 32 and ( |
通过观察可以发现,每一行后面减的数除以二就是flag
那就直接除以二
1 | XYCTF{q7WYGscUuptTYXjnjKoyUTKtG} |
给阿姨倒一杯卡布奇诺
是一个简单的tea,魔改的部分是一开始的data1和data2的异或
1 | void encrypt(uint32_t* v, uint32_t* k) |
这个还是相当于把传入当key,data1和2更像是加密的值,要解密直接在最后异或上前一个的最后值就出来了。
1 | void decrypt(uint32_t* v, uint32_t* k) |
这里要注意i要是反着的,因为加密的时候用了i
出来是
1 | 62333331 |
转成字符再用xyctf包起来(题目说的是flag{}但是试了不行):
1 | XYCTF{133bffe401d223a02385d90c5f1ca377} |
easy language
这个题好坑啊!!QAQ
先通过e-decompliner插件找到主要目的地
可以看到是aes
最后的判断是
根据signseacher扫描结果,发现有反调试,通过附加调试跳过
在
1 | v5 = 字节集比较((_BYTE *)byte_59D0F4 + 8, encoded, v3); |
得到byte_59D0F4中的值即正确的密文,
在
1 | mode = "AES-ECB"; |
中得到key
丢进在线工具解密aes
1 | RZy/zVEWMFxaCbzChAg8x26XZYr51rNVnM+zBoBp3gya93L9QQXpFRin1JE33vyx |
总结一下:如果遇到奇怪的字符串,像是部分不对的,以及有fake_flag可能有反调试
馒头
数据结构,直接按ans1把树画出来,直接画就好,
1 | XYCTF{xaf1svut7rojh3de0} |
week4
find_me
一共有三个文件,只有4号是可执行文件,打开分析,发现是把3号加密成1号,那么尝试还原3号,注意其中使用了rand,所以应该写c代码
1 |
|
这样就还原了3,打开3看一下,好像是通过3生成了一个here,那就执行一下,打开here一看,flag出来了
1 | flag{i_L0ve_Dor4emon_Fov3rver} |
舔狗四部曲–简爱
先看主函数,好像是两个tea接着一个vm,从后往前试一下,先解vm
1 | void processCode(int* input) { |
结果直接就出了
舔狗四部曲–相逢已是上上签
先用010edtior把指向pe头的偏移修好,改成0001。然后进去用z3把key求出来
1 | from prism import * |
然后后面是一个魔改tea,直接解
1 | void __cdecl dec2(DWORD* flag, int len_after) |
舔狗四部曲–记忆的时光机
第一次遇到这种jmp+寄存器的值,不过通过分析可以看出均为顺序跳转,直接trance,然后分析,大概得出加密逻辑
1 | 0000E808 .text:enc+4 sub rsp, 48h RSP=00007FFCB17CE120 CF=0 PF=0 SF=0 |
1 | # inp[i]^=(i+6)^0x66 |
那直接逆
1 | from prism import * |
舔狗四部曲–我的白月光
一开头给了flag{L0v3_
然后分析一下主函数,发现最后有一个base64,拿去解一下,发现解不出来,然后尝试一下是不是反向了什么的
在cyberchef里面直接
1 | reverse+from base64+reverse+from hex |
然后再看一下中间还干了什么
看到有一个
1 | if ( !(_DWORD)v22 ) |
这个sub好像很可疑,直接set ip 过去,在执行完函数后,在对应的hex窗口找到
1 | i8_a_k3y_and |
最后
1 | flag{L0v3_i8_a_k3y_and_memory_never_go_done_finally_thankyou_xiaowangtongxue} |
crypto
week1
Sign1n
1 | from Crypto.Util.number import * |
既然是对每一位的单独加密,那就直接爆破
1 | from Crypto.Util.number import long_to_bytes |
x0r
是AES的选择明文攻击,由于是异或得到结果,那就可以直接截获每一次的密钥
1 |
|
happy_to_solve1
1 | from Crypto.Util.number import * |
我们知道q是p异或11111…的结果,那么p+q就约等于2**512
我们可以根据这个和pq乘积两个等式尝试寻找p和q
1 | from Crypto.Util.number import * |
反方向的密码 相思
1 | from Crypto.Util.number import * |
相当于已知m低位,用Coppersmith定理可解
1 | from sage.all import * |
一开始怎么都爆不出来,结果发现是epsilon取大了,还没规定上下界(这个X=X=2**(i*8)就是确定为flag的长度的),这样就要写m = low + x*2**256。不然会撞上下界
week2
Sign1n_Revenge
和signin一样,不写了
1 | flag{09c24f8d-dbf8-463b-a16f-3dbc47e4a726} |
happy_to_solve2
1 | import random |
这个p和q每一位既然只有3种选择,那就可以从最低位开始爆破出p和q的值
1 | import numpy as np |
1 | e = 65537 |
MISC
week1
TCPL
拖入ida分析,,发现只是异或了i,得到没有替换的flag
1 | b = [0x46, 0x4D, 0x43, 0x44, 0x7F, 0x55, 0x4A, 0x44, 0x5C, 0x56, 0x4B, 0x65, 0x38, 0x52, 0x7C, 0x3E, 0x43, 0x52, 0x64, 0x4C, 0x6C, 0x24, 0x7E, 0x62, 0x79, 0x77, 0x74, 0x2A, 0x61] |
把1换成其它值,多试一下
1 | FLAG{PLCT_An4_r0SCv_x0huann0} |
ez_隐写
开头一个伪加密,改好了之后有一个hint.png和一个watermark.jpg的文件,但是water.jpg要解压,修改hint.png的长宽获得密码xyctf0401,然后解压watermark.jpg,用盲水印工具打开可得flag
1 | XYCTF{758-W5X-IJN-852} |
修仙传
4元婴
1 | 都2024年了不会还有人解不出U2FsdGVkX1+y2rlJZlJCMnvyDwHwzkgHvNsG2TF6sFlBlxBs0w4EmyXdDe6s7viL吧 |
key: 2024 TripleDes解密得密码
1 | The_fourth_floor_is_okay |
打开文件得到一个微信数据库文件和一个
1 | wqk:1m813onn17 p772q37rm137qpnqppqpn38nr704m56n2m9q22p r05r77 |
修改其中的字符
1 | 1A813CBB17C040358D772E37FA137EDBEDDEDB38BF704A56B2A9E22DC7F05F77 |
直接用脚本解密aes即可
7合体
1 | 密文:Tig+AF8-viakubq+AF8-vphrz+AF8-xi+AF8-uayzdyrjs |
放到维吉尼亚解密里面,AF8指密钥和密文长度一样
假设密钥是ABCDEFGHIJKLMNOPQRST
得到密码
1 | The_seventh_level_is_difficult |
得到一张颜色图片,8进制转换即可
1 | they_were_thr0ugh! |
8大乘
开头是密码,直接用网上的异或加合脚本爆出来pq
然后rsa求密码
1 | pruning_algorithm |
出来是一个yesno文件
根据压缩包的提示把yes改成1,no改成0生成图片
内容是原神的文字,转换
1 | Sm3rt_y0u_can_do |
week3
我的二维码为啥扫不出来?
根据定位点和时序图案还原
1 |
|
Rosk,Paper,Scissors!
根据看ai的逻辑,发现是检索我出的最多的那个来判断这一次出什么,那就反制这个,写脚本
1 | import socket |
美妙的歌声
用audacity打开,以频谱图模式观察,发现字符串:XYCTF_1s_w3ll
这个看起来不是flag,但是可能是其它东西,用deepsound打开,把这个当密码,得到flag.txt
内容是
1 | XYCTF{T0uch_y0ur_he3rt_d55ply!!} |
总结:
re部分还是比较简单,基本没有什么问题
大部分是基础内容,没有ollvm和复杂的花也没有强的壳,
就直接分析逻辑或者动调就可以解,re还是偏简单的
类型:
两道flag不是输入的题:龙芯和白月光
其它都是直接逆向的题:
自定义逻辑
asm
伪vm
…
baby unity里面的工具在使用后会直接还原csharp方法名,在dumpdll文件夹中
cry部分会不了一点,不过密码✌要带我,太好了
之后问一下rsa的部分,还有复数域的内容
misc部分还是做的少了,要多练,不然好多没见过的
这次学到了音频,二维码和水印
以及总结一下nc题的做法:
1 | import socket |
通过这个方法上传和解析服务器的数据并提交内容