freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

编程基础 | PHP代码审记(上 )
2020-03-11 16:14:13
所属地 河北省

红日安全推出的适合新手入门系列教程专刊上线啦!红日安全专注新手入门教程。转眼间红日安全又成长了一岁,在这一年里,团队成长了很多很多。目前团队所有的文章对外都是公开的,希望可以给新手一个填补空白的地方。2020年,团队开始新的方向,和一些安全培训厂商进行合作,希望做出更多安全作品。感谢团队每一位成员为团队的辛勤付出,希望每一个人在团队里面有更大的作为。也感谢一直在后面默默支持我们的红粉,也祝愿你们在新的一年学到更多的干货!

1.1 PHP安全入门到精通
1.1.1  概述

PHP安全入门到精通书刊,年后全部放出。为了团队发展,个人在闲暇时间为团队做了一个PHP安全入门到精通书籍,本次书籍摘出一部分让大家入门,更详细的会在年后发出,此次书籍希望让没有基础的安全人员也可以写自己网站,搭建自己的PHP工具和PHP靶场平台。本次专刊发表几节,因为整体文章还没有写完,所以先放出一部分供大家学习。后续文章在年后第二次专刊将在此奉献,希望大家在新的一年里,学习到更多的技能。全部内容如下:图片16.png1.1.2 PHP基础知识

1.1.2.1  全局变量认识

1.1.2.1.1  $GLOBALS

globals是PHP内置的可以自动获取当前页面中的所有变量的内容.

代码解释

图片19.png图片18.png图片17.png

1.1.2.1.2  $_SERVER

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。

代码解释:

echo '';foreach($_SERVER as $key  =>$value){echo '';echo ''.$key.''.''.$value.'';echo '';}echo '';?>

图片20.png1.1.2.1.3    $_FILES

说明:获取上传文件的信息代码说明:hr.html

红日安全文件名:

Hr.php

  0){echo "错误:: " . $_FILES["file"]["error"] . "";}else{echo "上传文件名: " . $_FILES["file"]["name"] . "";echo "文件类型: " . $_FILES["file"]["type"] . "";echo "文件大小: " . ($_FILES["file"]["size"] / 1024) .  "kB";echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] ."";// 判断当期目录下的 upload  目录是否存在该文件// 如果没有 upload 目录,你需要创建它,upload 目录权限为  777if (file_exists("upload/" . $_FILES["file"]["name"])){echo $_FILES["file"]["name"] . " 文件已经存在。 ";}else{// 如果 upload 目录不存在该文件则将文件上传到 upload  目录下move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $_FILES["file"]["name"]);echo "文件存储在: " . "upload/"  .$_FILES["file"]["name"];}}}else{echo "非法的文件格式";}?>

1.1.2.1.4  $_GET:URL方式传递数据

说明:其实就是浏览器的地址栏传递方式,传递方式:URL地址?参数1=值1&参数2=值2.................................传递形式:表单的get方式和超链接方式

代码解释:

USERNAME:PASSWORD:

$_GET方式是在URL地址栏里面直接对接传输。

图片21.png1.1.2.1.5  $_POST: HTTP POST方式传递数据

说明:通过HTTP协议的post方式来传递数据。POST方式传输是在地址栏里面看不见地址,例如隐式传输。利用谷歌浏览器查看。

USERNAME:PASSWORD:

1.1.2.1.6  $_REQUEST

图片23.png图片24.png

默认三种方式都可以提交。如果设置接受get方式,我们以POST方式进行提交,浏览器会找不到该值。1.1.3二正则表达式

1.1.3.1  正则表达式入门1.1.3.1.1  入门简介

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是和?。如果你想查找某个目录下的所有的Word文档的话,你会搜索.doc。在这里,*会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂——比如你可以编写一个正则表达式,用来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-12345678或0376-7654321)。正则表达式就像筛子,将我们需要的内容(符合规则的内容)漏下去,将不符合规则的内容过滤掉而我们学习正则表达式,主要是如何定义这一套规则1.1.3.2  正则表达式相关的函数

