Sunday, June 28, 2009

Zend Studio 7.0 Beta 注册验证分析(未完待补充)

查找 所有.class 文件夹,发现有一个 文件名为:RegisterAction.class的

Zend\Zend Studio - 7.0.0\plugins\com.zend.php.ui_7.0.0.v20090614-1641\com\zend\php\ui\actions
从目录看,应该是eclipse的图形化界面的shell接口操作

上一级目录中,有 PHPUIMessages.properties
其中发现有
RegisterAction.3=You will need to restart the workbench for the changes to take effect.\nRestart now?
SerialNumberDialog.5=The entered license key is invalid

等字样


使用jd-gui查看RegisterAction.class的代码
发现有

import com.zend.php.core.core.basic.c;
import com.zend.php.core.core.basic.d;

导入了两个class文件,这两个文件在一个jar中,直接解压
public void run(IAction paramIAction)

c localc = c.a(localr.a(), localr.b());
这个c就是import进来的basic.c
往下看
    if (localc == null)
    {
      MessageDialog.openError(this.a.getShell(), PHPUIMessages.a("RegisterAction.4"), PHPUIMessages.a("RegisterAction.0"));
      return;
    }
    try
    {
      d.b(localc);
      if (!(MessageDialog.openQuestion(this.a.getShell(), PHPUIMessages.a("RegisterAction.6"), PHPUIMessages.a("RegisterAction.3"))))
        return;
      PlatformUI.getWorkbench().restart();
    }
查查刚才的PHPUIMessages.properties
确认了一个事实:
可以猜测 localr.a() 和 localr.b() 取出的分别是 username 和 password
那么,首先用 c.a(a, b)进行计算,如果返回不为空,则进行 d.b(c) 的过程
根据返回值确定结果
PHPUIMessages.a()这个函数的参数,对应的那个 properties 文件的内容看,这个推断应该没错


好吧,首先看看 com.zend.php.core.core.basic.c
Zend\Zend Studio - 7.0.0\plugins\com.zend.php.core_7.0.0.v20090607-1658\com\zend\php\core\core\basic
用jd-gui打开 c.class
根据重载参数,找到
  public static c a(String paramString1, String paramString2)
  {
    c localc = null;
    try
    {
      if (localc != null)
        break label34;
      int k = Integer.parseInt(paramString2.substring(0, 1), 16);
      localc = f.a(k).a(paramString1, paramString2);
    }
    catch (Exception localException)
    {
    }
    label34: return localc;
  }

其中,f 是 com.zend.php.core.core.basic.parser.f
打开 Zend\Zend Studio - 7.0.0\plugins\com.zend.php.core_7.0.0.v20090607-1658\com\zend\php\core\core\basic\parser
再看参数
  public static b a(int paramInt)
  {
    if (3 == paramInt)
      return new e();
    throw new IllegalStateException("Unknown license version");
  }
也就是说,paramInt必须为3
那么回到前边的代码
localc = f.a(k).a(paramString1, paramString2);
k必须为3,这样就会返回一个 e();
于是,Integer.parseInt(paramString2.substring(0, 1), 16) == 3 ………………………………………………………………………………………… p2 第一个字符为3

进入 com.zend.php.core.core.basic.parser.e
看参数和返回值(localc = f.a(k).a(paramString1, paramString2);):
public c a(String paramString1, String paramString2)

这个代码:
      int i = Integer.parseInt(paramString2.substring(0, 1), 16);
      if (i != 3)
        return null;
再次验证了 p2[0] == 3的事实
String str1 = paramString2.substring(1, 3);
取出p2 的 [1] [2] 两个字符
String str2 = a(paramString2.substring(3, 16), str1 + paramString2.substring(16));
返回值是 String,看函数
private static String a(String paramString1, String paramString2)
其中是一个循环
算法的php实现是:
<?php
function a($p1, $p2) {
 $s = '';
 $i = 0;
 do {
  $j = 0;
  do {
   $s .= dechex(
    hexdec($p1[$i+$j]) ^ hexdec($p2[$j])
    );
  } while ($j < strlen($p2) && $i+$j < strlen($p1));
  $i += strlen($p2);
 } while( $i < strlen($p1) );
 return $s;
}
?>
根据这个16进制串的返回值,继续往后走,回到刚才的 a()
      int j = Integer.parseInt(str2.substring(0, 1), 16);
      int k = Integer.parseInt(str2.substring(1, 2), 16);
