Newsgroup: it.comp.www.php
Titolo: Obfuscator da cli

Conoscete un obfuscator che possa essere eseguito da CLI (linux) ?
Sono in cerca di qualche che, preferibilmente, converta un codice in una schifezza di "l1l1lll111l1lll" o "0OOOO0O00O0O0O0O"
 
al limite , anche un semplice replace randomico di funzioni, variabili, classi e sopratutto stringhe (magari con la controparte in HEX)
 
Tutti quelli che ho trovato o non convertono le stringhe, oppure sono per windows.
 
Se free meglio, se open, ancora meglio.

 Sono in cerca di qualche che, preferibilmente, converta un codice in una schifezza di "l1l1lll111l1lll" o "0OOOO0O00O0O0O0O"
 
Nessuno? Eppure ho visto parecchi codici fatti in questo modo...

On Thu, 14 Nov 2013 14:51:12 -0800 (PST), 
gandalf.co...@gmail.com
 
wrote:

Mmm... cosa vuoi ottenere, di preciso, offuscando il codice?
 
Tieni presente che la maggior parte degli "offuscatori" si tronca con
pochissimo sforzo: la "schifezza" non e' una garanzia. Questo qua per
dire
 
 
http://www.phpencode.org/
 
 
genera roba discretamente orrida, ma si rompe in due minuti.
 
La descrizione che dai mi fa pensare a POBS. Appariva terrificante, e
la maggior parte delle cose che uno potrebbe voler fare col codice...
dal modificarlo allo spacciarlo per proprio... te le lasciava fare.
 
Leonardo
 
-- 
 
Then felt I like some watcher of the skies, when a new planet swims into his ken;
Or like stout Cortez when with eagle eyes, he star'd at the Pacific; and all his men
Look'd at each other with a wild surmise - silent, upon a peak in Darien.

 Mmm... cosa vuoi ottenere, di preciso, offuscando il codice?
 
Scoraggiare i bimbiminkia, sostanzialmente.
So che un obfuscator non protegge, ma se non altro rompe un bel po i maroni.
 
Che poi la non-protezione è relativa, se rinomini tutte le variabili e tutte le funzioni in qualcosa di privo di significato ed irreversibile (random, O0, I1, md5, etc etc) sicuramente il reverse engineering del codice diventa ai limiti dell'assurdo.
 
Sommaci anche la versione hex delle stringhe (bucabile con poco, vero), e scoraggi il 99% dei curiosi.
 
Cerco appunto qualcosa che mi rinomini tutto il possibile in una sola direzione.

Scoraggiare i bimbiminkia, sostanzialmente.
 
Ma come fanno i bimbiminkia a mettere le mani sul tuo codice, pero'? :-?
 
E una volta che ce le avessero messe, di cosa hai paura?


 E una volta che ce le avessero messe, di cosa hai paura?
 
E' tutto molto semplice: il cliente ha acquistato un software, per il quale avevamo proposto, ad un cifra ridicola (300 euro in più rispetto alla versione chiusa, che costava 700), la consegna dei sorgenti e l'installazione su un suo server. 
Il codice in questione, per noi, non ha alcuna importanza, è dozzinale, avremmo guadagnato su tutto il resto del servizio, non sullo sviluppo di questa accozzaglia di codice.
 
Poi i rapporti sono un po degenerati e si è intromesso il consulente tennnnico del cugino dello zio del fratello che spara le sue solite stronzate e "suggerisce" di far installare il tutto su un server di $AziendaConcorrente affidando a loro la gestione del progetto (dove sicuramente il consulente avrà una %, aggiungo io)
A 'sto punto, visto che i sorgenti non li ha voluti comprare e che la gestione della parte 'sostanziosa' passa ad altri e noi ci teniamo (solo perchè già pagata) lo sviluppo della ciofeca, vorrei rendere quest'ultima indecifrabile, giusto per fargli un dispetto.
 
Se lo decritta (impossibile, se si usano md5 per ogni variabile/classe/metodo/funzione) almeno diventa cretino a capire chi fa cosa.
 
