Jump to content

Search the Community

Showing results for tags 'gas'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Informatii generale
    • Anunturi importante
    • Bine ai venit
    • Proiecte RST
  • Sectiunea tehnica
    • Exploituri
    • Challenges (CTF)
    • Bug Bounty
    • Programare
    • Securitate web
    • Reverse engineering & exploit development
    • Mobile security
    • Sisteme de operare si discutii hardware
    • Electronica
    • Wireless Pentesting
    • Black SEO & monetizare
  • Tutoriale
    • Tutoriale in romana
    • Tutoriale in engleza
    • Tutoriale video
  • Programe
    • Programe hacking
    • Programe securitate
    • Programe utile
    • Free stuff
  • Discutii generale
    • RST Market
    • Off-topic
    • Discutii incepatori
    • Stiri securitate
    • Linkuri
    • Cosul de gunoi
  • Club Test's Topics
  • Clubul saraciei absolute's Topics
  • Chernobyl Hackers's Topics
  • Programming & Fun's Jokes / Funny pictures (programming related!)
  • Programming & Fun's Programming
  • Programming & Fun's Programming challenges
  • Bani pă net's Topics
  • Cumparaturi online's Topics
  • Web Development's Forum
  • 3D Print's Topics

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Yahoo


Jabber


Skype


Location


Interests


Biography


Location


Interests


Occupation

