公司的应届生都会参加极客大赛,简单来说就是会给出各个部门根据自身业务而出的题目,参赛者从题目组里面选择一个自己感兴趣的题目进行参赛,选择同个题目的人就自动归为一组进行团体赛,团队的最大人数是八人

我最开始选择的题目是 漏洞利用攻击检测-0day/Nday漏洞利用攻击检测方案。蒽,结果比赛负责人说这个题目只有我一个人选orz,重新考虑了一下之后去了 漏洞研究-数网知来:重历经典漏洞的挖掘与利用历程,虽然团队加上我也只有三个人(人少不好摸鱼

为了做一个能够进行演示的demo,我们考虑做一个漏洞知识库+一键复现的靶场平台,团队的项目经理主要负责项目汇报和节点的把控,星哥进行漏洞复现,文档编写以及靶场环境的准备,我主要基于MrDoc魔改搭建知识库平台

MrDoc : https://github.com/zmister2016/MrDoc

先把MrDoc部署一下,分为了docker部署和源码部署

docker部署

ubuntu上进行docker一键搭建

出现报错

INSTALLED_EXTENSIONS = metadata.entry_points().get('markdown.extensions', ())

修改requirements.txt Markdown 的版本为 3.1.1

修改后重新docker-compose up运行成功,因为端口映射的原因,实际上运行在本地8080端口

源码部署

魔改的话还是得进行本地的源码部署

准备环境

  • python3

  • pycharm

  • 顺带把虚拟环境弄一下了,防止包混乱

pip安装包

pip install -r requirements.txt

验证一下Django是否成功安装

初始化数据库

生成数据库迁移

python manage.py makemigrations 

出现关于pymysql的报错

pip install PyMySQL==0.10.1

重新运行出现新报错

pip install mammoth

安装后重新运行,出现报错

django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'mrdoc-mysql' ([Errno 11001] getaddrinfo failed)")

说明没有连接到数据库,检查了一会文件结构发现配置文件在config目录下的config.ini文件中,修改其中数据库的相应配置即可

[database]
# engine,指定数据库类型,接受sqlite、mysql、oracle、postgresql
engine = mysql

# name表示数据库的名称
name = mrdoc 

# user表示数据库用户名
user = root

# password表示数据库用户密码
password = root

# host表示数据库主机地址,如果mysql是容器,要填容器的名字
host = 127.0.0.1

# port表示数据库端口
port = 3306

去mysql里面添加一个mrdoc数据库

重新运行 python manage.py makemigrations 就没有报错了

运行 python manage.py migrate,出现新的报错

django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1"))

报错原因是Django2.1不再支持MySQL5.5,必须5.6版本以上

检查我本地MySQL版本确实是5.5

phpmystudy mysql降版本还是比较麻烦,所以考虑降级django到2.0.0

pip install Django==2.0.0

虽然提醒我们可能会有复杂的依赖问题,但是本着没有出现问题就没有问题的原则,当作没有看见

重新运行 python manage.py migrate 即成功

检查数据库

数据库的初始化就完成了

创建管理员账户

初始化完数据库之后,需要创建一个管理员账户来管理整个Mrdoc,运行python manage.py createsuperuser

账号密码当然用最简单的:admin/admin123456

测试运行

运行 python manage.py runserver

浏览器访问 http://127.0.0.1:8000/

在终端可以看到访问的接口日志

管理员后台

我还找了半天是哪个接口管理员登录,发现原来和普通用户是一样的,在管理员后台可以对整站进行管理,因为普通用户的功能只是管理员的子集,所以咱们直接在管理员的基础上进行功能开发和实现,如果需要的话将对应的功能迁移到普通用户和游客身上去

到此为止实际上知识库的部分只需要填充文本就行了,现在需要考虑怎么跟靶场环境结合起来

连接靶场

想要点击启动靶场的时候,前端通过websocket连接到后端,后端连接到docker靶场,前端界面作为一个伪终端,用户在前端执行的命令能够传输到docker命令界面中,命令执行的结果回显在浏览器界面上

后端与docker连接

因为后端是python写的,这一步很容易实现

这里使用paramiko库中,基于用户名和密码的 transport 方式登录

安装paramiko

pip install paramiko

transport方式登录类似于python 使用session去保持请求,可以复用连接,执行多条命令,比如执行命令、上传/下载文件等

一个实例代码如下

import paramiko
 
# 建立连接
trans = paramiko.Transport(("xx.xx.xx.xx", 22))
trans.connect(username="root", password="you_passwd")
 
# 将sshclient的对象的transport指定为以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans
 
# 剩下的就和上面一样了
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("ls -l")
print(ssh_stdout.read())
 
# 关闭连接
trans.close()

使用AWDDocker测试一下 https://github.com/Cl0udG0d/AWDDocker

访问127.0.0.1:8000

测试用例

import paramiko

def test():

    # 建立连接
    trans = paramiko.Transport(("127.0.0.1", 8001))
    trans.connect(username="ctf", password="test123")

    # 将sshclient的对象的transport指定为以上的trans
    ssh = paramiko.SSHClient()
    ssh._transport = trans

    # 剩下的就和上面一样了
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("ls")
    print(str(ssh_stdout.read(),encoding = "utf-8") )

    # 关闭连接
    trans.close()


if __name__ == '__main__':
    test()

查看输出,因为用的python3.6的原因,会有一个警告,暂时先不管了

前端与后端连接

目的是

在浏览器前端模拟Linux终端命令行界面

当然这里我们并不是单纯的模拟,而是需要真正跟Linux进行交互

经过调研后发现可以使用xterm.js来实现这个目标

但是这里需要使用npm安装

npm install xterm

因为在这里我使用的是原生的前端,使用这种方式对我来说过于庞杂了,在github上面翻到了另外一个项目

里面有安装编译后的xterm.js文件

原来的这个项目使用有点问题,重新fork了一份进行魔改

安装

项目下载安装

git clone https://github.com/Cl0udG0d/websocket_terminal
cd websocket_terminal/server-python3
pip3 install -r requirements.txt

预备

这里我们先不运行脚本,而是先在本地使用docker起一个能够ssh链接的模拟服务器,这里使用以前的一个项目

git clone https://github.com/Cl0udG0d/AWDDocker

cd AWDDocker/web_1_example

docker-compose up -d

可以访问 http://127.0.0.1:8000/ 查看是否搭建成功

ssh的账号密码是 ctf/test123

ssh的端口映射为8001

修改server.py里面ssh的端口为8001

运行web服务器,这里的服务器后端是flask,连接服务器ssh的方式是websocket或者原始的tcp

python3 websocket_terminal.py

改错

浏览器访问网址出现报错

http://127.0.0.1:5002/?kind=ssh&username=ctf&password=test123

修改server.py文件获取参数的方式

重新访问即可

可以看到这里已经成功链接了服务器ssh

然后遇到了第二个问题,我们在界面上输入内容没有显示 orz

在script.js文件里面新增一行

现在输入就能够回显在界面上了

然后又出现了回车之后光标直接到了行首这个问题

给哥们搞沉默了

在这篇文章中有回车返回行首的解决办法 https://juejin.cn/post/6918911964009725959,但是处理方法比较复杂

切换demo

重新在github上寻找使用了xtermjs的项目,想要找一个已经实现、拿来简单修改就可用的,发现了这个

https://github.com/cs01/pyxtermjs

尝试安装运行一下这个项目

pip install -r requirements.txt

又是Windows和Linux的环境差异问题

参考 - https://blog.csdn.net/weixin_53660567/article/details/124929468

定位到报错这一行,直接注释掉

一顿改完之后又出现了新的问题

猜测不可能只有我一个人遇到这个问题,查看项目ISSUE

同样的问题 https://github.com/cs01/pyxtermjs/issues/25

该项目目前仅支持类UNIX系统

替换方案

试了这么久好像还是不行,虽然我自己可以实现一个简单的web前端界面,但是只能支持简单的命令,比如 ls 、ps、whoami这种单次回显的,对于交互比较复杂的top、vim就无能为力了

继续搜索之后发现了webssh https://github.com/huashengdun/webssh

没想到这个项目异常好用,直接实现了我想要的功能,只需要简单改一下连接服务器的方式,从表单填写修改为把密码直接通过GET或者POST方式进行传输即可

最后

然后就是在这个基础上进行了一些完善和美化,包括实现了一个演示的大屏界面,里面还填充了一个透明的3D词云(忽悠领导专用),对上传的dockerfile进行安全扫描等等

其中我们的项目经理还被裁了orz,本就人少的团队雪上加霜,所以自己不仅要改代码还需要修改PPT了。后面又因为工作上的事情转移了自己大部分的精力,本来还以为能够拿一等奖,最后在决赛又垫底了

技术宅拯救不了世界了 ????

END

建了一个微信的安全交流群,欢迎添加我微信备注进群,一起来聊天吹水哇,以及一个会发布安全相关内容的公众号,欢迎关注 ????

极客大赛的碎碎念-小白菜博客
GIF