0×00、前言
在企业安全建设过程当中,我们也不断在思考,做一个什么样的端口扫描才能企业业务需求。同时,伴随着企业私有云、混合云以及公有云业务部署环境的不断变化,我们适当也要对扫描策略做调整。前期的端口扫描设计在http://www.freebuf.com/articles/rookie/128526.html
在本文各个部分又所变动。
0×01、详细设计
@1、各个模块之间的交互:
一开始都是把产品想的特别完美,
(1) Web控制端
(2) worker工作节点
(3) 存储扫描结果(maybe: HDFS)
这样实现起来比较麻烦,当时说使用celery做调度,后来发现,celery对django有版本要求,超过1.10版本不成。等等现实问题。其实celery也是redis做调度数据同步。有时间可以自己做。
其实Web控制端和worker可以使用数据库做交互。用户通过Web控制端设置扫描策略和查看报表。Worker读取数据库中的配置信息,执行扫描任务,把扫描结果存储到数据库。
@2、功能需求
在对端口扫描功能的选型上,为啥选择nmap,
(1) 很多商用扫描器也是集成nmap扫描结果,例如:rapid7 Vulnerability Management。
(2) nmap扫描速度,肯定没有masscan、Zmap快,但是扫描结果有对服务banner和版本的探测,更重要的是有操作系统的探测。在云平台部署zmap等无状态扫描,会瞬间发出大量数据包,公有云EIP带宽QoS超过会立刻丢弃,对扫描结果有很大影响。
(3) libnmap 对扫描结果解析的相对完美,方便的提取我想要的数据到数据库中。
端口扫描后,我们还能做什么?
(1) 个人认为第一需求就是对新暴发的漏洞做企业内部评估。前几天的WannaCry就是445端口对外开发又可能触发MS-17-010的RCE。这里我集成了巡风漏洞扫描组件。
(2) 评估高危端口变化趋势,也是衡量企业安全管理人员工作成果的一个手段。
(3) 对企业内部部门漏洞分布有清晰的了解
0×02、交互设计
与用户交互部分,因为是安全管理员用,所以简单做。Axure是一个好的交互工具,可以帮助你梳理业务逻辑。
按照模块分:
(1)扫描配置
(2)扫描报表
0×03、前端实现
(1)开发环境建立:
brew install nodejs
npm install webpack –g
npm install --global vue-cli
vue init webpack CloudPScan
cd CloudPScan
npm install
npm install vue-resource
npm install element-ui
设置代理 config/dev.index.js
module.exports = {
//...
dev: {
proxyTable: {
// proxy all requests starting with /api to http://127.0.0.1:8000
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
}
}
}
(2)创建页面路由
import Vue from 'vue'
import Routerfrom 'vue-router'
import LoginViewfrom '@/components/LoginView'
import MainViewfrom '@/components/MainView'
import ScanSettingViewfrom '@/components/ScanSettingView'
import ScanReportViewfrom '@/components/ScanReportView'
import ElementUIfrom 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import VueResourcefrom 'vue-resource'
Vue.use(ElementUI)
Vue.use(Router)
Vue.use(VueResource)
export default new Router({
routes: [
{
path: '/',
name: 'LoginView',
component: LoginView
}
, {
path: '/MainView',
name: 'MainView',
component: MainView,
children: [{
name: 'ScanSettingView',
path: '/ScanSettingView',
component: ScanSettingView
}, {
name: 'ScanReportView',
path: '/ScanReportView',
component: ScanReportView
}]
}
]
})
(3)登陆页面
<template>
<div class="logincontainer" align="center">
<div class="form-signin" >
<img alt="云平台扫描系统">
</div>
<div class="form-signin--form" align="center">
<el-tabs>
<el-form label-position="center" @submit.native.prevent="doLogin" auto-complete="on" label-width="80px">
<el-form-item label="用户" :required ='true'>
<el-input v-model="params.username" auto-complete="on"></el-input>
</el-form-item>
<el-form-item label="密码" :required ='true'>
<el-input type="password" v-model="params.password" auto-complete="on"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit" style="180px;text-align:center;">登录</el-button>
<p v-if="fail" class="alert alert-danger">
{{ msg }}
</p>
</el-form-item>
</el-form>
</el-tabs>
<div class="sl-login_copyright">
GSGSoft Research <br/>© 2017 GSGSoft Tech.
</div>
</div>
</div>
</template>
<script>
export default {
name: 'LoginView'
, data: function () {
return {
fail: true
, msg: ''
, params: {
username: ''
, password: ''
}
}
}
, methods: {
doLogin () { //这个地方的处理就忽略了,其实就是请求查询数据库是否匹配提交的账号和密码,如果匹配然后跳转
this.$router.replace({
path: '/MainView'
})
}
}
, created () {
}
}
</script>
(4)扫描配置
<template>
<div>
<p>
<div class=panel-back>
<h4>扫描设置</h4>
<el-form :model="params" label-width="68px" label-position="left" @submit.native.prevent="submit">
<el-row :gutter="50">
<el-col :span="4">
<el-form-item label="任务名称">
<el-input size="small" type="text" v-model="params.task_id"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开始IP">
<el-input size="small" type="text" v-model="params.ipconf_startip"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="结束IP">
<el-input size="small" type="text" v-model="params.ipconf_endip"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="调度周期">
<el-input size="small" type="text" v-model="params.looptime"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button size="small" type="primary" @click.native="submit()">添加</el-button>
</el-col>
</el-row>
</el-form>
</div>
</p>
<p>
<div class=panel-back>
<h4>扫描任务</h4>
<el-table
:data="logs"
style=" 100%">
<el-table-column
property="task_id"
label="任务名称"
width="160">
</el-table-column>
<el-table-column
label="扫描状态"
inline-template
>
<el-progress :stroke-width="12" v-bind:percentage='scanstate' ></el-progress>
</el-table-column>
<el-table-column
property="ipconf_startip"
label="扫描开始IP"
width="130">
</el-table-column>
<el-table-column
property="ipconf_endip"
label="扫描结束IP"
width="130">
</el-table-column>
<el-table-column
inline-template
property="cops"
label="操作">
<div>
<el-button size="small" @click.native="StartTask(row)">启动</el-button>
<el-button size="small" @click.native="DeleteTask(row)">删除</el-button>
<el-button size="small" @click.native="VulTask(row)">漏洞</el-button>
</div>
</el-table-column>
</el-table>
<p>
<el-pagination