P.S: non ho paura di nulla, voglio solo fargli un dispetto, così, per pura soddisfazione personale, sto tizio mi sta sui maroni, è capitato certamente a tutti: analisi da parte nostra, settimane di lavoro a stagli dietro, preventivi, riunioni, etc etc poi arriva un pirla che, il giorno della firma ed analisi alla mano (fatta da noi) suggerisce di far fare tutto ad altri ad una frazione del costo (ovvio, l'analisi l'abbiamo fatta noi dopo settimane di incontri).
 
P.P.S: non posso compilare il codice, ne usare loader sul server. Il codice deve essere "aperto", illeggibile, indecifrabile, assurdo, ma comunque "open source" :) Nessuno vieta di programmare usando md5 come nomi delle funzioni.

 "open source" :) Nessuno vieta di programmare usando md5 come nomi delle funzioni.
 
Pero', questo genere di scherzo ti espone facilmente a un'accusa di scrivere
codice del menga.
 
Perche' fornire una giustificazione, un'arma, a qualcuno che non ami?
 
Io darei il codice sorgente agli "avversari" con un amichevole sorriso. Poi,
il karma fara' il resto :-D. Se proprio, puoi mettere in giro la voce che l'
autore del codice ha dichiarato che non vorrebbe essere nei loro panni.
 
E puoi perfino rassicurarli dicendo che non riusciranno mai a dimostrare che
in quel codice hai messo qualche porcheria intenzionalmente. Dato che non lo
avrai fatto, sara' la pura verita'...


non è che offuscando gli basta poi farsi fare un reverse da
qualcuno un po' piu' esperto di loro; considerando tutte le info in rete
potrebbero trovare soluzione e a basso costo; avranno codice senza commenti
e nomi alterati; forse quanto basta se devono ritoccare solo qualche
piccola parte; ma quanto è 'grande' questo codice?

 A 'sto punto, visto che i sorgenti non li ha voluti comprare
 
Non è chiaro, dici che gli avete proposto per 300 euro in più consegna 
dei sorgenti e istallazione su un suo server, e che lui non li ha 
voluti comprare.
Cosa ha comprato effettivamente?
Se il suo contratto non prevede la consegna dei codici non glieli date 
e buonanotte.
 
-- 
Andrea
 

 autore del codice ha dichiarato che non vorrebbe essere nei loro panni.
 
"Siediti comodo sulla sponda del fiume, e attendi: potresti
vedere il cadavere del nemico che passa trasportato dalla corrente".
 
proverbio cinese
 
 
 

 e buonanotte.
 
infatti, se nel contratto non c'è scritto allora assolutamente NON DEVE
dargli il codice, anche solo per non incorrere in eventuali ed inimmaginabili
problemi...
 
 

 vedere il cadavere del nemico che passa trasportato dalla corrente".
 
Io giro con le canne da pesca già montate.
 
-- 
Andrea
 

problemi...
 
Il problema e', come si fa? Se l'applicazione esiste solo come sorgente, visto
che PHP e' interpretato...
 
...o uno monta tutto su una VM chiusa: ma anche cosi', gestirla e' complesso e
mica tutti i provider possono prendersene carico.
 
Oppure uno da' i sorgenti con il vincolo che non devono essere modificati.
 
Siccome - anche per dimostrare di fare qualcosa - i nuovi gestori invece vanno
sicuramente a metterci le mani, qualsiasi casino e' interamente colpa loro. E,
anzi, a partire dalla prima modifica, anche problemi del codice originario non
sara' facile dimostrare che NON sono dovuti al loro smanettamento.
 
Ogniqualvolta in ditta abbiamo preso in carico codice PHP di "terze parti", e'
SEMPRE stato un lavoraccio. Purtroppo, PHP non e' il massimo dei linguaggi per
quanto riguarda la manutenibilita'.


 Oppure uno da' i sorgenti con il vincolo che non devono essere modificati.
 
Ma in questo caso il contratto "esteso" cosa offriva di più?
Cioè gli hanno proposto un sovrapprezzo per i sorgenti, il cliente non 
l'ha voluto, ora perché consegnargli i sorgenti?
 
