首页
论坛
课程
招聘
[原创]InlineHook网络数据发送接收函数(反钓鱼,反盗号)
2013-9-14 22:48 5730

[原创]InlineHook网络数据发送接收函数(反钓鱼,反盗号)

2013-9-14 22:48
5730
众所周知,现在几乎所有的“刷QB”以及“刷枪”软件都是病毒木马或者是钓鱼盗号软件。
在现在网络骗子盛行的年代,作为看雪的一员当然不能袖手旁观。

首先我们可以知道绝大多数的钓鱼或盗号程序都是通过邮件、FTP、ASP空间等方法来接受用户信息为了可以拦截到他们的行为,我们可以从send、recv这两个关键函数入手,在这里我使用的是Hook api 的方法,有兴趣的朋友可以去研究下其他方法!

开场白就讲到这里了,下面大家自己看代码吧(附注释)

// HookSR.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"   
#include <stdio.h>   
#include <Windows.h>   
//#include <Winsock2.h>   
   
   
#ifdef _MANAGED   
#pragma managed(push, off)   
#endif   
   
#define HOOK_API extern "C" _declspec(dllexport)   
//本dll的handle   
HANDLE g_hInstance = NULL;   
//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数   
BYTE g_btNewBytes[8] = { 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };   
//保存原API入口的8个字节   
DWORD g_dwOldBytes[2][2] = { 0x0, 0x0, 0x0, 0x0 };   
//钩子句柄   
HHOOK    g_hOldHook = NULL;   
//API中send函数的地址   
DWORD g_pSend = 0;   
DWORD g_pRecv = 0;   
//事务,解决同步问题   
HANDLE g_hSendEvent = NULL;   
HANDLE g_hRecvEvent = NULL;   
//自己的send函数地址,参数必须与API的send函数地址相同   
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags );   
int _stdcall hook_recv(IN SOCKET s,OUT char FAR * buf,IN int len,IN int flags );   
//要Hook的进程和主线程ID号   
DWORD g_dwProcessID = 0;   
DWORD g_dwThreadID = 0;   
   
// 如果是win9x,不能使用fopen函数   
void WriteLog(char *fmt,...)   
{   
    va_list args;   
    char modname[200];   
   
    char temp[5000];   
    HANDLE hFile;   
    SYSTEMTIME loaclTime;   
    GetLocalTime(&loaclTime);   
    GetModuleFileName(NULL, modname, sizeof(modname));   
   
    if((hFile =CreateFile("c:\\hookapi.log", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) <0)   
    {   
        return;   
    }   
   
    SetFilePointer(hFile, 0, NULL, FILE_END);   
   
    wsprintf(temp, "%d:%d:%d mydll.dll:%s:", loaclTime.wHour,loaclTime.wMinute,loaclTime.wMilliseconds, modname);   
    DWORD dw;   
    WriteFile(hFile, temp, strlen(temp), &dw, NULL);   
   
    va_start(args,fmt);   
    vsprintf(temp, fmt, args);   
    va_end(args);   
   
    WriteFile(hFile, temp, strlen(temp), &dw, NULL);   
   
    wsprintf(temp, "\r\n");   
    WriteFile(hFile, temp, strlen(temp), &dw, NULL);   
   
    CloseHandle(hFile);  
}   
   
int _stdcall hook_recv(IN SOCKET s,OUT char FAR * buf,IN int len,IN int flags )   
{   
    int nRet;   
    WaitForSingleObject( g_hRecvEvent, INFINITE );   
   
    //恢复API头8个字节   
    WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pRecv,( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );   
    /*  
    这里可以添加想要进行的处理过程  
    */   
    //真正执行API函数   
    nRet = recv(s,buf,len,flags);   
    //写入跳转语句,继续Hook   
    WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pRecv,( void* )g_btNewBytes, sizeof( DWORD )*2, NULL);   
    WriteLog("%s",buf);   
    SetEvent( g_hRecvEvent );   
    return nRet;   
}   
   
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags )   
{   
    int nRet;   
    WaitForSingleObject( g_hSendEvent, INFINITE );   
   
    //恢复API头8个字节   
    WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pSend,   
        ( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );   
    /*  
    这里可以添加想要进行的处理过程  
    */   
    WriteLog("Send:%s",buf);   
    //真正执行API函数   
    nRet = send( s, buf, len, flags );   
    //写入跳转语句,继续Hook   
    WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pSend,   
        ( void* )g_btNewBytes, sizeof( DWORD )*2, NULL );   
    SetEvent( g_hSendEvent );   
    return nRet;   
}   
   