1) preg_match使用正则表达式(规则)对字符串进行筛选,筛选到一个结果即停止图片25.png

2) preg_match_all使用正则表达式(规则)对字符串进行筛选,筛选到结果先保存到数组,并继续筛选,直到字符串结束图片26.png

3) preg_replace使用正则表达式(规则)对字符串进行筛选,再将筛选的内容进行替换图片27.png

4) preg_split使用正则表达式(规则)对字符串进行拆分explode()是根据某个字符进行分割

图片28.png使用 preg_split  可以先根据定义的规则进行筛选,再根据筛选的结果拆分字符串图片29.png

1.1.3.3  正则表达式应用场景

用户注册时,先定义用户名的规则(字母、数字、下划线的组合,6-10位),然后再使用该规则验证用户的输入图片30.png

内容采集(将其他网站的内容采集下来,保存到我们的数据库),需要告诉程序需要哪些内容(定义好规则)1.1.3.4  表达式语法

定界符:表示规则的边界,从哪里开始到哪里结束图片31.png元字符:元字符就表示筛选的内容(一个字符)例如:我们可以使用一个字符表示筛选的就是这个字符

$reg='/W/';$str='helloWorld';preg_match($reg,$str,$match);var_dump($match);

图片32.png除了使用一个字符表示筛选的字符之外,正则表达式还提供了一些特殊的符号表示筛选的内容例如:可以使用转义字符表示筛选范围中的一个\w  表示筛选的内容是字母、数字、下划线中的任意一个\W   \w的反义词,表示除了字母、数字、下划线之外的任意一个字符图片33.png

图片34.png

\d,表示筛选数字(0-9)范围中的任意一个

\D,表示除了数字之外的任意一个字符图片35.png

\s:space空格\S:除了空格之外的任意一个字符图片36.png

表示**中的任意一个字符[a-z],小写的a到小写的z之间的任意一个字符[hel],表示hel这几个字母之间的任意一个[^hel],中括号里面的^表示非,除了hel之外的任意一个字符

图片37.png图片38.png图片39.png

英文的点号,表示除了换行符之外的任意一个字符图片40.png

 |竖线,表示 或者图片41.png

量词默认情况下,正则表达式采用的是贪婪模式(尽可能多的匹配)量词表示元字符的数量,也就是筛选的内容的长度{m},固定数量m个{n,m},表示最少n个,最多m个{n,}   ,表示最少n个,最多无穷个*,表示0个或多个+,表示至少1个?,表示0个或1个

图片42.png?   的特殊使用? 如果放在元字符后面,表示0个或1个,但是如果放在量词的后面表示将贪婪模式修改为懒惰模式(尽可能少的匹配)举例说明:

图片43.png图片44.png

^ $  表示从开始到结束图片45.png

模式修正符模式修正符,用来对前面的正则表达式进行修饰作用1) i忽略大小写没有使用i模式修正符的时候

使用i模式修正符,表示忽略大小写

图片46.png2) s,表示万能点模式没有使用s修饰符的代码

图片47.png使用s以后

图片49.png3) U,表示将贪婪模式修改懒惰模式

默认是贪婪模式,就会尽可能多的去匹配图片50.png

4)  分组的使用使用正则表达式进行匹配的时候,可以使用()将需要的内容括起来,每个小括号的内容就会当做一个小组,并保存到数组中。第一个()的内容会保存到数组下标为1的元素中第二个()的内容会保存到数组下标为2个元素中以此类推Ÿ  $res='/<a.+href="(.+)">(.+)<\/a>/';筛选URL

图片51.png图片52.png1.1.3.5  正则实例

用户名验证

6-30位,字母、数字、下划线组合,字母开头

$reg='/^[a-zA-Z]\w{5-29}$/';$res='ehllo1123';preg_match($reg,$res,$match);if($match){echo "success";}else{echo "fail";}