-- 
Andrea
 

l'ha voluto, ora perché consegnargli i sorgenti?
 
Perche' magari non consegnarli e' impossibile, in quanto l'applicazione esiste
solo come sorgente (PHP e' interpretato).
 
Si potrebbe argomentare che sia stato poco lungimirante sdoppiare il contratto
in questo modo (un po' come vendere una macchina perfettamente funzionante, ed
aggiungere "...e si mette in moto" come optional!), perche' crea una soluzione
che costa MENO al cliente e DI PIU' al fornitore, che e' un caso pernicioso.
 
La via d'uscita piu' semplice e' "ripensarci" e regalare l'optional. Cosi', la
cosa almeno non costa un extra al fornitore.
 
Per la prossima volta, un'altra opzione possibile e' lo sconto in caso che una
installazione avvenga su macchine proprie: "Siccome le conosco e le so gestire
il mio costo di manutenzione e' inferiore, e sono disposto a girare a te tutto
questo risparmio. Se il mio software gira sulle mie macchine sono 300 EUR meno
del prezzo generico. Se lo vuoi tirare fuori di li', benissimo - pero' intanto
non hai piu' diritto allo sconto. E no, il software non e' TUO, e quelle righe
di codice non sono TUE, ce le hai in LICENZA: non e' vero che 'le hai pagate e
le installi dove ti pare', perche' quel codice - oltre a contenere il know-how
aziendale - si riflette sull'immagine dell'azienda, e se l'installi da qualche
parte assurda e non supportata dove funziona di merda, sembra che la colpa sia
nostra. Se vuoi la PROPRIETA' del codice c'e' da pagare un monte di piu', e un
paio di liberatorie, e noi ce ne laviamo le mani perche' appunto il codice poi
sara' TUO, non piu' nostro."
 
Ma appunto ormai questo va bene per la prossima volta.


 codice del menga.
 
Poco importa, l'idiota (sappiamo chi è) lo farebbe uguale.
Oramai il cliente è perso e con questo pseudo-consulente ci siamo già scontrati negativamente altre volte.
 
Quello che tu scrivi è certamente corretto, ed infatti è la prima volta che
devo offuscare/criptare qualcosa (da qui il motivo del thread) ma sto tizio mi sta talmente sui maroni, talmente tanto che farò tutto ciò che è in mio potere (ho sempre sognato dirlo) per dargli fastidio.

 e buonanotte.
 
Il preventivo prevedeva, come sempre, l'installazione dei codici sui nostri server quindi il problema dei sorgenti non si poneva (il cliente non accede ai nostri server se non tramite web e di conseguenza, non vede i sorgenti)
 
Poi però, complice una poca cura da parte nostra data la poca importanza del codice stesso, il commerciale di turno ha acconsentito ad installare il codice su un server della concorrenza gestito dal cliente/consulente.
 
Da qui il 2+2 è semplice: codice installato su server altrui = codice con sorgenti.
 
Dato che i sorgenti non li ha pagati, voglio fargli il dispetto, evitando, preferibilmente, l'utilizzo di esecutori lato server (zend, ioncube, etc)
perchè so già per certo che in caso di problemi poi sarebbero difficili da
giustificare. Glielo do bello offuscato, gira con tutti i server dell'universo
senza requisiti particolari ed allo stesso tempo è un massacro da mantenere
(per il consulente)
 
Inoltre l'offuscatore di cui parlo (ovvero quelli one-way) potrebbero tornarmi utili in futuro.

 con sorgenti.
 
OK, ma rimangono valide le protezioni legali sul codice.
Se non c'è una licenza esplicita, quel codice è copyright inalienabile 
dei programmatori. E` diventato proprietà dell'azienda perché i contratti 
di solito prevedono che quello che produci in orario di lavoro diventi 
proprietà dell'azienda.
 
Quindi controlla la licenza d'uso (se c'è). Potreste tranquillamente 
riprendervi i sorgenti, e fornirgli solo un dump del database (quei dati 
di solito sono di loro proprietà) ed eventualmente le immagini (dipende 
dal contratto anche qui).
 
Se la licenza non c'è, siete in tempo a stilarne una che lui sarà 
costretto ad accettare, se vuole continuare a usarli. E nella licenza 
potete metterci quello che volete, da "non puoi modificarli" a "ogni riga 
modificata ci dovete pagare 1 euro".
 
Come ho detto, l'unica protezione valida è quella legale. Le altre sono 
inutili.
 
Bye.

Oramai il cliente è perso e con questo pseudo-consulente ci siamo già scontrati negativamente altre volte.
 
Allora la situazione e' ideale - a patto che il tizio non legga Usenet.
 
Leva i commenti e lascia tutto com'e'. La prima modifica che dovra' fare, non
avra' scuse per non farla (scuse che altrimenti stai per dargli!), e, col 99%
di probabilita', ci si rompera' la schiena.
 
Magari cambia il copyright in
 
	/**
	 * Versione x.y.z per uso esclusivo di ABC.
	 * La diffusione di questo codice a terzi non e' consentita.
         * La rimozione di questa nota non e' consentita.
	 * ACME SRL declina qualunque responsabilita' derivante dall'uso
         * di questo codice.
         * Buon lavoro! -- Gandalf.
	*/
 
Che "Buon lavoro" in quel contesto sia una minaccia di stile mafioso lo sa lui
e lo sai tu - ma non puo' essere dimostrato. Anche perche' il resto del codice
sara' identico al codice di produzione, intatto e immacolato.
 
Ma prova a lavorare con del codice che non ti e' familiare col sospetto che ci
siano delle trappole.
 
===
 
Cosi' per ridere e cambiando discorso, che' non e' piu' offuscamento generico,
potremmo parlare di scherzi perfidi come questo:
 
        switch($mime = (
               ( $fmt == 'G' ) ? 'gif'  :
               ( $fmt == 'J' ) ? 'jpeg' :
               ( $fmt == 'T' ) ? 'tiff' :
               // ( $fmt == 'P' ) ? 'png'  : // Supporto PNG a pagamento
               'text/html') ) {
                case 'png':
                        // Header("Content-Type: image/{$mime}");
                        // ImagePNG($gd);
                case 'gif':
                        Header("Content-Type: image/{$mime}");
                        ImageGIF($gd);
                        return;
                case 'jpeg':
                        Header("Content-Type: image/{$mime}");
                        ImageJPEG($gd);
                        return;
                case 'tiff':
                        sendTiffImage($file);
                        return;
                case 'html':
                        die("Format {$fmt} is not supported!");
        }
	// Other code
 
...la funzione viene chiamata con un parametro $fmt che e' G, J o T. Almeno in
apparenza gestisce dei formati grafici. Ma ovviamente, non ci deve essere unit
testing sopra.
 
Senza guardare la soluzione, indovina cosa fa :-D
 
(Sarebbe molto difficile giustificare questo codice in sede civile se non come
un caso di estrema incompetenza da parte del programmatore... qualsiasi perito
ravviserebbe immediatamente la truffa aggravata e premeditata :-D ).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Se il parametro e' G, J, o T esegue comunque sendTiffImage($file). E in tutti
gli altri casi, e.g. "Z", esegue "Other code", perche' $mime e' text/html, ma
lo switch imposta "text/html". I casi GIF e JPEG sono ignorati. E attivare il
supporto PNG sembra semplice ma fa si' che il codice smetta di funzionare; e'
fornito un motivo apparente per questo, un fallthru, che non e' quello vero.


 fornito un motivo apparente per questo, un fallthru, che non e' quello vero.
 
LOL

 	// Other code
 
Non è molto diverso da questo:
 
<?php
class gJEJMhxy {
public $fUoXDE85 = \x88\x82\x83; public function G8wKwpGK($xd2TfKWc, $sVMhqa7Y) {
echo $fOoXDE85.$fUoXDE85;
}
}
 
o
 
<?php
class O0O000O0000 {
public $0O0O0 = \x88\x82\x83; public function 000OO0O0($0OOO000OO, $O000O) {
echo $0OO0O0.$0O0000;
}
}
 
quest'ultimo ancora più difficile da leggere perchè ti si ingarbuglia la vista (ed è ciò che vorrei ottenere)
 
la differenza rispetto al tuo è che il tuo va studiato a tavolino, il secondo lo si ottiene da solo in qualche modo. E non è tecnicamente deoffuscabile dato che non c'è alcun riferimento a
 
prova = 0O000OO0O0
 
quindi se hai solo gli 0/O non tornerai mai al "prova" originale che ti consentirebbe un debug. devi leggere tutto il codice, riga per riga, solo per capire chi fa cosa.
 
Gli offuscatori tradizionali che si trovano in giro fanno, solitamente, un base64 del codice, seguito da uno o più rot13 ed eventuali compressioni gz.
Si decriptano in breve tempo. L'unica parte 'complessa' è il rot13, che se
se eseguito più volte non ti permette di sapere quante volte decriptarlo.
(ma puoi andare di php --lint fino ad ottenere un codice valido)
 
Io cerco un altra cosa.

la differenza rispetto al tuo è che il tuo va studiato a tavolino
 
...e che NON SEMBRA codice offuscato intenzionalmente :-D


 ...e che NON SEMBRA codice offuscato intenzionalmente :-D
 
Ma anche se fosse? Dove c'è scritto che il codice va consegnato "in chiaro" ?
Io non lo posso compilare, ma posso benissimo offuscarlo.

Ma anche se fosse?
 
Quale parte di
 
	cambiando discorso, che' non e' piu' offuscamento generico...
 
avrei dovuto sottolineare meglio? :-?
 
Il discorso sull'offuscamento e' giunto alla sua fine naturale: ho espresso
l'unica mia opinione in merito e altre non ne ho, e che comunque la prima e
l'ultima parola (e tutte quelle in mezzo), in merito, spettino a te e' cosa
pacifica e mai in discussione: del resto, son mica io parte in causa.
 
Se sei sicuro di non utilizzare costrutti del tipo
 
	${$a.$b}
 
magari puoi cercare tutti i token \$[A-Za-z_0-9] nel codice con uniq, e poi
far passare i sorgenti da una apocalisse di "sed" (il cd. "Armaseddon") per
rimpiazzarli tutti. Li riordini, li numeri, converti il numero in binario e
assegni O allo zero e 0 all'1. Prependi un O al numero e hai un altro token
valido.
 
bash -c "sed $( grep "\$[A-Za-z_][A-Za-z_0-9]*" $1 | sed -e
"s/\$[A-Za-z_][A-Za-z_0-9]*/\n&\n/g" | grep "\$[A-Za-z_][A-Za-z_0-9]*" | sort
| uniq | awk 'function bs(b,d,m){if (b==0){return
"0"};for(m=1;b!=0;b=rshift(b,1)){d=(and(b,m)?"0":"O")
d};while(length(d)<12){d="O" d};return d} { print "-e \"s/\\" $0 "\\b/\\$"
bs(FNR) "/g\"" }' | tr "\n" " " ) < $1 > $( basename $1 .php )-obf.php"
 
Prima:
 
        function smtp_error($code, $text)
        {
                GLOBAL  $smtp_error_code, $smtp_error_text;
                if (isset($smtp_error_code)) $smtp_error_code        = $code;
                if (isset($smtp_error_text)) $smtp_error_text        = $text;
                if (function_exists('user_smtp_error'))
                        return user_smtp_error($code, $text);
                if ($code != 0)
                {
 
dopo "armased sendmail.php", "sendmail-obf.php" contiene:
 
        function smtp_error($OOOOOOO0O0OO, $OOOOOO00OOOO)
        {
                GLOBAL  $OOOOOO0O0O00, $OOOOOO0O00OO;
                if (isset($OOOOOO0O0O00))   $OOOOOO0O0O00   = $OOOOOOO0O0OO;
                if (isset($OOOOOO0O00OO))   $OOOOOO0O00OO   = $OOOOOO00OOOO;
                if (function_exists('user_smtp_error'))
                        return user_smtp_error($OOOOOOO0O0OO, $OOOOOO00OOOO);
                if ($OOOOOOO0O0OO != 0)
 
La possibilita' di convertire anche
 
	function\s*([\W]+)\s*\(
 
e' lasciata per esercizio ;-D
 
Modificando and(b,m)?"0":"O") d};while(length(d)<12){d="O" d}
in          and(b,m)?"1":"l") d};while(length(d)<12){d="l" d}
 
le variabili diventano della forma "$llll1lll11l".


fantastico! perché non lo metti su qualche sito di collaborazione
collettiva?
 

collettiva?
 
...un one-liner? :-D Vabbene che c'e' crisi e la gente si contenta di
poco, ma di qui a un lavoro fatto bene ci corre TROPPO.
 
Se qualcuno se la sente puo' prendere qualche tokenizzatore per PHP -
c'e' quello di CodeSniffer, per esempio - e modificarlo da li'. Pero'
rimane sempre il problema delle variabili "arrayabili e non arrayate"
come per es.
 
	$pointsCreate	= 25;
	$pointsDelete	= 10;
 
	$credits += ${'points'.$operation};
 
...il "compilatore" non avrebbe modo di sapere che "$pointsCreate" e'
una variabile che verra' referenziata per nome. La piu' semplice puo'
essere supportare un
 
	$pointsCreate	= 25; //!LEAVE_ALONE
	$pointsDelete	= 25; //!LEAVE_ALONE
 
e poi togliere dall'elenco delle variabili tutte quelle che compaiono
in una riga che contiene //!LEAVE_ALONE. Si puo' fare con una riga di
bash <vbeg>.
 
Un tokenizzatore tipo CS potrebbe anche fare di peggio - come appunto
predisporre una tabella di tutti i simboli utilizzati e iniettarla in
fase di setup dello script. A quel punto il codice diventa
 
        function OO0OO0OO0OO0($OOOOOOO0O0OO,$OOOOOO00OOOO){
            GLOBAL $OOOOOO0O0O00,$OOOOOO0O00OO;
            if (isset($OOOOOO0O0O00))$OOOOOO0O0O00=$OOOOOOO0O0OO;
            if (isset($OOOOOO0O00OO))$OOOOOO0O00OO=$OOOOOO00OOOO;
            if (function_exists($OO0OO0OO0OOO))
                return $OO0OO0OO0OOO($OOOOOOO0O0OO,$OOOOOO00OOOO);
            if ($OOOOOOO0O0OO!=$O000O0OO0OOO)
 
Ma in realta' mi e' venuta un'idea ancora piu' malvagia. Dato che PHP
adesso e' (o DOVREBBE) essere UTF8-compliant - e i caratteri speciali
da U+F01E a U+F02C sono considerati caratteri identificatori validi -
si potrebbe addirittura scrivere del codice che con ogni probabilita'
non e' neanche stampabile o editabile da un editor "umano".
 
Leonardo "e poi ci sarebbe il codeset arabo, quello ebraico, il..."


 non e' neanche stampabile o editabile da un editor "umano".
 
ottimo, si darebbe l'impressione agli utonti di trovarsi davanti
a del codice compilato! Chissà che faccia farebbero! Ahahahahahahahha XD
 
 
 
 

 d'accapo! :D
 
Appunto. Questo è esattamente il tipo di offuscatore che cerco.
Ho visto svariati codici fatti in questo modo, mi risulta difficile
credere che tutti si siano fatti il proprio offuscatore.

 credere che tutti si siano fatti il proprio offuscatore.
 
si ma in giro ne ho visti alcuni anche io, ed in effetti riescono ad
offuscare sia gli identificatori delle variabili che delle funzioni.
Quello che non ho approfondito è se è possibile risalire dai nomi
offuscati a quelli in chiaro.
 
 

 offuscati a quelli in chiaro.
 
Ovviamente no, salvo implementazioni palesemente errate dell'algoritmo di offuscamento. (del tipo: A = 0, a=O, B=00, b = OO, e così via)