Vraag:
Segmentatiefout tijdens het duwen op de stapel
Dhayalan Pro
2016-05-28 03:53:29 UTC
view on stackexchange narkive permalink

Dus ik heb een aantal tutorials over assembly gevolgd en de instructeur compileert de volgende code:

 ; hello3.asm probeert de codepositie onafhankelijk te makensection .textglobal _start_start:; wis de registers we gaan needxor eax, eaxxor ebx, ebxxor ecx, ecxxor edx, edx; write (int fd, char * msg, unsigned int len) mov al, 4mov bl, 1; Owned !!! = 4f, 77,6e, 65,64,21,21,21; push!,!,!, Dpush 0x21212164; push e, n, w, O push 0x656e774fmov ecx, espmov dl, 8int 0x80; exit (int ret) mov al, 1xor ebx, ebxint 0x80  

Merk op dat het bericht Owned !!! in de stapel wordt gepusht in plaats van in de .text segment. Dus als ik het probeer uit te voeren, krijg ik een Segment Fault -fout!

Als ik in plaats daarvan het bericht in de .text laat staan, dan, alles werkt prima.

De commando's die ik gebruikte om uit te voeren:

  $ > nasm -f elf64 hello4.asm $ > ld -o hallo hallo4.o  

Om het even welke ideeën?

@perror wow, je kunt het niet beantwoorden, maar wil rep verdienen door de vraag -_- te corrigeren
Ik krijg geen reputatie door je spelling te corrigeren ... Het deed gewoon pijn aan mijn ogen, dus ik repareer het. Wees de volgende keer voorzichtiger, we hebben enkele normen bij het stellen van vragen hier (zelfs domme).
@DhayalanPro Het is niet nodig om het zo hard aan te pakken, alle StackExchange-sites staan ​​indien nodig community-bewerkingen toe, ik zie daar niets mis mee.
Drie antwoorden:
JeffreyZ
2016-05-28 15:27:20 UTC
view on stackexchange narkive permalink

De segmentatiefoutfout heeft niets te maken met het pushen van de strings op de stapel.

Ik heb gdb gebruikt om het te debuggen, en het probleem ligt bij:

 ; exit (int ret) mov al, 1xor ebx, ebxint 0x80  

Wijzigen

  mov al, 1  

to

  mov eax, 1  

Lost de segmentatiefout op.

Getest op Kali Linux.

ja, maar het feit dat het hebben van mov eax, 1 00 in de payload introduceert, daarom gebruiken we mov al, 1 zou graag willen weten waarom het crasht, ik gebruik ook kali
Als je op Kali bent, laat msfvenom daar dan voor zorgen. Voorbeeld: msfvenom --platform linux -a x86 -f elf -b "\ x00 \ xff" -o outputbin
Ik ken msfvenom, ik leer Exploit-schrijven zo: D
Als u dit zonder msfvenom wilt doen, kunt u "mov eax, 1" vervangen door "xor eax, eax inc eax" om de 00s te vermijden
ja ik heb zojuist de code veranderd in `xor rax, rax''mov al, 0x3c`, maar er komt nog steeds 00 omdat ik een` mov di, 2` enig idee heb?
in dit geval, aangezien we 2 naar di moeten verplaatsen, kunnen we twee keer meerderen, maar wat als we voor een groter aantal en plus geheugen verspillen voor herhaaldelijk inc: /
broadway
2016-05-28 21:27:53 UTC
view on stackexchange narkive permalink

Naast het antwoord van @ user2389688 is het belangrijk op te merken dat de syscall-nummers verkeerd zijn als je amd64 doet, net als de doorgegeven in registers. Hier is een 64 bit abi-versie die de verschillen corrigeert en de beoogde uitvoer levert.

 ; hello3.asm probeert de codepositie onafhankelijk te maken; herschrijven van hello3.asm om 64 bit syscall-interfacesectie te gebruiken .textglobal _start_start: xor rax, rax; syscallxor rdi, rdi; arg1xor rsi, rsi; arg2xor rdx, rdx; arg3; write (int fd, char * msg, unsigned int len) mov al, 1mov di, axe; Owned !!! = 4f, 77,6e, 65,64,21,21,21; push!,!,!, D; push e, n, w, Osub rsp, 8mov dword [rsp], 'Owne'mov dword [rsp + 4], 'd !!!' mov rsi, rspmov dl, 8 syscall; exit (int ret); syscall-fouten zullen ertoe leiden dat rax een negatieve waarde heeft, zodat u; kan niet zomaar almov eax, 0xffffffc3not eaxxor rdi, rdisyscall  
verplaatsen
ja we kunnen inderdaad alles verplaatsen, dat is wat ze doen om ervoor te zorgen dat de lading geen 00 in zich heeft
Het elimineren van 0 kan op verschillende manieren worden gedaan. Als de vorige syscall echter een fout had, zullen de bovenste bits van eax niet 0 zijn. Ik heb de code in mijn antwoord bijgewerkt om de nullen te elimineren.
eigenlijk werkt dit te mov al, 0x3c
alleen als het schrijven geen fout opleverde. U kunt het echter eerst gebruiken om dat probleem te vermijden. Er zijn veel manieren om 0 bytes te vermijden.
Fernando
2016-06-06 01:23:44 UTC
view on stackexchange narkive permalink

Ik heb je code in een 64-bits machine geprobeerd en er zijn enkele overwegingen:

als je op de 2 fragmenten van de string drukt, bevat de stapel een leeg woord ertussen:

  Breekpunt 1, 0x000000000040009a in _start () [bp before int 0x80] (gdb) x / 4wx $ rsp0x7fffffffde30: 0x656e774f 0x00000000 0x21212164 0x00000000  

syscall mislukt (aangezien we aangeven dat de lengte 8 is). Dus, direct na de syscall, in het register % rax bevat een foutcode:
  (gdb) ni0x000000000040009c in _start () (gdb) info regrax 0xfffffffffffffff2 -14 

Daarna verplaatsen we een byte met mov al, 1 , MAAR de resulterende waarde van % rax is: 0xffffffffffffff01 .

De exit syscall zal niet worden uitgevoerd en de code gaat verder met de inhoud van het geheugen ... De resultaten zijn niet deterministisch ... (De segfault komt ergens voor, in mijn geval probeert hij toegang te krijgen tot *% rsi wanneer het register % rsi een 0 bevat.

Ik hoop dat dit voor iedereen helpt.

BTW. Voor het geval dat, beter als je een null-waarde invoert voor de string, op deze manier weet je zeker dat de string zal eindigen op een NULL waarde. Anders, als het geheugen een andere waarde bevat, kan write () enkele vreemde tekens afdrukken.



Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...