图片53.png手机号验证

使用正则表达式(规则)对字符串进行筛选,筛选到一个结果即停止图片54.png

密码验证

6-20位,字母、数字或符号如果纯字母、纯数字的话,提示密码太简单了如果字母、数字的组合的话,提示密码比较安全如果是字母、数字、特殊符号的组合,提示密码杠杠的图片55.png

邮箱验证

邮箱没有固定的规则,该规则自己定,可以参考下面的合法的邮箱,自己定义规则图片56.png

正则漏洞

$ip = '1.1.1.1  abcd'; //  可以绕过if(!preg_match("/(\d+).(\d+).(\d+).(\d+)/",$ip)) {die('error');} else  {echo('key...');}

在这里没有限制开始和结束,导致输入危险字符绕过。n  第二个案例利用\s空格在shell环境下执行命令成功。

$file_name = $_GET["path"];if(!pregmatch("/^[/a-zA-Z0-9-s]+.rpt$/m", $file_name))  {echo "regex failed";} else  {echo exec("/usr/bin/file -i -b " .  $file_name);}

图片57.png

n  第三个正则案例

https://blog.chaitin.cn/phpmailer-cve-2016-10033/
1.1.4  socket函数讲解1.1.4.1  socket 介绍Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。相同的有MySQL等类似操作,而MySQL它只是已经封装好了,我们直接调用就可以。连接服务端,输入账号和密码就可以。而socket貌似只给我们提供了一堆函数。通过函数我们可以去直接利用。关于socket,我们讲两种方案,一种是基于内核的socket,另外一种是PHP扩展带有的socket功能。l  基于内核的socketŸ   fsockopenŸ   pfsockopenl  PHP扩展模块带有的socket功能Ÿ  socket_createŸ    socket_bindŸ  socket_connectŸ  socket_accept首先先讲关于扩展模块socket功能。Socket连接图(图片来源于网络),其实和Python原理是一样的。图片58.png

Ÿ   socket关键函数—socket_create()socket的关键函数1:socket_create($net参数1,$stream参数2,$protocol参数3)作用:创建一个socket套接字,说白了,就是一个网络数据流。返回值:一个套接字,或者是false,参数错误发出E_WARNING警告Ÿ  socket关键函数—socket_connect()socket_connect($socket参数1,$ip参数2,$port参数3)作用:连接一个套接字,返回值为true或者false参数1:socket_create的函数返回值参数2:ip地址参数3:端口号Ÿ  socket关键函数—socket_bind()socket_bind($socket参数1,$ip参数2,$port参数3)作用:绑定一个套接字,返回值为true或者false参数1:socket_create的函数返回值参数2:ip地址参数3:端口号Ÿ  socket关键函数—socket_listen()socket_listen($socket参数1,$backlog  参数2)作用:监听一个套接字,返回值为true或者false参数1:socket_create的函数返回值参数2:最大监听套接字个数Ÿ  socket关键函数—socket_accept  ()socket_accept($socket)作用:接收套接字的资源信息,成功返回套接字的信息资源,失败为false参数:socket_create的函数返回值Ÿ  socket关键函数—socket_read  ()socket_read($socket参数1,$length参数2)作用:读取套接字的资源信息,返回值:成功把套接字的资源转化为字符串信息,失败为false参数1:socket_create或者socket_accept的函数返回值参数2:读取的字符串的长度Ÿ  socket关键函数—socket_wrete  ()socket_write($socket参数1,$msg参数2,$strlen参数3)作用:把数据写入套接字中返回值:成功返回字符串的字节长度,失败为false参数1:socket_create或者socket_accept的函数返回值参数2:字符串参数3:字符串的长度Ÿ  socket关键函数—socket_close  ()socket_close($socket)作用:关闭套接字返回值:成功返回true,失败为false参数:socket_create或者socket_accept的函数返回值函数讲解完成以后,我们需要对socket建立服务端和客户端。首先一下是建立服务端。

