fix direction again; make sure injection happens after low-ttl reponse was received

This commit is contained in:
Christian Ulrich 2020-07-18 12:41:07 +02:00
parent c2c36c3a1e
commit 10f9ca135a
No known key found for this signature in database
GPG Key ID: 8241BE099775A097
1 changed files with 12 additions and 13 deletions

View File

@ -84,13 +84,12 @@ proc injectSyns(rawFd: AsyncFD, srcIp: IpAddress, srcPort: Port,
seqNums: seq[uint32]) {.async.} = seqNums: seq[uint32]) {.async.} =
for seqNum in seqNums: for seqNum in seqNums:
let ipPacket = IpPacket(protocol: tcp, let ipPacket = IpPacket(protocol: tcp,
tcpIpSrc: dstIp, tcpIpSrc: srcIp,
tcpIpDst: srcIp, tcpIpDst: dstIp,
tcpPortSrc: srcPort, tcpPortSrc: srcPort,
tcpPortDst: dstPort, tcpPortDst: dstPort,
tcpSeqNumber: seqNum, tcpSeqNumber: seqNum,
tcpFlags: {SYN}) tcpFlags: {SYN})
echo &"injecting {dstIP}:{dstPort.int} -> {srcIp}:{srcPort.int} (seq {seqNum})"
try: try:
let packet = serialize(ipPacket) let packet = serialize(ipPacket)
var sockaddr: Sockaddr_storage var sockaddr: Sockaddr_storage
@ -100,7 +99,7 @@ proc injectSyns(rawFd: AsyncFD, srcIp: IpAddress, srcPort: Port,
cast[ptr SockAddr](addr sockaddr), sockaddrLen) cast[ptr SockAddr](addr sockaddr), sockaddrLen)
echo &"injected {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} (seq {seqNum})" echo &"injected {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} (seq {seqNum})"
except OSError as e: except OSError as e:
echo "cannot inject: ", e.msg echo "cannot inject {srcIp}:{srcPort.int} -> {dstIp}:{dstPort.int} (seq {seqNum}): ", e.msg
proc initPuncher*(srcPort: Port, dstIp: IpAddress, dstPorts: array[3, Port], proc initPuncher*(srcPort: Port, dstIp: IpAddress, dstPorts: array[3, Port],
seqNums: seq[uint32] = @[]): Future[TcpSyniPuncher] {.async.} = seqNums: seq[uint32] = @[]): Future[TcpSyniPuncher] {.async.} =
@ -133,22 +132,25 @@ proc doConnect(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress,
discard discard
proc doAccept(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress, dstPort: Port, proc doAccept(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress, dstPort: Port,
future: Future[AsyncSocket]) {.async.} = seqNums: seq[uint32], future: Future[AsyncSocket]) {.async.} =
let sock = newAsyncSocket() let sock = newAsyncSocket()
try:
sock.setSockOpt(OptReuseAddr, true) sock.setSockOpt(OptReuseAddr, true)
sock.getFd.setSockOptInt(IPPROTO_IP, IP_TTL, 2) sock.getFd.setSockOptInt(IPPROTO_IP, IP_TTL, 2)
sock.bindAddr(srcPort, $srcIp) sock.bindAddr(srcPort, $srcIp)
try:
await sock.connect($dstIp, dstPort) await sock.connect($dstIp, dstPort)
echo "connected during accept phase" echo "connected during accept phase"
sock.close() sock.close()
except OSError: except OSError:
discard discard
try: try:
let rawFd = setupTcpInjectingSocket()
asyncCheck injectSyns(rawFd, dstIp, dstPort, srcIp, srcPort, seqNums)
sock.getFd.setSockOptInt(IPPROTO_IP, IP_TTL, 64)
let connectedSock = await sock.accept() let connectedSock = await sock.accept()
future.complete(connectedSock) future.complete(connectedSock)
except OSError as e: except OSError as e:
echo &"accepting connection {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} failed: ", e.msg echo &"accepting connection {dstIP}:{dstPort.int} -> {srcIp}:{srcPort.int} failed: ", e.msg
discard discard
proc connect*(puncher: TcpSyniPuncher, proc connect*(puncher: TcpSyniPuncher,
@ -163,9 +165,6 @@ proc connect*(puncher: TcpSyniPuncher,
proc accept*(puncher: TcpSyniPuncher): Future[AsyncSocket] = proc accept*(puncher: TcpSyniPuncher): Future[AsyncSocket] =
result = newFuture[AsyncSocket]("tcp_syni.accept") result = newFuture[AsyncSocket]("tcp_syni.accept")
let rawFd = setupTcpInjectingSocket()
for dstPort in puncher.dstPorts: for dstPort in puncher.dstPorts:
asyncCheck doAccept(puncher.srcIp, puncher.srcPort, puncher.dstIp, dstPort, asyncCheck doAccept(puncher.srcIp, puncher.srcPort, puncher.dstIp, dstPort,
result) puncher.seqNums, result)
asyncCheck injectSyns(rawFd, puncher.srcIp, puncher.srcPort, puncher.dstIp,
dstPort, puncher.seqNums)