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

csrmsg.PortMessage.MessageSize=0x4c;
csrmsg.PortMessage.DataSize=0x34;

csrmsg.CsrssMessage.Opcode=0x10000;


ZwRequestWaitReplyPort(handleIndex,(PORT_MESSAGE*)&csrmsg,
(PORT_MESSAGE*)&csrmsg);
}
}

The solution to the problem was obvious; Switch context to one in
which the port is open, e.g. to the context of any win32-process. I inser-
ted KeAttachProcess(HelperProcess) before calling Nebbet's InformCsrss,
and KeDetachProcess afterwards. The role of the HelperProcess was taken
by calc.exe.

When I tried using KeAttachProcess that way I failed though: The con-
text was switched (visible using the proc command in SoftICE), but Csr-
ClientCallServer returned STATUS_ILLEGAL_FUNCTION. Only Uncle Bill knows
what was happening inside CSRSS.

When trying to frame the whole process creation function into
KeAttachProcess/KeDetachProcess led to the following error when calling
ZwCreateProcess: "Break Due to KeBugCheckEx (Unhandled kernel mode
exception) Error=5 (INVALID_PROCESS_ATTACH_ATTEMPT) ... ".

A different way to execute my code in the context of an arbitrary
process is APC. The APC may be kmode or user-mode. As long as only kmode
APC may overcome nonalertable wait state, all code for process creation
must be done in kernel mode. Nebbet's code normally works at
IRQL == APC_LEVEL
Code execution in the context of a given win32-process by means of APC is
implemented in the StartShell() function, in file ShellAPC.cpp.

Interaction with the process
=============================

Starting a process isn't all. The Backdoor still needs to communicate
with it: It is necessary to redirect it's stdin/stdout/stderr to our
driver. We could do this like most "driver+app"-systems: Create a device
that is visible from user-mode, open it using ZwOpenFile and pass the
handle to the starting process (stdin/stdout/stderr). But a named device
is not stealthy, even if we automatically create a random names. This is
why I have chosen to use named pipes instead.

Windows NT uses named pipes with names like Win32Pipes.%08x.%08x (here
%08x is random 8-digit numbers) for emulation of anonymous pipes. If we
create one more such pipe, nobody will notice. Usually, one uses 2 anon-
ymous pipes r redirecting I/O of a console application in Win32, but when
using a named pipe one will be sufficient as it is bi-directional. The
driver must create a bi-directional named pipe, and cmd.exe must use it's
handle as stdin/stdout/stderr.

The handle can be opened in both kmode and user-mode. The final ver-
sion uses the first variant, but I have also experimented with the second
variant -- being able to implement different variants may help evade anti-
viruses. Starting a process with redirected I/O has been completely imple-
mented in kernel mode in the file NebbetCreateProcess.cpp.

There are two main differences between my and Nebbet's code: The fun-
ctions that are not exported from ntoskrnl.exe but from ntdll, are dyn-
amically imported (see NtdllDynamicLoader.cpp). The handle to the named
pipe is opened with ZwOpenFile() and passed to the starting process with
ZwDuplicateObject with DUPLICATE_CLOSE_SOURCE flag.

For opening the named pipe from user mode I inject code into a start-
ing process. I attached the patch (NebbetCreateProcess.diff) for edu-
cational purposes. It adds a code snippet to a starting process. The
patch writes code (generated by a C++ compiler) to a process's stack. For
independence that code is a function which accepts a pointer to a struc-
ture containing all the necessary data (API addresses etc) as parameter.
This structure and a pointer to it are written to the stack together with
the code of the function itself. ESP of the starting thread is set 4 bytes
bellow the pointer to the parameters of the function, and EIP to it's en-
try point. Once the injected code is done executing, it issues a CALL back
to the original entry point. This example can be modified to be yet
another way of injecting code into a working userland process from kernel
mode.

