content: package fuzion24.device.vulnerability.vulnerabilities.framework.zip;
  
  import android.content.Context;
  
  import org.apache.commons.compress.archivers.zip.ModdedZipArchiveOutputStream;
  import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
  
  import java.io.ByteArrayOutputStream;
  import java.io.DataInputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.zip.CRC32;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipException;
  import java.util.zip.ZipFile;
  
  import fuzion24.device.vulnerability.util.CPUArch;
  import fuzion24.device.vulnerability.vulnerabilities.VulnerabilityTest;
  
  /*
    C++   Header   64k Local File header name   Data
        +--------> +----------------------> +---------->
        length=64k classes.dex dex\035\A... dex\035\B...
        +--------> +---------> +---------->
   Java   Header     11 Name       Data
   */
  public class ZipBug9950697 implements VulnerabilityTest {
  
      public String getCVEorID(){
          return "ZipBug 9950697";
      }
  
      @Override
      public List<CPUArch> getSupportedArchitectures() {
          ArrayList<CPUArch> archs = new ArrayList<>();
          archs.add(CPUArch.ALL);
          return archs;
      }
  
      public boolean isVulnerable(Context context) throws Exception {
          ByteArrayOutputStream fileNameFunz = new ByteArrayOutputStream();
          ModdedZipArchiveOutputStream zaos = new ModdedZipArchiveOutputStream(fileNameFunz);
          ZipArchiveEntry zae = new ZipArchiveEntry("test_file");
          byte [] originalData = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes();
          byte [] modifiedData = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB".getBytes();
          zae.setMethod(ZipEntry.STORED);
          zae.setSize(originalData.length);
          CRC32 checker = new CRC32();
          checker.update(originalData);
          zae.setCrc(checker.getValue());
          zaos.putArchiveEntry(zae, originalData);
          zaos.write(originalData);
          zaos.closeArchiveEntry();
          zaos.writeRaw(modifiedData, 0, modifiedData.length);
  
          for(int i = 0; i < originalData.length - modifiedData.length; i++){
              zaos.writeRaw(new byte[]{0}, 0, 1);
          }
  
          zaos.flush();
  
          List<ZipArchiveEntry> entries = new ArrayList<>();
          entries.add(zae);
  
          zaos.finish(entries, new ArrayList<ZipArchiveEntry>());
  
          byte [] testZip = fileNameFunz.toByteArray();
  
          // write the result to a file
          File outputDir = context.getCacheDir();
          File badZip = File.createTempFile("prefix", "extension", outputDir);
          badZip.deleteOnExit();
          FileOutputStream outstream = new FileOutputStream(badZip);
          outstream.write(testZip);
          outstream.close();
  
          // see if we can still handle it
          ZipFile bad = new ZipFile(badZip);
          if(bad.size() != 1)
              throw new ZipException("Unexpected number of entries");
  
          ZipEntry ze = bad.entries().nextElement();
          DataInputStream dis = new DataInputStream(bad.getInputStream(ze));
          byte [] buf = new byte[(int)ze.getSize()];
          dis.readFully(buf);
          bad.close();
          return new String(buf).startsWith("AAAAAAAAAAAAAAA");
      }
  }
  