Server_socket.php

小提示:请注意上面的socket_bind,socket_listen,socket_accept三个函数的执行顺序不可更改,也就是说必须先执行socket_bind,再执行socket_listen,最后才执行socket_accept客户端代码Client_server.php 1, "usec" =>  0));//发送套接流的最大超时时间为6秒socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec"=> 6, "usec" =>  0));/*设置socket连接选项,这两个步骤你可以省略///连接服务端的套接流,这一步就是使客户端与服务器端的套接流建立联系if(socket_connect($socket,'127.0.0.1',8888) == false){echo 'connect failmassege:'.socket_strerror(socket_last_error());}else{$message = 'l love you 我爱你 socket';//转为GBK编码,处理乱码问题,这要看你的编码情况而定,每个人的编码都不同$message = mb_convert_encoding($message,'GBK','UTF-8');//向服务端写入字符串信息if(socket_write($socket,$message,strlen($message)) ==false){echo'failtowrite'.socket_strerror(socket_last_error());}else{echo 'client write success'.PHP_EOL;//读取服务端返回来的套接流信息while($callback = socket_read($socket,1024)){echo 'server return message is:'.PHP_EOL.$callback;}}}socket_close($socket);//工作完毕,关闭套接流

1.1.4.2 PHP fsockopen   使用方法讲解讲解fsockopen函数,主要是后面我们会讲到主机端口扫描,所以这个函数我们必须讲解。上面在讲socket编程的时候,已经稍微讲解一点fsockopen函数。phpfsockopen是一个非常强大的函数,支持socket编程,可以使用fsockopen实现邮件发送等socket程序等等,使用fsockopen需要自己手动拼接出header部分,本文章向大家介绍fsockopen使用方法和实例讲解,需要的朋友可以参考一下。Php fsockopen介绍fsockopen — 打开一个网络连接或者一个Unix套接字连接。语法:resource fsockopen  ( string $hostname  [, int $port  = -1  [, int&$errno  [, string &$errstr  [, float $timeout  =ini_get("default_socket_timeout")  ]]]] )参数:(1)hostname 如果安装了OpenSSL,那么你也许应该在你的主机名地址前面添加访问协议ssl://或者是tls://,从而可以使用基于TCP/IP协议的SSL或者TLS的客户端连接到远程主机。(2)port 端口号。如果对该参数传一个-1,则表示不使用端口,例如unix://。(3)errno 如果errno的返回值为0,而且这个函数的返回值为  FALSE  ,那么这表明该错误发生在套接字连接(connect())调用之前,导致连接失败的原因最大的可能是初始化套接字的时候发生了错误。(4)errstr  错误信息将以字符串的信息返回。(5)timeout  设置连接的时限,单位为秒。返回值:fsockopen()  将返回一个文件句柄,之后可以被其他文件类函数调用(例如:fgets() , fgetss() , fwrite() , fclose() 还有 feof()  )。如果调用失败,将返回 FALSE  。图片59.png

