php代码审计靶场,代码审计 | Wavsep靶场审计防御

0cfeca7ed03fc5d59ce67a97d0fcc764.gif

——————   昨日回顾  ——————

红日安全出品|转载请注明来源

文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!(来源:红日安全)

d4ef957c310e0f925649be7338a95af6.png

—————— —————— —————

(点击上方文字可直接阅读哦)

1.1 基于wavsep靶场的jsp代码审计防御

本次实验是基于wavsep进行设计,因此我们主要做了sql注入及xss跨站请求

漏洞的实验结束。

1.1.1 wavsep靶场搭建

1、java环境搭建 因为本地已搭建好java环境,因此不进行演示了,网上也有很多java环境搭建教程。

2、wavsep靶场搭建 在网上下载wavsep.war包,将war包放在tomcat下的webapps下则会自动解压为wavsep文件夹;在浏览器中打开

http://127.0.0.1:8080/wavsep/:

c45d7aee370ee4a5f84806a88eda5ea5.png

通过页面信息我们可知当我们需要打开sql注入或者xss跨站脚本请求漏洞进行

实验时只需在url:http://127.0.0.1:8080/wavsep/ 后面跟上  index-xss.jsp

等练习页面即可。

1.1.2 SQL注入代码审计防御

1.字符型(String)sql注入 打开本次sql注入页面(wavsep中GET500中的

case1):

http://127.0.0.1:8080/wavsep/SInjection-Detection-Evaluation-GET-500E

rror/Case1-InjectionInLogin-String-LoginBypass-WithErrors.jsp?username=textvalue&password=textvalue2

839ef7a804a38ce5d3775e11fb5013e0.png

在用户名和密码处插入注入语句进行尝试绕过登录('or'7'='7):

85a51fa6da36f4590afbfa3649915d95.png

服务器回显"hello user1",登陆成功,该点存在注入,查看一下源码:

pageEncoding="windows-1255"%>html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

charset=windows-1255">

Case1-Injectionintostringvaluesinaloginpagewitherroneous

responses

if (request.getParameter("username") == null

&& request.getParameter("password") == null    ) {

%>Login Page:

action="Case1-InjectionInLogin-String-LoginBypass-WithErrors.jsp"

method="POST">

}

else {

try {

String username = request.getParameter("username"); String password =

request.getParameter("password");

/* Test loading driver */

String driver = DatabaseConstants.DATABASE_DRIVER;

Class.forName(driver).newInstance();

/* Test the connection */

String url = DatabaseConstants.CONNECTION_STRING;

Connection conn=DriverManager.getConnection(url);

System.out.print("Connection Opened Successfully");

String SqlString =

"SELECT username, password " +

"FROM users " + "WHERE username='" + username + "'" + " AND password='"

+ password + "'"; Statement stmt = conn.createStatement(); ResultSet rs

= stmt.executeQuery(SqlString); if(rs.next()) { out.println("hello " +

rs.getString(1)); } else { out.println("login failed"); }

out.flush();

} catch (Exception e) {

response.sendError(500,"Exception details: " + e);

}

} //end of if/else block

%>

以上便是这个页面的所有源码,看一下其中的查询语句:String SqlString =

"SELECT username, password " +

"FROM users " + "WHERE username='" + username + "'" + " AND password='"

+ password + "'"; Statement stmt = conn.createStatement(); ResultSet rs

= stmt.executeQuery(SqlString);