j 为 上一个返回 str2 的 [0], k 为 [1],两个都是10进制整数。
      int l = Integer.parseInt(str2.substring(2, 4), 16);
      int i1 = Integer.parseInt(str2.substring(4, 5), 16);
      int i2 = Integer.parseInt(str2.substring(5, 7), 16);
又是三个整数变量 然后根据前边定义的
Date localDate = null;
判断:
      if ((l != 0) || (i1 != 0) || (i2 != 0))
      {
        Calendar localCalendar = GregorianCalendar.getInstance();
        localCalendar.set(5, l);
        localCalendar.set(2, i1 - 1);
        localCalendar.set(1, 2000 + i2);
        localDate = localCalendar.getTime();
      }
//……………………………………………………………………………………………………………………代码求解释
      int i3 = Integer.parseInt(str2.substring(7, 9), 16);
      long l1 = Long.parseLong(str2.substring(9, 13), 16);
      long l2 = a(paramString1, i, str1, j, k, localDate, i3, l1).longValue();
      long l3 = Long.parseLong(paramString2.substring(16), 16);
又是对 str2的运算 其中,又将刚才算出来的localDate代入到另外一个a里边
private static Long a(String paramString1, int paramInt1, String paramString2, int paramInt2, int paramInt3, Date paramDate, int paramInt4, long paramLong)
这个函数里边主要做了一些字符串的合并,和时间数据的字符串化(ddMMyy),猜测可能是与expiration有关 补了00000在串后 而后加了一个crc32的计算校验 这个函数的返回值就是 那个 crc32的long值 而其中的那个00000的补全就不知道有何意义了………………莫非函数引用传值? 再次回到最初的a()
if (l3 != l2)
        break label403;
也就是说,l3 == l2 下边又是一个循环
      do
      {
        if ((()Math.pow(2.0D, i4) & l1) != 0L)
        {
          int i5 = 0;
          if (bool);
          do
          {
            localArrayList.add(d[i4][i5].getId());
            ++i5;
          }
          while (i5 < d[i4].length);
        }
        ++i4;
      }
      while (i4 < d.length);
这里的 localArrayList 在循环结束后
return new c(i, paramString1, j, k, localDate, i3, (String[])localArrayList.toArray(new String[localArrayList.size()]));
送进构造另外一个对象 这个c是 com.zend.php.core.core.basic.c ======================================================================================== 跳出加密验证部分 回到对话框界面的数据获取 还是 RegisterAction.class
    r localr = new r(this.a.getShell());
    if (localr.open() == 1)
      return;
    c localc = c.a(localr.a(), localr.b());
看看 r这个类的东西 package com.zend.php.ui.core.dialogs; 看看两个参数的获取:
  public String a()
  {
    return this.j.getText().trim();
  }

  public String b()
  {
    return this.k.getText().trim();
  }
i和j的定义在:
    this.j = new StringDialogField();
    this.j.setLabelText(PHPUIMessages.a("SerialNumberDialog.1"));
    this.j.setDialogFieldListener(new i(this));
    this.j.doFillIntoGrid(localComposite, 2);
    LayoutUtil.setHorizontalGrabbing(this.j.getTextControl(null));
    this.j.setFocus();
    this.k = new StringDialogField();
    this.k.setLabelText(PHPUIMessages.a("SerialNumberDialog.2"));
    this.k.setDialogFieldListener(new j(this));
    this.k.doFillIntoGrid(localComposite, 2);
    LayoutUtil.setHorizontalGrabbing(this.k.getTextControl(null));
对应的串:
SerialNumberDialog.1=User Name / Order #:
SerialNumberDialog.2=License Key:
断定数据肯定是在这儿了 但是刚才看了看6版的注册机,license首字节不是限制在1,2,-1之间(虽然6.1代码里只有这三个判断数据) 所以,我觉得这里肯定会有一些数据的预处理过程 继续找
Zend\Zend Studio - 7.0.0\plugins\com.zend.php.ui_7.0.0.v20090614-1641\com\zend\php\ui\core\dialogs
r.class
i.class
现在先尝试按照ui的流程将验证过程实现
然后再做keygen
但是有些初始值怎么定还是个问题

Saturday, June 20, 2009

悲剧,各种悲剧

rt


悲剧人生啊

Monday, June 15, 2009

貌似又被NIC盯上了

