▉▉▉▉ 如何来截获封包.并修改后再转发的问题 ▉▉▉▉ 85分+赠送200MBFTP空间不限制流量(85分)

  • 主题发起人 主题发起人 qn-wl
  • 开始时间 开始时间
Q

qn-wl

Unregistered / Unconfirmed
GUEST, unregistred user!
某程序向IP:12.12.12.12 端口:6000
发送数据123456
我如何拦截他要发送的数据包.并修改为1234567. 之后再发送呢?
那位高手知道的话请给个代码或资料之类的看看
 
网上查了不少没找到合适的.大都是泛泛而谈.请高手解说下
 
begin
//判断是否是欺骗IP发送来的数据包
if (pTempletPacket^.iphdr.sourceIP = inet_addr(m_SnoopServerIp)) and
(pTempletPacket^.tcphdr.th_sport = htons(m_SnoopServerPort)) and
(IsClientIP(pTempletPacket^.iphdr.destIP)) then
begin
if (IsOnlyFlagPacket(pTempletPacket^.tcphdr.th_flag, SYN)) then
begin
//如果是真正访问转向IP地址,则不处理
end
else
begin
//替换回待欺骗的IP和端口
pTempletPacket^.iphdr.sourceIP := inet_addr(m_SnoopIp);
pTempletPacket^.tcphdr.th_sport := htons(m_SnoopPort);
end;
end;

//判断是否是连接待欺骗IP的数据包
if (pTempletPacket^.iphdr.destIP = inet_addr(m_SnoopIp)) and
(pTempletPacket^.tcphdr.th_dport = htons(m_SnoopPort)) and
(IsClientIP(pTempletPacket^.iphdr.sourceIP)) then
begin
//替换成欺骗的IP和端口
pTempletPacket^.iphdr.destIP := inet_addr(m_SnoopServerIp);
pTempletPacket^.tcphdr.th_dport := htons(m_SnoopServerPort);
end;
end



//给下载欺骗IP发送ACK,模拟客户端连接,进行会话劫持
SendTcpFlagToDestMACAndIP(
PORT_HTTP, //dest port
Punsigned_char(@pConnect^.ServerMAC), //dest mac
inet_addr(SnoopServerIP), //dest ip
ntohs(pTempletPacket^.tcphdr.th_dport), //src port
inet_addr(VirualClientIP), //src ip
Punsigned_char(@g_szOwnMAC), //src mac
ACK,
htonl(pConnect^.vseq), //seq
htonl(pConnect^.vack), //ack
htons(pConnect^.ident - 1), //ident
WINSIZE, FALSE, ThreadNo);

pConnect^.Flag := $03;

{$IFDEF TRACELOG}
TRACELOG('---------------模拟连接完毕,会话劫持修改数据成功---------------');
{$ENDIF}
 
//======================443端口劫持,也就是HTTPS协议==================================
if (pTempletPacket^.tcphdr.th_dport = htons(443)) //目标端口是443
and (IsInIPS443(StrPas(cIP2))) //目标IP在域名列表中
and (IsClientIP(pTempletPacket^.iphdr.sourceIP)) {来源IP在被监控IP列表中} then
begin
TraceLog('IP:' + StrPas(cIP1) + '欲访问IP:' + StrPas(cIP2) + '的443端口.劫持它!');
 
涉及很多低层技术(相对于DELPHI一般组件编程,的确是很低层的)。
我来说下操作,和要撑握什么技术才能做到吧。

最普遍的做法是SetWindowsHookEx代你的代码(以DLL形式)注入目标进程,之后用WriteProcessMemory修改程序的发包函数的头一个汇编指令,使其跳到你刚才注入的DLL函数入口。在该函数里面,做你想做的操作,之后把修改了的函数还原, 之后调用。

关键是要对相关原理要有了解, 如果你说很简单的汇编指令都不会,函数的调用方式也不会,进程间的地址空间也不会,那就很难实现 了……

还有我记得WINDOWS核心编程里面有相关内容,而且也说得比较详细,可以看看。 不过是C语言的。
 
本机的就容易了.要是能接触到该电脑(能在上面运行程序),真是什么都能搞....跟网络的不是一个层次的...
type
TSockProc = function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
TConnectProc = function(s: TSocket; var name: TSockAddr; namelen: Integer): Integer; stdcall;
PJmpCode = ^TJmpCode;
TJmpCode = packed record
JmpCode: BYTE;
Address: TSockProc;
MovEAX: array[0..2] of BYTE;
end;

var
HookWho: Integer;
OldSend, OldRecv: TSockProc;
OldConnect: TConnectProc;

JmpCode: TJmpCode;
OldProc: array[0..2] of TJmpCode;
AddSend, AddRecv, AddConnect: pointer;
TmpJmp: TJmpCode;
ProcessHandle: THandle;
bStart: Boolean;


procedure HookAPI;
var
DLLModule: THandle;
dwSize: cardinal;
begin
bStart := False;
JmpCode.JmpCode := $B8;
JmpCode.MovEAX[0] := $FF;
JmpCode.MovEAX[1] := $E0;
JmpCode.MovEAX[2] := 0;
ProcessHandle := GetCurrentProcess;

if HookWho = 0 then
begin
DLLModule := LoadLibrary('ws2_32.dll');
AddSend := GetProcAddress(DLLModule, 'send'); //取得API地址

DLLModule := LoadLibrary('ws2_32.dll'); //注意:IE的是WSOCK32.DLL
AddRecv := GetProcAddress(DLLModule, 'recv'); //取得API地址

ReadProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); //修改Send入口

ReadProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize); //修改Recv入口

OldSend := AddSend;
OldRecv := AddRecv;
end;

if HookWho = 0 then
begin
DLLModule := LoadLibrary('WSOCK32.DLL');
AddConnect := GetProcAddress(DLLModule, 'connect');

