Squareroots CTF‑Workshop – Oktober 2017

September 21, 2017

This page is intentionally left german.

Auch dieses Semester veranstalten wir, die squareroots, am Wochenende von Freitag den 27. bis Sonntag den 29. Oktober 2017 einen Workshop in den Räumlichkeiten der Universität Mannheim.
Wie bereits bei unseren vorherigen Workshops werden wir neben Einführungen in verschiedene Technologien und Werkzeuge auch den Ablauf von CTF-Wettbewerben vorstellen.

Anmeldungen sind ab sofort möglich auf https://anmeldung.sqrts.de/!

(more…)

0

MRMCDCTF 2017

September 5, 2017

As some of you already recognized, we organized a CTF on the MRMCD 2017 together with our friends from the Wizards of DOS Team (with who we already participated in other CTFs two times before).

MRMCDCTF2017

We hope, that this wasn’t the last time and that you also enjoyed it!

MRMCDCTF2017-Final Top10

0

Squareroots CTF‑Workshop – Mai 2017

April 13, 2017

This page is intentionally left german.

Auch dieses Semester veranstalten wir, die squareroots, am Wochenende von Freitag den 5. bis Sonntag den 7. Mai 2017 einen Workshop in den Räumlichkeiten der Universität Mannheim.
Wie bereits bei unseren vorherigen Workshops werden wir neben Einführungen in verschiedene Technologien und Werkzeuge auch den Ablauf von CTF-Wettbewerben vorstellen.

Anmeldungen sind ab sofort möglich auf http://anmeldung.sqrts.de/!

(more…)

0

Squareroots CTF‑Workshop – Oktober 2016

September 12, 2016

This page is intentionally left german.

UPDATE: Der Workshop wird dieses Semester in einem neuen Format angeboten

Auch dieses Semester veranstalten wir, die squareroots, am Wochenende von Freitag den 07. bis Sonntag den 09. Oktober 2016 an den sieben aufeinanderfolgenden Donnerstagabenden vom 13. Oktober bis zum 24. November einen Workshop in den Räumlichkeiten der Universität Mannheim.
Wie bereits bei unseren vorherigen Workshops werden wir neben Einführungen in verschiedene Technologien und Werkzeuge auch den Ablauf von CTF-Wettbewerben vorstellen.

(more…)

0

IceCTF 2016 – Geocities (web 100)

August 26, 2016

TLDR: shellshock, metasploit, pivot, sqlmap

A cool web challenge, here the description:

I recently stumbled onto this old http://geocities.vuln.icec.tf/ site, it’s a miracle that it’s still up! It must be running some ancient technology and probably hasn’t been updated in years, it’s our lucky day boys!

0

I first solved it like probably everyone else (index.cgi -> shellshock -> list files -> (search for flag on the server…) -> see perl script that connects to a DB on the internal network -> creates a modified version of the perl script in /tmp and executes it to get the DB content as there was no mysql on the vulnerable server).

But then this challenge was really cool, it’s not every day that you have a multiple machines environment (you can practice it in a Windows and Active Directory environment here :), so time to get the big guns, metasploit and sqlmap 🙂

I used the apache_mod_cgi_bash_env_exec Shellshock exploit to get a meterpreter shell.

1

From there, list the files and display the perl script to get the DB connection details (host, port, user, password, database name).

2

3

To get the IP address of the DB server, look into /etc/hosts

4

Then use the port forwarding command to forward all connections made to a port of the local machine to the DB server in order to be able to use sqlmap on the remote DB

5

And finally starts sqlmap using a direct connection to the local machine and the port defined above to dump the DB

6

8

PS: from the hosts file, an attentive reader would find another interesting sounding host, but its exploitation is left as an exercise for the reader

0

Google CTF 2016 – Ill intentions (mobile) – Take Two

May 3, 2016

After publishing my write-up and my “problem” with Inspeckage (I was able to see the intent but not their content), a really nice guy called mastho (from the khack40 CTF team) told me it was actually possible to do everything from Inspeckage. So time to have a deeper look!

After installation, you have to select which app you want to analyse.

inspeckage1

Then you start the web UI and can see all the activities (exported and non exported).

inspeckage2

It is possible to start them from here. So no need to use adb to start a broadcast intent.

inspeckage3

After the activity starts, you then click on the button and another intent with a message is sent. Under the IPC tab, you can see that a broadcast intent was sent but not its content. That’s where I stopped during the CTF and went back to writing my own Xposed module.

