如何使用scapy从ftp服务器检索文件?

时间:2018-02-26 13:35:18

标签: python scapy

我试图通过FTP协议使用来自指定目的地的scapy来获取文件但是它失败了,即使我能够创建连接并登录到FTP服务器但是没有检索到文件。

'''

! /usr/bin/python2.7

usage: sudo python2.7 client.py [ftp-server-ip]

username and password is currently hardcoded
'''

from scapy.all import *
from random import randint
import sys



class FTPClinet:

    def __init__(self, dst):
        self.sport = random.randint(1024, 65535)
        # self.src = src
        self.dst = "90.130.70.73"
        self.next_seq = 1000
        self.next_ack = 0
        self.basic_pkt = IP(src="127.0.0.1",dst=self.dst)/TCP(sport=self.sport, dport=21)
        self.tcp_flags = {
            'TCP_FIN': 0x01, 
            'TCP_SYN': 0x02, 
            'TCP_RST': 0x04, 
            'TCP_PSH': 0x08, 
            'TCP_ACK': 0x10, 
            'TCP_URG': 0x20, 
            'TCP_ECE': 0x40, 
            'TCP_CWR': 0x80
        }

    def send_syn(self):
        synack = None
        ip = IP(dst=self.dst)
        syn = TCP(sport=self.sport, dport=21, flags='S', seq=self.next_seq, ack=self.next_ack)
        while not synack:
            synack = sr1(ip/syn, timeout=1)

        self.next_seq = synack[TCP].ack
        return synack

    def send_ack(self, pkt):
        l = 0
        ip = IP(dst=self.dst)
        self.next_ack = pkt[TCP].seq + self.get_next_ack(pkt)
        ack = TCP(sport=self.sport, dport=21, flags='A', seq=self.next_seq, ack=self.next_ack)
        send(ip/ack)

    def get_next_ack(self, pkt):
        total_len = pkt.getlayer(IP).len
        ip_hdr_len = pkt.getlayer(IP).ihl * 32 / 8
        tcp_hdr_len = pkt.getlayer(TCP).dataofs * 32 / 8
        ans = total_len - ip_hdr_len - tcp_hdr_len
        return (ans if ans else 1)

    def handshake(self):
        synack = self.send_syn()
        self.send_ack(synack)
        print "sniff called"
        sniff(timeout=4, lfilter=self.sniff_filter, prn=self.manage_resp)
        print "Handshake complete"

    def get_file(self, user, passwd, filen):
        user = "USER " + user + '\r\n'
        passwd = "PASS " + passwd + '\r\n'
        filen = "RETR " +filen + '\r\n'
        cwd = "PASV" + '\r\n'
        pkt = self.basic_pkt
        pkt[TCP].flags = 'AP'
        pkt[TCP].seq = self.next_seq
        pkt[TCP].ack = self.next_ack
        ftp_user = pkt/user
        self.send_pkt(ftp_user)
        print "userid sent"     
        pkt[TCP].seq = self.next_seq
        pkt[TCP].ack = self.next_ack
        ftp_pass = pkt/passwd
        self.send_pkt(ftp_pass)
        print "password sent"       
        pkt[TCP].sport = pkt[TCP].sport - 1     
        pkt[TCP].dport = 20     
        pkt[TCP].seq = self.next_seq
        pkt[TCP].ack = self.next_ack
        ftp_filen = pkt/filen
        self.send_pkt(ftp_filen)
            print "retrieved file"

    def sniff_filter(self, pkt):
        return pkt.haslayer(IP) and pkt[IP].src==self.dst and pkt.haslayer(TCP) and pkt[TCP].dport == self.sport and pkt[TCP].sport == 21

    def manage_resp(self, pkt):
        print pkt.show()
        if (pkt[TCP].flags == 16L):
            self.next_seq = pkt[TCP].ack
        elif (pkt[TCP].flags & self.tcp_flags['TCP_ACK']):
            self.next_seq = pkt[TCP].ack
            self.send_ack(pkt)
        elif Raw in pkt:
            print "raw packet khamar"
            print pkt[Raw]
            send_ack(pkt)
        else:
            print 'Unknown'
            print pkt.show()
            send_ack(pkt)

    def send_p(self,pkt=None):
        if pkt:
            sr1(pkt)
        sniff(timeout=4, lfilter=self.sniff_filter, prn=self.manage_resp)
        return


    def send_pkt(self, pkt=None):
        if pkt:
            send(pkt)
        sniff(timeout=4, lfilter=self.sniff_filter, prn=self.manage_resp)
        return

    def close(self):
        resp = None
        pkt = self.basic_pkt
        pkt[TCP].flags = 'FA'
        pkt[TCP].seq = self.next_seq
        pkt[TCP].ack = self.next_ack
        print pkt.show()
        while not resp:
            resp = sr1(pkt, timeout=4)
        # self.send_ack(resp)
        self.send_pkt(resp)

h = FTPClinet(sys.argv[1])
h.handshake()
h.get_file("anonymous","","1KB.zip")
h.close()

0 个答案:

没有答案