利用Py-Socket模块做的一个不登陆windows服务器自动实现替换或者调用自动拨号功能

xu言:

最近,有个朋友让我帮忙“搞点事情”,然后正好在学习socket模块,这个模块666啊,基本上可以实现远程服务器cmd shell的大部分功能。好,话不多说,直接上码~

由于很多电信运营商都会封杀UDP端口,外网服务器这种就不建议使用UDP端口了。直接使用TCP来实现,那么还有一个问题。windows的拨号和把账号填入adsl客户端上面的方法怎么处理呢?

 

cmd自带命令:

rasdial 宽带连接 /disconnect && rasdial 宽带连接 %s %s

 

三方工具:

http://www.nirsoft.net/utils/dialupass.html

Dialupass /setpass 宽带连接 %s %s

 

如果以上两个命令你都搞清楚是什么了,那么下面代码就很好写了:

 

Server:

复制代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "loki"

import json
import socket
import struct
import subprocess
import time

s_ip = ("0.0.0.0", 19999)
c_time = time.strftime("%Y-%m-%d %X", time.localtime())

win_ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
win_ser.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
win_ser.bind(s_ip)
win_ser.listen(5)
print('Server listening begin ,port %s' % s_ip[1])

#  get socket
while 1:
    conn, address = win_ser.accept()

    while 1:
        try:
            cmd = conn.recv(1024)
            print('Receive client[%s] command : %s %s' % (address, cmd, c_time))
            client_cmd = cmd.decode('utf-8')
            client_cmd = client_cmd.split()
            cmd_len = len(client_cmd)
            if cmd_len == 3 and client_cmd[0] == 'Dial':
                username = client_cmd[1]
                password = client_cmd[2]
                # command = "echo %s %s" % (username, password)
#                 command = "rasdial 宽带连接 /disconnect && rasdial 宽带连接 %s %s" % (username, password)
                command = "Dialupass /setpass 宽带连接 %s %s" % (username, password)
                cmd_execute = subprocess.Popen(command,
                                               shell=True,
                                               stdout=subprocess.PIPE,
                                               stderr=subprocess.PIPE)
                stdout = cmd_execute.stdout.read()
                stderr = cmd_execute.stdout.read()
                # if not cmd:
                #     break

                # DIY head
                header_dict = {
                    'total_size': len(stdout) + len(stderr),
                    'filename': None
                }
                header_bytes = json.dumps(header_dict).encode('utf-8')

                # Send head length
                header_len = struct.pack('i', len(header_bytes))
                conn.send(header_len)
                # Send head
                conn.send(header_bytes)
                # conn.send(cmd_execute)

                # Send data
                conn.send(stdout)
                conn.send(stderr)
            else:
                print('hello...')
                stdout = 'Please input correct command!Format:Dial <username> <password>'.encode('utf-8')
                # DIY head
                header_dict = {
                    'total_size': len(stdout),
                    'filename': None
                }
                header_bytes = json.dumps(header_dict).encode('utf-8')

                # Send head length
                header_len = struct.pack('i', len(header_bytes))
                conn.send(header_len)
                # Send head
                conn.send(header_bytes)
                # conn.send(cmd_execute)

                # Send data
                conn.send(stdout)

        except Exception as e:
            print(e)
            break
    conn.close()
# win_ser.close()
复制代码

 

Client:

复制代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "loki"

import json
import socket
import struct

c_ip = ('127.0.0.1', 19999)
win_cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
win_cli.connect(c_ip)

while 1:
    mes = input('>>').strip()
    if mes == 'Quit':
        break
    if not mes:
        continue

    win_cli.send(mes.encode('utf-8'))
    # receive head length
    res_head_len = win_cli.recv(4)
    # unpack head length
    # print(res_head_len, type(res_head_len))
    head_size = struct.unpack('i', res_head_len)[0]
    # receive head length content
    header_bytes = win_cli.recv(head_size).decode('utf-8')
    # to head dic json
    header_json = json.loads(header_bytes)
    # get data length
    data_size = header_json['total_size']

    # receive data to the length  of the header
    receive_size = 0
    total_data = b''
    while receive_size < data_size:
        data_receive = win_cli.recv(1024)
        if (data_size - len(data_receive)) < 1024:
            left_data = win_cli.recv(data_size - len(data_receive))
            total_data += left_data
        total_data += data_receive
        receive_size += len(data_receive)

    print(total_data.decode('GBK'))
复制代码

 

Warp-up:

1.期间遇到系统是xp、win2003大部分都是32位,建议编译的时候使用最高不能超过python34版本

2.为了更好的配合windows服务启动 使用pyinstaller -F 把py代码转换为exe

3.使用exe to 服务包把exe程序作为服务启动(期间用到:instsrv.exe <服务名> x:\xxx\srvany.exe,并且自己创建注册表项Parameters.项下面需要2个字符串值AppDirectory(目录路径)和Application(绝对路径)),添加服务成功后还需要在相应创建的服务上 服务-属性-登陆-打勾“服务与桌面交互”

 

遗留问题,如何配合服务关闭的时候kill掉这个socket的server进程。感觉还有很多地方都可以用到,比如监控、比如自动化执行某些任务。。。当然,安全问题也需要深入研究。避免被恶意利用做非法用途。以上代码仅供学习研究之用,切勿做非法用途!

 

posted @   Cong0ks  阅读(315)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示