保留账号的操作,hmm,貌似因此又被NIC的老师盯上了
早起MSN就收到消息。。。。。

lol

后续在live spaces里

注入的处理?

两个比较恶心的问题,都源于字符过滤。

php+mysql

对于一个字符串型注入点,没开magic_quote_gpc。如果过滤了 "=" 那就意味着,假设有update或者insert型的注入,无法对其他字段进行操作;而且mysql里没有看到任何类似 ++ -- 的操作。


同样的注入点,如果没有过滤 "=",但是过滤了 "," ,以至于无法进行union查询。

有啥解决方案?

以前处理一个insert型的注入,根据字段长,一次一次地substring()处理load_file的结果,已经很恶心了

Friday, June 12, 2009

【转载+评论】跨上草尼马,挥刀斩河蟹-绿坝V3.17超长URL溢出漏洞exploit by seer

原文地址 http://hi.baidu.com/hex1337/blog/item/13cc5bd014fff2da572c840d.html

2009-06-12 23:02

28度的冰 19:29:31
哪里有绿坝下载啊。我正需要这样一款软件。
28度的冰 19:29:39
平时上网总是有暴力

28度的冰 19:29:45
色情网站蹦出来
28度的冰 19:29:48
可讨厌了
也云 19:29:54
2
28度的冰 19:29:58
正好用绿坝过滤一下
seer 19:30:01
2
28度的冰 19:30:29
这么好的软件就算收费也是值得的
28度的冰 19:30:49
况且还免费预装
seer 19:30:48
我们要相信ZF是在保护孩子们
28度的冰 19:30:51
太好了
seer 19:31:12
比如,它只拦截IE

这就从小教会了孩子们使用Firefox

============用群里的某段聊天来开篇==============

为了监视用户的浏览网页行为,绿坝注入了IE进程,在处理超长的URL时,就会在IE的进程空间中触发一个典型的栈溢出.具体原理可以看看密歇根大学的牛人们给出的分析http://www.cse.umich.edu/~jhalderm/pub/gd/, 不错的学校...

Exploit中使用了.net部署shellcode的方式,(BlackHat2008上公布的那招),这是一种比HeapSpray更稳定的方式,而且不卡IE,还能绕过Vista下的DEP和ASLR. 懒得写生成器了,我给出的利用程序shellcode是弹出XP sp2的计算器,所以更接近一个PoC,要换shellcode的话需要手动改下.net中的shellcode,然后用VS重新编译exploit.dll,这也算是防止被菜鸟们滥用的一个小小的门槛吧...

Tips1:由于带有.net控件,这个exploit必须在IIS上发布(需要服务器装有.net framework,IIS不需要特别的设置),直接点开是不行的

Tips2:具体的编译方式放在附件中了,复制粘贴吧,只要你有VS开发环境...

exploit下载:http://www.namipan.com/d/40c1b70f9ed40b2baf3e0fbe826254a324c2823755090000

Enjoy Hacking~;-)

=====================================================================

1 居然qq聊天记录里没有我说话,真悲剧
2 我们要和谐
3 为啥zzjinhui.com连不上了呢?来人爆破md5吧....呃,没用,那个站都连不上了,admin的密码有了也白费
4 算了还是继续不和谐吧。。


然后,再赞一下milw0rm的速度
http://milw0rm.com/exploits/8938

Saturday, June 6, 2009

祝 吴旭炜 小朋友高考顺利

拿出文科第一的样子来,9月份的北京欢迎你。

Friday, June 5, 2009

官方的非正式个人声明

今天发现有一个(加上马甲算是一小撮吧)不法分子,在某几个论坛仿用我的ID注册了ID=sskaje6540的号。
// 可是我从来觉得在自己ID里使用数字是个很2的行为(1337 excluded) :x

首先xb一个联盟上的回帖
飞翔已经让人ban了,然后9*等6上线就行了
硕博怎么说我还是个贵宾

四大论坛,玩转

哇咔咔

动力貌似被LX动手了吧,NP想必他不敢注册,FX和9*还有硕博,料想他不知道我在各大论坛的水有多深,怎么说我也比他大一级,虽然年龄不见得大吧,哇咔咔。(二度显摆,很恶心的来句,oh yeah!)

然后,很和谐地bs一下那个无聊的小孩。

我没兴趣和小人玩,要玩自己随便,别逼我把某次不和谐言论的证据拿出来。

=========================================================================