通过上述登录成功('or'7'='7')的事例可以

发现其sql查询语句为:select  username,password from users where

username=''or'7'='7' and password=''or'7'='7''当username或username

和password为真的时候则查询成功,为否则查询失败;这个就是利用相关语句组合的查询语句造成注入成功的注入语句;对于这类sql注入漏洞该如何预防呢?"WHERE username='" + username + "'" + " AND password='" + password + "'";发现传入值为单引号进行包含起来了,该注入为字符型查询,针对字符型查询直接可以将其单引号替换成双引号,数据为库oracle、mssql:则函数为String.replace("'",""");数据库为mysql:则函数为

String.replace("'","'");具体在源码中进行替换如下:

String username = request.getParameter("username").replace("'","'");

String password = request.getParameter("password").replace("'","'");

在对该源码进行替换防御后我们再次实验,在用户名和密码处插入注入语句进行

尝试绕过登录('or'7'='7):

c8ac1a7911f8fd3a9cae9cdb6facefca.png

登录失败,说明此方法对单引号进行转译,起到了对SQL注入的防护作用。 上面通过对单引号的转译,防止了sql注入漏洞,同时,还可以利用参数化查询的方式防止字符型sql注入漏洞,对于参数化查询我们可以先看看owasp官网上的

文档:

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

实例如下:

String custname = request.getParameter("customerName"); // This should

REALLY be validated too

// perform input validation to detect attacks

String query = "SELECT account_balance FROM user_data WHERE user_name

= ? ";

PreparedStatement pstmt = connection.prepareStatement( query );

pstmt.setString( 1, custname);

ResultSet results = pstmt.executeQuery( );

参考上述实例,我们对源码中sql查询语句进行修改:

pageEncoding="windows-1255"%>html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

charset=windows-1255">

Case1-Injectionintostringvaluesinaloginpagewitherroneous

responses

if (request.getParameter("username") == null

&& request.getParameter("password") == null    ) {

%>Login Page:

action="Case1-InjectionInLogin-String-LoginBypass-WithErrors.jsp"

method="POST">

}

else {

try {

String username = request.getParameter("username"); String password =

request.getParameter("password");

/* Test loading driver */

String driver = DatabaseConstants.DATABASE_DRIVER;

Class.forName(driver).newInstance();

/* Test the connection */

String url = DatabaseConstants.CONNECTION_STRING;

Connection conn=DriverManager.getConnection(url);

System.out.print("Connection Opened Successfully");

String SqlString1 =

"SELECT username, password " +

"FROM users " +

"WHERE username=?" + " AND password=?"; //用?代替参数  PreparedStatement

prepstmt = conn.prepareStatement(SqlString1);

prepstmt.setString( 1, username); //利用set给一个值

prepstmt.setString(2,password);ResultSetrs=prepstmt.executeQuery();

//进行查询 if(rs.next()) { out.println("hello " + rs.getString(1)); }

else { out.println("login failed"); }

out.flush();

} catch (Exception e) {

response.sendError(500,"Exception details: " + e);

}

} //end of if/else block

%>

在查询语句中,利用?代替我们传入的username、password,然后再分别给其

set一个值进行查询,进行实验一下:

552f2fc5fc6a4a33ff43f413aeb5bc7b.png登录失败,参数化查询防护成功。以上就是本次字符型sql注入的测试及防护。

2.数字型sql注入  针对数字型sql注入,利用函数进行防护,把常见参数转换

成数字类型进行查询,该函数如下:

Integer.parseInt(s)

3.非字符非数字型对于非字符型又非数字型的sql注入该如何应对,先访问该页

面(wavsep中GET500中的

case5):http://127.0.0.1:8080/wavsep/SInjection-Detection-Evaluation-G

ET-500Error/Case5-InjectionInSearchOrderBy-String-BinaryDeliberateRun

timeError-WithErrors.jsp?orderby=msgid:

636437812ac22098adc35d9868a7934f.png

在参数后边加上单引号,页面出现sql报错,存在sql注入:

86c0ea0903cf5cf1731585d20d091e1e.png

查询一些该页面源码:

pageEncoding="windows-1255"%>html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

charset=windows-1255">

Case 5 - Injection into an order by clause (any type) in a search

page with erroneous responses

if (request.getParameter("orderby") == null) {

%>View Messages and Organize Results According to the Field:

action="Case5-InjectionInSearchOrderBy-String-BinaryDeliberateRuntim

eError-WithErrors.jsp" method="POST">

value="msgid" >

}

else {

try {

String order = request.getParameter("orderby"); if

(InputValidator.validateSemicolon(order)) { throw new

Exception("Invalid Characters in Input: Semicolon (;)"); }

/* Test loading driver */

String driver = DatabaseConstants.DATABASE_DRIVER;

Class.forName(driver).newInstance();

/* Test the connection */

String url = DatabaseConstants.CONNECTION_STRING;

Connection conn=DriverManager.getConnection(url);

System.out.print("Connection Opened Successfully");

String SqlString =

"SELECT msgid, title, message " +

"FROM messages " + "ORDER BY " + order; Statement stmt =

conn.createStatement(); ResultSet rs = stmt.executeQuery(SqlString);

out.println("The list of messages:"); out.println("

out.println("

");

out.println("

");

out.println("");

out.println("MsgId");

out.println("");

out.println("

");

out.println("

");

out.println("");

out.println("Title");

out.println("");

out.println("

");

out.println("

");

out.println("");

out.println("Message");

out.println("");

out.println("

");

out.println("

");

while(rs.next()) { out.println("

"); out.println("");

out.println(rs.getString(1)); out.println("

");

out.println("

"); out.println(rs.getString(2));

out.println("

"); out.println("");

out.println(rs.getString(3)); out.println("

");

out.println("

"); } out.println("");

out.flush();

} catch (Exception e) {

response.sendError(500,"Exception details: " + e);

}

} //end of if/else block

%>

通过查阅源码,可以发现在查询时即不是字符型也不是数字型,是通过orderby  进行传参查询,因为一般表名的长度是有一定的长度限制的,所以这个时候可以利用限制查询时的字符长度来进行防护;在源码上进行防护修改,在 String order = request.getParameter("orderby");下面加入长度判断条件:

String order = request.getParameter("orderby");

if(order.length()>10){

return;

}

首先在未进行限制参数长度的情况下插入超过   10  个以上字符的参数:

d603f065142b784a64d22538cd29da0a.png

出现sql报错;

接下来对站点传入参数长度进行限制,并插入超过   10  个以上的字符参数:

18b3fd7b8e56cd662b4d8f1986cc007e.png

未出现sql报错,该防护成功。以上就是在wavsep上相对具有代表性的三类注

入,对其进行了测试及防护。

1.1.3 XSS跨站请求漏洞代码审计防御

本次xss跨站请求漏洞代码审计防御实验选取GET型中的反射性xss漏洞做

实例进行查看及防御;首先访问存在反射型xss漏洞地址(xssGET中的case1):

http://127.0.0.1:8080/wavsep/RXSS-Detection-Evaluation-GET/Case1-Tag2

HtmlPageScope.jsp?userinput=textvalue

00e0d175d98131661582bf05b4715a74.png

1.1.4 jsp代码审计防御

在userinput后面填写xss脚本代码进行提交:

3c5ee20a5cb670b8e80b1c65dec5a7de.png

查看该页面源码:

pageEncoding="windows-1255"%>

html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

charset=windows-1255">

Case 1 - RXSS via tag injection into the scope of an HTML

page

if (request.getParameter("userinput") == null) {

%>

Enter your input:

action="Case1-Tag2HtmlPageScope.jsp" method="POST">

}

else {

try {

String userinput = request.getParameter("userinput");

out.println("The reflected value: " + userinput);

out.flush();

} catch (Exception e) {

out.println("Exception details: " + e);

}

} //end of if/else block

%>

我们发现在插入的userinput参数未做任何防御,直接进行插入,导致xss反射脚本执行成功。对于 xss跨站请求漏洞在代码层的防御简单介绍以下一种,

如下是我们需要插入的防御代码:

String csHTML(String text){

if(text == null)return "";

StringBuffer results = null;

char[] orig = null;

int beg = 0, len = text.length();

for(int i = 0;i 

char c = text.charAt(i);

switch(c){

case 0:

case '&':

case '

case '>':

case '"':

if(results == null){

orig = text.toCharArray();

results = new StringBuffer(len + 10);

}

if(i>beg)results.append(orig,beg,i-beg);

beg = i + 1;

switch(c){

default://case 0:

continue;

case '&':

results.append("&ampamp;");

break;

case '

results.append("&amplt;");

break;

case '>':

results.append("&ampgt;");

break;

case '"':

results.append("\"");

break;

}

break;

}

}

if(results == null) return text;

results.append(orig,beg,len - beg);

return results.toString();

}

%>

我们将此防御代码插入到页面源码中:

pageEncoding="windows-1255"%>

html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

charset=windows-1255">

Case 1 - RXSS via tag injection into the scope of an HTML

page

String HTML(String text){

if(text == null)return " ";

StringBuffer results = null;

char[] orig = null;

int beg = 0, len = text.length();

for(int i = 0;i 

char c = text.charAt(i);

switch(c){

case 0:

case '&':

case '

case '>':

case '"':

if(results == null){

orig = text.toCharArray();

results = new StringBuffer(len + 10);

}

if(i>beg)results.append(orig,beg,i-beg);

beg = i + 1;

switch(c){

default://case 0:

continue;

case '&':

results.append("&ampamp;");

break;

case '

results.append("&amplt;");

break;

case '>':

results.append("&ampgt;");

break;

case '"':

results.append("\"");

break;

}

break;

}

}

if(results == null) return text;

results.append(orig,beg,len - beg);

return results.toString();

}

%>

if (request.getParameter("userinput") == null) {

%>

Enter your input:

action="Case1-Tag2HtmlPageScope.jsp" method="POST">

}

else {

try {

Stringuserinput=HTML(request.getParameter("userinput"));

out.println("The reflected value: " + userinput);

out.flush();

} catch (Exception e) {

out.println("Exception details: " + e);

}

} //end of if/else block

%>

访  问   该   页  面   ,  提   交   xss    脚   本  代   码  :

70c4e3f9cdb26aa14de43a8c341c3ffd.png

插入 xss  脚本代码解析失败,防御代码生效。一次修复方法可以对靶机内所有

的xss跨站请求漏洞进行实验修复。

——————  互动话题 ——————

# 你对红日的代码审计课程有什么建议#

快留言给小编

分享你的学习心得〜

—————— —————— —————

海量安全课程   点击以下链接   即可观看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 爬虫抓取代理IP,并检测联通性

帮朋友抓了一些代理IP,并根据测试联的通性,放在了不通的文件夹下。特将源码分享 注意: 1,环境Python3.5 2,安装BeautifulSoup4 requests 代码如下: 123456789101112131415161718192021222324252627282930313233343536…

php gps坐标转换经纬度,GPS坐标(经纬度转换xy坐标算法)

我用GPS-DG16测得某地的经纬度,然后想将该经纬度转换为80坐标系的经纬。1.看你的精度要求,如果厘米级的,则需要至少3个已知点,这3个点上要有80坐标系的经纬度,另外你再去用gps-dg16采集这三个点的wgs84经纬度&#xff…

java初始化顺序

原文地址http://blog.sina.com.cn/s/blog_4cc16fc50100bjjp.html对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通…

php审批流设计思路,审批流设计器-字段说明

1.允许转发:勾选,则在信息中心处理此审批动作对应的待处理任务时,可以将此任务转发给其他用户;不勾选,则在信息中心的待处理任务不支持转发功能,点击转交提示:审批动作设置为不允许转发。2.允许…

第一百二十六节,JavaScript,XPath操作xml节点

第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准DOM去查找XML中的节点方式,大大降低了查找难度,方便…

matlab 控制实验指导,智能控制系统-实验指导书-实验一-BP算法的MATLAB实现

实验一、BP算法的MATLAB实现一、实验目的1、了解MATLAB集成开发环境2、了解MATLAB编程基本方法3、加深对BP算法的理解和掌握二、实验内容1、MATLAB基本指令和语法。2、BP算法的MATLAB实现三、实验步骤1、熟悉MATLAB开发环境2、输入…

电力电子技术 matlab仿真指导,在_电力电子技术_课程教学中展开Matlab仿真训练_唐贤伦...

教学改革广角中国电力教育2009年10月上 总第146期 “电力电子技术”是电气工程及其自动化等专业的重要专业基础课,也是实用性、工程性和综合性很强的课程。作为自动化、电气工程及其自动化等专业的学生,学好这门课程将为后续专业课的学习和今后的工作打下…

Python补充01 序列的方法

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 在快速教程中,我们了解了最基本的序列(sequence)。回忆一下,序列包含有定值表(tuple)和表(list)。此外,字符串…

java socketchannel api,SocketChannel API

Netty是当前非常流行的网络通讯框架,当程序对网络数据处理时,需要保证高并发和高可靠,底层就可以用Netty支撑。本套课程详细讲解了Netty核心技术点,同时进行底层机制和源码剖析,并编写了大量的应用实例。通过学习可以快…

CLR via C# 阅读 笔记

初读  CLR Via C# 有一些 名词需要记忆: 1、CLR: Common Language Runtime (公共语言运行时) 可有多种编程语言使用的Runtime. 其核心功能是: 内存管理、 程序集加载、 安全性、 异常处理和线程同步等; 2、 Managed Module (托管模块) 托管模…

php异步轮询如何实现,深入剖析JavaScript异步之事件轮询

本篇文章给大家带来的内容是关于深入剖析JavsScript异步之事件轮询,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。JavsScript 是一门单线程的编程语言,这就意味着一个时间里只能处理一件事,也就是说 …

ECMAScript 实现继承的几种方式

1. 原形链 function Father() { this.fatherName "licus"; } function Children() { this.chidrenName "king"; } Children.prototype new Father(); 2.借用构造函数 function Father() { this.fatherName "licus"; } function Children() {…

微信小程序php实现登陆的代码,微信小程序实现微信登录

步骤:1.调用wx.login得到code返回的结果示例:{code:"051nI5Pa1XJkDs0773Pa1OWYOa1nI5PF"errMsg:"login:ok"}2.拿code换取session_key与openid这里使用服务端来请求,以php为例$code $this->input->post(code);$jso…

《C++ Primer Plus(第六版)》(25)(第十三章 类继承 笔记)

1.派生类构造函数的要点: 首先创建基类对象; 应通过成员初始化列表将基类的初始化信息传递给基类的构造函数; 派生类构造函数应初始化新增的数据成员 2.首先执行派生类的析构函数,然后自动调用基类的析构函数. 3.基类指针可以在不进行显式类型转换的情况下指向派生类对象,基类引…

php实际应用小例子,PHP4实际应用经验篇(6)

现在,你已经明白PHP允许你嵌套条件语句。然而,如果你再看看那个用来示范此概念的例子时你将同意那是既复杂又令人感到可怕。--------------------------------------------------------------------------------if($day"Thursday"){if($time&q…

electron知识点

1.打开chrome开发工具栏: BrowserWindow.openDevTools(); 转载于:https://www.cnblogs.com/cag2050/p/6227987.html

oracle 12c缩容磁盘组,oracle 表收缩

当使用delete表数据后,空间无法释放,可以使用表收缩释放表空间;注意:当delete表大量数据的时候要注意undo,可以使用:alter table emp nologging; 让其不生产日志一、表的增长方式当表被创建后&#xff0…

php解决与处理网站高并发 大流量访问的方法

方法/步骤 首先,确认服务器硬件是否足够支持当前的流量 普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大, 那么必须首先配置一台更高性能的专用服务器才能解决问题 ,否则怎么优化都不可能彻底解决性能问题。 …

oracle 自动表分析,Oracle自动分析索引,表

--分析表REATE OR REPLACE PROCEDURE analyze_tables IS--rec integer;v_date1 number(10);v_date2 number(10);V_SQL varchar2(512);v_msg varchar2(512);BEGINFOR rec IN (SELECT table_name FROM user_tables)LOOPv_date1 : dbms_utility.get_time;V_SQL : ANALYZE TABLE |…

JavaScript 函数(作用域以及闭包)

JavaScript 函数(作用域以及闭包) ・执行环境及作用域 执行环境定义了变量或函数有权访问的其他数据。 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量或函数都保存在这个对象中, 虽然我们编写的代码无法访问这个对…