---[ 4.2 - Activation and communication with the remote client

If a listening socket is permanently open (and visible to netstat -an)
it is likely to be discovered. Even if one hides the socket from netstat
is insufficient as a simple portscan could uncover the port. To remain
stealthy a backdoor must not have any open ports visible locally or re-
motely. It is necessary to use a special packet, which on the one hand
must be unambigously identified by the backdoor as activation signal, yet
at the same time must not be so suspicious as to trigger alerts or be fil-
tered by firewalls. The activation signal could e.g. be a packet contain-
ing a set of packets at any place (header or data) -- all characteristics
of the packet (protocol, port etc) should be ignored. This allows for max-
imum flexibility to avoid aggressive packet filters.

Obviously, we have to implement some sort of sniffer in order to
detect such a special packet. In practice, we have several choices on how
to implement the sniffer:

1) NDIS protocol driver (advantage: possibility not only to receive
packets, but also to send - thus making covert channel for
communication with remote client possible; disadvantage: difficulties
with supporting all types of network devices) - applied in ntrootkit;

2) use service provided by IpFilterDriver on w2k and higher
(advantages: simple implementation and complete independence
from physical layer; disadvantage: receive only);

3) setup filter on 1 of network drivers, through which packets pass
through (see [5]);

4) direct appeal to network drivers by some other means for receive
and send packets (advantage: can do everything; disadvantage:
unexplored area).

I have chosen variant 2 due to it's simplicity and convenience for both
described variants of starting a shell. IpFilterDriver used only for
activation, further connection is made via TCP by means of TDI.

An example of the usage of IpFilterDriver can be seen in Filtering.cpp
and MPFD_main.cpp. InitFiltering() loads the IpFilterDriver if it isn't
yet loaded. Then it calls SetupFiltering, which sets a filter with
IOCTL_PF_SET_EXTENSION_POINTER IOCTL. PacketFilter() is then called on
each IP packet. If a keyword is detected StartShellEvent is set and causes
a shell to be started.

The variant using shellcode in an existing process works with the
network in user-mode, thus we do not need to describe anything in detail.

A Kernel-mode TCP shell is implemented in NtBackd00r.cpp. When cmd.exe
is started from a driver with redirected I/O, the link is maintained by
the driver. I took the tcpecho example as base for the communitcation mod-
ule in order not to waste time coding a TDI-client from scratch.
DriverEntry() initialises TDI, creates a listening socket and an unnamed
device for IoQueueWorkItem.

For each conenction an instance of the Session class is created. In
it's OnConnect handler a sequence of operations for creating a process.
process. As long as this handler is called at IRQL==DISPATCH_LEVEL, it's
impossible to do all necessary operations directly in it. It's even
impossible to start a thread because PsCreateSystemThread must be called
only at PASSIVE_LEVEL according to the DDK. Therefore the OnConnect
handler calls IoAllocateWorkItem and IoQueueWorkItem in order to do any
further operations accomplished in WorkItem handler (ShellStarter
function) at PASSIVE_LEVEL.

ShellStarter calls StartShell() and creates a worker thread
(DataPumpThread) and 2 events for notifying it about arriving packets and
named pipe I/O completion. Interaction between the WorkItem/thread and
Session class was built with taking a possible sudden disconnect and
freeing Session into account: syncronisation is accomplished by disabling
interrupts (it's equivalent of raise IRQL to highest) and by means of
DriverStudio classes (SpinLock inside). The Thread uses a copy of some
data that must be available even after instance of Session was deleted.

Initially, DataPumpThread starts one asynchronous read operation
(ZwReadFile) from named pipe -- event hPipeEvents[1] notifies about it's
completion. The other event hPipeEvents[0] notifies about data arrival
from the network. After that ZwWaitForMultipleObjects executed in a loop
waits for one of these events. In dependence of what event was signaled,
the thread does a read from the named pipe and sends data to client, or
does a read read from FIFO and writes to pipe. If the Terminating flag
is set, thread closes all handles, terminates the cmd.exe process, and
then terminates itself. Data arrival is signaled by the hPipeEvents[0]
event in Session::OnReceive and Session::OnReceiveComplete handlers.
It also used in conjunction with the Terminating flag to notify the thread
about termination.

Data resceived from the network is buffered in pWBytePipe FIFO.
DataPumpThread reads data from the FIFO to temporary buffers which are
allocated for each I/O operation and writes data asynchronously to the
pipe (ZwWriteFile). The buffers are freed asynchronously in the ApcCallback-
WriteComplete handler.

Data transfers from the pipe to the network are also ac

上一页  [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算法分析历程
    普通文章雨过天晴自我注册
    精彩专题