然后无聊一下这个http://d*g*.com/b******n,这个小孩儿的杰作啊。

可惜啊,我不玩sns,不玩所谓的twitter,fanfou类似的东西

居然还把我的blog放上去。。。。可惜了,可惜了,没法挂广告,要不然又可以用流量挣钱了,虽然不多

lol

==========================================================================


我是不是真的对学生会太不友善了。。。。。。。。rofl



==========================================================================

一句话的声明:我没那么2的ID,请认准 /\bsskaje\b/ 无任何 pattern modifiers,两端单词边界。


===========================================================================

Update:
我突然才发现,那个山寨ID居然用了我qq号的后四位诶。真假啊

Wednesday, June 3, 2009

图片分层透明化

给JeRegle的幼儿园分色,给我的是一个gif文件,除了底色白色之外,只有三种颜色。
需要将这三种颜色的点分别提取出来,并背景透明化存成独立文件。

之前处理图片的时候,也给他做过一次背景透明化的东西,用gd库的imagecolortransparent清理背景色。
<?php
$image = imagecreatefromgif('totrans.gif');
$dim = array(imagesx($image), imagesy($image));

var_dump($dim);
$im = imagecreatetruecolor($dim[0], $dim[1]);
$bg = imagecolorallocate($im, 255,255,255);

imagecopyresampled($im, $image, 0, 0, 0, 0, $dim[0], $dim[1], $dim[0], $dim[1]); 

$white = imagecolorallocate($im, 255,255,255);
imagecolortransparent($im, $white);
imagegif($im, 'trans.gif');?>


但是这次分色的时候,发现imagegif出来gif颜色有问题。生成了好几次,觉得有可能是gif色库的问题。印象中标准gif只能描述256种颜色,所以需要一个类似于bmp的调色板的东西。

用imagepng生成之后,继续去颜色,然后列出一个表格:
original:   gif   :   png  
#93B1FD : #94B2FC : #93B1FD
#B6CBFE : #B4CAFC : #B6CBFE
#D9E4FE : #DCE6FC : #D9E4FE

虽然png的颜色没问题,但是给他之后,居然ps没法识别背景的透明化。

突然想到了 ImageMagick。
有打算用imagick或者magickwand for php来试试
但是有点不大靠谱,没时间翻文档。
突然想到ImageMagick的一个二进制程序 convert
印象中见有人用它做过透明化的处理。
先把gd代码的透明化给注视掉,让背景色全为白色,然后上网查了下,
E:\sskaje>convert 4_1.png -background transparent -transparent white 5_1.png
然后把图给他,测试没问题。

php代码:
<?php
/*
original:   gif   :   png  
#93B1FD : #94B2FC : #93B1FD
#B6CBFE : #B4CAFC : #B6CBFE
#D9E4FE : #DCE6FC : #D9E4FE

transparent the background with imagemagick/convert:
 E:\sskaje>convert 4_1.png -background transparent -transparent white 5_1.png
*/
$image = imagecreatefromgif('3.gif');
$dim = array(imagesx($image), imagesy($image));
$prefix = '4_';
$im = imagecreatetruecolor($dim[0], $dim[1]);
$bg = imagecolorallocate($im, 255,255,255);
$white = imagecolorallocate($im, 255,255,255);
$red = imagecolorallocate($im, 255, 0, 0);

$layers = array(
 1 => array(
  imagecolorallocate($im, 0x93,0xb1,0xfd),
  0x93B1FD,
 ),
 2 => array(
  imagecolorallocate($im, 0xb6,0xcb,0xfe),
  0xB6CBFE,
 ),
 3 => array(
  imagecolorallocate($im, 0xd9,0xe4,0xfe),
  0xD9E4FE,
 ),
);

foreach ($layers as $k=>$v)
{
 echo $k, "\n";

 imagecopyresampled($im, $image, 0, 0, 0, 0, $dim[0], $dim[1], $dim[0], $dim[1]); 

 for ($i=0; $i<$dim[0]; $i++)
 {
  for ($j=0; $j<$dim[1]; $j++)
  {
   if (imagecolorat($im, $i, $j) != $v[1])
   {
    imagefill($im, $i, $j, $white);
   }
   else
   {
    imagefill($im, $i, $j, $v[0]);
   }
  }
 }

 #imagecolortransparent($im, $white);
 #imagegif($im, $prefix.$k.'.gif');
 imagepng($im, $prefix.$k.'.png');
}?>