更详细可以参考手册。(http://php.net/manual/zh/function.fsockopen.php)案例:尝试去访问一个本地80端口,我们查看一下返回值,有什么效果。

\n";}else{fputs($fp,"GET / HTTP/1.0\N HOST:127.0.0.1\n\n");while(!feof($fp)){echo fgets($fp,128);}fclose($fp);}

图片60.png

和BurpSuite访问效果相同。

图片61.png内容显示效果是一样的呢。我们可以看到如果返回200证明80端口开启。以这个原理,我们开始写一个端口扫描器,利用fsockopen函数。既然测试端口,我们先看一下常见安全端口和对应属性一般默认常用端口扫描介绍:


3311:3312 kangle主机管理系统3389  远程登录4440 rundeck是用java写的开源工具5672 rabbitMQ5900 VNC6082 varnish  参考WooYun: Varnish HTTP accelerator CLI  未授权访问易导致网站被直接篡改或者作为代理进入内网6379 redis  一般无认证,可直接访问7001 weblogic8080 tomcat8089 jboss8161 activeMQ8649 ganglia集群系统监控软件9000 fastcgi服务9090 IBM服务9200,9300 elasticsearch  参考WooYun: 多玩某服务器ElasticSearch命令执行漏洞9999 amg加密版10050 zabbix11211  memcache  未授权访问27017,28017 mongodb  未授权访问   mongodb默认无口令登录3777  大华监控设备50000 sap netweaver远程命令执行漏洞50060 50070 hahoop、apache hasoop21 默认是ftp端口   主要看是否支持匿名,也可以跑弱口令22 默认是ssh端口23 默认是telnet端口25 默认是smtp服务53 默认是DNS123 是NTP161,162,8161 snmp服务(8161 IBM一款产品所开放的SNMP)389 ldap团体443  openssl  、hearthleed512,513 rlogin服务或者是exec873 rsync  主要看是否支持匿名,也可以跑弱口令1433 mssql数据库1080 socks代理1521 oracle1900 bes默认后台2049 nfs服务2601,2604 zebra路由 默认密码zebra2082,2083 cpanel主机管理系统3128,3312 squid代理默认端口,如果没设置口令很可能就直接漫游内网了3306 mysql数据库4899 R-admin  连接端4440 rundeck rundeck  参考WooYun:  借用新浪某服务成功漫游新浪内网8834 nessus4848 glashfish


我们需要在代码里面设置相关数组,设置端口一个数组,然后在设置一个属性的数组。简单框架如下

<html>
<title>红日安全</title>
<body align="center">
<form action="#" method="post">
<h4><b>Please input IP address </b></h4><input  type="text"
name="ip"  />

<input type="submit" name="submit"/>
</form>
</body>
</html>
<?php
$port=$_POST['ip'];
.....
?>

图片62.png根据框架,我们开始补充代码,进行不断加强。代码只是入门级代码,我们没有进过任何修饰。

图片63.png首先我们定义了一个表格头,内容如下

<table border="1px" align="center">
<tr>
<td>id</td>
<td>Port</td>
<td>Server</td>
<td>Status</td>
</tr>

核心PHP文件如下

<?php
$ip=$_POST['ip'];
if(ip2long($ip)){
$_ip=explode($ip,".");
foreach($_ip as $key =>  $value){
if($value <0 ||  $value>255){
die("Invalid IP");
}
}
//判断ip地址是否符合,利用两个函数,一个ip2long函数。另外一个利用
explode函数,explode函数主要对ip地址进行分割。ip2long  — 将 IPV4  的
字符串互联网协议转换成长整型数字
}
$port=array(
21,
23,
25,
79,
80,
110,
135,
137,
138,
139,
143,
443,
445,
1433,
3306,
);
$msg=array(
'Ftp',
'Telnet',
'Smtp',
'Finger',
'Http',
'Pop3',
'Location Service',
'Netbios-NS',
'Netbios-DGM',
'Netbios-SSN',
'IMAP',
'Https',
'Microsoft-DS',
'MSSQL',
'MYSQL',
'Terminal Services',
);
//定义了两个数组,一个是端口数组,另外一个是对端口的解释。
foreach($port as $key  =>$value){
echo '<tr>';
echo '<td>'.$key.'</td>';
echo '<td>'.$value.'</td>';
echo '<td>'.$msg[$key].'</td>';
$fp=@fsockopen($ip,$value,$errno,$errstr,1);
$res=$fp?'<span>Open</span>':'<span>Close</span>';
echo '<td>'.$res.'</td>';
}
//主要通过fsockopen这个函数进行判断端口是否打开,如果为真则返回
true,为假则执行false
?>

你怎么看待红日发布的这款新专刊?

你认为它有爆红的潜质吗?
欢迎在评论区留言

享你的观点和看法

banner.jpg

# web安全 # php漏洞 # php代码审计 # 编辑基础
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者