ctf练习(杂)
分为re、crypto、misc三部分,用作记录思路和用得上的gadget。
以下二级标题不带网站的默认为buuoj对应分区题目。
re/mobile
xctf-50: catch-me
getenv函数用来获取环境变量,python中手动设置环境变量的脚本如下:
1 | # if ASIS == CTF == 0x4ff2da0a, then |
我那几十行的浮点指令白看了
buu-n1book: babyalgo
常见算法识别,容易看见密文和密钥,就猜是什么加密算法呗。
(30min后......)
cyberchef一个个都试完了,全都解不出来...
查看题解,发现是RC4,然后发现cyberchef的base64加密和RC4的解密结果都是错的,真无语。
RC4算法识别:
从网上嫖来的解密脚本:
1 | import base64 |
susctf: DigitalCircuits
给出了一个python打包的exe。我们使用PyInstaller Extractor
解包。
得到了一堆pyc、pyd、dll文件,我们找到DigitalCircuits
文件和struct
文件,将后者的前16个字节append到前者的文件头,使用uncompyle6
或者pycdc
反编译为源码。
通过数电知识,我们可以分析前九个函数对应的含义,得到以下代码:
1 | import time |
将f10中的10011110001101110111100110111001
转为16进制结果为0x9e3779b9
,上网查询是TEA/XTEA/XXTEA的一种特殊常数,再进一步分析源码可知是TEA。
附上C解密脚本:
1 |
|
starctf: Simple File System
沿用了新生赛时PVZ的做法,先尝试将flag改成一个全0串,然后导出bury的flag。
发现导出的加密值是固定不变的,比PVZ还简单一些。
于是将flag改成所有的可见字符串,再导出,可以形成一个明文到密文的映射。
输入:
1 | !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} |
输出:
因为*CTF对应的密文是00 d2 fc d8
,在image.flag
中找到这串16进制数后,再解密回来即可。
1 |
|
Youngter-drive
一道多线程的题目:
注意这个程序创建了两个线程,其中前面一个线程会对输入字节进行处理,并将位置指针dword_418008
减1,后面那个只是把dword_418008
减一,指针的值直到-1
为止。
注意到dword_418008
的初始值是29,因此程序只会对奇数位的值进行变换(其实奇数位试一次,偶数位再试一次也可以),另外也可以得知输入长30位。
由于加密后只对比前29位(0~28),因此最后一位需要手动爆破。
1 |
|
Universe_final_answer
z3模板题,这里只贴z3部分的代码便以后参阅。
1 | from z3 import * |
equation
js解密jsfuck脚本:
正则匹配是个好东西,可惜我不会。
1 | <script> |
解出来一堆等式,用正则表达式替换,将&&
替换成\n
,方便多行编辑。
然后使用z3解方程:
1 | from z3 import * |
[网鼎杯 2020 青龙组]jocker
脑洞题+smc自解密——idc初体验。
1 |
|
按c可以从二进制数据生成代码,按p可以从代码块构造函数。
n1book: 数字壳的传说
frida-hook
在root的安卓虚拟机或模拟器上的/data/local/tmp
上拷贝frida-server并启动,在物理机上安一个frida-dexdump
。
虚拟机启动app,主机执行脱壳命令:
1 | frida-dexdump -FU |
输出几个classes.dex
,选择没有序号的那个打开,定位到Secret
类,内容如下:
1 | package com.sec.n1book1; |
它调用了encryptString2Base64(String content, String password, String iv)
这个方法,从而得知这是一个CBC加密,密钥为flag前6位,iv为123456。
然而我并不知道填充怎么处理,参考网上的一些脚本才知道是用空格处理。
1 | from Crypto.Cipher import AES |
corctf2022 Microsoft ❤️ Linux
前半部分直接ida加载32位elf格式,将指定范围的bytes
ror 13
即可。(其实就是ror 5
)
后半部分ida用二进制模式打开,选择16位,可以发现是dos指令,加密方式是xor 13
,长度为18,然而加密范围好像有点问题。
密文只可能存在于0x210~0x233之间,整个异或13之后发现后18位像flag,与前面拼接即可。
crypto
buu-re: rsa
真不知道这道题为什么要放在re里面。
已知公钥pub.key和密文flag.enc,而且公钥较小可暴力分解p、q。
openssl rsa -pubin -text -modulus -in pub.pem
获取和 . 使用factordb分解
,得到 与 . python rsatool.py -o private.pem -e <your e> -p <your p> -q <your q>
输出密钥。适配python3的rsatool的下载地址:https://github.com/ius/rsatool
openssl rsautl -decrypt -in flag.enc -inkey private.pem
获得原文。
N1book_N1DES
一个稍微魔改了一下的des,循环次数由16位变为32位。
仍然是feistel结构,只需照加密函数写出解密函数即可。
这是加密函数:
1 | def encrypt(self, plaintext): |
解密脚本如下:
1 | inv_s = [178, 218, ... 62, 208] |
rsa1
已知p、q、dp、dq、c,求原文。
证明链接:https://blog.csdn.net/qq_32350719/article/details/102719279
1 | from gmpy2 import * |
corctf2022 tadpole
题面:
1 | from Crypto.Util.number import bytes_to_long, isPrime |
下减上得:
左右相减是p的倍数,分解质因数即可(其实就是质数)。
corctf2022 luckyguess
1 | #!/usr/local/bin/python |
使用不动点,构造
故
gmpy2.invert
即可。
corctf2022 exchanged
1 | from Crypto.Util.number import * |
(以下相等默认在模
将mult
展开得:
推一下式子可得:
将B错位相减得:
故可求得
注意aes CBC模式的key与iv都是大端序。
1 | from Crypto.Util.number import * |
misc
tqlctf2022-misc: wizard
哈希碰撞 + 瞎蒙答案:
1 | from pwn import* |
xctf-mobile-(beginner)-6: easy-apk
换表base64,上python脚本
1 | import base64 |
NepCTF2022 signin
usb隐写脚本
1 | #!/usr/bin/env python |
corctf2022 whack-a-frog
拿到一个pcap文件,查看发现有很多get请求。
先提取这些get请求:
1 | cat whacking-the-froggers.pcap| grep -a 'anticheat?x=' > in |
其中都含有x坐标和y坐标。使用正则表达式提取:
1 | from pwn import * |
然后用c语言转换成字符画,结果之前把x和y搞反了:
1 |
|
gedit缩小查看,发现笔画大致是对的,那应该就是flag了:
[NPUCTF2020]OI的梦
经典路径计数问题,使用矩阵快速幂即可,copilot2分钟写完。
1 |
|