static LRESULT WINAPI HookProc( int nCode, WPARAM wParam, LPARAM lParam )   
{   
    return CallNextHookEx( g_hOldHook, nCode, wParam, lParam );   
}   
HOOK_API BOOL StartHook(HWND hWnd)   
{   
    //通过传入的窗口句柄获取线程句柄   
    g_dwThreadID = GetWindowThreadProcessId( hWnd, &g_dwProcessID );   
    //WH_CALLWNDPROC类型的Hook   
    g_hOldHook = SetWindowsHookEx( WH_CALLWNDPROC,   HookProc,( HINSTANCE ) g_hInstance, g_dwThreadID );   
    if( g_hOldHook == NULL )   
        return FALSE;   
   
    return TRUE;   
}   
   
HOOK_API void StopHook(void)   
{   
    if(g_hOldHook != NULL)   
    {   
        WaitForSingleObject( g_hSendEvent, INFINITE );   
   
        HANDLE hProcess = NULL;   
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_dwProcessID);   
   
        DWORD dwOldProc;   
        DWORD dwNewProc;   
        //改变页面属性为读写   
        VirtualProtectEx( hProcess, ( void* )g_pSend, 8, PAGE_READWRITE, &dwOldProc );   
        //恢复API的首8个字节   
        WriteProcessMemory( hProcess, ( void* )g_pSend,   
            ( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );   
        //恢复页面文件的属性   
        VirtualProtectEx( hProcess, ( void* )g_pSend, 8, dwOldProc, &dwNewProc );   
   
        CloseHandle(g_hSendEvent);   
   
        UnhookWindowsHookEx( g_hOldHook );   
    }   
}   
   
DWORD WINAPI ThreadFunc( LPVOID lpParam )    
{    
	WriteLog("Start Thread"); 
    //char szMsg[MAX_PATH];   
    //wsprintf( szMsg, "Parameter = %d.", *(DWORD*)lpParam );    
    //MessageBox( NULL, szMsg, "ThreadFunc", MB_OK );   
    while(1) 
	{
	Sleep(1000);   
	}
    return 0;    
}    
   
BOOL APIENTRY DllMain( HMODULE hModule,   
                       DWORD  ul_reason_for_call,   
                       LPVOID lpReserved   
                     )   
{   
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)   
    {   
        WriteLog("Start HOOK");   
        //获取本dll句柄   
        g_hInstance = hModule;   
   
        //创建事务   
        g_hSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );   
   
        //重写API开头的8字节   
        HMODULE hWsock = LoadLibrary( "ws2_32.dll" );   
        g_pSend = ( DWORD )GetProcAddress( hWsock, "send" );   
        g_pRecv = (DWORD)GetProcAddress( hWsock, "recv" ); 
		if(g_pSend==0||g_pRecv==0)
		{
			return false;
		}
        //保存原始字节   
        ReadProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pSend,( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );   
        //将00400000改写为我们函数的地址   
        *( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_send;   
        WriteProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pSend,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );   
   
//      //保存原始字节   
//      ReadProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pRecv,( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );   
//      //将00400000改写为我们函数的地址   
//      *( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_recv;   
//      WriteProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pRecv,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );   
 
		WriteLog("Hook Succeed"); 
        DWORD dwThreadId, dwThrdParam = 1;    
        HANDLE hThread;    
        char szMsg[80];   
   
        hThread = CreateThread(    
            NULL,                        // default security attributes    
            0,                           // use default stack size     
            ThreadFunc,                  // thread function    
            &dwThrdParam,                // argument to thread function    
            0,                           // use default creation flags    
            &dwThreadId);                // returns the thread identifier    
   	
        // Check the return value for success.    
        if (hThread == NULL)    
        {   
            wsprintf( szMsg, "CreateThread failed." );    
            MessageBox( NULL, szMsg, "main", MB_OK );   
        }   
        else    
        {   
            CloseHandle( hThread );   
        }   
    }   
    return TRUE;   
}   
   
#ifdef _MANAGED   
#pragma managed(pop)   
#endif  


将代码编译成DLL后可直接注入到钓鱼进程中,这样他的一举一动(就是对send 、recv函数的调用)就会被记录下来输出到C盘的hookapi.log文件中.

下面再附加一张成功反钓鱼的信息截图(对方用的好象是FTP空间收信)


第五届安全开发者峰会(SDC 2021)10月23日上海召开!限时2.5折门票(含自助午餐1份)

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 273
活跃值: 活跃值 (627)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
sxpp 活跃值 1 2013-9-14 23:06
2
0
偶要编译好的dll
雪    币: 1040
活跃值: 活跃值 (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Rookietp 活跃值 2013-9-15 00:37
3
0
=,= 俺以为自动识别骗子,原来还是要人肉```
游客
登录 | 注册 方可回帖
返回