Actually there is a tab called “+Hooks” that allows to create hooks on the fly. How good is that! In this case, just create a hook for the “putExtra” method of the “Intent” class…

inspeckage4

… and tada! it’s in the logs!

inspeckage5

 

Thanks mastho, no need to write code at all!

0

Google CTF 2016 – Ill intentions (mobile)

May 2, 2016

And another challenge solved using the Xposed  framework.

So we have an Android application, let’s start it in the emulator (Genymotion).

app1

It’s quite ugly and doesn’t seem to be finished. It just tells us to use “Send_to_Activity”…
So let’s decompile it using jadx .

The MainActivity registers the Send_to_Activity as a BroadcastReceiver using the filter “com.ctf.INCOMING_INTENT”.


IntentFilter filter = new IntentFilter();
filter.addAction("com.ctf.INCOMING_INTENT");
registerReceiver(new Send_to_Activity(), filter, permission._MSG, null);

Depending on the intent “msg” content, it launches another activity


public void onReceive(Context context, Intent intent) {
String msgText = intent.getStringExtra("msg");
if (msgText.equalsIgnoreCase("ThisIsTheRealOne")) {
  context.startActivity(new Intent(context, ThisIsTheRealOne.class));

In those activities, a button is displayed and clicking on it send another intent with a “msg”. This “msg” is the result of a complex calculation involving native code and probably contains the flag…


public void onClick(View v) {
  Intent intent = new Intent();
  intent.setAction("com.ctf.OUTGOING_INTENT");
  String a = DefinitelyNotThisOne.this.getResources().getString(R.string.str1);
  intent.putExtra("msg", DefinitelyNotThisOne.this.definitelyNotThis(Utilities.doBoth(DefinitelyNotThisOne.this.getResources().getString(R.string.test)), Utilities.doBoth("Test")));
    DefinitelyNotThisOne.this.sendBroadcast(intent, permission._MSG);
}

So three possibilities: spend a lot of time reversing the native library doing the calculation, modify the app to directly write the msg content in the logs or do some dynamic analysis and write an Xposed module to intercept the intents and logs the message. I picked number 3 🙂

Actually I first tried to use Inspeckage – a tool developed to offer dynamic analysis of Android applications. By applying hooks to functions of the Android API, Inspeckage will help you understand what an Android application is doing at runtime.. I could see the intents and that they have some content but not the content itself… :/

inspeckage

So now back to solution 3 and the Xposed module to intercept the intents and log them


findAndHookMethod(ContextWrapper.class, "sendBroadcast", Intent.class, String.class, new XC_MethodHook() {

protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  Intent intent = (Intent) param.args[0];
  XposedBridge.log("sendBroadcast: " + intent.getStringExtra("msg"));

}
});

 

We just have to send the broadcast intents using adb:


mooh$ adb shell am broadcast -a com.ctf.INCOMING_INTENT --es msg ThisIsTheRealOne
Broadcasting: Intent { act=com.ctf.INCOMING_INTENT (has extras) }
Broadcast completed: result=0
mooh$ adb shell am broadcast -a com.ctf.INCOMING_INTENT --es msg DefinitelyNotThisOne
Broadcasting: Intent { act=com.ctf.INCOMING_INTENT (has extras) }
Broadcast completed: result=0
mooh$ adb shell am broadcast -a com.ctf.INCOMING_INTENT --es msg IsThisTheRealOne
Broadcasting: Intent { act=com.ctf.INCOMING_INTENT (has extras) }
Broadcast completed: result=0

click on the buttons

app2

 

and finally read the logs


04-29 17:01:04.694 1569-1569/com.example.hellojni I/Xposed: sendBroadcast: KeepTryingThisIsNotTheActivityYouAreLookingForButHereHaveSomeInternetPoints!
04-29 17:01:37.475 1569-1569/com.example.hellojni I/Xposed: sendBroadcast: Told you so!
04-29 17:02:05.279 1569-1569/com.example.hellojni I/Xposed: sendBroadcast: Congratulation!YouFoundTheRightActivityHereYouGo-CTF{IDontHaveABadjokeSorry}

 

 

0

Squareroots CTF‑Workshop – März 2016

March 4, 2016

This page is intentionally left german.

Auch dieses Semester veranstalten wir, die squareroots, am Wochenende von Freitag den 18. bis Sonntag den 20. März 2016 einen Workshop in den Räumlichkeiten der Universität Mannheim.
Wie bereits bei unseren vorherigen Workshops werden wir neben Einführungen in verschiedene Technologien und Werkzeuge auch den Ablauf von CTF-Wettbewerben vorstellen.

Anmeldungen sind ab sofort möglich auf http://anmeldung.sqrts.de/!

(more…)

0

32C3 CTF – Android Reverse-Engineering libdroid

January 9, 2016

I unfortunately didn’t have time to participate to the CCC CTF this year, but I wanted to look at the android reverse challenge and see if I could solve it using the Xposed Framework. So here we go, same toolkit as last time, Jadx, Genymotion and Android Studio (see here)

Firing up an emulator with API 23 and starting the app shows a keypad with cute little smileys. After clicking on “bear”, “bear”, “ghost”, “monkey”,”heart”, “burger”, a message appears, “no rootkit for you”. Same happens after pressing the “get flag” button.

app

So let’s open the app in jadx. There we can see an obfuscated class with native calls

    public static native String generateConfusion();

    public static native String getFlag();

    public static native String getOperatingSystem();

    public static native String getPhoneNumber();

    public static native String installRootkit();

    public static native String installiOS();

    public static native String obtainWorldDomination();

    private static native void phoneHome(byte[] bArr, byte[] bArr2);

    static {
        System.loadLibrary("libdroid");
        a = a(getOperatingSystem(), 1);
        b = a(getPhoneNumber(), 1);
        c = a(installRootkit(), 1);
        d = a(generateConfusion(), 1);
        f = a(obtainWorldDomination(), 1);
        g = a(installiOS(), 1);
        flag = a(getFlag(), 1);
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView((int) R.layout.activity_a);
        try {
            a(a);
        } catch (Exception e) {
        }
        this.e = BuildConfig.FLAVOR;
    }

    void a(String a) throws Exception {
        InputStream b = getAssets().open(a);
        ByteArrayOutputStream b2 = new ByteArrayOutputStream();
        byte[] data = new byte[AccessibilityNodeInfoCompat.ACTION_COPY];
        while (true) {
            int nRead = b.read(data, 0, data.length);
            if (nRead == -1) {
                break;
            }
            b2.write(data, 0, nRead);
        }
        b2.flush();
        BufferedReader b4 = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(a(b2.toByteArray(), b))));
        while (true) {
            String c = b4.readLine();
            if (c != null) {
                if (c.startsWith(g)) {
                    g = c.substring(g.length());
                }
                if (c.startsWith((String) f)) {
                    f = Base64.decode(c.substring(((String) f).length()), 0);
                }
            } else {
                return;
            }
        }
    }

