mirror of
https://github.com/snltty/linker.git
synced 2025-09-27 05:25:57 +08:00
ack欺骗
This commit is contained in:
10
.github/workflows/dotnet.yml
vendored
10
.github/workflows/dotnet.yml
vendored
@@ -220,16 +220,6 @@ jobs:
|
||||
asset_path: ./public/publish-zip/linker-linux-musl-arm64.zip
|
||||
asset_name: linker-linux-musl-arm64.zip
|
||||
asset_content_type: application/zip
|
||||
- name: upload-version-oss
|
||||
id: upload-version-oss
|
||||
uses: tvrcgo/oss-action@v0.1.1
|
||||
with:
|
||||
region: oss-cn-shenzhen
|
||||
key-id: ${{ secrets.ALIYUN_OSS_ID }}
|
||||
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
|
||||
bucket: ide-qbcode
|
||||
asset-path: ./public/version.txt
|
||||
target-path: /downloads/linker/version.txt
|
||||
- name: upload-install-service-oss
|
||||
id: upload-install-service-oss
|
||||
uses: tvrcgo/oss-action@v0.1.1
|
||||
|
@@ -48,6 +48,7 @@
|
||||
- **服务器穿透:** 使用端口或域名访问内网服务(支持`计划任务`,定时定长自动开启关闭,例如每天在上9点自动开启穿透,1小时后自动关闭穿透)。
|
||||
|
||||
##### 特色功能
|
||||
- **TCP-in-TCP优化:** 伪造ACK包优化TCP-in-TCP隧道
|
||||
- **网段映射:** 当多个设备不同的局域网使用相同的内网网段(如`192.168.1.0/24`)存在冲突时,网段映射可以让你继续顺利的使用点对网和网对网,例如配置`192.168.188.0/24->192.168.1.0/24`,就可以使用`192.168.188.2`访问`192.168.1.2`。
|
||||
- **应用层NAT:** 内置了使用`WinDivert`实现的应用层NAT,即使在`win7/8,win server2008/2012`这样的老系统无法使用系统NAT时也可以顺利使用点对网和网对网。
|
||||
- **应用层防火墙:** 内置了防火墙功能,应用于虚拟网卡、端口转发、socks5,可以精细控制客户端的访问权限,例如只允许A访问B的3389,其它客户端无法访问
|
||||
|
@@ -87,7 +87,7 @@ function writeUpload(data, tagName) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
data.jobs.build.steps.push({
|
||||
name: `upload-version-oss`,
|
||||
id: `upload-version-oss`,
|
||||
@@ -101,7 +101,7 @@ function writeUpload(data, tagName) {
|
||||
'target-path': `/downloads/linker/version.txt`
|
||||
}
|
||||
});
|
||||
|
||||
*/
|
||||
|
||||
data.jobs.build.steps.push({
|
||||
name: `upload-install-service-oss`,
|
||||
|
@@ -5,7 +5,9 @@ using System.Net.Sockets;
|
||||
|
||||
namespace linker.tun
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 伪造ACK操作类
|
||||
/// </summary>
|
||||
public unsafe sealed class FakeAckTransfer
|
||||
{
|
||||
private readonly ConcurrentDictionary<FackAckKey, FackAckState> dic = new(new FackAckKeyComparer());
|
||||
@@ -23,7 +25,7 @@ namespace linker.tun
|
||||
|
||||
fixed (byte* ptr = packet.Span)
|
||||
{
|
||||
FakeAckPacket originPacket = new FakeAckPacket(ptr);
|
||||
FakeAckPacket originPacket = new(ptr);
|
||||
if (originPacket.Version != 4 || originPacket.Protocol != ProtocolType.Tcp || originPacket.IsOnlySyn)
|
||||
{
|
||||
return false;
|
||||
@@ -73,26 +75,29 @@ namespace linker.tun
|
||||
{
|
||||
fixed (byte* ptr = packet.Span)
|
||||
{
|
||||
FakeAckPacket fakeAckTCPPacket = new FakeAckPacket(ptr);
|
||||
if (fakeAckTCPPacket.Version != 4 || fakeAckTCPPacket.Protocol != ProtocolType.Tcp || fakeAckTCPPacket.IsOnlySyn)
|
||||
FakeAckPacket originPacket = new(ptr);
|
||||
if (originPacket.Version != 4 || originPacket.Protocol != ProtocolType.Tcp || originPacket.IsOnlySyn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
FackAckKey key = new() { srcAddr = fakeAckTCPPacket.SrcAddr, srcPort = fakeAckTCPPacket.SrcPort, dstAddr = fakeAckTCPPacket.DstAddr, dstPort = fakeAckTCPPacket.DstPort };
|
||||
FackAckKey key = new() { srcAddr = originPacket.SrcAddr, srcPort = originPacket.SrcPort, dstAddr = originPacket.DstAddr, dstPort = originPacket.DstPort };
|
||||
//收到连接连接
|
||||
if (fakeAckTCPPacket.TcpFlagSyn && fakeAckTCPPacket.TcpFlagAck)
|
||||
if (originPacket.TcpFlagSyn && originPacket.TcpFlagAck)
|
||||
{
|
||||
FackAckState state = new() { Seq = fakeAckTCPPacket.Seq + 1 };
|
||||
FackAckState state = new() { Seq = originPacket.Seq + 1 };
|
||||
dic.AddOrUpdate(key, state, (a, b) => state);
|
||||
}
|
||||
//断开连接
|
||||
else if (fakeAckTCPPacket.TcpFlagFin || fakeAckTCPPacket.TcpFlagRst)
|
||||
else if (originPacket.TcpFlagFin || originPacket.TcpFlagRst)
|
||||
{
|
||||
dic.TryRemove(key, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
sealed class FackAckState
|
||||
{
|
||||
public uint Seq { get; set; }
|
||||
@@ -104,6 +109,9 @@ namespace linker.tun
|
||||
return drop;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 四元组缓存key
|
||||
/// </summary>
|
||||
struct FackAckKey
|
||||
{
|
||||
public uint srcAddr;
|
||||
@@ -111,6 +119,9 @@ namespace linker.tun
|
||||
public uint dstAddr;
|
||||
public ushort dstPort;
|
||||
}
|
||||
/// <summary>
|
||||
/// 四元组缓存key比较器
|
||||
/// </summary>
|
||||
sealed class FackAckKeyComparer : IEqualityComparer<FackAckKey>
|
||||
{
|
||||
public bool Equals(FackAckKey x, FackAckKey y)
|
||||
@@ -125,6 +136,9 @@ namespace linker.tun
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据包解析
|
||||
/// </summary>
|
||||
readonly unsafe struct FakeAckPacket
|
||||
{
|
||||
private readonly byte* ptr;
|
||||
@@ -200,44 +214,43 @@ namespace linker.tun
|
||||
/// 制作一个ACK包
|
||||
/// </summary>
|
||||
/// <param name="seq">给定一个序列号,可以从syn+ack包中+1获得</param>
|
||||
/// <param name="dstPtr">目标内存</param>
|
||||
/// <param name="ipPtr">目标内存</param>
|
||||
/// <returns></returns>
|
||||
public readonly unsafe ushort ToAck(uint seq, byte* dstPtr)
|
||||
public readonly unsafe ushort ToAck(uint seq, byte* ipPtr)
|
||||
{
|
||||
//复制一份IP+TCP头部
|
||||
int _ipHeadLength = (*ptr & 0b1111) * 4;
|
||||
int _tcpHeaderLength = (*(ptr + _ipHeadLength + 12) >> 4) * 4;
|
||||
int _headerLength = _ipHeadLength + _tcpHeaderLength;
|
||||
new Span<byte>(ptr, _headerLength).CopyTo(new Span<byte>(dstPtr, _headerLength));
|
||||
new Span<byte>(ptr, _headerLength).CopyTo(new Span<byte>(ipPtr, _headerLength));
|
||||
|
||||
byte* tcpPtr = dstPtr + _ipHeadLength;
|
||||
//TCP头指针
|
||||
byte* tcpPtr = ipPtr + _ipHeadLength;
|
||||
|
||||
ushort totalLength = BinaryPrimitives.ReverseEndianness(*(ushort*)(dstPtr + 2));
|
||||
int ipHeaderLength = (*dstPtr & 0b1111) * 4;
|
||||
ushort totalLength = BinaryPrimitives.ReverseEndianness(*(ushort*)(ipPtr + 2));
|
||||
int ipHeaderLength = (*ipPtr & 0b1111) * 4;
|
||||
int tcpHeaderLength = (*(tcpPtr + 12) >> 4) * 4;
|
||||
uint payloadLength = (uint)(totalLength - ipHeaderLength - tcpHeaderLength);
|
||||
totalLength = (ushort)(ipHeaderLength + tcpHeaderLength);
|
||||
|
||||
//交换地址和端口
|
||||
(*(uint*)(dstPtr + 16), *(uint*)(dstPtr + 12)) = (*(uint*)(dstPtr + 12), *(uint*)(dstPtr + 16));
|
||||
(*(uint*)(ipPtr + 16), *(uint*)(ipPtr + 12)) = (*(uint*)(ipPtr + 12), *(uint*)(ipPtr + 16));
|
||||
(*(ushort*)(tcpPtr + 2), *(ushort*)(tcpPtr)) = (*(ushort*)(tcpPtr), *(ushort*)(tcpPtr + 2));
|
||||
|
||||
|
||||
//设置总长度 = IP头长度 + TCP头长度
|
||||
*(ushort*)(dstPtr + 2) = BinaryPrimitives.ReverseEndianness(totalLength);
|
||||
//设置总长度
|
||||
*(ushort*)(ipPtr + 2) = BinaryPrimitives.ReverseEndianness(totalLength);
|
||||
|
||||
//重置分片相关信息
|
||||
*(ushort*)(dstPtr + 4) = 0; // 清除分片偏移和标志
|
||||
*(ushort*)(dstPtr + 6) = 0; // 清除更多分片标志
|
||||
*(ushort*)(ipPtr + 4) = 0; // 清除分片偏移和标志
|
||||
*(ushort*)(ipPtr + 6) = 0; // 清除更多分片标志
|
||||
|
||||
//源序列号
|
||||
uint _seq = BinaryPrimitives.ReverseEndianness(*(uint*)(tcpPtr + 4));
|
||||
//新确认号 = 序列号+ 数据长度
|
||||
uint cq = _seq + payloadLength;
|
||||
|
||||
//设置序列号
|
||||
*(uint*)(tcpPtr + 4) = BinaryPrimitives.ReverseEndianness(seq);
|
||||
//设置确认号
|
||||
*(uint*)(tcpPtr + 8) = BinaryPrimitives.ReverseEndianness(cq);
|
||||
*(uint*)(tcpPtr + 8) = BinaryPrimitives.ReverseEndianness(_seq + payloadLength);
|
||||
|
||||
//设置TCP标志位为ACK,其他标志位清除
|
||||
*(tcpPtr + 13) = 0b00010000;
|
||||
@@ -246,7 +259,7 @@ namespace linker.tun
|
||||
*(ushort*)(tcpPtr + 14) = BinaryPrimitives.ReverseEndianness((ushort)65535);
|
||||
|
||||
//计算校验和
|
||||
ChecksumHelper.Checksum(dstPtr, totalLength);
|
||||
ChecksumHelper.Checksum(ipPtr, totalLength);
|
||||
|
||||
//只需要IP头+TCP头
|
||||
return totalLength;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
v1.9.0
|
||||
2025-08-30 15:59:20
|
||||
2025-08-30 20:51:10
|
||||
1. 一些累计更新
|
||||
2. 服务器转发多节点
|
||||
3. 虚拟网卡下伪造ACK为TCP-in-TCP隧道提速
|
||||
|
Reference in New Issue
Block a user