[XCTF-Reverse] 31-36

31,easy_Maze

迷宫题,先由step_0和step_1生成迷宫,然后按上下左右把走的线路输入。step_0还好办,step_1就比较麻烦了,很难对照写出程序。不过这个有个简单方法,用gdb在step_1后边下断点,然后前49个int就是生成的迷宫。然后手工写下来就行了

  Step_0((int (*)[7])v9, 7, (int (*)[7])v7);
  Step_1((int (*)[7])v7, 7, (int (*)[7])v5);
  v3 = std::operator<<<std::char_traits<char>>(&_bss_start, "Please help me out!");
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  Step_2((int (*)[7])v5);
'''
gdb-peda$ x/50d 0x7fffffffdc80
0x7fffffffdc80:	1	0	0	1
0x7fffffffdc90:	1	1	1	1
0x7fffffffdca0:	0	1	1	0
0x7fffffffdcb0:	0	1	1	1
0x7fffffffdcc0:	1	0	1	1
0x7fffffffdcd0:	1	0	0	0
0x7fffffffdce0:	1	1	0	0
0x7fffffffdcf0:	1	1	1	1
0x7fffffffdd00:	0	0	0	1
0x7fffffffdd10:	0	0	0	1
0x7fffffffdd20:	1	1	1	1
0x7fffffffdd30:	1	1	1	0
0x7fffffffdd40:	1	0
'''
a = [
1,0,0,1,1,1,1,
1,0,1,1,0,0,1,
1,1,1,0,1,1,1,
0,0,0,1,1,0,0,
1,1,1,1,0,0,0,
1,0,0,0,1,1,1,
1,1,1,1,1,0,1]

s = 'ssddwdwdddssaasasaaassddddwdds'
#UNCTF{ssddwdwdddssaasasaaassddddwdds}

32,ReverseMe-120

这里有一小段比较难理解,4个字符变3个,猜是base64

后边就是与0x25异或后与指定串对比。

  if ( v18 && *v19 >= v13 )
  {
    v21 = 3;
    v14 = 0;
    for ( source_lena = 0; v5; --v5 )
    {
      v15 = *v7;
      if ( *v7 != 13 && v15 != 10 && v15 != 32 )
      {
        v16 = byte_414E40[v15];
        v21 -= v16 == 64;
        v14 = v16 & 0x3F | (v14 << 6);
        if ( ++source_lena == 4 )
        {
          source_lena = 0;
          if ( v21 )
            *v12++ = BYTE2(v14);
          if ( v21 > 1 )
            *v12++ = BYTE1(v14);
          if ( v21 > 2 )
            *v12++ = v14;
        }
      }
      ++v7;
    }
    *v19 = v12 - v18;

解码

from base64 import b64encode

a = b"you_know_how_to_remove_junk_code"
b = ''.join([chr(i^0x25) for i in a])
print(b64encode(b.encode()))

33,school-ctf-winter-2015_secret-string-400

js的程序虽然都是原码,但看起来也是巨难的。经过一段神操作后然后执行代码。

function run(){
	while(this.PC < this.code.length){
		var command = parseCommand.call(this)
		command.execute(this);
	}
	//this.end()
}

为了知道这个代码是啥在执行前打印一下

function run(){
	while(this.PC < this.code.length){
		var command = parseCommand.call(this)
		console.log('xxxxxxxxxxxxxx'+command.args);
		command.execute(this);
	}
	//this.end()
}

然后从console能看到输入的代码

var i = f.length//
var nonce = 'groke';//
var j = 0;//
var out = [];//
var eq = true;//
while(j < i){//
out.push(f.charCodeAt(j) ^ nonce.charCodeAt(j%5))//      <------------输入数据nonce异或运算后与 ex 比较
j++;//
}//
var ex =  [1, 30, 14, 12, 69, 14, 1, 85, 75, 50, 40, 37, 48, 24, 10, 56, 55, 46, 56, 60];//
if (ex.length == out.length) {//
j = 0;//
while(j < ex.length){//
if(ex[j] != out[j])//
eq = false;//
j += 1;//
}//
if(eq){//
alert('YOU WIN!');//
}else{
alert('NOPE!');
}}else{alert('NOPE!');}//ÿ	ÿÿÿ

解码

nonce = b'groke'
ex =  [1, 30, 14, 12, 69, 14, 1, 85, 75, 50, 40, 37, 48, 24, 10, 56, 55, 46, 56, 60]
print( ''.join([chr(nonce[i%5] ^ v) for i,v in enumerate(ex)]) )

#flag is: WOW_so_EASY

34,高校网络信息安全运维挑战赛_IgniteMe

main里调用sub_4011C0实现检查功能,先转换大小写再查表异或

bool __cdecl sub_4011C0(char *a1)
{
  size_t v2; // eax
  signed int v3; // [esp+50h] [ebp-B0h]
  char v4[32]; // [esp+54h] [ebp-ACh]
  int v5; // [esp+74h] [ebp-8Ch]
  int v6; // [esp+78h] [ebp-88h]
  size_t i; // [esp+7Ch] [ebp-84h]
  char v8[128]; // [esp+80h] [ebp-80h]

  if ( strlen(a1) <= 4 )
    return 0;
  i = 4;
  v6 = 0;
  while ( i < strlen(a1) - 1 )
    v8[v6++] = a1[i++];
  v8[v6] = 0;
  v5 = 0;
  v3 = 0;
  memset(v4, 0, 0x20u);
  for ( i = 0; ; ++i )
  {
    v2 = strlen(v8);
    if ( i >= v2 )
      break;
    if ( v8[i] >= 97 && v8[i] <= 122 )
    {
      v8[i] -= 32;
      v3 = 1;
    }
    if ( !v3 && v8[i] >= 65 && v8[i] <= 90 )    // 大小写互换
      v8[i] += 32;
    v4[i] = byte_4420B0[i] ^ sub_4013C0(v8[i]);
    v3 = 0;
  }
  return strcmp("GONDPHyGjPEKruv{{pj]X@rF", v4) == 0;
}

解法

a = b"GONDPHyGjPEKruv{{pj]X@rF"
b = bytes.fromhex('0D1317110201201D0C02192F172B241F1E16090F152713260A2F1E1A2D0C2204')

for i in range(len(a)):
    c = a[i]^b[i]
    d = ((256+(c-72))%256)^0x55
    if d>=97 and d<=122:
        d -=32
    elif d>=65 and d<=90:
        d +=32
    print(chr(d), end='')
#wadx_tdgk_aihc_ihkn_pjlm
#EIS{wadx_tdgk_aihc_ihkn_pjlm}

35,XCTF 3rd-GCTF-2017_debug

用ida打开时提示.net格式,第一回弄搜了一下要用ILSpy打开,打开后左边这个程序点开,一个个点找到里边的代码(这个东西比较坑人的是函数没有函数名,好在就4个)

对照写出代码

'''
	private static int ᜀ(int A_0, int A_1)
	{
		return (new int[30]
		{
			2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
			31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
			73, 79, 83, 89, 97, 101, 103, 107, 109, 113
		})[A_1] ^ A_0;
	}
'''

'''
	private static string ᜀ(string A_0)
	{
		byte[] bytes = Encoding.ASCII.GetBytes(A_0);
		return "flag{" + BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(bytes)).Replace("-", "") + "}";
	}
'''
import hashlib
def show(a):
    flag = 'flag{' + hashlib.md5(a.encode()).hexdigest().upper() + '}'
    print(flag)

'''
	private static void ᜀ(string A_0, int A_1, ref string A_2)
	{
		int num = 0;
		if (0 < A_0.Length)
		{
			do
			{
				char c = A_0[num];
				int num2 = 1;
				do
				{
					c = Convert.ToChar(ᜀ(Convert.ToInt32(c), num2));
					num2++;
				}
				while (num2 < 15);
				A_2 += c;
				num++;
			}
			while (num < A_0.Length);
		}
		A_2 = ᜀ(A_2);
	}
'''

tab = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113]
def compare(a0):
    a2 = ''
    for c in a0:
        for n2 in range(1,15):
            c = tab[n2]^c
        a2 +=chr(c)
    return a2 
