ORA-01031: insufficient privileges很明显,权限方面出了问题。想想也应该,我们的 Windows 服务使用的应该是 NT AUTHORITY/SYSTEM(S-1-5-18) 的权限在运行。于是方案 A 出台了。
方案 A:将 SYSTEM 帐户加入 ORA_DBA 组。
从 UI 是看不到 SYSTEM 帐户的,只有用命令行的方式加。
net localgroup ORA_DBA system /add结果还是得到了 ORA-01031。分析了一下,有可能是因为操作系统认证需要从操作系统的用户帐号来进行,而 SYSTEM 帐号是个内置帐号,在用户管理里面是看不到的。于是这个方案宣告失败。
基本上,方案 A 走不通的话,那就只有这种办法了。首先是建立一个 Windows 帐户,并加入 ORA_DBA 组中。密码自己随便定一个就好。
net user dbauser 1qaz2wsx /add但是具体怎么切换呢?
net localgroup ORA_DBA dbauser /add
一般 RunAs 服务(也就是 Secondary Logon)都是启动的,所以首先想到用 Windows 2000 / XP / 2003 自带的命令 runas 来实现。
runas /user:dbauser "sqlplus \"/ as sysdba\" ……"没报错,可是没反应。噢,麻烦来了。这个 runas 命令是要问密码的。
上 Google 找了一下解决方案。试了一下用 vbs 的 SendKeys 那种,手动状态下似乎勉强可行,但要放在 Windows 服务中,没戏。因为它毕竟是模拟客户端的输入来键入密码的。有个自称可以让 runas 支持管道输入密码的小工具 sanur 也没戏,感觉它俩的原理是类似的。
既然 runas 这条路走不通,就彻底抛开它另寻出路了。
有个工具 lsrunas 自称可以替代 runas,于是下载下来一试。虽然参数比较罗嗦,但的确是可以替代。不过这个替代也仅限于通常情况下,一旦放到我们的 Windows 服务中,就没有反应了。
另外有人推荐了一个 cpau。这个工具还是不行,不过它倒是留下了一个提示信息,这个信息成了重要的线索:
ERROR: CPAU doesn't support running from LocalSystem.看来还是 SYSTEM 的权限问题。
看来这些工具都没问题,但是应该都不支持在 SYSTEM 的权限下面切换用户。听说以前某个同事也为这个问题研究了好些天,最后还是放弃了。老实说,听到这个消息我有一点点绝望感。
这 SYSTEM 权限吧,说它低,却能操作很多系统级别的东西。可要说它高呢,有些本来很容易的事情它又做不了。不过理论上通常还是认为 SYSTEM 的权限比较「高」,所以很多黑客都以获得 SYSTEM 权限为目标在半肉鸡上奋斗着。于是,我以 SYSTEM 降权为主要话题,去黑客站点看了看。
还真是有收获,得到了一段代码,是一个利用 API 自己实现的 runas 工具程序。在命令行下使用了一下,感觉挺好,比 Windows 那个 runas 好用多了。
不过,放进 Windows 服务里面,还是不行。真的是快绝望了。
由于我们的系统有现成的接口用来启动一个 PipeCmd,所以到目前为止我都是用它去运行了一个批处理,然后在批处理中去做上述操作。该接口其实是用 CreateProcess 实现,因此新建的进程就继承了父进程的权限,也就是 SYSTEM。
但,在那段黑客代码中,切换帐户其实是使用了 CreateProcessWithLogonW 来完成。估计各个工具都类似,因此应该可以跳过中间的多余步骤,用 API 切换帐户来直接运行 sqlplus。
HANDLE hToken;想偷懒的人还是看看代码稍微理解一下吧,因为我也想偷一下懒,直接 Copy & Paste 可能会有问题的。
LogonUser("dbauser", NULL, "1qaz2wsx", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);
STARTUPINFO si;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
PROCESS_INFORMATION pi;
CreateProcessAsUser(hToken, NULL, cmdbuf, &sa, NULL, TRUE, NULL, NULL, NULL, &si, &pi);
另外说明一下,CreateProcessWithLogonW 应该也是可以做到的,但是我一直没能试成功。倒是 CreateProcessAsUser 一次成功,于是就这样用下去了。
net localgroup Administrators dbauser /add但是在 XP 下面要这样做的话,就有可能会让 Windows 把 dbauser 当成了主管理员,特别是在某些装好之后默认用 Administrator 用户登录的系统上。这样会给用户带来不小的困扰哦,所以最佳的做法应该是判断一下操作系统的版本再去做相应的处理。