中国网络实验室's

phper 发表于 2007-12-15 05:54

从黑客角度检验oracle数据库

</div>
<P>一 State of Oracle Security (oracle的安全状态)</P>
<P>1 来之媒体的报道:</P>
<P>超过十分之一的于internet上公司数据库有安全隐患。一份来之750家美国数据库开发商开始对数据库安全表示忧虑。</P>
<P>2 黑客世界的秘密:</P>
<P>讨论会对数据库被黑的报道增多。</P>
<P>– Blackhat, Defcon Expliots 蠕虫侵蚀着数据库<BR>– Alpha Voyager<BR>– Spida worm</P>
<P>攻击oracle的白皮书</P>
<P>3 oracle网站-Alerts Web page</P>
<P><A href="http://otn.oracle.com/deploy/securi...Info&amp;alerts.htm">http://otn.oracle.com/deploy/securi...Info&amp;alerts.htm</A><BR>&nbsp;Prior to July 2000<BR>-One vulnerability acknowledged by Oracle<BR>&nbsp;From July 2000 to August 2002<BR>-41 vulnerability reports on the Oracle website<BR>&nbsp;Vulnerabilities reported on<BR>SecurityFocus.com<BR>-About 75 vulnerabilities reported about Oracle</P>
<P>4 防火墙后边神秘的oracle是安全的</P>
<P>大多数的折衷安全是内部工作的结果<BR>内部威胁是最危险的<BR>数据库中的非特权用户</P>
<P>5 面对这样状况我们要做什么</P>
<P>对漏洞的修复<BR>警惕风险和威胁<BR>找到正确的解决方案</P>
<P>二 Securing the Listener service</P>
<P>1 监听(listener)的脆弱</P>
<P>监听是客户端和数据库的代理</P>
<P>重要性:</P>
<P>i) 分离了鉴定和审核</P>
<P>ii) 以一个独立的进程运行</P>
<P>iii) 接受命令执行数据库的外部任务</P>
<P>监听服务的脆弱性</P>
<P>在客户端和数据库建立的连接进程中,监听作为一个代理。客户端指向对监听的一个连接,监听依次来和数据库进行连接握手。</P>
<P>问题存在于监听分离了鉴证,被外部数据库控制管理。监听作为一个独立的进程,在过去称为UID,接受命令执行任务。</P>
<P>2 监听服务的安全问题</P>
<P>带有password的监听是安全的</P>
<P>-默认配置是无<BR>-lsnrctl设在password<BR>必须建立一个健壮的password<BR>-对暴力破解是不易攻击的<BR>保护好listener.ora文件<BR>-password存储在这里<BR>不要远程管理监听<BR>-在网络上password是不加密的。<BR>如何对监听进行安全控制:</P>
<P>首先:在监听服务中设置passwod,许多DBA甚至没有意思到在必须在监听服务中设置password,监听服务接受远程的命令,如果你没有设置,任意人都可以发送命令。</P>
<P>两种设置方法:</P>
<P>1) 使用监听控制实用工具 – lsnrctl.</P>
<P>2) 在listener.ora文件中设置。</P>
<P>你必须设置一个强壮的password,一个不少于8位用数字和特殊单词组成的。如果设置比较脆弱,黑客程序将会试出你的密码。</P>
<P>Password是存在listener.ora的文件中,如果用户可以读取,可以利用password日志远程的监听。</P>
<P>同时也推荐你不要远程管理listener,因为密码在网上被明文传播,有可能被监听。推荐你只用来进行连接。</P>
<P>监听命令:</P>
<P>-LSNRCTL&gt; help<BR>The following operations are available<BR>start stop status<BR>quit exit set*<BR>show*</P>
<P>password rawmode displaymode<BR>trc_file trc_directory trc_level<BR>log_file log_directory log_status<BR>current_listener connect_timeout startup_waittime<BR>use_plugandplay save_config_on_stop</P>
<P>可以通过set password来进行设置。有两个问题在password中:</P>
<P>password是没有lockout feature。命令审核是和标准oracle的审核数据是分开的。Password是不过期的,因为没有passwod的管理特性。</P>
<P>3 监听包(listener packet)</P>
<P>当一个命令输入到监听控制器中会发生:</P>
<P>向监听发生一条命令,如果监听是远程的,命令通过网络传播,上图是发送的数据包,我们可以看到报头中一些特殊的字符。在报尾可以看到listener要执行的远程命令,在这个例子中:<BR>COMMAND=status</P>
<P>三 listener attacke demo<BR><A href="http://www.jammed.com/~jwa/hacks/security/tnscmd/">http://www.jammed.com/~jwa/hacks/security/tnscmd/</A></P>
<P>1 缓冲区溢出:</P>
<P>覆盖堆栈的内存,执行恶意的代码。</P>
<P>监听服务的缓冲区溢出:</P>
<P>1) 一个连接字符串的例子:<BR>– (DESCRIPTION=(CONNECT_DATA=(CID=(PROGRAM=)(HO<BR>ST=)(USER=))(COMMAND=status) (SERVICE=LIST80)(VERSION=135294976)))</P>
<P>2) 寻找缓冲区溢出<BR>:<BR>改变适当的值看看会发生什么情况<BR>– Try USER= with 4,000 Xs after it<BR>– Try SERVICE= with 4000 Xs after it<BR>– Etc…</P>
<P>黑客是如何发现缓冲区溢出的:</P>
<P>当一个命令发生到监听服务时,黑客试图在连接字符中加很长的字符串,例如发生USER=一个很上的字符串。如果数据库开发人员只为username分配了一个1024字节长的单元,当发送超过了1024个字节,其他的字符将覆盖后边的单元。所以程序要能自能的对长度进行检查。</P>
<P>2 监听器服务缓冲区溢出</P>
<P>i) Oracle 8.1.7<BR>发生1k的字节COMMAND= dwon机<BR>超过4k会使系统崩溃。</P>
<P>ii) oracle 9.0.1<BR>发生1k的字节SERVICE=</P>
<P>3 利用报头区的值</P>
<P>典型的命令:<BR>– .T.......6.,...............:................4.............(CONNECT_DATA=.)<BR>垃圾字符描述了报头的信息<BR>– Offset to data<BR>– Size of connection string<BR>– Size of packet<BR>– Type of packet</P>
<P>4 窃取监听命令</P>
<P>发生一下的命令:<BR>– .T.......6.,...............:................4.............(CONNECT_DATA=.)</P>
<P>改变报头表明40字节<BR>– ......."...(DESCRIPTION=(ERR=1153)(VSNNUM=135290880)(ERROR_<BR>STACK=(ERROR=(CODE=1153)(EMFI=4)(ARGS='(CONNECT_DAT<BR>A=.)ervices))CONNECT'))(ERROR=(CODE=3 03)(EMFI=1))))</P>
<P>改变报头表明200字节<BR>– ........"..&gt;.H.......@(DESCRIPTION=(ERR=1153)(VSNNUM=135290880)<BR>(ERROR_STACK=(ERROR=(CODE=1153)(EMFI=4)(ARGS='(CONNE<BR>CT_DATA=.)ervices))CONNECT_DATA=(SID=orcl)(global_dbname=te<BR>st.com)(CID=(PROGRAM=C:Oraclebinsqlplus.exe)(HOST=anewman)<BR>(USER=aaron))')) (ERROR=(CODE=303)(EMFI=1))))</P>
<P>如果你伪造数据包的大小,监听将随意返回任何数据在它的命令字符中将超过你发生的字符长。例如一个用户上交了100字符的命令,而对你的返回要10字符,监听将先返回10字符对你的原先的拷贝,但这样的返回不会终结,还会返回</P>
<P>90个先前命令的字符。可以获得username,当然这样是难的,不过这样的危险还是存在的。</P>
<P>6 外部程序</P>
<P>动态库和共享lib中的函数</P>
<P>能被pl/sql调用的<BR>通过创建lib和packages进行设置:<BR>– CREATE LIBRARY test AS ‘msvcrt,dll’;<BR>CREATE PACKAGE test_function IS PROCEDURE<BR>exec(command IN CHAR);<BR>CREATE PACKAGE BODY test_function IS<BR>PROCEDURE exec(command IN CHAR)<BR>IS EXTERNAL NAME “system”<BR>LIBRARY test;</P>
<P>有许多安去问题和外部服务进程有关,Xprocs允许在oracle中创建函数,参照DLL或共享库文件在操作系统上。这个很强的特性使得数据库能任何操作系统可以做得事情。当然权利越大责任也越大。</P>
<P>创建一个Xproc可以指向操作系统的任何一个dll,使得你可以执行操作系统的命令。同样象获得数据库服务器的资源那样,来获得系统资源。</P>
<P>第一关心的是你有没有给一个用户creat library和create procedure的特权。</P>
<P>7 远程回调外部进程</P>
<P>非‘正式’支持<BR>但它很有效<BR>ExtPorcs 是监听的另一个连接点<BR>– SID_LIST_LISTENER =<BR>– (SID_LIST =<BR>– (SID_DESC =<BR>– (SID_NAME = PLSExtProc)<BR>– (ORACLE_HOME = E:oracleora81)<BR>-(PROGRAM = extproc)<BR>ExtProc任何审核一个用户<BR>――它是无效的!!!!!</P>
<P>8 默认设置-对外进程</P>
<P>自动配置<BR>-Oracle 8i –YES<BR>-Oracle 9i-NO<BR>Call listener<BR>-Do not create ExtProc as another listener endpoint<BR>-Create its own entry in the listener.ora file</P>
<P>三 Oracle in a Web application</P>
<P>1 绕过防火墙的攻击:</P>
<P>防火墙的配置:<BR>– Block access through port 1521<BR>– Only allow traffic to port 80<BR>– Block UDP as well as TCP<BR>SQL 注入<BR>– Not specific to Oracle<BR>-a web programming problem</P>
<P>许多管理都认为防火墙的数据库是安全的。及时是你的防护墙配置是很恰当的,也可以通过web应用程序进行攻击。这些攻击主要是由于开发应用程序者一些错误的编程所致。</P>
<P>我们可以发现许多站点在这个方面都很脆弱。虽然因数据库不同攻击而异,但基本问题还是相同的对所有的数据库来讲。</P>
<P>最简单的一个检验你的数据库是否脆弱,是通过嵌入一个请求在没有地方,然后来验证结果。有些站点会返回语法错误。而许多只是捕获了错误,没有报道。当然这些站点仍然有脆弱,但是这些可以不被利用如果你不过任何错误消息发送反馈信息。</P>
<P>2 How does it work</P>
<P>修改请求</P>
<P>改变这样的查询:<BR>– Select * from my_table where column_x = ‘1’<BR>To: – Select * from my_table where column_x = ‘1’<BR>UNION select password from DBA_USERS<BR>where ‘q’=‘q’</P>
<P>exploit是如何工作的?它是通过改变一个sql语句成另为一种,例如上面的例子,一个简单查询变成了2个查询。</P>
<P>你可以嵌入第二条命令在查询中在其他的数据库中,Oracle不运行这样做,而代替的是攻击者需要去补充查询请求的结尾。</P>
<P>注意结尾的‘q’=’q’,这样用的原因是我们可以处理第二条查询,ASP将加他加入网页的结尾,这条语句值是真的。</P>
<P>3 Example JSP page</P>
<P>Package myseverlets;<BR>&lt;….&gt;<BR>String sql = new String(“SELECT * FROM<BR>WebUsers WHERE Username=’” +<BR>request.getParameter(“username”) + “’<BR>AND Password=’” +<BR>request.getParameter(“password”) + “’”<BR>stmt = Conn.prepareStatement(sql)<BR>Rs = stmt.executeQuery()<BR>Exploiting the problem is much simpler if you can access the source of the web<BR>page. You should not be able to see this data, however there are many bugs that<BR>allow you to view the source, and I’m sure there are still lots that have not yet been<BR>discovered.<BR>The problem with our ASP code is that we are concatenating our SQL statement<BR>together without parsing out any single quotes. Parsing out single quotes is a good<BR>first step, but its recommended that you actually use parameterized SQL statements<BR>instead.</P>
<P>4 有效的输入</P>
<P>如果用户和密码设置为:<BR>– Username: Bob<BR>– Password: Hardtoguesspassword<BR>sql语句: – SELECT * FROM WebUsers WHERE<BR>Username=’Bob’ AND<BR>Password=’Hardtoguess’<BR>这是我们一个典型的检验机制在登陆到web site上时,然后通过select语句和数据库进行匹配,如果匹配建立,用户被鉴别。如果在我们的代码中记录集合为空,将准备一个无效的username或者password,登陆被拒绝。</P>
<P>5 黑客的输入</P>
<P>代替password的输入:<BR>– Aa’ OR ‘A’=‘A‘<BR>相应的sql语句:<BR>– SELECT * FROM WebUsers WHERE<BR>Username=’Bob’ AND Password=’Aa’ OR<BR>‘A’=‘A’<BR>黑客已经进入了数据库。</P>
<P>6 Selecting from other Tables</P>
<P>To select data other than the rows from the<BR>table being selected from<BR>&nbsp;UNION the SQL Statement with the<BR>DBA_USERS view.</P>
<P>这是另一个例子取得数据从其他的表中,这与当前的查询无直接联系。最好的方法是查找屏幕中包含选项的动态列表。如果这个sql只是注意一个单值,黑客不能得到其他数据。</P>
<P>而且一些小技巧单一查询变成2个查询或者是把他们组合起来,这有点难道,你要匹配列数还有列的数据类型。然后一些服务器提供你一个错误的消息,使得这项是可行的。一些Error类似为:</P>
<P>Number of columns does not match<BR>Or<BR>2nd column in UNION statement does not match the type of the first statement.</P>
<P>7Sample ASP Page</P>
<P>Dim sql<BR>Sql = “SELECT * FROM PRODUCT WHERE<BR>ProductName=’” &amp; product_name &amp; “’”<BR>Set rs = Conn.OpenRecordset(sql)<BR>‘ return the rows to the browser<BR>Once again we have the ASP page. An attacker does not really need this, but it does<BR>make our lives easier for demonstration purposes. Once again we are not using<BR>parameterized queries, but instead are concatenating a string to build our SQL<BR>statement.</P>
<P>8 有效的输入:</P>
<P>&nbsp;Set the product_name to :<BR>– DVD Player<BR>&nbsp;The SQL Statement is now:<BR>– SELECT * FROM PRODUCT WHERE<BR>ProductName=’DVD Player’</P>
<P>9 黑客输入:</P>
<P>&nbsp;Set the product_name to :<BR>– test’ UNION select username, password from<BR>dba_users where ‘a’ = ‘a<BR>&nbsp;The SQL Statement is now:<BR>– SELECT * FROM PRODUCT WHERE<BR>ProductName=’test’ UNION select username,<BR>password from dba_users where ‘a’=‘a’</P>
<P>黑客可以从password的拷贝中获得一些杂乱的信息,来进行暴力破解。通过添加UNION的命令和第二语句,来得到dba_users表的内容。</P>
<P>10 防止SQl的注入</P>
<P>验证用户的输入</P>
<P>解析避免单一查询为双重查询</P>
<P>使用对象参数来设在参数<BR>- Bind variables</P>
<P>回顾升级你的CGI脚步,ASP page,etc… 建议你对web设计者制订程序的方针,主要着重使用参数化查许和对sql语句的无连接字符串。<BR>11 SQL Injection demo<BR>ASP page, IIS web server ,Oracle database</P>
<P>四 Database Vulnerabilities</P>
<P>1 数据库安全问题<BR>sqlnet.log<BR>普遍的oracle安全问题<BR>PL/SQL 的脆弱性。<BR>主机操作系统<BR>– Known Issues Installing Oracle<BR>-Lockdown Protection Procedures</P>
<P>2 sqlnet.log</P>
<P>当来自一个机器的连接失败后会在目录下建立一个文件,记录失败的连接。<BR>得到一些信息: username, IP,address, date, etc…</P>
<P>3 普遍的oracle安全问题</P>
<P>默认的passwords:<BR>– SYS, SYSTEM, DBSNMP, OUTLN,MDSYS,SCOTT<BR>Password的管理特性没有激活,通过pfiles文件执行复用参数。<BR>– No password lockout by default<BR>– No password expiration by default<BR>Public角色有对ALL_USERS视图的允许权限。</P>
<P>4 PL/SQL的脆弱性</P>
<P>动态SQL的问题<BR>– EXECUTE IMMEDIATE<BR>– DBMS_SQL<BR>允许用户传递sql语句中的参数危险性<BR>这些问题和sql 注入问题几乎一样。<BR>There are two ways to create SQL Statements on the fly in PL/SQL code – Execute<BR>immediate and through the package DBMS_SQL.</P>
<P>5 动态sql语句的例子</P>
<P>CREATE PROCEDURE BAD_CODING_EXAMPLE ( NEW_PASSWORD<BR>VARCHAR2&nbsp; AS<BR>TEST VARCHAR2;<BR>BEGIN<BR>-- DO SOME WORK HERE<BR>EXECUTE IMMEDIATE 'UPDATE ' || TABLE_NAME || ' SET ' ||<BR>COLUMN_NAME || ' = ''' || NEW_PASSWORD || '''‘ WHERE USERNAME=<BR>= ''' || CURRENT_USER_NAME || ''';<BR>END BAD_CODING_EXAMPLE;<BR>有效的输入 from any OCI connection, ODBC connection, SQL*Plus, etc…</P>
<P>– EXEC BAD_CODING_EXAMPLE( ‘testabc’ ;<BR>&nbsp;SQL Created<BR>– UPDATE APPLICATION_USERS SET PASSWORD = ‘testabc’<BR>WHERE USERNAME = ‘aaron’<BR>这个要求有一个有效的帐户,和对过程的可执行。<BR>黑客的输入<BR>– EXEC BAD_CODING_EXAMPLE( ‘testabc’’, ADMIN=1,<BR>FULL_NAME=‘’TEST’ ;<BR>SQL Created<BR>– UPDATE APPLICATION_USERS SET PASSWORD = ‘testabc‘,<BR>ADMIN=1, FULL_NAME=‘TEST’ WHERE USERNAME =<BR>‘aaron’</P>
<P>通过在输入中附加一条语句,使得ADMIN列更新,使得用户成为应用程序的管理员。</P>
<P>注意我们应该附近另一列在末尾来出来最后的单一请求。</P>
<P>6 Getting to the operating system</P>
<P>在NT中oracle以localSystem身份,作为系统权限的一部分。</P>
<P>在Unix为oracle user来运行,对oralce的所用文件有权限。</P>
<P>进程:– UTL_FILE, UTL_HTTP</P>
<P>系统权利类似于create library</P>
<P>一但用于了对数据库的权限,就可以进入操作系统,可以使用很多进程– UTL_FILE是最致命的,给你对文件的读写权。不过UTL_FILE_DIR参数可以进行限制,管理员可以修改这个参数。Oracle运行你加载libraries到一个独立的进程空间使用EXTOROC可执行文件。一些共享libraries和DLL也是可行的。</P>
<P>7 操作系统</P>
<P>&nbsp;Oracle 有许多tUID文件<BR>&nbsp;Oratclsh was setUID root<BR>– TCL debugger<BR>– Allowed you to run a script as root<BR>– Change setuid immediately, even if you are not using</P>
<P>Setuid有很多问题,以前oracle捆绑了15setuid文件。最大的问题是TCL debugger,为应用程序设计在他们用于DBSNMP引擎前。这个debugger是steuid的而且由root拥有。所以很容易获得root权限,虽然有patch,不过还是有很多文件可以被利用的,这个问题即使是dbsnmp agent 不使用也会有。</P>
<P>Other SetUID files<BR>&nbsp;Were many until Oracle8i release 2<BR>– Cmctl, tnslsnr, etc…<BR>&nbsp;Very important one – oracle<BR>– Main database engine<BR>&nbsp;Relies on ORACLE_HOME directory<BR>– To load the pwdSID.ora file<BR>– Allows you to load a rogue database</P>
<P>8.1.6已经取消了许多SetUIDbits. Dbsnmp和oracle files然后保留,这两个都需要SetUID才能恰当的工作。推荐使用不同策略,可以是任何人不可以可执行权限除了所有者。Oracle是主要的可执行程序,如果你设置为可执行的话,任何在server有帐户的人可以开启一个实例,通过UTL_FILE package去写一些文件。这些依赖于$ORACLE_HOME的环境变量的设置。</P>
<P>8 安装Oracle</P>
<P>oracle在安装的时候会在/tmp目录下建立一些文件,虽然umask是022,不过有人可以在安装之前生产一些目录和文件,一些保留的旧文件使得黑客可以注入一些代码在安装的时候。而且有很多脚本使得代码注入很简单,黑客可以很轻松的创建root toolkit。</P>
<P>9 锁定操作系统</P>
<P>在安装之前对其他的os用户进行锁定<BR>设置TMP_DIR为一个安全的目录<BR>锁定ORACLE_HOME许可权限<BR>删除setUID从所有的文件<BR>重新命令UNIXoracle的帐户</P>
<P>五 Resources, Conclusion, and Wrap Up</P>
<P>How to Combat Hackers:<BR>&nbsp;Stay patched –<BR>– <A href="http://metalink.oracle.com">http://metalink.oracle.com</A><BR>&nbsp;Security alerts:<BR>– <A href="http://www.oraclesecurity.net/resources/mailinglist.html">www.oraclesecurity.net/resources/mailinglist.html</A><BR>&nbsp;Security Discussion Board<BR>– <A href="http://www.oraclesecurity.net/cgi-bin/ubb/ultimatebb.cgi">www.oraclesecurity.net/cgi-bin/ubb/ultimatebb.cgi</A><BR>&nbsp;Check out security solutions at:<BR>– <A href="http://www.appsecinc.com">www.appsecinc.com</A><BR>&nbsp;Defense in depth<BR>&nbsp;Multiple levels of security<BR>– Perform audits and pen tests on your database<BR>on a regular basis<BR>– Encryption of data-in-motion<BR>– Encryption of data-at-rest<BR>– Monitor your log files<BR>– Implement intrusion detection</P>

raymanlion 发表于 2008-11-21 08:00

(*^__^*)

页: [1]

Powered by 英文版 6.1.0  © 2001-2007 CnLabs.Net