Found 3 results

  1. Hackers – possibly affiliated with Anonymous – have already attacked at least one internet-connected gas (petrol) station pump monitoring system. Evidence of malfeasance, uncovered by Trend Micro, comes three weeks after research about automated tank gauge vulnerabilities from Rapid7, the firm behind Metasploit. Automated tank gauges (ATGs) are used to monitor fuel tank inventory levels, track deliveries, raise alarms that indicate problems with the tank or gauge (such as a fuel spill). The technology can also be used to perform leak tests. ATGs are used by nearly every fuelling station in the United States and tens of thousands of systems internationally. ATGs can typically be programmed and monitored through a built-in serial port, a plug-in serial port, a fax/modem, or a TCP/IP circuit board. In order to facilitate remote monitoring over the internet, ATG serial interfaces are often mapped to an internet-facing port. This opens door to potential trouble, especially since serial interfaces are rarely password protected. Rapid7 estimates that 5,800 ATGs are exposed to the internet without a password. Over 5,300 of these ATGs are located in the US. Put another way, around one in 30 of the 150,000 fuelling stations in the country are exposed to attack, leaving the door open to all sorts of mischief. “An attacker with access to the serial port interface of an ATG may be able to shut down the station by spoofing the reported fuel level, generating false alarms, and locking the monitoring service out of the system,” Rapid7’s HD Moore warns. “Tank gauge malfunctions are considered a serious issue due to the regulatory and safety issues that may apply." But what’s actually happening at the pump? Independent researcher Stephen Hilt and Kyle Wilhoit, a senior threat researcher at Trend Micro, teamed up to investigate whether or not attackers were actively attempting to compromise these internet-facing gas pump monitoring systems. In particular the duo looked at deployments of the Guardian AST Monitoring System, internet-ready kit designed to monitor inventory, pump levels, and assorted values of pumping systems typically found in gas stations. Shodan, the well-known search engine for Internet-connected devices, and popular port-scanning tool Nmap create a ready mechanism for interested parties to hunt for inter-connected petrol pump kit. Hilt and Wilhoit discovered more than 1,515 vulnerable gas pump monitoring devices worldwide, less than a third of the figure logged by HD Moore last month. That would be reason for cautious optimism – except that the duo also uncovered evidence of tampered Guardian AST devices. The US-located system, left wide open on the net, had been hacked, apparently by mischief-makers, referencing one of ragtag hacker group Anonymous’s favourite catch phrases. An attacker had modified one of these pump-monitoring systems in the US. This pump system was found to be internet facing with no implemented security measures. The pump name was changed from “DIESEL” to “WE_ARE_LEGION.” The group Anonymous often uses the slogan “We Are Legion,” which might shed light on possible attributions of this attack. But given the nebulous nature of Anonymous, we can’t necessarily attribute this directly to the group. An outage of these pump monitoring systems, while not catastrophic, could cause serious data loss and supply chain problems. For instance, should a volume value be misrepresented as low, a gasoline truck could be dispatched to investigate low tank values. Empty tank values could also be shown full, resulting in gas stations having no fuel. The insecure gas pump monitoring system issue is part of the wider problem of insecure SCADA (industrial control) devices. “Our investigation shows that the tampering of an internet-facing device resulted in a name change,” a blog post by Trend Micro on the research concludes. “But sooner or later, real world implications will occur, causing possible outages or even worse. Hopefully, with continued attention to these vulnerable systems, the security profile will change. Ideally, we will start seeing secure SCADA systems deployed, with no Internet facing devices. Source
  2. Reversing the bomb Acest tutorial are ca scop o introducere in domeniul reversing , aici voi discuta despre modul in care poate fi schimbat fluxul unui program.In acelasi timp va fi si un raspuns pentru challenge-ul pe care l-am creat .Vom avea urmatorul exemplu:Un program in care user-ului i se cere o cheie pentru a putea schimba fluxul , in acelasi timp se presupune ca user-ul nu poate ghici care este aceasta cheie sau serial.Vom lua executabilul bomb32 si il vom analiza.Vom folosi urmatoarele tool-uri pentru a face aceasta inspectie: Un debugger , eu prefer gdb dar poate fi oricare altul.Un Hex editor , voi folosi bvi dar exista diverse altele cu interfata grafica precum bless , okteta sau wxHexEditor.In acest articol voi folosi objdump si nm . Tin sa precizez faptul ca nu intotdeauna se pot extrage unele informatii folosind objdump sau nm.In urmatorul exemplu vom vedea sectiile create in acest executabil. [pyth0n3@mc]$ nm bomb 080491e0 A __bss_start 080491e0 A _edata 080491e0 A _end 08048081 T _start 0804919e d arm 08048085 t armed 080490f4 d buf 00000095 a bufl 08049174 d bufs 08049189 d dis 080480c6 t disarm 080491b1 d do 080480d8 t explode 080480e8 t out 08048074 t print 080480bb t wires Folosind un debugger vom putea pune un breakpoint si analiza fiecare sectie , dar inainte vom dezasabla fiecare sectie de cod folosind objdump [pyth0n3@mc]$ objdump -S bomb bomb: file format elf32-i386 Disassembly of section .text: 08048074 <print>: 8048074: b8 04 00 00 00 mov $0x4,%eax 8048079: bb 01 00 00 00 mov $0x1,%ebx 804807e: cd 80 int $0x80 8048080: c3 ret 08048081 <_start>: 8048081: 90 nop 8048082: 90 nop 8048083: 90 nop 8048084: 90 nop 08048085 <armed>: 8048085: 8d 0d 9e 91 04 08 lea 0x804919e,%ecx 804808b: ba 13 00 00 00 mov $0x13,%edx 8048090: e8 df ff ff ff call 8048074 <print> 8048095: 8d 0d b1 91 04 08 lea 0x80491b1,%ecx 804809b: ba 2f 00 00 00 mov $0x2f,%edx 80480a0: e8 cf ff ff ff call 8048074 <print> 80480a5: b8 03 00 00 00 mov $0x3,%eax 80480aa: bb 00 00 00 00 mov $0x0,%ebx 80480af: b9 f4 90 04 08 mov $0x80490f4,%ecx 80480b4: ba 95 00 00 00 mov $0x95,%edx 80480b9: cd 80 int $0x80 080480bb <wires>: 80480bb: 31 c0 xor %eax,%eax 80480bd: 3d 09 03 00 00 cmp $0x309,%eax 80480c2: 75 14 jne 80480d8 <explode> 80480c4: cd 80 int $0x80 080480c6 <disarm>: 80480c6: 8d 0d 89 91 04 08 lea 0x8049189,%ecx 80480cc: ba 16 00 00 00 mov $0x16,%edx 80480d1: e8 9e ff ff ff call 8048074 <print> 80480d6: eb 10 jmp 80480e8 <out> 080480d8 <explode>: 80480d8: 8d 0d 74 91 04 08 lea 0x8049174,%ecx 80480de: ba 15 00 00 00 mov $0x15,%edx 80480e3: e8 8c ff ff ff call 8048074 <print> 080480e8 <out>: 80480e8: b8 01 00 00 00 mov $0x1,%eax 80480ed: bb 00 00 00 00 mov $0x0,%ebx 80480f2: cd 80 int $0x80 Voi comenta fiecare sectie pentru a avea o idee putin mai clara.Aici vine declarata o functie care va stampa pe ecran valori (momentan a fost doar declarata functia , dar poate fi chemata in alte sectii) Daca ati citit articolul pe care l-am scris despre assembly veti putea interpeta fiecare valoare care vine pusa in registrii. 08048074 <print>: 8048074: b8 04 00 00 00 mov $0x4,%eax 8048079: bb 01 00 00 00 mov $0x1,%ebx 804807e: cd 80 int $0x80 8048080: c3 ret De la sectia start incepe executarea programului iar 4 valori chemate nop nu fac absolut nimic .In sectia armed vin incarcate cateva valori in registri dupa care vine chemata functia print care nu face altceva decat sa stampeze aceste valori pe ecran. 08048081 <_start>: 8048081: 90 nop 8048082: 90 nop 8048083: 90 nop 8048084: 90 nop 08048085 <armed>: 8048085: 8d 0d 9e 91 04 08 lea 0x804919e,%ecx 804808b: ba 13 00 00 00 mov $0x13,%edx 8048090: e8 df ff ff ff call 8048074 <print> 8048095: 8d 0d b1 91 04 08 lea 0x80491b1,%ecx 804809b: ba 2f 00 00 00 mov $0x2f,%edx 80480a0: e8 cf ff ff ff call 8048074 <print> 80480a5: b8 03 00 00 00 mov $0x3,%eax 80480aa: bb 00 00 00 00 mov $0x0,%ebx 80480af: b9 f4 90 04 08 mov $0x80490f4,%ecx 80480b4: ba 95 00 00 00 mov $0x95,%edx 80480b9: cd 80 int $0x80 Pentru a analiza exact ce vine facut in aceasta sectie vom folosi gdb (gdb) break armed Breakpoint 1 at 0x8048085 (gdb) run Starting program: /home/pyth0n3/Desktop/bomb Breakpoint 1, 0x08048085 in armed () (gdb) s Single stepping until exit from function armed, which has no line number information. 0x08048074 in print () (gdb) s Single stepping until exit from function print, which has no line number information. [COLOR="#00FF00"]Bomb Armed ______ 0x08048095 in armed ()[/COLOR] (gdb) s Single stepping until exit from function armed, which has no line number information. 0x08048074 in print () (gdb) s Single stepping until exit from function print, which has no line number information. [COLOR="#00FF00"]Disarm the bomb by cutting the correct wires > 0x080480a5 in armed ()[/COLOR] (gdb) s Single stepping until exit from function armed, which has no line number information. [COLOR="#00FF00"]Aici vine cerut un input [/COLOR] Am pus un breakpoint in sectia armed dupa care am rulat programul si am vazut ce face in fiecare step.Am evidentiat in culoare verde ceea ce vine executat in aceasta sectie.Dupa cum observati vin stampate cateva informatii si vine cerut un input de la user.Vom merge mai departe sa analizam urmatoarea sectie. 080480bb <wires>: 80480bb: 31 c0 xor %eax,%eax 80480bd: 3d 09 03 00 00 cmp $0x309,%eax 80480c2: 75 14 jne 80480d8 <explode> 80480c4: cd 80 int $0x80 080480c6 <disarm>: 80480c6: 8d 0d 89 91 04 08 lea 0x8049189,%ecx 80480cc: ba 16 00 00 00 mov $0x16,%edx 80480d1: e8 9e ff ff ff call 8048074 <print> 80480d6: eb 10 jmp 80480e8 <out> 080480d8 <explode>: 80480d8: 8d 0d 74 91 04 08 lea 0x8049174,%ecx 80480de: ba 15 00 00 00 mov $0x15,%edx 80480e3: e8 8c ff ff ff call 8048074 <print> Imediat dupa armed vine executata sectia wires .Vom analiza fiecare instructie.xor %eax,%eax nu face altceva decat sa puna valoarea 0 in registrul eax. cmp $0x309,%eax compara numarul 777 cu registrul eax.309 in hex este echivalent cu 777.In eax avem valoarea 0 datorita instructiei precedente.Deci vine comparat 777 cu 0 , asadar aceste 2 valori nu sunt egale deci este fals deoarece 777 nu este egal cu 0.Urmatoarea instructie va fi executata in baza rezultatului acestei instructii si anume jne va face un jump in urmatoarea adresa de memorie 80480d8 daca valorile in urma comparatiei nu sunt egale .Cum am mai spus 777 nu este ega cu valoarea din eax asadar se va face un jump .Dupa cum observati la adresa 80480d8 incepe sectia <explode>.In acest caz imediat dupa instructia jne va fi executata aceasta sectie.Tin sa precizez faptul ca in momentul in care comparatia ar fi fost adevarata si anume valoarea din eax ar fi fost 777 atunci 777 este egal cu 777 si instructia jne nu va mai face un jump in sectia explode ci va fi executata urmatoarea instructie imediat dupa.jne face un jump atata timp cat valorile care au fost comparate in instructia precedenta nu sunt egale in mod divers vine executata urmatoarea instructie dupa jne.Evident datele nu au fost alterate dupa input asadar se va face un jump in explode iar sectia disarm nu va fi executata.Ia sa vedem ce se intampla in explode.Am incarcat executabilul in gdb dupa care am pus un breakpoint in sectia explode (gdb) break explode Breakpoint 1 at 0x80480d8 (gdb) run Starting program: /home/pyth0n3/Desktop/bomb [COLOR="#00FF00"]Bomb Armed ______ Disarm the bomb by cutting the correct wires > test [/COLOR] Breakpoint 1, 0x080480d8 in explode () (gdb) s Single stepping until exit from function explode, which has no line number information. 0x08048074 in print () (gdb) s Single stepping until exit from function print, which has no line number information. [COLOR="#00FF00"]***BOOM! You Failed![/COLOR] 0x080480e8 in out () (gdb) s Single stepping until exit from function out, which has no line number information. [COLOR="#00FF00"]Program exited normally.[/COLOR] Asadar programul va fi rulat, userului ii vine cerut un input , am pus "test" dupa care ajungem direct in sectia explode unde am facut un breakpoint.Dupa cum observati instructiile din sectia explode stampeaza niste informatii dupa care programul vine terminat.Deci pana aici am observat ca nu vine facut nici un control asupra datelor pe care le-am introdus.(am scris programul in acest fel pentru a explica faptul ca oricare ar fi input-ul user-ului nu exista nici o probabilitate sa coincida cu serialul sau cu cheia pentru a dezarma bomba.) Acum daca nu s-ar fi facut un jump in sectia explode s-ar fi executat intructiile exact dupa sectia wires si anume disarm. 080480bb <wires>: 80480bb: 31 c0 xor %eax,%eax 80480bd: 3d 09 03 00 00 cmp $0x309,%eax 80480c2: 75 14 jne 80480d8 <explode> 80480c4: cd 80 int $0x80 Ei bine ca sa fie executate aceste intructii valoarea care vine confruntata cu eax trebuie sa fie egala cu valoarea din eax.Acest lucru poate fi doar cazual in momentul in care eax dintro oarecare greseala ar fi avut valoarea 777 dar este si imposibil deoarece urmatoarea instructie va pune 0 in eax xor %eax,%eax.Daca nu ar fi existat xor o probabilitate ar fi ca eax sa aiba alta valoare dar nu este confirmat ca aceasta valoare ar fi fost egala cu 777.Asadar nu cunoastem serialul dar stim ca daca valorile confruntate nu sunt egale vine facut un jump in sectia explode si vin executate instructiile de acolo.Hai sa vedem ce face sectia disarm care nu vine executata niciodata. (gdb) disas disarm Dump of assembler code for function disarm: 0x080480c6 <disarm+0>: lea 0x8049189,%ecx 0x080480cc <disarm+6>: mov $0x16,%edx 0x080480d1 <disarm+11>: call 0x8048074 <print> 0x080480d6 <disarm+16>: jmp 0x80480e8 <out> End of assembler dump. (gdb) x/20cb 0x8049189 0x8049189 <dis>: 66 '[COLOR="#00FF00"]B[/COLOR]' 111 '[COLOR="#00FF00"]o[/COLOR]' 109 '[COLOR="#00FF00"]m[/COLOR]' 98 '[COLOR="#00FF00"]b[/COLOR]' 32 ' ' 68 '[COLOR="#00FF00"]D[/COLOR]' 105 '[COLOR="#00FF00"]i[/COLOR]'115 '[COLOR="#00FF00"]s[/COLOR]' 0x8049191 <dis+8>: 97 '[COLOR="#00FF00"]a[/COLOR]' 114 '[COLOR="#00FF00"]r[/COLOR]' 109 '[COLOR="#00FF00"]m[/COLOR]' 101 '[COLOR="#00FF00"]e[/COLOR]' 100 '[COLOR="#00FF00"]d[/COLOR]' 32 ' ' 95 '_' 95 '_' 0x8049199 <dis+16>: 47 '/' 32 ' ' 95 '_' 95 '_' Dupa cum observati vin incarcate in eax datele de la adresa 0x8049189 si anume "Bomb Disarmed __/ __" dupa care vine chemata functia print care le stampeaza si se face un jump in out care e urmatoarea sectie 080480e8 <out>: 80480e8: b8 01 00 00 00 mov $0x1,%eax 80480ed: bb 00 00 00 00 mov $0x0,%ebx 80480f2: cd 80 int $0x80 Aici programul iese.Acum am observat care sunt datele in sectia disarm , am observat faptul ca nu vine executata aceasta sectie.Pentru a rezolva problema nu ne ramane decat sa facem in asa fel incat sectia disarm sa fie executata.CUM?Pentru ca aceasta sectie sa fie executata valorile care vin comparate trebuie sa fie egale sau sa nu fie executata instructia jne.Deci va trebui lucrat asupra sectiei wires deoarece aici vine facut controlul asupra fluxului: 080480bb <wires>: 80480bb: 31 c0 xor %eax,%eax 80480bd: 3d 09 03 00 00 cmp $0x309,%eax 80480c2: 75 14 jne 80480d8 <explode> 80480c4: cd 80 int $0x80 1. Putem modifica valoarea care vine comparata cu eax in asa fel incat sa fie 0 asadar 0==0 si instructia jne nu va face un jump ci se vor executa urmatoarele instructii si anume sectia disarm.Va trebui doar sa modificam valoarea 777 cu 0 , acest lucru se poate face cu un hex editor. 0x080480bb in wires () (gdb) (gdb) disas wires Dump of assembler code for function wires: 0x080480bb <wires+0>: xor %eax,%eax 0x080480bd <wires+2>: cmp $[COLOR="#00FF00"]0x309[/COLOR],%eax 0x080480c2 <wires+7>: jne 0x80480d8 <explode> 0x080480c4 <wires+9>: int $0x80 End of assembler dump. (gdb) x/4bx wires+2 0x80480bd <wires+2>: 0x3d [COLOR="#00FF00"]0x09 0x03[/COLOR] 0x00 (gdb) Asadar daca modificam urmatoarele valori 09 03 cu 00 00 programul isi va schimba fluxul deoarece comparatia va da True deoarece 0 este egal cu 0 00000090 E8 DF FF FF FF 8D 0D B1 91 04 08 BA 2F 00 00 00 ............/... 000000A0 E8 CF FF FF FF B8 03 00 00 00 BB 00 00 00 00 B9 ................ 000000B0 F4 90 04 08 BA 95 00 00 00 CD 80 31 C0 3D [COLOR="#00FF00"]09 03[/COLOR] ...........1.=.. 000000C0 00 00 75 14 CD 80 8D 0D 89 91 04 08 BA 16 00 00 ..u............. 000000D0 00 E8 9E FF FF FF EB 10 8D 0D 74 91 04 08 BA 15 ..........t.... 2. Putem modifica instructia jne cu nop (care este echivalent la no operation performed) asadar nu va face jump deoarece nop nu face nimic si va fi executata urmatoarea instructie care apartine sectiei disarm.Va trebui doar sa gasim valoarea care corespunde instructiei jne in hex si sa o modificam.Acest lucru poate fi facut folosind gdb. Dump of assembler code for function wires: 0x080480bb <wires+0>: xor %eax,%eax 0x080480bd <wires+2>: cmp $0x309,%eax 0x080480c2 <wires+7>: [COLOR="#00FF00"]jne [/COLOR] 0x80480d8 <explode> 0x080480c4 <wires+9>: int $0x80 End of assembler dump. (gdb) x/4bx wires+7 0x80480c2 <wires+7>:[COLOR="#00FF00"] 0x75 0x14[/COLOR] 0xcd 0x80 (gdb) Dupa cum observati una din valori sau poate chiar 2 pot apartine instructiei jne .exlud ultima 0x80 si penultima deoarece instructia e la inceput asadar verific 75 si 14 000000B0 F4 90 04 08 BA 95 00 00 00 CD 80 31 C0 3D 09 03 ...........1.=.. 000000C0 00 00 [COLOR="#00FF00"]75 14[/COLOR] CD 80 8D 0D 89 91 04 08 BA 16 00 00 ..u............. 000000D0 00 E8 9E FF FF FF EB 10 8D 0D 74 91 04 08 BA 15 ..........t..... 000000E0 00 00 00 E8 8C FF FF FF B8 01 00 00 00 BB 00 00 ................ 000000F0 00 00 CD 80 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Aici se afla instructia jne pe care o vom inlocui cu nop , nop in hex e 90 si va trebui sa inlocuim 2 B asadar vom pune 90 90 in locul 75 14. Problem solved.! [pyth0n3@mc]$ ./bomb Bomb Armed ______ Disarm the bomb by cutting the correct wires > test Bomb Disarmed __/ __ Puteti testa fiecare ceea ce am descris mai sus.Cum am ajuns la problema? Simplu , verificand structurele de control conditionat sau inconditionat.Pentru mai multe informatii in legatura cu instructiile care pot schimba fluxul X86 Assembly/Control Flow In momentul in care exista un program care cere un serial sau un cod , va exista intotdeauna o instructie care ii poate schimba fluxul, trebuie doar gasita si modificata.Challenge-ul a fost rezolvat de catre Flubber si em, DarkyAngel a individuat problema dar era confuz asupra valorilor, nu am mai primit raspuns. Codul l-am scris doar pentru a demonstra cum functioneaza structurele de control in asembly sintaxa e AT&T Gas ISA Intel 32 biti .data buf: .space 0x80 bufs: .ascii "***BOOM! You Failed!\n" bufl= .-buf dis: .ascii "Bomb Disarmed __/ __\n" arm: .ascii "Bomb Armed ______ \n" do: .ascii "Disarm the bomb by cutting the correct wires\n> " .text #.global main .globl _start .type print, @function print: movl $4, %eax movl $1, %ebx int $0x80 ret #main: _start: nop nop nop nop armed: leal arm,%ecx movl $0x13, %edx call print leal do,%ecx movl $0x2F,%edx call print movl $0x3,%eax movl $0x0,%ebx movl $buf,%ecx movl $bufl,%edx int $0x80 wires: xorl %eax, %eax cmp $0x309,%eax jne explode int $0x80 disarm: leal dis,%ecx movl $0x16, %edx call print jmp out explode: leal bufs,%ecx movl $0x15, %edx call print out: movl $0x1,%eax movl $0x0,%ebx int $0x80 Am tradus codul si pentru arhitectura Intel 64 bit , sintaxa e tot AT&T Gas .data buf: .space 0x80 bufs: .ascii "***BOOM! You Failed!\n" bufl= .-buf dis: .ascii "Bomb Disarmed __/ __\n" arm: .ascii "Bomb Armed ______ \n" do: .ascii "Disarm the bomb by cutting the correct wires\n> " .text #.global main .globl _start .type print, @function print: movq $0x1, %rax movq $0x1, %rdi syscall retq _start: nop armed: movq $arm,%rsi movq $0x13, %rdx call print movq $do,%rsi movq $0x2E,%rdx call print movq $0x0,%rax movq $0x0,%rdi movq $buf,%rsi movq $bufl,%rdx syscall wires: xor %rax, %rax cmp $0x309,%rax jne explode syscall disarm: movq $dis,%rsi movq $0x15, %rdx call print jmp out explode: movq $bufs,%rsi movq $0x15, %rdx call print out: movq $0x3C,%rax movq $0x0,%rdi syscall
  3. In acest tutorial voi descrie caracteristicile de baza a limbajului de programare assembly.Vom avea un simplu exemplu de baza si anume stamparea unei variabile in stdout, structura instructiilor , definirea sectiunilor de baza , memoria, registrii de baza care pot fi intalniti in arhitectura procesoarelor de 32 biti Intel , nu in ultimul rand voi converti un exemplu de cod assembly scris pentru arhitectura intel 32 biti in 64 biti.Voi folosi cei mai simpli termeni pentru a descrie structura instructiilor si a unui registru.Pentru a nu duce in erroare un user ma voi folosi doar de registrii indispensabili.Assembly este un limbaj de programare Low Level.Spre deosebirea celorlalte limbaje de programare assembly necesita o traducere simpla in Machine Code deoarece fiecare cuvant sau mai bine spus instructie in assembly vine transformata intro instructie macchine code.Intructiile in machine code sunt intructii binare care pot fi interpretate foarte simplu de catre un computer dar putin mai greu de catre o persoana.De aceea pentru fiecare instructie binara a fost creata o instructie in assembly care poate fi denumita human readable deoarece creierului uman este mai simplu sa memoreze un anumit alias decat o instructie in 0 si 1.Fiecare procesor are un set de instructii assembly care difera de la o arhitectura la alta.Pentru a traduce instructiile assembly in operation code (macchine instruction code) vine folosit un traducator chemat assembler.Acesta este un software care interpreteaza instructiile scrise in assembly si le traduce in macchine code.Ei bine exista mai multe tipuri de assembler si fiecare are o anumita sintaxa.Instructiile scrise de catre un anumit assembler nu pot fi traduse in opcode de catre alt tip de assembler deoarece instructiile sunt diverse.Cele mai cunoscute tipuri de assembler sunt urmatoarele: NASM Windows, Linux, Mac OS X, DOS, OS/2 MASM Windows, DOS, OS/2 TASM Windows, DOS Yasm Windows, DOS, Linux, Unix-like HLA Windows, Linux, FreeBSD, Mac OS X GAS Unix-like, Windows, DOS, OS/2 Evident lista poate fi mult mai lunga , dar ma limitez aici.Ceea ce este important sa intelegeti este faptul ca fiecare are o sintaxa particulara pentru a scrie intructiile si ca exista diverse moduri de a programa in assembly.Pentru acest tutorial si urmatoarele exemple eu voi folosi GAS ca assembler.Ce este important sa cunoasteti este ca acest tip de assembler permite scrierea instructiilor assembly in 2 moduri.De default este folosita sintaxa AT&T dar poate fi folosita si sintaxa Intel.Ambele sintaxe pot traduce instructiile in opcode compatibil cu procesoarele Intel doar ca difera modul in care sunt scrise instructiile. Intex Syntax instructie dest,source AT&T Syntax instructie source,dest In urmatoarele exemple voi folosi doar AT&T Syntax.Assembly nu este un limbaj de programare cross platform deci anumite instructii vor putea fi executatea doar pe anumite platforme si nu pe altele.Exemplele sunt create pentru sistemele Linux 32 Biti Intel.In final voi traduce exemplul din tutorial si pentru arhitectura Intel 64 biti Linux.De obicei limbajele de programare se invata intrun anumit mod .Vin invatate structurele de date, instructiile , structurele de control , functiile si cu putina practica o persoana poate incepe sa programeze.Ei bine in assembly este putin diverssi pentru a obtine o anumita functie vor trebui scrise mai multe linii de cod.Pentru a cunoaste assembly necesita cunostinta sistemului operativ, a structurii procesorului si cum vine alocata memoria in ambientul respectiv.Acest tutorial este basic deoarece am vrut sa merg pe principul keep it simple .Vom incepe cu descrierea arhitecturii a unui computer.Avem un procesor , 3 tipuri de memorie (cache memory, main memory , secondary memory) ,Input/Output Devices (tastiera spre exemplu).Procesorul acceseaza date in memorie in urmatorul fel:Va cauta in mod direct existenta datelor in cache memory , main memory(ram) si in mod indirect date in secondary memory (hard disk).In cazul in care datele nu se gasesc in casche memory sau in main memory vor fi incarcate din secondary memory in main memory dupa care procesorul va avea access direct la ele.Conceptul programarii in assembly este urmatorul: Procesorul preia date din memorie executa operatii aritmetice asupra datelor si stocheaza rezultatul inapoi in memorie sau il stampeaza in stdout (monitorul user/ului).La randul lor datele pot fi preluate din stdin (tastiera) , pot fi procesate si stocate in memorie sau pe ecranul user-ului.In momentul in care datele vin preluate de catre cpu din main memory(ram) pentru a executa anumite operatii asupra lor vin stocate intrun alt spatiu de memorie, acest spatiu vine chemat registu.Un cpu detine mai multi registrii pentru a stocain mod temporar datele atunci cand se fac operatii asupra lor dupa care datele vin puse la locul de unde au fost luate .Ceea ce probabil il pune pe user intro stare de umra este faptul ca procesorul poate detine multi registrii.Nu e nevoie sa cunosti fiecare registru daca nu il folosesti atunci cand programezi in assembly .In acest articol nu voi descrie toti registrii deoarece voi crea o confuzie.Ceea ce este important sa cunoasteti este faptul ca atunci cand o valoare este preluata din memorie trebuie stocata intrun anumit loc temporar unde pentru a face operatii asupra ei dupa care rezultatul va fi stocat inapoi in memorie iar registrul temporar va prelua urmatoarea valoare. Ca in fiecare limbaj de programare si in assembly programul vine impartit in anumite sectii.Exista o sectie unde pot fi declarate anumite tipuri de date.Spre exemplu exista o sectie chemata .data , aici pot fi declarate tipurile de date cu care se va lucra, Aceasta sectie poate fi paragonata cu declararea variabilelor in alte limbaje de programare. O alta sectie este .bss , in aceasta sectie se pot declara alte tipuri de date a caror valoare spre exemplu nu este cunoscuna initial.O alta sectie este .text , aici pot fi scrise instructiile care vor procesa datele declarate si procesate in sectiile .data .bss.O alta sectie importanta este .globl , aici pot fi chemate functii/librari externe care au fost deja create in precedenta.Vom avea si o sectie _start de unde instructiile vor incepe sa fie executate.Aceasta sectie poate fi paragonata cu functia main() in c. Pentru a scrie un simplu program in assembly se vor crea sectiile respective, se vor umple cu date dupa care se vor chema instructii asupra datelor declarate.In urmatoarele exemple vom vedea cum se pot declara date , cum vin declarate instructiile? , ce se intampla atunci cand instructiile vin traduse in opcode?, cum vin incarcate datele din memorie intrun registru?, cum pot fi chemate functii externe asupra datelor? Pentru a putea face o operatie asupra unei valori , va trebui declarata valoarea respoectiva , acelasi lucru si pentru oricare alt tip de date.Initial vom construi o sectie .data unde vom stoca un nickname. Declar o sectie data in memorie .data Declar o eticheta pentru tipul de date pe care il voi crea NickName: Declar tipul de date pe care vreau sa le stochez in memorie .ascii "pyth0n3\n: Asadar am creat o sectie, o eticheta , un tip de date Eticheta va avea o adresa in memoria RAM , la adresa respectiva se vor gasi datele pe care le-am declarat Etichetei ii vine atribuita o adresa de memorie NickName data variable address 0x8049098 La adresa 0x8049098 vom avea datele stocate si anume pyth0n3\n NickName data variable content in excaped hex 0x70 0x79 0x74 0x68 0x30 0x6e 0x33 0x0a p y t h 0 n 3 \n Evident o data ce instructia .ascii "pyth0n3\n" va fi tradusa in opcode de catre assembler vom avea urmatorul cod Nick Name data variable content in binary giant, 8 bytes 0000101000110011011011100011000001101000011101000111100101110000 Important este sa intelegeti faptul ca acest cod se afla la o anumita adresa si anume la 0x8049098 ,am tradus adresa in hex dar pentru procesor va fi tot o valoare in 0 si 1.Dupa ce am declarat datele ramane sa decidem ce vrem sa facem cu ele .Vom stampa pe ecran ceea ce am stocat la adresa 0x8049098.Evident pentru a face acest lucru exista mai multe alternative.In Linux ne putem folosi de syscall.Trebuie individuate functiile de care avem nevoie pentru a stampa datele + functia pentru a inchide programul.Fiecare syscall are un anumit id numeric .In fiecare sistem linux lista se poate gasi in /usr/include/asm .In fisierul unistd_32.h se vor gasi functiile pentru procesoarele 32 biti iar in unistd_64.h pentru procesoarele 64 biti.Vom folosi 2 syscall diverse 1 pentru a stampa datele declarate 2 pentru a iesi din program. Pentru a stampa datele vom folosi #define __NR_write care are ca id numarul 4 Pentru a iesi din program vom folosi #define __NR_exit care are ca id numarul 1 Datele care vin procesate trebuie incarcate in registrii asadar vom folosi 4 registrii a procesorului pentru a stoca temporar date care vor fi executate.Asadar vom folosi EAX,EBX,ECX,EDX care pot fi paragonate cu 4 variabile temporare unde vom stoca date care trebuie executate. In momentul in care nu am specificat nici o instructie registrii momentan nu au nici o valoare eax 0x0 0 ecx 0x0 0 edx 0x0 0 ebx 0x0 0 Probabil va intrebati in care ordine pot fi introduse datele in registrii spre exemplu care este primul registru? Ei bine ordinea este urmatoarea EAX EBX ECX EDX.Vom muta valoarea functiei write in primul registru Pentru a scrie instructiile trebuie creata o sectie .text , avand in vedere oricum faptul ca vom chema si functii externe syscall va trebui specificata si o sectie pentru external routines si anume .globl _start dupa care vom crea sectia _start unde vom incepe sa executam instructiile pe care le vom scrie Asadar vom incepe cu prima instructie .text .globl _start _start movl $4, %eax Dupa executarea acestei instructii registrul EAX va avea valoarea 4 eax 0x4 4 ecx 0x0 0 edx 0x0 0 ebx 0x0 0 Functia write are nevoie de cateva argumente pentru a stampa datele si anume primul argument pe care va trebui sa il specificam functiei dupa ce a fost incarcata in registrul EAX este unde anume vrem sa stampam datele? In linux exista 3 tipuri de fisiere chemate file descriptor Standard input identificat de catre valoarea 0 acet fisier preia input-ul de la tastiera spre exemplu Standard output identificat de catre valoarea 1 , acest file este folosit pentru a stampa informatia Standard error indenbtificat de catre valoarea 2, acest file este folosit pemtru a stampa mesajele de erroare. Pentru a stampa datele vom folosi standard output, asadar primul argument va fi specificat in al doilea registru si anume EBX , standard output are ca valoare 1 asadar urmatoarea instructie pe care o vom scrie este movl $1, %ebx Acum registrii au urmatoarele valori eax 0x4 4 ecx 0x0 0 edx 0x0 0 ebx 0x1 1 Al doilea parametru a functiei care trebuie specificat este adresa in memorie unde se afla datele pe care vrem sa la stampam.In urmatorul registru vom incarca adresa etichetei cu urmatoarea instructie leal NickName, %ecx Asadar registrii vor avea urmatoarele valori eax 0x4 4 ecx 0x8049098 134516888 edx 0x0 0 ebx 0x1 1 Dupa cum observati instructia leal NickName, %ecx a incarcat in ECX adresa unde se afla datele si anume 0x8049098 care este echivalent cu 134516888 in decimal.Al treilea argument al functiei care trebuie incarcat in urmatorul registru si anume EDX este lungimea pe care vrem sa o stampam din datele pe care le/am declarat (lungimea nickname-ului este pyth0n3 7+1 newline). movl $8, %edx In acest moment registrii vor avea urmatoarele date eax 0x4 4 ecx 0x8049098 134516888 edx 0x8 8 ebx 0x1 1 Deci pana aici i-am spus procesorului sa faca urmatorul lucru.Mergi la adresa 0x8049098 si stampeaza pe ecran urmatoarele 8 caractere.Daca am fi specificat mai multe caractere ar fi stampat ceea ce se afla dupa 8 caractere pe care le-am declarat in memorie(incercati, o sa va stampeze garbage).In momentul in care instructiile au fost declarate ,nu ramane decat sa chemam procesorul ca sa execute ceea ce am facut pana acum.Urmatoarea instructie va face acest lucru , este un interupt (kernelul va trimite un semnal procesurului ca sa execute ceea ce a fost incarcat in registrii acum. int 0x80 O data ce aceasta instructie vine executata , vor fi stampate pe ecran 8 caractere din datele declarate.(ultimul caracter este doar un newline).Dupa ce datele vor fi stampate registrii vor avea urmatoarele valori eax 0x8 8 ecx 0x8049098 134516888 edx 0x8 8 ebx 0x1 1 Dupa cum observati valoarea din registru EBX este in EAX acum.Dupa ce codul vine executat se va face un return in EAX.Acum nu ramane decat sa declaram instructiile necesare pentru a iesi din program , asadar vom folosi ca syscall exit care are valoarea 1.Dupa cum am specificat , ordinea pentru a incarca instructiile in registrii este urmatoarea .Prima valoare in EAX , iar urmatorii parametrii in EBX,ECX,EDX.Atentie acest lucru este valabil doar pentru procesoarele intel 32 biti.Deci vom chema valoare 1 in registrul EAX. movl $1, %eax Asadar vom avea urmatoarele valori eax 0x1 1 ecx 0x8049098 134516888 edx 0x8 8 ebx 0x1 1 Dupa cum observati registrii nu au fost modificati si unele valori pe care le-am incarcat inainte au ramas in registrii.Atunci cand veti scrie cod putin mai complicat in assembly va trebui sa aduceti registrul la statul initial sau uneori sa daceti un decrement dealtfel registrul va detine valoarea care a fost incarcata initial. Urmatorul parametru pentru functia exit este un return code.Aici putem specifica modul in care vrem sa iesim din program.Un return cod 0 va iesi curat , se poate specifica un return code 1 cand vrem sa iesim cu o erroare. In cazul nostru nu exista o erroare , asadar vom iesi cu 0.Primul si singurul parametru al functiei exit va fi 0. movl, $0 %ebx Dupa cum observati instructiile pe care le-am declarat au fost executate si valorile au fost urcate in registrii EAX va avea valoarea 1 , EBX va avea valoarea 0 iar restul registrilor vor avea valorile precedente eax 0x1 1 ecx 0x8049098 134516888 edx 0x8 8 ebx 0x0 0 Pentru a executa ceea ce este acum in EAX va trebui sachemam un inerrupt , acest semnal va spune procesorului sa execute ce gaseste acum in EAX.Nu vor fi executate datele din registrul ECX si EDX deoarece valoarea pe care am puso in registrul EAX si este echivalenta cu functia exit chiama doar un singur parametru si anume 0 pe care l-am pus in registrul EBX .Asadar vor fi executate datele din EAX SI EBX int $0x80 In acest caz am iesit din program , nu mai vine nimic stampat pe ecran , dar totusi putem observa cu care exist status am iesit.In Linux se poate face acest lucru folosind urmatorul comand imediat dupa ce am executat un program. echo $? In acest tutorial am facut un simplu exemplu in assembly si am observat ce se intampla atunci cand fiecare instructie vine executata. Acest lucru poate fi facut cu un debugger,asadar nu uitati sa asablati codul cu extensii pentru debugging daca vreti sa vedetice face pentru a asambla codul se vafolosi as. as -ggstabs nickname.s -o nickname.o Note: Am specificat optiunea ggstabs doar pentru debugging ,asadar il puteti urca intrun debugger preferat ca sa observati cum vin alocate datele.In momentul de fata vom avea un objec code nickname.o care trebuie ytrecut prin linker.Vom folosi ld pentru linking , asadar vom crea un executabil. ld nickname.o -o nickname Evident in momentul in care il veti trece in debugger veti observa mai multi registrii.Eu m-am limitat ca sa nu duc in erroare.Fiecare registru are rolul lui si fiecare registru este necesar.Un simplu exemplu pe care il veti pbserva atunci cand si doar daca veti face debugging este urmatorul.Presupunem ca am creat un breakpoint inainte ca prima instructie sa fie executata si vrem sa observam valorile care sunt stocate in momentul de fata in registrii.Atentie nu in fiecare registru trebuie neaparat sa existe valori, unii vor avea un flag sau nici o valoare. eax 0x0 0 ecx 0x0 0 edx 0x0 0 ebx 0x0 0 esp 0xbffff840 0xbffff840 ebp 0x0 0x0 esi 0x0 0 edi 0x0 0 eip 0x8048074 0x8048074 <_start> eflags 0x200212 [ AF IF ID ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x0 0 Dupa cum observati unii registrii au anumite valori precum registrul ESP care va avea intotdeuna o adresa de memorie si anume adresa dintyrun anumit segment de memorie chemat stack (probabil este interesant atunci cand se va scrie un exploit , stack overflow spre exemplu sau buffer overflow).EIP va detine intotdeuna adresa din top a segmentului de memorie chemat stack.Un alt registru inportant este EIP care este un instruction pointer , acest registru va detine intoteauna urmatoarea adresa urmatoarei sintructii care trebuie executate.Sa nu uitam faptul ca si instructiile pe care le folosim trebuie sa fie stocate undeva in memorie.Pentru acest tutorial ma voi opri aici deoarece in momentul de fata nu am folosit alti registrii pentru a putea explica ceea ce fac.Va las exemplele codului din acest tutorial si nu in ultimul rand pentru cai care sunt curiosi voi traduce codul assembly 32 bit in 64 bit doar ca sa observati diferentele. #nickname.s 32 bit intel gas AT&T syntax assembly .data NickName: .ascii "pyth0n3\n" .text .globl _start _start: movl $4, %eax movl $1, %ebx leal NickName, %ecx movl $24, %edx int $0x80 movl $1, %eax movl $0, %ebx int $0x80 #nickname.s 64 bit intel gas AT&T syntax assembly .data NickName: .ascii "pyth0n3\n" .text .globl _start _start: movq $1, %rax movq $1, %rdi movq $NickName, %rsi movq $8, %rdx syscall movq $60, %rax movq $0, %rdi syscall Cum am mai spus exista mai multe variante pentru a scrie acest cod. Exemplu : Vom stampa "OK" pe ecran intrun mod divers sintaxa pentr 32 bit .text .globl _start _start: pushl $0x0a6b6f mov %esp, %ecx mov $0x4, %edx mov $0x4, %eax movl $1, %eax movl $0, %ebx int $0x80 Probabil exista greseli de exprimare, nu ezitati sa scrieti , le voi corecta. ###END
×
×
  • Create New...