'''
	private static void ᜀ(string[] A_0)
	{
		string A_ = null;
		string value = $"{DateTime.Now.Hour + 1}";
		string a_ = "CreateByTenshine";
		ᜀ(a_, Convert.ToInt32(value), ref A_);
		string text = Console.ReadLine();
		if (text == A_)
		{
			Console.WriteLine("u got it!");
			Console.ReadKey(intercept: true);
		}
		else
		{
			Console.Write("wrong");
		}
		Console.ReadKey(intercept: true);
	}
'''  
def main():
    a1 = b"CreateByTenshine"
    a2 = compare(a1)
    show(a2)

main()
#flag{967DDDFBCD32C1F53527C221D9E40A0B}

36,XCTF 3rd-GCTF-2017_hackme

程序入口都找不到,从start里一个个点找到main是sub_400F8E

函数里除了v6比较难确定外其它都很容易,不过猜这个就是从头遍历v8,不然也不知道该干啥。

  puts((unsigned __int64)"Give me the password: ");
  scanf((__int64)"%s", v8, a2);
  for ( i = 0; v8[i]; ++i )
    ;
  v18 = i == 22;
  v17 = 10;
  do
  {
    v6 = sub_406D90((__int64)"%s", (__int64)v8, v2, v3, v4, v5);// 猜是从0开始遍历输入串
    v3 = (unsigned int)(v6 % 22);
    v14 = v6 % 22;
    v16 = 0;
    v13 = byte_6B4270[v6 % 22];
    v12 = v8[v6 % 22];
    v11 = v6 % 22 + 1;
    v15 = 0;
    while ( v15 < v11 )
    {
      ++v15;
      v16 = 1828812941 * v16 + 12345;
    }
    v2 = v16;
    v10 = v16 ^ v12;
    if ( v13 != ((unsigned __int8)v16 ^ v12) )
      v18 = 0;
    --v17;
  }
  while ( v17 );
  if ( v18 )
    v9 = puts((unsigned __int64)"Congras\n");
  else
    v9 = puts((unsigned __int64)"Oh no!\n");
  return 0LL;

解码

a = bytes.fromhex('5FF25E8B4E0EA3AAC793813D5F74A309912B49289367')
for i,v in enumerate(a):
    v16 = 0
    for j in range(i+1):
        v16 = 1828812941 * v16 + 12345
    print(chr(v^( v16 & 0xff )), end='')
#flag{d826e6926098ef46}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值