反序列化漏洞最近一直不得安宁,先有Apache Commons Collections通过反序列化实现远程代码执行,再有Spring RMI 反序列化漏洞,最新又有了common upload file的反序列化漏洞CVE-2016-1000031(https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000031)
/** * Reads the state of this object during deserialization. * * @param in The stream from which the state should be read. * * @throws IOException if an error occurs. * @throws ClassNotFoundException if class cannot be found. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // read values in.defaultReadObject(); /* One expected use of serialization is to migrate HTTP sessions * containing a DiskFileItem between JVMs. Particularly if the JVMs are * on different machines It is possible that the repository location is * not valid so validate it. */ if (repository != null) { if (repository.isDirectory()) { // Check path for nulls if (repository.getPath().contains("\0")) { throw new IOException(format( "The repository [%s] contains a null character", repository.getPath())); } } else { throw new IOException(format( "The repository [%s] is not a directory", repository.getAbsolutePath())); } } OutputStream output = getOutputStream(); if (cachedContent != null) { output.write(cachedContent); } else { FileInputStream input = new FileInputStream(dfosFile); IOUtils.copy(input, output); dfosFile.delete(); dfosFile = null; } output.close(); cachedContent = null; }DiskFileItem里面封装了反序列的方法,在反序列化的方法里
private transient DeferredFileOutputStream dfos; public OutputStream getOutputStream() throws IOException { if (dfos == null) { File outputFile = getTempFile(); dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); } return dfos; }dfos 是不可序列化的,反序列化中dfos为空,只能获取临时文件
protected File getTempFile() { if (tempFile == null) { File tempDir = repository; if (tempDir == null) { tempDir = new File(System.getProperty("java.io.tmpdir")); } String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId()); tempFile = new File(tempDir, tempFileName); } return tempFile; }
Apache Commons FileUpload DiskFileItem File Manipulation Remote Code ExecutionDiskFileItem中注入执行代码,也无法在反序列化的时候被执行,这个和collection的反序列化的漏洞的风险是完全不同的,不清楚为何描述成可以操纵执行远端代码,是否是只要是反序列化的漏洞就是可以执行远端代码?
final boolean isInvalid() { if (status == null) { status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED : PathStatus.INVALID; } return status == PathStatus.INVALID; }
if (repository != null) { if (repository.isDirectory()) { // Check path for nulls if (repository.getPath().contains("\0")) { throw new IOException(format( "The repository [%s] contains a null character", repository.getPath())); } } else { throw new IOException(format( "The repository [%s] is not a directory", repository.getAbsolutePath())); } }
String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId());