PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : (PHP) - kleines PHP script zur Berechnung von CRC16 (CCITT, XMODEM, KERMIT, 1d0f, IBM)



noobee
18.10.2016, 16:06
Joah, im Titel ist bereits alles genannt. Es reicht bereits ein Eingabefeld, in die ich die Nachricht eingebe (Bsp.: 06 00 0e 00 00 00 9e 09 78 06 06 26 04 0a 02 06 d3 03) und ein Ausgabefeld, in der dann die Checksum steht (hier: d3 01 für KERMIT bzw CCITT-TRUE).
Ich möchte bei der Eingabe mittels dropdown wählen können, ob die Eingabe in HEX, BIN oder DEC geschieht.

Ich weiß, dass die Coder gerne Preise sehen wollen. Ich kann die Arbeit jedoch nicht einschätzen. Deshalb muss ich mich hier mal mit Preisen per PN zutexten lassen ;);)

Anforderungen: es sollte ab php 5.4 sein, nicht älter. Bei Fragen einfach fragen :emoji39:

- - - - - - - - - - Beitrag nachträglich erweitert - - - - - - - - - -

Hier noch ein Nachtrag:

Es gibt bereits Code für crc16. Allerdings für CRC-CCIT FALSE. Hier müsste aber vor dem down-shifting das lowbit geprüft werden. Allerdings bekomme ich das nicht hin, da ich das nicht so recht verstehe.


<?php
// CCITT, X24
define(CRC16POLYN,0x1021);
define(CRC16POLYI,0x8408);

// for "STANDARD" use 0x8005 and 0xA001

function CRC16Normal($buffer) {
$result = 0xFFFF;
if ( ($length = strlen($buffer)) > 0) {
for ($offset = 0; $offset < $length; $offset++) {
$result ^= (ord($buffer[$offset]) << 8);
for ($bitwise = 0; $bitwise < 8; $bitwise++) {
if (($result <<= 1) & 0x10000) $result ^= CRC16POLYN;
$result &= 0xFFFF; /* gut the overflow as php has no 16 bit types */
}
}
}
return $result;
}

function CRC16Inverse($buffer) {
$result = 0xFFFF;
if ( ($length = strlen($buffer)) > 0) {
for ($offset = 0; $offset < $length; $offset++) {
$result ^= ord($buffer[$offset]);
for ($bitwise = 0; $bitwise < 8; $bitwise++) {
$lowBit = $result & 0x0001;
$result >>= 1;
if ($lowBit) $result ^= CRC16POLYI;
}
}
}
return $result;
}

echo '
0x',dechex(CRC16Normal('06000e0000009e097806062604 0a0206d303')),' == 0xd301<br />
<br />
0x',dechex(CRC16Inverse('06000e0000009e09780606260 40a0206d303')),' == 0xd301<br />
?>

HaZe
18.10.2016, 18:12
Und du willst das unbedingt in PHP? Da is das leider echt durch die untypisierten Variablen "a real pain in the arse".
Vllt schreibst dir einfach n Execwrapper für n Konsolentool, falls sich niemand meldet..

noobee
18.10.2016, 18:20
japp, php wäre schon cool.

mhh, meinst du in der shell berechnen wäre besser? das könnte man ja auch in php an die shell senden und dann wieder abgreifen. oder was meinst mit execwrapper?

fralix
18.10.2016, 20:29
Was meinst du mit Dropdown: Willst du das quasi in einem HTML-Frontend um das dann an das Script zu senden?
Ich muss mich erstmal belesen, was die ganzen Namen da oben bedeuten :D

HaZe
18.10.2016, 21:31
ja genau das meine ich. Mit $crc = exec('crc16calculatortool '.$daten); führst du den Befehl auf der Konsole aus und hast dann die Rückgabe (Achtung, nur die letzte ausgegebene Zeile) in $crc...

noobee
18.10.2016, 21:46
Was meinst du mit Dropdown: Willst du das quasi in einem HTML-Frontend um das dann an das Script zu senden?
Ich muss mich erstmal belesen, was die ganzen Namen da oben bedeuten :D
Öhm, jain. Also im Prinzip reichen schon die php-funktionen. dropdown und checkboxen/radiobuttons sind fix selber drumrum gebastelt :-p Vllt sollte ich das oben doch rausnehmen. Ist ja eigentlich wirklich einfaches Gedöns -.-
Es sollte also mindestens für folgende crc16 je eine php-funktion geben: CCITT TRUE, CCITT FALSE, KERMIT, XMODEM. Die anderen zwei (1d0f, IBM) sind mal außen vor, also eher ein Nebenprodukt, falls wer zu viel Zeit habt :emoji39:


