[XCTF-Reverse] 49 nullcon-hackim-2016_zorropub

爆破题

先是输入一个数字作种子,然后生成30个随机数,这些数转10进制字符串的md5给出,这些数与给定数异或得到flag

  seed = 0;
  puts("Welcome to Pub Zorro!!");
  printf("Straight to the point. How many drinks you want?", a2);
  __isoc99_scanf("%d", &v5);
  if ( v5 <= 0 )
  {
    printf("You are too drunk!! Get Out!!");
    exit(-1);
  }
  printf("OK. I need details of all the drinks. Give me %d drink ids:", (unsigned int)v5);
  for ( i = 0; i < v5; ++i )
  {
    __isoc99_scanf("%d", &v6);
    if ( v6 <= 16 || v6 > 0xFFFF )
    {
      puts("Invalid Drink Id.");
      printf("Get Out!!");
      exit(-1);
    }
    seed ^= v6;
  }
  i = seed;
  v9 = 0;
  while ( i )
  {
    ++v9;
    i &= i - 1;                                 // v6里有多少个1(2进制)
  }
  if ( v9 != 10 )
  {
    puts("Looks like its a dangerous combination of drinks right there.");
    puts("Get Out, you will get yourself killed");
    exit(-1);
  }
  srand(seed);
  MD5_Init(&v10);
  for ( i = 0; i <= 29; ++i )
  {
    v9 = rand() % 1000;
    sprintf(&s, "%d", v9);
    v3 = strlen(&s);
    MD5_Update(&v10, &s, v3);
    v12[i] = v9 ^ LOBYTE(dword_6020C0[i]);
  }
  v12[i] = 0;
  MD5_Final(v11, &v10);
  for ( i = 0; i <= 15; ++i )
    sprintf(&s1[2 * i], "%02x", (unsigned __int8)v11[i]);
  if ( strcmp(s1, "5eba99aff105c9ff6a1a913e343fec67") )
  {
    puts("Try different mix, This mix is too sloppy");
    exit(-1);
  }
  return printf("\nYou choose right mix and here is your reward: The flag is nullcon{%s}\n", v12);

本来想学学ctypes但是这个程序本身就运行不起来(要求的libcrypto版本太旧),所以直接写了个小的随机数程序

#include <stdlib.h>
#include <stdio.h>

int main()
{
	int i,j,k;
	while(1){
	        puts("Input:");
		scanf("%d", &i);
		srand(i);
		for(j=0;j<30;j++)printf("%d,",rand());
	}
	return 0;
}

然后爆破,因为16位整数二进制含10个1的情况并不多,所以爆破很容易

#from ctypes import *
from hashlib import md5
from pwn import *

key = [0x3c8, 0x32, 0x2ce, 0x302, 0x7f, 0x1b8, 0x37e, 0x188, 0x349, 0x27f,
       0x5e, 0x234, 0x354, 0x1a3, 0x96, 0x340, 0x128, 0x2fc, 0x300, 0x28e,
       0x126, 0x1b, 0x32a, 0x2f5, 0x15f, 0x368, 0x1eb, 0x79, 0x11d, 0x24e]

p = process('./c_rand')
context.log_level = 'debug'

def getv12(seed):
    p.sendlineafter(b'Input:\n', str(seed).encode())
    v12 = b''
    sv9 = ''
    for i in range(30):
        v9 = int(p.recvuntil(b',', drop=True))%1000
        sv9 += str(v9)
        v12 += p8(v9 ^ key[i])
    else:
        v11 = md5(sv9.encode()).hexdigest()
        if v11 == "5eba99aff105c9ff6a1a913e343fec67":
            print(v12)
            pause()

def get10():
    for k in range(59306,0xfff0):
        i = k
        j = 0
        while i !=0:
            i &= i-1
            j +=1
        if j == 10:
            print(k, bin(k)[2:])
            getv12(k)
        
get10()

#nu11c0n_s4yz_x0r1n6_1s_4m4z1ng
#nullcon{nu11c0n_s4yz_x0r1n6_1s_4m4z1ng}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值