Blog
Nov 20, 2012
Fun with AIX Shellcode and Metasploit
In one of our recent pentests, we discovered an 0day for a custom C application server running on the AIX Operating System. After debugging the crash, we discovered that the bug could lead to remote code execution and since we don’t deal very often with AIX exploitation, we decided to write an exploit for it. The first steps were accomplished pretty quickly and we successfully diverted the execution flow by jumping to a controlled buffer. At this point, we thought we could easily generate some shellcode from MSF and enjoy our remote shell.
6 min read
Author: Matteo Memelli
AIX Shellcode and Metasploit
In one of our recent pentests, we discovered an 0day for a custom C application server running on the AIX Operating System. After debugging the crash, we discovered that the bug could lead to remote code execution and since we don’t deal very often with AIX exploitation, we decided to write an exploit for it. The first steps were accomplished pretty quickly and we successfully diverted the execution flow by jumping to a controlled buffer. At this point, we thought we could easily generate some shellcode from MSF and enjoy our remote shell.
MSF AIX Shellcode Failure
Unfortunately for us, none of the MSF PowerPC payloads was working correctly. As you can see in the following pictures, the shellcode embedded in a simple C program, is executing “/bin/csh” but it’s not binding it to a tcp port as it should.
At this point, we were forced to dig around a bit more into the AIX shellcode internals in order to understand what was wrong.
Metasploit Source to the Rescue
As usual, the Metasploit framework is a huge source of information and by looking at the code of an AIX bind shell present in the external subdirectory (/opt/metasploit/msf3/external/source/unixasm/aix-power-bndsockcode.c in Backtrack), we realized what was going on:
The bindshell code in the above picture supports different versions of the AIX operating system but even minor version changes in the OS have an impact on the payload implementation. By looking at the actual msf bindshell payload module (/opt/metasploit/msf3/modules/payloads/singles/aix/ppc/shell_bind_tcp.rb in Backtrack) , it became evident that the differences are related to the system call numbers used in order to invoke the operating system services.
A quick Google search on the topic confirmed all of the above:
AIX Shellcode in Metasploit
All of the AIX metasploit payload modules import the aix.rb library, which can be found at /opt/metasploit/msf3/lib/msf/core/payload/aix.rb in BackTrack. Looking through the code in this library helps provide us with a direction to follow in getting our shellcode to work.
The easiest way to port the existing MSF AIX shellcodes to other operating system versions is by adding a ruby hash with the relative sys call set to the aix.rb library:
At this point, we identified the target OS version of our exploit:
[cc lang=”python” lines=”-1″]
aix-box$ oslevel -s
6100-07-00-0000
[/cc]
This above output tells us that we are running AIX Version 6 Technology Level (TL) 7 with no service packs (00-0000). The term Maintainance Level in the above tweet is now reserved for legacy AIX systems. The new IBM methodology dictates two TL releases per year.
Finding System Call Numbers
To identify the right system call numbers for our AIX specific version, we compiled a C program that uses the same function set used by our shellcode. A bind shell C program found on the Internet, for example, can do the trick:
[cc lang=”c” lines=”-1″]
#include
#include
#include
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int result , sockfd;
int port;
struct sockaddr_in sin;
sockfd = socket(AF_INET,SOCK_STREAM,0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(12345); //port number
bind (sockfd,(struct sockaddr *)&sin,sizeof(sin));
listen(sockfd,5);
result = accept (sockfd,NULL,0);
dup2(result,2);
dup2(result,1);
dup2(result,0);
execl(“/bin/sh”,”sh”,NULL);
return EXIT_SUCCESS;
}
[/cc]
By setting a few breakpoints on the involved functions (socket, bind, listen, accept, close, kfcntl, and execve), we can step through the system call invocation in gdb and check the argument values:
In the PowerPC architecture, the sc instruction is used whenever the operating system services are to be called. The r2 CPU register denotes the system call number and registers r3-r10 are appropriately filled with the given system call arguments (AIX 6.1 Information, “AIX PowerPC buffer overflow step by step”). In our case, r2, before branching the ctr register to execute the system call, is holding the value 254; we now know the socket sys call number for AIX 6.1.7.
We then identified the remaining sys call numbers and filled up an aix_617_syscalls hash in the aix.rb library:
and added a line to the version hash:
Our final step was to generate and test our newly edited payload:
Success! Our AIX shellcode works as expected. We have updated the MSF AIX payloads to include these newer versions of AIX Patch Levels – these should be committed to Metasploit soon.
Cybersecurity leader resources
Sign up for the Secure Leader and get the latest info on industry trends, resources and best practices for security leaders every other week
Latest from OffSec
Enterprise Security
Red Team vs Blue Team in Cybersecurity
Learn what a red team and blue team in cybersecurity are, pros and cons of both, as well as how they work together.
Dec 13, 2024
13 min read
Enterprise Security
Building a Future-Ready Cybersecurity Workforce: The OffSec Approach to Talent Development
Learn all about our recent webinar “Building a Future-Ready Cyber Workforce: The OffSec Approach to Talent Development”.
Dec 13, 2024
4 min read
Enterprise Security
How to Become the Company Top Cyber Talent Wants to Join
Become the company cybersecurity talent wants to join. Learn how to attract, assess, and retain experts with strategies that set you apart.
Dec 4, 2024
5 min read