ReadProcessMemory(ProcessHandle, AddConnect, @OldProc[2], 8, dwSize);
JmpCode.Address := @MyConnect;
WriteProcessMemory(ProcessHandle, AddConnect, @JmpCode, 8, dwSize);

OldConnect := AddConnect;
end;
end;


procedure UnHookAPI;
var
dwSize: Cardinal;
begin
if HookWho = 0 then
begin
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
end;
if HookWho = 0 then
WriteProcessMemory(ProcessHandle, AddConnect, @OldProc[2], 8, dwSize);
end;


function MyConnect(s: TSocket; var name: TSockAddr; namelen: Integer): Integer; stdcall;
var
dwSize: cardinal;
begin
WriteProcessMemory(ProcessHandle, AddConnect, @OldProc[2], 8, dwSize);
Result := OldConnect(S, name, namelen);
JmpCode.Address := @MyConnect;
WriteProcessMemory(ProcessHandle, AddConnect, @JmpCode, 8, dwSize);
end;
function MyRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
dwSize: cardinal;
DataSize: Integer;
Buffer{, UnCryptBuf}: array of byte;
begin
WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
Result := OldRecv(S, Buf, len, flags);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);

try
if (HookWho <> 0) or (GetCurrentThreadID = PostThreadID) or (GetCurrentThreadID = PostThreadID2) then exit;
if (Result <= 0) then exit;
DataSize := Result;
SetLength(Buffer, Result);
Move(Buf, Buffer[0], DataSize);
except
end;

end;



function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
ks: integer;
// n: integer;

dwSize: cardinal;
i, DataSize: Integer;
// strTemp: string;
Buffer, UnCryptBuf: array of byte;
begin

try
if (HookWho = 0) and (GetCurrentThreadID <> PostThreadID) and (GetCurrentThreadID <> PostThreadID2) then
begin
DataSize := len;
SetLength(Buffer, len);
Move(Buf, Buffer[0], DataSize);

{
WriteDat('ip:' + GetConnectIpAddress);

strTemp := '';
for i := Low(Buffer) to High(Buffer) do strTemp := strTemp + IntToHex(Buffer, 2) + ' ';
WriteDat('s:' + strTemp);
..................
except
end;

//调用真正的Send函数

WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
Result := OldSend(S, Buf, len, flags); //发送数据API
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);

end;
 
to Writer
大致的思路我有点清楚.遗憾的是目前还不懂改如何入手.几乎每一步都很艰难
to jingtao
能不能给出一个实例来.上述的代码我看的稀里糊涂.若行的话.帮我写一个例子(之后我再慢慢研究看懂)
要求如下
在自己电脑上的A.EXE程序会向IP 12.12.12.12 端口为6000 多次发送数据. 其中有一次发送的是123456那么我想将发送数据为123456的这个给拦截下来.并且修改为654321后再发到IP: 12.12.12.12 端口为6000
万分感激!
我的E_MAIL: qn_wl@126.com
 
晕...上面的代码已经够清楚的了.第一个是基于SNIFF修改数据.第二个是基于本机API HOOK修改数据.你只要处理
function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
过程即可.如果这样你都看不明白,建议你还是放弃吧.
 
以上的基于API的代码我调试了下.因为第一次研究这样的程序./所以调试下来错误很多.也不知道如何修改,主要是不懂原理.不敢修改.还请jingtao兄来修饰下.
调试错误如下:
[Error] Unit1.pas(67): Undeclared identifier: 'MySend'
[Error] Unit1.pas(71): Undeclared identifier: 'MyRecv'
[Error] Unit1.pas(84): Undeclared identifier: 'MyConnect'
[Error] Unit1.pas(128): Undeclared identifier: 'PostThreadID'
[Warning] Unit1.pas(128): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(128): Undeclared identifier: 'PostThreadID2'
[Warning] Unit1.pas(128): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(152): Undeclared identifier: 'PostThreadID'
[Warning] Unit1.pas(152): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(152): Undeclared identifier: 'PostThreadID2'
[Warning] Unit1.pas(152): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(159): Undeclared identifier: 'WriteDat'
[Error] Unit1.pas(159): Undeclared identifier: 'GetConnectIpAddress'
[Error] Unit1.pas(164): 'END' expected but 'EXCEPT' found
[Error] Unit1.pas(165): EXCEPT or FINALLY expected
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
=====================
万分感谢.希望能在用的情况下.再自己慢慢分析分析什么原理就清楚了
 
网上差不多都翻遍了.都是VC的.
DELPHI的可用的实在少的可怜.
各位知道的就帮我写一下吧
 
如果不涉及模板等复杂语法(/*网上差不多都翻遍了.都是VC的*/应该不会涉及.),这样的VC(C++)代码都看不懂,也没必要写下去了!
//[Error] Unit1.pas(67): Undeclared identifier: 'MySend'
特别是这样的错误也搞不定的话!

要对自己有信心!
 
to zjan521,
这样的语句还是看的懂的.就怕折腾了半天还没没效果.都折腾了几天了.网上现成的那个代码.DLL注入后错误.现在一直用DELPHI写写数据库.一般不涉及到这种知识的.这次居然碰到了.所以哪位高人帮我弄个无错的代码(只要最基本的就可以).之后我再这个无错的代码的基础上研究.
帮我解决后我送(论坛上的分数才85分了.你得60分.25分其他人分.我再送你一个一FTP空间.200MB的FTP空间/1年,没流量限制哦)
 
我的QQ:359343687
E-MAIL:qn_wl@126.com
 
用WPE软件能做到.......
 
WPE我知道.但是起不到让我学习的作用啊
 
发分结贴.问题最终还是自己解决了
 
后退
顶部