端口转发工具(python)

  • 内容
  • 相关

利用 Python 的 Socket 端口转发,用于远程维护
如果连接不到远程,会 sleep 36s,最多尝试 200 次(即两小时)

rtcp.py使用场景之一如下:


A服务器在内网,公网无法直接访问这台服务器,但是A服务器可以联网访问公网的B服务器(假设IP为222.2.2.2)。
我们也可以访问公网的B服务器。我们的目标是访问A服务器的22端口。那么可以这样:
1. 在B服务器上运行:
./rtcp.py l:10001 l:10002
表示在本地监听了10001与10002两个端口,这样,这两个端口就可以互相传输数据了。
2. 在A服务器上运行:
./rtcp.py c:localhost:22 c:222.2.2.2:10001
表示连接本地的22端口与B服务器的10001端口,这两个端口也可以互相传输数据了。
3. 然后我们就可以这样来访问A服务器的22端口了:
ssh 222.2.2.2 -p 10002

原理很简单,这个命令执行后,B服务器的10002端口接收到的任何数据都会传给10001端口,此时,A服务器是连接了B服务器的10001端口的,数据就会传给A服务器,最终进入A服务器的22端口。

作者:余弦


#!/usr/bin/env python
# coding=utf-8

'''
filename:rtcp.py
@desc:
利用python的socket端口转发,用于远程维护
如果连接不到远程,会sleep 36s,最多尝试200(即两小时)
@usage:
./rtcp.py stream1 stream2
stream为:l:port或c:host:port
l:port表示监听指定的本地端口
c:host:port表示监听远程指定的端口
@author: watercloud, zd, knownsec team
@web: www.knownsec.com, blog.knownsec.com
@date: 2009-7
'''

import socket
import sys
import threading
import time

streams = [None, None]  # 存放需要进行数据转发的两个数据流(都是SocketObj对象)
debug = 1  # 调试状态 0 or 1

def _usage():
    print 'Usage: ./rtcp.py stream1 stream2\nstream : l:port  or c:host:port'

def _get_another_stream(num):
    '''
    从streams获取另外一个流对象,如果当前为空,则等待
    '''
    if num == 0:
        num = 1
    elif num == 1:
        num = 0
    else:
        raise "ERROR"

    while True:
        if streams[num] == 'quit':
            print("can't connect to the target, quit now!")
            sys.exit(1)

        if streams[num] != None:
            return streams[num]
        else:
            time.sleep(1)

def _xstream(num, s1, s2):
    '''
    交换两个流的数据
    num为当前流编号,主要用于调试目的,区分两个回路状态用。
    '''
    try:
        while True:
            #注意,recv函数会阻塞,直到对端完全关闭(close后还需要一定时间才能关闭,最快关闭方法是shutdow)
            buff = s1.recv(1024)
            if debug > 0:
                print num,"recv"
            if len(buff) == 0: #对端关闭连接,读不到数据
                print num,"one closed"
                break
            s2.sendall(buff)
            if debug > 0:
                print num,"sendall"
    except :
        print num,"one connect closed."

    try:
        s1.shutdown(socket.SHUT_RDWR)
        s1.close()
    except:
        pass

    try:
        s2.shutdown(socket.SHUT_RDWR)
        s2.close()
    except:
        pass

    streams[0] = None
    streams[1] = None
    print num, "CLOSED"

def _server(port, num):
    '''
    处理服务情况,num为流编号(第0号还是第1号)
    '''
    srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    srv.bind(('0.0.0.0', port))
    srv.listen(1)
    while True:
        conn, addr = srv.accept()
        print "connected from:", addr
        streams[num] = conn  # 放入本端流对象
        s2 = _get_another_stream(num)  # 获取另一端流对象
        _xstream(num, conn, s2)

def _connect(host, port, num):
    '''	处理连接,num为流编号(第0号还是第1号)
    @note: 如果连接不到远程,会sleep 36s,最多尝试200(即两小时)
    '''
    not_connet_time = 0
    wait_time = 36
    try_cnt = 199
    while True:
        if not_connet_time > try_cnt:
            streams[num] = 'quit'
            print('not connected')
            return None

        conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            conn.connect((host, port))
        except Exception, e:
            print ('can not connect %s:%s!' % (host, port))
            not_connet_time += 1
            time.sleep(wait_time)
            continue

        print "connected to %s:%i" % (host, port)
        streams[num] = conn  #放入本端流对象
        s2 = _get_another_stream(num) #获取另一端流对象
        _xstream(num, conn, s2)


if __name__ == '__main__':
    if len(sys.argv) != 3:
        _usage()
        sys.exit(1)
    tlist = []  # 线程列表,最终存放两个线程对象
    targv = [sys.argv[1], sys.argv[2] ]
    for i in [0, 1]:
        s = targv[i]  # stream描述 c:ip:port 或 l:port
        sl = s.split(':')
        if len(sl) == 2 and (sl[0] == 'l' or sl[0] == 'L'):  # l:port
            t = threading.Thread(target=_server, args=(int(sl[1]), i))
            tlist.append(t)
        elif len(sl) == 3 and (sl[0] == 'c' or sl[0] == 'C'):  # c:host:port
            t = threading.Thread(target=_connect, args=(sl[1], int(sl[2]), i))
            tlist.append(t)
        else:
            _usage()
            sys.exit(1)

    for t in tlist:
        t.start()
    for t in tlist:
        t.join()
    sys.exit(0)





  文件名稱:响应国家号召,禁止资源下载

  更新時間:

  下載声明:响应国家号召,禁止资源下载

立即下載

下载链接

网盘下载

响应国家号召,禁止资源下载

本文标签:

版权声明:若无特殊注明,本文皆为《颓废》原创,转载请保留文章出处。

收录状态:[百度已收录] | [360已收录] | [搜狗已收录]

本文链接:端口转发工具(python) - https://www.0dayhack.com/post-662.html

严重声明:本站内容来自于互联网,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规,黑客不是骇客,黑客维护网络安全

发表评论

电子邮件地址不会被公开。 必填项已用*标注