So when the app is starting, some static values are initialized and then modified again in the a(a) method.
The interesting part is the click event handler a(View v).


public void a(View v) {
        if (v.getId() == R.id.button) {
            this.e += d.charAt(1);
        }
        if (v.getId() == R.id.button2) {
            this.e += d.charAt(2);
        }
        if (v.getId() == R.id.button3) {
            this.e += d.charAt(3);
        }
        if (v.getId() == R.id.button4) {
            this.e += d.charAt(4);
        }
        if (v.getId() == R.id.button5) {
            this.e += d.charAt(5);
        }
        if (v.getId() == R.id.button6) {
            this.e += d.charAt(6);
        }
        if (v.getId() == R.id.button7) {
            this.e += d.charAt(7);
        }
        if (v.getId() == R.id.button8) {
            this.e += d.charAt(8);
        }
        if (v.getId() == R.id.button9) {
            this.e += d.charAt(9);
        }
        if (v.getId() == R.id.button10) {
            this.e += d.charAt(0);
        }
        if (this.e.length() == 6 || v.getId() == R.id.button11) {
            CharSequence flag = flag;
            try {
                InputStream b = getAssets().open(g);
                ByteArrayOutputStream b2 = new ByteArrayOutputStream();
                byte[] data = new byte[AccessibilityNodeInfoCompat.ACTION_COPY];
                while (true) {
                    int nRead = b.read(data, 0, data.length);
                    if (nRead == -1) {
                        break;
                    }
                    b2.write(data, 0, nRead);
                }
                b2.flush();
                byte[] j = b2.toByteArray();
                byte[] f_ = new byte[16];
                System.arraycopy((byte[]) f, 0, f_, 0, ((byte[]) f).length);
                System.arraycopy(this.e.getBytes(), 0, f_, 10, this.e.getBytes().length);
                phoneHome(j, f_);
                if (new String(j).startsWith(c)) {
                    flag = new String(j);
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            Snackbar.make(v, flag, 0).setAction((CharSequence) "Action", null).show();
            this.e = BuildConfig.FLAVOR;
        }
    }

So everytime a key is pressed, a new character will be appended to the attribute “e”. If its length is 6 or the “get flag” button is pressed, some magic is done and a result is displayed in a message using a Snackbar.

Let’s bruteforce it! There are only 999999 possibilities.
The idea is then to set the variable “e” and simulate a click on the “get flag” button.

We first need to find the charset for “e”, ie we need the value of “d” (this.e += d.charAt(x);). We have seen above that “d” is set in the onCreate method, so let’s hook it


findAndHookMethod("ctf.stratumauhhur.libdroid.a", lpparam.classLoader, "onCreate", Bundle.class, new XC_MethodHook() {

	@Override
	protected void afterHookedMethod(MethodHookParam param) throws Throwable {
	    String d = (String) XposedHelpers.getObjectField(param.thisObject,"d");
	    XposedBridge.log("d= " + d);
	}
});

Running the app returns

I/Xposed: d=  1234567890

So the charset is only digits, isn’t it? Wrong, wrong, wrong! (it did take me some time to realize my mistake…) It’s not “1234567890” but ” 123456789″…

Now we are nearly ready to start the brute force. We need somehow to log the popup message to get the flag. So let’s hook the make() method of the snackbar and log everything that doesn’t start with the default error message:

findAndHookMethod("android.support.design.widget.Snackbar", lpparam.classLoader, "make", View.class, CharSequence.class, int.class, new XC_MethodHook() {

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        if (!((String) param.args[1]).startsWith("Sorry")) {
            XposedBridge.log("message= " + param.args[1]);
        }
    }
});

Here the pseudo-code for the brute force

String formatted = String.format("%06d", cnt.getAndIncrement());
if (formatted.endsWith("00000")) {
    XposedBridge.log("Count= " + formatted);
}
formatted = formatted.replaceAll("0"," ");
XposedHelpers.setObjectField(object, "e", formatted);
XposedHelpers.callMethod(object, "a", p.args[0]);

And then we start the app and press the “get flag” button to start the brute force. In less than 2 minutes, we get the flag

flag

Thanks again 0x3cute for showing me this framework!

0

SECCON 2015 Online CTF – Reverse-Engineering Android APK 1

December 7, 2015

After reading a write up of the Trend Micro CTF about someone discovering the Xposed Framework and wanting to use it to solve CTF challenges, I decided to do the same.
In short, the Xposed framework allows to hook methods from an android application without having to modify the app.

What I used:
Genymotion (site) (android emulator faster than the stock one)
Xposed Framework (site)
jadx (site) dex to java decompiler
Android Studio (to write the Xposed module)

After opening the apk in jadx, the relevant parts are found in the MainActivity

Screen Shot 2015-12-07 at 12.56.16

In particularly:

if (1000 == MainActivity.this.cnt) {
    tv3.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
}

So after winning 1000 times in a row, the flag is displayed. It is calculated based on the counter and the result of the calc() method. Unfortunately here, the calc method is a native method.Instead of starting Hopper and reversing the native lib or patching the apk to display directly the flag, let’s try to write a Xposed module for it.

Idea is then to hook up the onClick method and set the attributes to the correct values (ie set count to 999 and the attribute m and n in order to make it a wining move)

public class RPS implements IXposedHookLoadPackage {
    public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {

        if (!lpparam.packageName.equals("com.example.seccon2015.rock_paper_scissors"))
            return;
        findAndHookMethod("com.example.seccon2015.rock_paper_scissors.MainActivity", lpparam.classLoader, "onClick", View.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                // set the modified values
                XposedHelpers.setIntField(param.thisObject, "cnt", 999);
                XposedHelpers.setIntField(param.thisObject, "m", 0);
                XposedHelpers.setIntField(param.thisObject, "n", 1);
            }
        });
}

Finally we start the application in the emulator, click on any button and the flag is displayed!

Screen Shot 2015-12-07 at 12.55.38

0
Get Adobe Flash player