ja genau das meine ich. Mit $crc = exec('crc16calculatortool '.$daten); führst du den Befehl auf der Konsole aus und hast dann die Rückgabe (Achtung, nur die letzte ausgegebene Zeile) in $crc...
naja, dafür müsste ich auch erst das tool basteln... Der Anfang war ja schon mit shell_exec() da, aber irgendwie reichts eben nicht. Also rein mit der shell gehts nicht. Es müsste also ein "eigenes" tool her, welches dann mittels shell_exec genutzt werden kann. Ich glaub, da ist php besser. Auch wenn du natürlich damit
untypisierten Variablen "a real pain in the arse". absolut recht hast. Was ich da schon manchmal an Zeiot verloren habe -.-


Achja, zum Testen gibts die bekannte Seite https://www.lammertbies.nl/comm/info/crc-calculation.html

Und hier mehr über CRC16 Catalogue of parametrised CRC algorithms (http://reveng.sourceforge.net/crc-catalogue/16.htm)

Darkbasic
18.10.2016, 23:34
Damit das läuft, Jungs, muss auch shell_exec in der php.ini aktiviert sein.

HaZe
19.10.2016, 22:20
In c z.b. gäb es das als fertige Funktion.. ich würde annehmen die anderen Implementierungen kann man auch finden.
c - Function to Calculate a CRC16 Checksum - Stack Overflow (http://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum)

noobee
20.10.2016, 06:32
Naja, deshalb hab ich es ja hier "in Auftrag" gegeben, weil ich doch n bissi zu bleede dafür bin. Selbst wenn der c-code gehen würde. Ich könnte ihn nicht auf php ummünzen.

Shell_exec funzt, es muss also jemand in meiner php.ini schon eingestellt haben :-D

y0l0sw4gg3r
20.10.2016, 11:59
Ich muss sagen, gut, dass du noch nichts unternommen hast. Vor allem das Shell-Exec solltest du tunlichst vermeiden. Die Algorithmen sind nun wirklich denkbar simpel. Solltest du noch weiteren Bedarf an der Lösung haben kannst du dich bei mir per PN melden - am besten direkt mit weiteren Kontaktmöglichkeiten (jabber/icq/....).

noobee
20.10.2016, 19:56
ich suche vergebens deine icq nummer

HaZe
20.10.2016, 21:23
Nu bin ich gespannt: Wieso sollte man Shell_Exec vermeiden?

Unlimiter
20.10.2016, 21:42
Weil shell_exec ein Sicherheitsrisiko darstellen kann (nicht zwingend muss). Deswegen sollte man es auch nur dann anwenden, wenn es gar nicht anders möglich ist und man weiß was man macht.

Ein Fall wo es z.b. wäre: man hat in einer Variable, die bei Shell_exec verwendet wird, einen Userinput dabei, der nicht ausreichend geprüft wird.

Im Prinzip dasselbe wie bei ner plain-sql query mit Userinput. In beiden Fällen hängts davon ab, was der Coder davor für Überprüfungen gemacht hat (für zulässige Inputs) oder überhaupt nur fixe Inputs zulässt (im Code festgelegt).

// Ist sehr wahrscheinlich etwas, dass du direkt schon voraussetzt, aber der ein oder andere gar nicht beachtet.

syrius
20.10.2016, 21:51
In shell_exec sehe ich keinerlei Risiko. Ob nun der Server minderwertig gesichert ist, oder das Script ... der Webservice läuft unter restricted User. Wenn also wer den Server anhand einer Injection hackt, dann kommt das dem Ausnutzen von shell_exec gleich.

Unlimiter
20.10.2016, 22:19
Ne, ist absolut kein Risiko in einem PHP Script :D

Schon mal diese 2 Zeilen ausprobiert?


$var = ""; // beliebige variable
var_dump(exec($var));
oder

$var = ""; // beliebige variable mit parameter
var_dump(exec(ls . $var));

Sowas nennt man dann "Risiko", weil eventuell möchte man nicht, dass der User sich den gesamten File-Tree ansieht (einfachstes Beispiel). Darum rät man auch gerne davon ab es zu verwenden, oder es nur dann einzusetzen, wenn man weiß was man macht (Inputvalidierung).

// Wir stellen uns einfach vor das $var wäre mit einem $_GET oder $_POST Parameter befüllt.

syrius
20.10.2016, 22:25
Damit ein Besucher PHP-Quellcode ändern kann, müsste er den Server / Script gehackt haben. Und dann ist eh alles verloren. Ob schwach geschützter Server oder Script - läuft beides aufs gleiche raus.

Unlimiter
20.10.2016, 22:27
Wenn man einen Command-Befehl hat, der eine Variable beinhaltet die frei vom User gewählt wurde, ermöglicht man ihm (ohne weitere Absicherung, wie Validierung) die Fähigkeit den Befehl beliebig zu erweitern.

Dazu muss man nichts hacken.

syrius
20.10.2016, 22:28
Was auf unzureichende Entwicklung zurückzuführen ist.

Unlimiter
20.10.2016, 22:31
Was genau einer der Punkte ist weswegen man Leuten davon abrät diesen Befehl zu nutzen, um so keine mögliche Angriffsfläche zu bieten.

Man kann das "Risiko" bei der Verwendung nicht einfach relativieren oder gar streichen.

syrius
20.10.2016, 22:40
Sicher, aber wie schon gesagt, hängt es allein von der Entwicklung ab. Man kann shell_exec ohne Probleme anwenden wenn man sich bewusst ist welche Risiken es birgt. Ist das gleiche wenn man einen Linux-Server nutzt - der birgt noch viel mehr Risiken. Man nutzt auch nicht just4fun beliebige Funktionen/Module ohne sich im Voraus ausreichend informiert zu haben. Und wer es ganz sicher haben möchte, installiert sich einfach eine zweite Instant des Webservice, legt diese auf einen unbekannten Port und regelt per IPTables :) natürlich eher für Backend-Anwendungen. Außerdem bin ich mir ziemlich sicher, dass man genauer definieren kann wovon es angesprochen werden darf.

;P

HaZe
20.10.2016, 23:49
Wer Werte aus $_GET oder $_POST ungefiltert verwendet hat eh die Kontrolle über sein Leben verloren.

- - - - - - - - - - Beitrag nachträglich erweitert - - - - - - - - - -

Um noch etwas Konstruktives hinzuzufügen:
SQL darf auch nicht mit ungefiltertem Userinput gefüttert werden. Trotzdem rät man nicht generell von SQL ab.
PHP: escapeshellarg - Manual (http://php.net/manual/en/function.escapeshellarg.php)
PHP: escapeshellcmd - Manual (http://php.net/manual/en/function.escapeshellcmd.php)

Unlimiter
21.10.2016, 04:27
Man kann shell_exec ohne Probleme anwenden wenn man sich bewusst ist welche Risiken es birgt

Ja, aber warum denn Syr? Es ist doch ohne Probleme nutzbar. Jetzt auf einmal muss man sich doch des Risikos bewusst sein? Das war genau der Teil, der bei deinem ersten Kommentar gefehlt hat :D. Das Informieren über Risiken ist etwas, dass viele Frischlinge und selbst ein Teil der erfahrenen Leute unterlassen.

Die Frage war, weswegen man es nicht nutzen sollte und die Antwort war auch, wenn man nicht genügend Hirn hat, sollte man es lassen.

Würde ich es persönlich unter Voraussetzung der Asicherung verwenden? Ja, denn die Laufzeit ist wesentlich geringer. Würde ich es jedoch auf biegen und brechen verwenden? Nein.

@HaZe:
Danke für deine Ergänzung, anscheinend hat es sich zu allgemein gelesen. Erst bei Syr kritisieren, dass er früher etwas nicht im Text erwähnt hat und dann selbst das gleiche machen :D. Ich füge jetzt an der Stelle noch was dazu (editierter Text, weil erst unlogischer Zusammenhang):

Häufig wird dazu geraten, für jede Kleinigkeit eine Alternative und nicht den direkten Weg zu nehmen. An der Stelle hätten wir "verwende immer Prepared Statements", verwende immer Wrapper, nutze möglichst nie exec (usw.). Für Frischlinge und Leute die sich nicht viel mit dem Thema auseinander setzen ist sowas oft besser (können auch Probleme entstehen). Bei Experten die ein Schweizer-Taschenmesser entdecken kann es passieren, dass sie gar nicht mehr auf Alternativen achten, bei denen z.b. die Validierung schon beinhaltet ist.

An der Stelle aber jetzt genug von mir davon, ansonsten findet sich hier noch ein Text über mehrere Seiten wieder, der "sinnvolles" und "nicht sinnvolles" verwenden von Funktionen beinhaltet. Gibt ja viel darüber zu sagen.

Nimbus
21.10.2016, 09:37
Eingaben in SQL unzureichend gefiltert zu benutzen ist gefährlich. Allerdings lässt sich die Nutzung von SQL meist nicht (sinnvoll) vermeiden. Daher rät dir keiner vor SQL ab.
Eingaben in Befehlen unzureichend gefiltert zu benutzen ist deutlich gefährlicher. Es lässt sich oft und vermutlich auch hier sehr gut vermeiden. Daher rät man allgemein vor der Nutzung tendenziell eher ab.

Die genannten escape-Funktionen sind da leider auch keine Wunderwaffen und es sind durchaus subtilere Bugs denkbar. Auf der wirklich sicheren Seite ist man nur, wenn man nur User-Input in diesen Befehlen verarbeitet bei dem man sich 100% sicher ist, dass er ungefährlich ist. Diese Sicherheit hat man (meiner Meinung) allerdings nur dann, wenn man gegen eine Whitelist prüft.


EDIT: Nicht schön, aber selten


<pre>
<?php
define( 'CRC16POLYN', 0x1021 );
define( 'CRC16POLYI', 0x8408 );

function CRC16Normal( $buffer, $result ) {
if ( ( $length = strlen( $buffer ) ) > 0 ) {
for ( $offset = 0; $offset < $length; $offset++ ) {
$result ^= ( ord( $buffer[$offset] ) << 8 );
for ( $bitwise = 0; $bitwise < 8; $bitwise++ ) {
if ( ( $result <<= 1 ) & 0x10000 ) $result ^= CRC16POLYN;
$result &= 0xFFFF;
}
}
}
return $result;
}

function CRC16Kermit( $buffer ) {
$result = 0;
for ( $x=0; $x<strlen( $buffer ); $x++ ) {
$result = $result ^ ord( $buffer[$x] );
for ( $y = 0; $y < 8; $y++ ) {
if ( ( $result & 0x0001 ) == 0x0001 ) $result = ( ( $result >> 1 ) ^ CRC16POLYI );
else $result = $result >> 1;
}
}

$lowBit = ( $result & 0xff00 ) >> 8;
$highBit = ( $result & 0x00ff ) << 8;
$result = $highBit | $lowBit;

return $result;
}


function out( $in ) {
echo "0x".strtoupper(dechex($in));
echo "\n";
}

if (isset($_POST['mode']) && isset($_POST['input'])) {

switch ($_POST['mode']) {
case 'hex':
$input = hex2bin($_POST['input']);
$mod = "HEX";
break;
case 'dec':
$input = decbin($_POST['input']);
$mod = "DEC";
break;
default:
$input = $_POST['input'];
$mode = "ASCII";
break;
}

echo "Input '".htmlspecialchars($input, ENT_QUOTES, 'UTF-8')."' (mode ".$mode.")\n";


echo "CRC-CCITT (XModem):\t";
echo out(CRC16Normal($input, 0x0000));

echo "CRC-CCITT (0xFFFF):\t";
echo out(CRC16Normal($input, 0xFFFF));

echo "CRC-CCITT (0x1D0F):\t";
echo out(CRC16Normal($input, 0x1D0F));

echo "CRC-CCITT (Kermit):\t";
out(CRC16Kermit($input));
}
?>

<form method="post">
<input type="text" name="input">
<select name="mode">
<option value="ascii">ASCII</option>
<option value="hex">HEX</option>
<option value="dec">DEC</option>
<input type="submit">
</select>
</form>
</pre>

Unlimiter
21.10.2016, 16:35
Warum sprechen wir eigentlich davon von "SQL" abzuraten?

Es geht ja um folgende Ratschläge:


Verwende nicht mysql_connect sondern PDO [ gleichzusetzen mit: verwende curl_exec anstatt exec(curl..) - dass eine ist ein Func-Call, dass andere ein neuer Prozess , weswegen man davon abrät ]
Verwende nicht direkt Variablen sondern Prepared Statements [ Wie wir wissen können prep-statements ohne Validierung sinnlos sein und trotzdem SQL-Inj. erlauben. Das könnte man gleichsetzen mit exec ohne die Validierung des Inputs des Users der gegebenenfalls weitere Parameter einschleust, weswegen man davon abrät ]


In Wirklichkeit könnten wir auch noch ein Dutzend anderer Befehle listen, die Sicherheitsrisiken bieten, wenn man nicht korrekt validiert. Auch kann man sagen, dass im Grunde (ohne andere Fakten zu betrachten) das meiste sicher ist, sofern man alles korrekt spezifiziert und validiert. Validierung heißt in dem Fall sowohl die Eingaben, als auch Ausgaben an jeder Stelle, egal ob Input durch User oder nicht, egal was man nicht macht oder zusätzlich macht.

Aus dem Grund hat auch jeder von uns das Korrekte zu exec gesagt:

Syr und HaZe, die voraussetzen, dass korrekt validiert wird (deswegen keine Gefahr sehen)
Nimbus und ich, die darauf Hinweisen, dass man sich durch schlampiges Verhalten selbst eine Sicherheitslücke dadurch schaffen kann (unter anderem wegen der Frage - wieso rät man davon ab)
y0l0sw4gg3r keine Ahnung warum, denn er hat seinen möglichen Grund für die Ablehnung des Befehls nicht genannt.


Fälle wann etwas sinnvoller wäre steht ja nicht im Raum. Das würde dann jedoch eine über Seiten führende Debatte bzw. Zusammenfassung werden. Immerhin hängts vom "was" und "wie" ab.

Wieso rät man davon ab ist eine Verallgemeinerung - nicht jeder wird einem davon abraten, manchmal ist es sogar dumm jemanden von seinem vorhaben abzuraten, wenn es am Ende so sogar mehr Peformance liefert und gleich sicher oder noch sicherer wird (wink auf Prepared Statements - die für manche der Universalschutz gegen SQL-Inj. sind).

HaZe
22.10.2016, 12:24
Warum sprechen wir eigentlich davon von "SQL" abzuraten?

Weil der Hinweis nicht war "Achtung, denk an die Inputvalidierung", sondern "Benutz es lieber nicht!".
Es gibt gute Gründe bestimmte Dinge auszulagern, u.A. Performance oder - wie in diesem Fall hier - bestehende Librarys in anderen Sprachen.
Ich hatte ja auch davon gesprochen einen Wrapper zu schreiben (nichts anderes ist curl_exec ja im Grunde).

Nimbus
23.10.2016, 12:03
Um SQL führt aber nicht viel bzw. nichts herum (notwendiges Übel) außerdem gibt es prepared statements, die SQL-Injections ziemlich effektiv vermeiden. Daher hinkt der Vergleich meiner Meinung nach.

Ich denke ein Hauptgrund für diese Uneinigkeit ist, dass das Risiko-Nutzen-Verhältniss unterschiedlich eingeschätzt wird. Einfachheit (oder manchmal auch Faulheit) und Effizienz sind zwar toll, aber man muss auch die Risiken kennen und hier kann man mit einem kleinen Fehler großen Ärger anrichten. Die angesprochene Input-Validierung ist hier gerade der springende Punkt: sie sollte Perfekt sein und genau das ist schwierig.

Ein PHP Modul (?) um bestehende CRC-Libraries einzubinden klingt für mich nach totalem Overkill.

Unlimiter
23.10.2016, 16:16
Das einzige das hier hinkt ist, dass man manchmal Beiträge anders versteht, als sie gemeint sind oder gegebenenfalls zwischenzeitlich nur selektiv liest.

Nimmt man SQL her, könnte man sagen, dass manchmal gesagt wird : Nimm lieber NoSQL anstatt SQL, aber da wären wir ja immer noch beim Punkt (den hat jeder richtig erkannt), dass es kein guter Vergleich wäre.

Was wäre der passende Vergleich? Siehe letzter Beitrag.

@HaZe: Du hast doch nur die simple Frage gestellt, wieso vom Befehl abzuraten sei und die erste Antwort lieferte schon, dass es an der Validierung des Inputs liegt. Hat ja nichts mit deinem zusätzlichen Vorschlag des Wrappers zutun, wo so etwas bereits bedacht wird ;).

FLX
23.10.2016, 17:04
Von der Frage des Erstellers dieses Threads ist das aber nun etwas abgeschweift, oder?

Nimbus
23.10.2016, 17:15
Wir sind zwar etwas abgeschweift, aber es ist durchaus eine interessante Diskussion.
Der Threadersteller hat sich zwar nicht mehr öffentlich gemeldet, aber nach meinem Stand tut mein gepostete Code wohl was er soll.

Unlimiter
23.10.2016, 19:36
Es ist alles noch im Rahmen.

Da der User sein Problem bereits mit exec gelöst hat (wie einige Beiträge zuvor zu entnehmen ist - bzw. aus dem Kommentar "shell_exec funzt"), war der weitere Verlauf, also die Diskussion im Zusammenhang mit der Verwendung von exec (und alternativen Beispielen) absolut zulässig.

Es empfiehlt sich jedoch den Melde-Button zu betätigen, wenn man denkt, dass ein Gesprächsverlauf ins Off-Topic über geht.

noobee
23.10.2016, 20:34
ich wollte die interesante Diskussion nicht stören. Nimbus sein Code läuft bisher bestens. Danke nochmal öffentlich dafür :-)
Und jetzt, weiter diskutieren :-D