作业7.13

1、分析并复现原生jdbc注入漏洞,简述什么情况下采用jdbc预编译也无法防御注入漏洞。

分析:

漏洞成因:

如下代码第二十三行将接受到的参数直接拼接到sql语句中并且在第二十五行处执行了。

代码解释成因:

靶场使用的是报错注。如果将第41行的代码注释了报错注入也就行不通了。 我通过实验发现也可以使用联合注入。此时就还需要43行的代码将结果返回。

/**
     * @vul JDBC模式下,采用拼接的SQL语句
     * @poc http://127.0.0.1:8888/SQLI/jdbc?id=1' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)--%20+
     */
@RequestMapping("/jdbc")
public String sql_1(String id) {
StringBuilder result = new StringBuilder();
try {
    Class.forName("com.mysql.cj.jdbc.Driver");
    // 建立连接
    Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);
    // 执行查询
    Statement stmt = conn.createStatement();
    String sql = "select * from users where id = '" + id + "'";
    System.out.println("[*] 执行SQL语句:" + sql);
    ResultSet rs = stmt.executeQuery(sql);
    // 获取查询结果
    while (rs.next()) {
        String res_name = rs.getString("user");
        String res_pass = rs.getString("pass");
        String info = String.format("查询结果 %s: %s", res_name, res_pass);
        result.append(info);
    }
    rs.close();
    conn.close();
​
} catch (Exception e) {
    // 输出错误,用于报错注入。。。
    return e.toString();
}
return result.toString();
}

复现:

如下情况预编译也无法防御注入漏洞: PrepareStatement虽然进⾏了预编译,但在预编译前进行了以拼接⽅式构造SQL语句的情况下仍然会产⽣SQL注⼊

2、分析并复现mybatis注入漏洞复并简述审计方法和漏洞原理

分析:

首先找到路由位置。

/**
     * @vul order by 注入,#{} 会将对象转成字符串,形成 order by "user" desc 造成错误,因此很多研发会采用${}来解决,从而造成SQL注入
     * @poc http://127.0.0.1:8888/SQLI/mybatis/vul/order?field=id&sort=desc,1
     */
@GetMapping("/mybatis/vul/order")
public List<User> orderBy(String field, String sort) {
    return userMapper.orderBy(field, sort);
}

通过跟踪可以找到调用userMapper.orderBy的地方。

/**
* 传统的xml配置
*/
List<User> orderBy(String field, String sort);
List<User> orderBySafe(String field);

发现是传统的xml配置,继续跟进。最终找到底层进行sql查询的语句,发现漏洞所在,即将field和sort参数直接拼接进sql语句中。

<!-- id的值必须和数据处理层的接口名一致 -->
<select id="orderBy" resultType="com.best.hello.entity.User">
  select *
  from users
  order by ${field} ${sort}
</select>

复现:

3、分析并复现命令执行漏洞,简述什么情况下无法进行命令注入以及原因。

分析:

ProcessBuilder方式

漏洞成因: 在代码第四行将外部获取的参数拼接进入命令并在第九行执行。期间没进行过滤。 并在后续代码中将命令执行的结果全部添加到stringbuilder对象中,最后转成字符串输出。

