系列文章专栏地址:
一、序言
本期,我们主要是完成了数据库设计,部分网页设计,以及部分靶场设计。
其中网页设计主要包括:登录注册、导航栏和背景等的修改、论坛和课程管理的初步设计。
靶场设计主要是sql注入和RCE
二、网页设计
1.登录注册:
界面背景颜色设置background-image: linear-gradient(to bottom right, #000000, #483D8B);
就可以设为渐变色。
2.解决跨域问题
因为前端端口是8080,而后端是9090,所以我们程序在访问的时候会访问不到,因为跨域了,解决方法:设置代理跳转到9090,创建vue.config.js文件,内容如下:
// 跨域配置
module.exports = {
devServer: { //记住,别写错了devServer//设置本地默认端口 选填
port: 8080,
proxy: { //设置代理,必须填
'/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
target: 'http://localhost:9090', //代理的目标地址
changeOrigin: true, //是否设置同源,输入是的
pathRewrite: { //路径重写
'^/api': '' //选择忽略拦截器里面的内容
}
}
}
}
}
3.论坛初设计
每条writeup放置在一张卡片上,写有标题、内容、作者和发表时间
4.管理系统初设计
这个界面是面向老师的,老师可以查看自己每个课程的学生信息,包括靶场题目完成进度,然后可以将学生成绩导出,也可以进行一些增删查操作。
实现后的界面如下:
点击邀请二维码,弹出二维码,但目前未实现
点击添加学生,弹出一个dialog
显示学生信息和分页查找功能
测试结果
将.data.records赋值给表单。加载信息
测试一下搜索:
三、数据库设计
从需求分析入手,我们设计的数据库如下:
User
problem
stuproblem
course
每一个courseid对应一个Teacherid,一个老师可以教多门课,表的结构如下:
stucourse
用以存储学生选课信息,注意的是courseid和userid共同构成了主键
四、靶场设计
设计了以下两个攻防靶场:
1.rce漏洞
RCE (Remote Code/Command Execute) :远程代码/命令执行
漏洞产生原因:在 Web 应用中开发者为了灵活性,简洁性等会让应用调用代码或者系统命令执行函数去处理,同时没有考虑用户的输入是否可以被控制,造成代码/系统命令执行漏洞。
其实这个漏洞也是像大多数漏洞一样,即没有检查或者没有严格的过滤用户所输入内容,而是直接带入执行,导致了远程代码执行漏洞的产生。
相较于使用 php 而言,使用 java 搭建的网站出现远程代码执行漏洞的几率较小些,因为 php 有很多内置的函数,可以执行相关命令,但是仍然会出现这种漏洞。
这个漏洞一经发现,几乎就是高危漏洞。
实现一个含rce漏洞的靶场页面:
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RCE-ping</title>
</head>
<body>
<form action="http://localhost:8080/RCE/ping" method="get">
请输入ip地址: <input type="text" name="ip" />
<input type="submit" value="ping" />
</form>
</body>
</html>
后端:
package com.example.sqli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class indexController {
@RequestMapping(value={"/","/index.html"})
public String index(){
return "index";
}
@RequestMapping(value={"RCE_ping"})
public String RCE_ping_index(){
return "RCE_ping";
}
}
package com.example.sqli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
@Controller
@RequestMapping("/RCE/")//接口注解
public class RCE {
//RCE-ping漏洞(测试payload:127.0.0.1 | whoami 或者 127.0.0.1 && whoami)
@RequestMapping("ping")
public String RCE_ping(@RequestParam(value = "ip",required = false) String ip, Model model) throws SQLException, IOException {
// Runtime rt = Runtime.getRuntime();
// Process p = rt.exec("cmd.exe /c ping "+ip);
// System.out.println(p.toString());
// return "RCE_ping";
Runtime runtime = Runtime.getRuntime();
try {
String cmd = "cmd /c ping "+ip;
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
process.waitFor();
process.exitValue() ;
//BufferedReader br = new BufferedReader(new InputStreamReader(runtime.exec("ping "+ip).getInputStream(),"GBK"));
String line=null;
System.out.println(cmd);
StringBuffer b=new StringBuffer();
while ((line=br.readLine())!=null) {
b.append(line+"\n");
}
System.out.println("ping输出结果:"+b.toString());
} catch (Exception e) {
e.printStackTrace();
}
return "RCE_ping";
}
}
2.sql注入
SQL注入是网站存在最多也是最简单的漏洞,主要原因是程序员在开发用户和数据库交互的系统时没有对用户输入的字符串进行过滤,转义,限制或处理不严谨,导致用户可以通过输入精心构造的字符串去非法获取到数据库中的数据。
部分后端代码:
//数字型SQL注入漏洞(测试payload:-1 or 1=1 --)
@RequestMapping("num")
public Result sqli_num(@RequestParam(value = "id",required = false) String id,Model model) {
try{
Connection connection = dataSource.getConnection();
Statement stmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
sql="select * from usersqli where id = "+ id;
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
// 通过此对象可以得到表的结构,包括,列名,列的个数,列数据类型
rs.last();
int row = rs.getRow();
rs.beforeFirst();
System.out.println("查找到行数为"+row);
String[] result = new String[row];
String result1 = "";
int count = 0;
rs.next();
for (int i = 0; i < row; i++) {
result[i] = rs.getString("name");
result1 = result1 + "name"+(i+1)+": "+result[i]+"; ";
rs.next();
}
rs.close();
connection.close();
System.out.println("result:"+result1);
Result res=new Result(Constants.CODE_200,null,"result:"+result1);
return res;
} catch (SQLException e) {
e.printStackTrace();
Result res=new Result(Constants.CODE_200,null,"result:"+e.toString());
return res;
}
}
测试: