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…

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

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

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

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

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

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

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

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

《DSP using MATLAB》第6章开始了

看到第6章了,标记一下,全书近一半,继续加油 构建滤波器的三种元件: 下面是函数floor和size的部分帮助截图 转载于:https://www.cnblogs.com/ky027wh-sx/p/6235509.html

codeql php,使用codeql 挖掘 ofcms

前言网上关于codeql的文章并不多,国内现在对codeql的研究相对比较少,可能是因为codeql暂时没有中文文档,资料也相对较少,需要比较好的英语功底,但是我认为在随着代码量越来越多,传统的自动化漏洞挖掘工具的…

php 连接符.,PHP怎么在数字之间添加连接符

PHP实现数字之间添加连接符,我们可以通过PHP中的for循环思想来实现。这里的连接符指的是“-”符号。推荐参考:《PHP教程》那么对于新手来说,可能有一定难度。下面我们就通过简单的代码示例,给大家介绍PHP给数字之间添加连字符的实…

嵌入式linux 时间同步,解决嵌入式Linux中的时区问题

如果说让我做上层软件的工作,我做起来可以得心应手,但是让我做平台方面的工作(系统问题解决、驱动编写、软件移植等工作),确实不熟悉。所以很多问题都是摸着石头过河,没有经验。许多问题在有经验的朋友那里是小菜一碟,…

bzoj2243

2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6753 Solved: 2496[Submit][Status][Discuss]Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点…

eclipse linux windows 乱码,Ubuntu下Eclipse打开Windows下的工程文件乱码解决办法

Eclipse在Windows下默认使用的是GBK(包括GB2312)编码,而在Linux系统默认使用的是UTF-8编码,并且eclipse编码设置下拉列表不提供GBK编码可选项。如果eclipse打开工程或者文本乱码,基本可以肯定(因为常用的就这两种)这个工程/文本使用的是GBK编…

linux桌面旋转了180度,[多图]回顾每一款默认Ubuntu壁纸

每个默认的Ubuntu壁纸Ubuntu 4.10’Warty Warthog’当人们抱怨Ubuntu发行版中的“ 褐色 ”时,我经常想回到Ubuntu的第一张墙纸,以便他们的意见可以转变为“上下文”。事后看来,这只墙纸完全是一块毫无生气的带有徽标的棕色块。当然&#xff0…

【转】Apache 配置虚拟主机三种方式

Apache 配置虚拟主机三种方式 原文博客http://www.cnblogs.com/hi-bazinga/archive/2012/04/23/2466605.html一、基于IP 1. 假设服务器有个IP地址为192.168.1.10,使用ifconfig在同一个网络接口eth0上绑定3个IP: [rootlocalhost root]# ifconfig eth0:1 1…

linux weblogic 防火墙,本地访问weblogic控制台无反应,关闭linux操作系统防火墙

有时候,我们在Linux操作系统上成功启动了weblogic,也查看了7001端口的状态是开启的。但是访问weblogic控制台没有反应,也没有报错。使用 netstat -ano | grep 7001 查看端口的状态可是访问weblogic控制台,还是没有反应。我们在本地…

fedora linux搜狗输入法,在Fedora 28系统下安装搜狗输入法

以下介绍在Fedora 28系统下安装搜狗输入法,也适用在Fedora 27下的安装,亲测可以。先声明一下,在Fedora 27及以后版本中出现的输入框候选词界面变形但不影响使用。第一步:安装fzug软件源具体方法如下:1.添加 FZUG 源Fed…

linux reboot命 过程,IDRAC安装dell服务器操作系统(linux or windows),用到生命周期管理器...

1、首先给服务器装上idrac模块,然后给idrac配置一个远程IP,用作管理2、在web界面输入IP,弹出以下界面,输入账号密码登录3、认证成功后,点击虚拟控制台启动4、进入如下界面,点击菜单栏的《虚拟介质》&#x…

DroidPlugin插件化开发

360手机助手使用的 DroidPlugin,它是360手机助手团队在Android系统上实现了一种插件机制。它可以在无需安装、修改的情况下运行APK文件,此机制对改进大型APP的架构,实现多团队协作开发具有一定的好处。 它是一种新的插件机制,一种免安装的运行…

io wait linux,另辟蹊径-诊断工具之 IO wait

导读最近在做日志的实时同步,上线之前是做过单份线上日志压力测试的,消息队列和客户端、本机都没问题,但是没想到上了第二份日志之后,问题来了:1、问题:集群中的某台机器 top 看到负载巨高,集群…

Oracle第二天

Oracle第二天 整体安排(3天) 第一天:Oracle的安装配置(服务端和客户端),SQL增强(单表查询)。 第二天:SQL增强(多表查询、子查询、伪列-分页)&…

linux搭建虚拟化平台报告,部署KVM虚拟化平台------搭建(示例代码)

一 、部署KVM虚拟化平台hyper-v是windows中的虚拟化1、KVM模块直接整合在Linux内核中,kvm是内核模块,虚拟机与kvm模块之间为管理工具2、KVM组成1.KVM Driver---虚拟机创建---虚拟机内存分配---虚拟CPU寄存器读写---虚拟CPU运行2.QEMU (经过简化与修改)--…