@RequestMapping("/ProcessBuilder")
public static String cmd(String filepath) {
// 提供一个命令字典
String[] cmdList = {"sh", "-c", "ls -l " + filepath};
StringBuilder sb = new StringBuilder();
String line;
​
// 利用指定的操作系统程序和参数构造一个进程生成器
ProcessBuilder pb = new ProcessBuilder(cmdList);
pb.redirectErrorStream(true);
​
// 使用此进程生成器的属性启动一个新进程
Process process = null;
try {
    process = pb.start();
    // 取得命令结果的输出流
    InputStream fis = process.getInputStream();
    // 用一个读输出流类去读
    InputStreamReader isr = new InputStreamReader(fis);
    // 用缓存器读行
    BufferedReader br = new BufferedReader(isr);
    //直到读完为止
    while ((line = br.readLine()) != null) {
        System.out.println(line);
        sb.append(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}
return sb.toString();
}
runtime方式

漏洞成因: 成因和processBuilder方式相同,区别在于执行方式不同。不过runtime最底层还是调用ProcessBuilder方法来实现的。

@RequestMapping("/runtime")
public static String cmd2(String cmd) {
StringBuilder sb = new StringBuilder();
String line;
​
try {
    // 执行命令
    Process proc = Runtime.getRuntime().exec(cmd);
​
    InputStream fis = proc.getInputStream();
    InputStreamReader isr = new InputStreamReader(fis);
    BufferedReader br = new BufferedReader(isr);
    while ((line = br.readLine()) != null) {
        System.out.println(line);
        sb.append(line);
    }
​
} catch (IOException e) {
    e.printStackTrace();
}
return sb.toString();
}

复现:

ProcessBuilder方式

因为是win10系统搭建的环境无法执行linux的命令

runtime方式

 如果参数是以数组形式传进来的并且在执行前没有调用StringTokenizer()方法,则可以直接利用。 当一下情况是ProcessBuilder无法实现命令注入。

  • ls -lh; id => ["ls", "-lh;", "id"]

分割完后方法会将id作为参数执行而不是命令,因此会报错。 ls: illegal option

  • ls -lh;id => ["ls", "-lh;id"]

同样的会将-lh;id作为参数执行而不是将id作为单独的命令执行,因此也会报错。 ls: illegal option

  • sh -c 'ls -lh;id' => ["sh", "-c", "'ls", "-lh;id'"]

如命令中两边有单引号也是无法执行的因为单引号没有闭合,因此会报错。

-lh;id’: -c: line 0: unexpected EOF while looking for matching `’’ 
  • sh -c "ls;id" => ["sh", "-c", ""ls;id"]

会报如下错误,看报错我猜测是将ls;id当做命令执行。

sh: ls;id: command not found

4、简述表达式注入漏洞原理及常见漏洞函数及利用方法

漏洞成因:

通过ex获取外部的的参数并且没有进行任何过滤,在第八行代码进行表达式的解析是形成漏洞的关键。

@GetMapping("/spel")
public String rce(String ex) {
// 1. 创建解析器:SpEL使用ExpressionParser接口表示解析器,提供SpelExpressionParser默认实现
ExpressionParser parser = new SpelExpressionParser();
​
// 2. 解析表达式: 使用ExpressionParser的parseExpression来解析相应的表达式为Expression对象
// 3. 求值:通过 Expression 接口的 getValue 方法根据上下文获得表达式值
String result = parser.parseExpression(ex).getValue().toString();
System.out.println(result);
return result;
}

常见漏洞函数及利用方法

Spring SPEL
String expression = "T(java.lang.Runtime).getRuntime().exec(/"calc/")";
String result = parser.parseExpression(expression).getValue().toString();
​
Struts2 OGNL
//模版
@[类全名(包括包路径)]@[方法名 |  值名],例如:
@java.lang.String@format('foo %s', 'bar')
//实例
ActionContext AC = ActionContext.getContext();
String expression = "${(new java.lang.ProcessBuilder('calc')).start()}";
AC.getValueStack().findValue(expression));
JSP JSTL_EL
<spring:message text="${/"/".getClass().forName(/"java.lang.Runtime/").getMethod(/"getRuntime/",null).invoke(null,null).exec(/"calc/",null).toString()}">
</spring:message>
Elasticsearch MVEL
String expression = "new java.lang.ProcessBuilder(/"calc/").start();";  
Boolean result = (Boolean) MVEL.eval(expression, vars);

5、简述actuator模块的作用及常见漏洞利用方式

作用:

Spring Boot Actuator 是 Spring Boot 提供的一个监控和管理生产环境应用程序的模块,它允许开发者在应用程序运行时获取关于应用程序运行状况、性能指标、日志级别、环境配置等方面的信息。Actuator 提供了一些内置的端点(endpoints),可以通过 HTTP 端点或 JMX 管理端点获取这些信息,同时也可以自定义端点来暴露应用程序的其他内部信息。 

常见漏洞利用方式

  1. 未授权访问:如果 Actuator 端点没有进行适当的安全配置,可能导致未经授权的用户可以访问敏感信息,如环境配置、敏感数据等。

  2. 信息泄露:如果 Actuator 端点暴露了过多的信息,可能导致泄露敏感数据,如数据库连接信息、用户凭证等。

  3. POST 请求利用:某些 Actuator 端点可能包含可以执行敏感操作的端点,如果未进行权限验证或安全控制,可能被攻击者利用进行恶意操作。

6、逻辑漏洞中,越权漏洞一般审计思路及常见功能点有哪些?

审计思路:

  1. 识别功能点:首先要了解应用程序的功能、用户角色权限和数据访问权限,识别可能存在越权漏洞的功能点。

  2. 模拟攻击:通过模拟攻击者行为,尝试利用逻辑漏洞访问未授权的功能或数据。

  3. 测试权限验证:测试用户身份验证和授权机制的完整性和正确性,确认是否能够越过权限验证逻辑进行越权操作。

  4. 分析代码逻辑:审查应用程序的代码逻辑,特别关注与用户权限、访问控制相关的部分,查找可能存在的逻辑漏洞。

常见功能点:

  1. 用户身份验证:登录认证过程中可能存在缺陷导致越权。

  2. 数据访问:查询、添加、修改或删除数据的功能点中,未正确校验用户权限可能导致越权。

  3. 功能访问控制:功能级别的访问控制机制,如管理页面、操作按钮等的权限验证不完善。

  4. 重置密码:重置密码功能存在越权漏洞时,攻击者可能重置其他用户的密码。

  5. 文件上传:文件上传功能中未正确限制访问权限可能导致越权下载文件。

7、部署华夏erp的前后端并实现功能正常使用

前端: 用小皮搭建网站,新建网址域名随便取,端口85,根目录是华夏erp前端包中含义index.html文件的目录。

启动前端http://域名:85

后端: 将后端源码用IDEA打开然后等待maven配置和下载完成然后启动,需要注意的是JDK需要8版本。 前后端联系: 在小皮面板的设置->配置文件->vhosts.conf中有个名字为域名_85的文件点开。 在红框位置输入如下代码 

location /jshERP-boot/ {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:9999/jshERP-boot/;
        }
posted @   0kooo  阅读(4)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示