2013 csaw CTF Quals Writeup

Reversing1 - 100pt

안티 디버깅 걸려있는데 상관 안쓰고 풀었다.

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  unsigned int len; // kr00_4
  unsigned int v4; // ecx

  if ( IsDebuggerPresent() )
  {
    len = strlen(Text);
    v4 = 0;
    if ( len >> 2 != -1 )
    {
      do
        *&Text[4 * v4++] ^= 0xCCDDEEFF;
      while ( v4 < (len >> 2) + 1 );
    }
    MessageBoxA(0, Text, "Flag", 2u);
  }
  else
  {
    MessageBoxA(0, Text, "Flag", 2u);
  }
  ExitProcess(0);
}

Text 변수 긁어와서 xor연산해주는데 그거 역연산 짜주면 된다.

from idaapi import *
from idautils import *
from itertools import *

a = []
for i in range(32):
  a.append(hex(Byte(0x408B20+i)))
a = [int(i,16) for i in a]
b = [0xff,0xee,0xdd,0xcc]
flag = ""
for x,y in zip(a,cycle(b)):
	flag += chr(x^y)
print flag

FLAG : flag{this1isprettyeasy:)}


Reversing2 - 200pt

이 문제도 아까랑 그냥 거의 비슷하다.

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  HANDLE v3; // edi
  char *v4; // esi
  unsigned int v5; // ecx
  unsigned int v6; // eax

  v3 = HeapCreate(0x40000u, 0, 0);
  v4 = HeapAlloc(v3, 8u, 37u);
  memcpy_s(v4, 36u, &unk_409B10, 36u);
  if ( !*(*(__readfsdword(0x18u) + 48) + 2) )
  {
    __debugbreak();
    v5 = 0;
    v6 = (strlen(v4 + 1) >> 2) + 1;
    if ( v6 > 0 )
    {
      do
        *&v4[4 * v5++] ^= 0x8899AABB;
      while ( v5 < v6 );
    }
  }
  MessageBoxA(0, v4, "Flag", 2u);
  HeapFree(v3, 0, v4);
  HeapDestroy(v3);
  ExitProcess(0);
}

할당해주는 값 긁어와서 xor해주면된다.

from idaapi import *
from idautils import *
from itertools import *
a = []
for i in range(40):
	a.append(hex(Byte(i+0x409b10)))
a = [int(i,16) for i in a]
b = [0xbb,0xaa,0x99,0x88]
flag=""
for x,y in zip(a,cycle(b)):
	flag += chr(x^y)
print flag 

FLAG : flag{number2isalittlebitharder:p}


DotNet - 100pt

값을 입력받아서 그것과 num2랑 xor한 값이 num3면 된다고 한다.

밑에 부분은 AES Decrypt 해주는 부분이 있는데 맞는 입력 값을 넣으면 저기서 플래그를 만들어주는 거다.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading;

namespace dotnetreversingchallenge
{
	// Token: 0x02000002 RID: 2
	internal class aClass
	{
		// Token: 0x06000001 RID: 1 RVA: 0x00002060 File Offset: 0x00000260
		private static void Main(string[] args)
		{
			Console.WriteLine("Greetings challenger! Step right up and try your shot at gaining the flag!");
			Console.WriteLine("You'll have to know the pascode to unlock the prize:");
			string value = Console.ReadLine();
			long num = Convert.ToInt64(value);
			long num2 = 53129566096L;
			long num3 = 65535655351L;
			if ((num ^ num2) == num3)
			{
				Console.WriteLine("yay");
			}
			else
			{
				Console.WriteLine("Incorrect, try again!");
			}
			try
			{
				byte[] iv = new byte[]
				{
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue,
					byte.MaxValue
				};
				byte[] array = new byte[16];
				BitConverter.GetBytes(num).CopyTo(array, 0);
				BitConverter.GetBytes(num).CopyTo(array, 8);
				string s = "ls/5RTxwflDrqr5G8pO9cQ1NlgQcFjcJj9x4z7oIhlfY4w42GAFqKbyzwqHAZQBZa5ctysKKWIbTgU2VxoRYohxCbPyV6sEU/tn+sIxNg6A/r5OJnIMqTs0seMrzWh5J";
				Thread.Sleep(500);
				Console.WriteLine(aClass.DecryptStringFromBytes_Aes(Convert.FromBase64String(s), array, iv));
				Console.WriteLine("Success!!");
			}
			catch (Exception arg)
			{
				Console.WriteLine("ERROR!!! darn. huh? how did I get here? Hmm, something must have gone wrong. What am I doing?", arg);
			}
			Console.WriteLine("press key to continue");
			Console.ReadKey();
		}

		// Token: 0x06000002 RID: 2 RVA: 0x00002174 File Offset: 0x00000374
		private static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
		{
			if (plainText == null || plainText.Length <= 0)
			{
				throw new ArgumentNullException("plainText");
			}
			if (Key == null || Key.Length <= 0)
			{
				throw new ArgumentNullException("Key");
			}
			if (IV == null || IV.Length <= 0)
			{
				throw new ArgumentNullException("Key");
			}
			byte[] result;
			using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider())
			{
				aesCryptoServiceProvider.Key = Key;
				aesCryptoServiceProvider.IV = IV;
				ICryptoTransform transform = aesCryptoServiceProvider.CreateEncryptor(aesCryptoServiceProvider.Key, aesCryptoServiceProvider.IV);
				using (MemoryStream memoryStream = new MemoryStream())
				{
					using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
					{
						using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
						{
							streamWriter.Write(plainText);
						}
						result = memoryStream.ToArray();
					}
				}
			}
			return result;
		}

		// Token: 0x06000003 RID: 3 RVA: 0x000022CC File Offset: 0x000004CC
		private static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
		{
			if (cipherText == null || cipherText.Length <= 0)
			{
				throw new ArgumentNullException("cipherText");
			}
			if (Key == null || Key.Length <= 0)
			{
				throw new ArgumentNullException("Key");
			}
			if (IV == null || IV.Length <= 0)
			{
				throw new ArgumentNullException("IV");
			}
			string result = null;
			using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider())
			{
				aesCryptoServiceProvider.Key = Key;
				aesCryptoServiceProvider.IV = IV;
				ICryptoTransform transform = aesCryptoServiceProvider.CreateDecryptor(aesCryptoServiceProvider.Key, aesCryptoServiceProvider.IV);
				using (MemoryStream memoryStream = new MemoryStream(cipherText))
				{
					using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read))
					{
						using (StreamReader streamReader = new StreamReader(cryptoStream))
						{
							result = streamReader.ReadToEnd();
						}
					}
				}
			}
			return result;
		}
	}
}

간단하다 매우 53129566096 ^ 65535655351해주면 13371337255이 나오는데 이거 입력해주면 된다.

FLAG : flag{I'll create a GUI interface using visual basic...see if I can track an IP address.}


bikinibonanza - 150pt

.NET 파일이다.

여기 마지막에 플래그 출력해주는 분기가 있는데 brfalse.s를 brtrue.s로 바꿔주면 된다.

CIL instructions

그러면 플래그 출력해주는 분기로 가서 아무거나 입력해도 플래그가 출력된다.

FLAG : key(0920303251BABE89911ECEAD17FEBF30)