众所周知,现在几乎所有的“刷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空间收信)
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法