buu 红帽杯 XX
一.拖入ida,静态分析
__int64 __fastcall sub_7FF65D4511A0(__int64 a1, __int64 a2)
{
  signed __int64 v2; // rbx
  signed __int64 v3; // rax
  __int64 v4; // rax
  __int64 v5; // r11
  __int128 *v6; // r14
  int v7; // edi
  _BYTE *v8; // rsi
  char v9; // r10
  int v10; // edx
  __int64 v11; // r8
  unsigned __int64 v12; // rcx
  signed __int64 v13; // rcx
  unsigned __int64 v14; // rax
  unsigned __int64 i; // rax
  __int64 v16; // rax
  size_t v17; // rsi
  _BYTE *v18; // rbx
  _BYTE *v19; // r9
  signed int v20; // er11
  char *v21; // r8
  signed __int64 v22; // rcx
  char v23; // al
  signed __int64 v24; // r9
  signed __int64 v25; // rdx
  __int64 v26; // rax
  size_t Size; // [rsp+20h] [rbp-48h]
  __int128 v29; // [rsp+28h] [rbp-40h]
  int v30; // [rsp+38h] [rbp-30h]
  int v31; // [rsp+3Ch] [rbp-2Ch]
  int Code[4]; // [rsp+40h] [rbp-28h]
  int v33; // [rsp+50h] [rbp-18h]
  *(_OWORD *)Code = 0i64;
  v33 = 0;
  sub_7FF65D4518C0(std::cin, a2, Code); //根据cin,知道是在输入字符串,存入Code里面
  v2 = -1i64;
  v3 = -1i64;
  do
    ++v3;
  while ( *((_BYTE *)Code + v3) );
  if ( v3 != 19 )   //字符串长度为19
  {
    sub_7FF65D451620(std::cout, "error\n");
    _exit((unsigned __int64)Code);
  }
  v4 = sub_7FF65D451E5C(5ui64);  //根据后面的判断是申请内存空间
  v5 = *(_QWORD *)&::Code;  //这里有点迷惑性,看似是输入的字符串,实际点进去就知道是个常量
  v6 = (__int128 *)v4;
  v7 = 0;
  v8 = (_BYTE *)v4;
  do
  {
    v9 = v8[(_QWORD)Code - v4];
    v10 = 0;
    *v8 = v9;
    v11 = 0i64;
    v12 = -1i64;
    do
      ++v12;
    while ( *(_BYTE *)(v5 + v12) );
    if ( v12 )
    {
      do
      {
        if ( v9 == *(_BYTE *)(v5 + v11) )
          break;
        ++v10;
        ++v11;
      }
      while ( v10 < v12 );
    }
    v13 = -1i64;
    do
      ++v13;
    while ( *(_BYTE *)(v5 + v13) );
    if ( v10 == v13 )
      _exit(v5);
    ++v8;
  }
  while ( (signed __int64)&v8[-v4] < 4 );
  *(_BYTE *)(v4 + 4) = 0;                  //判断字符串的前四位在字符串常量中,基本判断出是flag
  do
    ++v2;
  while ( *((_BYTE *)Code + v2) );    //字符串常量长度为36
  v14 = 0i64;
  v29 = *v6;
  while ( *((_BYTE *)&v29 + v14) )
  {
    if ( !*((_BYTE *)&v29 + v14 + 1) )
    {
      ++v14;
      break;
    }
    if ( !*((_BYTE *)&v29 + v14 + 2) )
    {
      v14 += 2i64;
      break;
    }
    if ( !*((_BYTE *)&v29 + v14 + 3) )
    {
      v14 += 3i64;
      break;
    }
    v14 += 4i64;
    if ( v14 >= 0x10 )
      break;
  }                              //测试那段内存空间字符串的长度
  for ( i = v14 + 1; i < 0x10; ++i )  //补齐16位,也就是128bits
    *((_BYTE *)&v29 + i) = 0;
  v16 = sub_7FF65D451AB0(Code, v2, &v29, &Size); //结合题目,和上面的基本判定是xxtea加密
  v17 = Size;
  v18 = (_BYTE *)v16;
  v19 = (_BYTE *)sub_7FF65D451E5C(Size);
  v20 = 1;
  *v19 = v18[2];
  v21 = v19 + 1;
  v19[1] = *v18;
  v19[2] = v18[3];
  v19[3] = v18[1];
  v19[4] = v18[6];
  v19[5] = v18[4];
  v19[6] = v18[7];
  v19[7] = v18[5];
  v19[8] = v18[10];
  v19[9] = v18[8];
  v19[10] = v18[11];
  v19[11] = v18[9];
  v19[12] = v18[14];
  v19[13] = v18[12];
  v19[14] = v18[15];
  v19[15] = v18[13];
  v19[16] = v18[18];
  v19[17] = v18[16];
  v19[18] = v18[19];
  v19[19] = v18[17];
  v19[20] = v18[22];
  v19[21] = v18[20];
  v19[22] = v18[23];
  for ( v19[23] = v18[21]; v20 < v17; ++v21 )  //打乱了下加密字符串的顺序
  {
    v22 = 0i64;
    if ( v20 / 3 > 0 )
    {
      v23 = *v21;
      do
      {
        v23 ^= v19[v22++];
        *v21 = v23;
      }
      while ( v22 < v20 / 3 );
    }
    ++v20;
  }
  *(_QWORD *)&v29 = -4569681940847739698i64;
  v24 = v19 - (_BYTE *)&v29;
  *((_QWORD *)&v29 + 1) = 3819887636644928495i64;
  v25 = 0i64;
  v30 = -939386845;
  v31 = -95004953;
  do
  {
    if ( *((_BYTE *)&v29 + v25) != *((_BYTE *)&v29 + v25 + v24) )   //比较是否正确
      _exit(v7 * v7);
    ++v7;
    ++v25;
  }
  while ( v25 < 24 );
  v26 = sub_7FF65D451620(std::cout, "You win!");
  std::basic_ostream<char,std::char_traits<char>>::operator<<(v26, sub_7FF65D4517F0);
  return 0i64;
}
思路;
先找到最终正确的加密字符串
逆向那个异或的算法
再移位回来
再xxtea的解密,
得出flag

然后写脚本逆向回去就好了。
import struct
_DELTA = 0x9E3779B9
def _long2str(v, w):
    n = (len(v) - 1) << 2
    if w:
        m = v[-1]
        if (m < n - 3) or (m > n): return ''
        n = m
    s = struct.pack('<%iL' % len(v), *v)
    return s[0:n] if w else s
def _str2long(s, w):
    n = len(s)
    m = (4 - (n & 3) & 3) + n
    s = s.ljust(m, "\0")
    v = list(struct.unpack('<%iL' % (m >> 2), s))
    if w: v.append(n)
    return v
def encrypt(str, key):
    if str == '': return str
    v = _str2long(str, True)
    k = _str2long(key.ljust(16, "\0"), False)
    n = len(v) - 1
    z = v[n]
    y = v[0]
    sum = 0
    q = 6 + 52 // (n + 1)
    while q > 0:
        sum = (sum + _DELTA) & 0xffffffff
        e = sum >> 2 & 3
        for p in range(n):
            y = v[p + 1]
            v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff
            z = v[p]
        y = v[0]
        v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffff
        z = v[n]
        q -= 1
    return _long2str(v, False)
def decrypt(str, key):
    if str == '': return str
    v = _str2long(str, False)
    k = _str2long(key.ljust(16, "\0"), False)
    n = len(v) - 1
    z = v[n]
    y = v[0]
    q = 6 + 52 // (n + 1)
    sum = (q * _DELTA) & 0xffffffff
    while (sum != 0):
        e = sum >> 2 & 3
        for p in range(n, 0, -1):
            z = v[p - 1]
            v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff
            y = v[p]
        z = v[n]
        v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff
        y = v[0]
        sum = (sum - _DELTA) & 0xffffffff
    return _long2str(v, True)
res=[0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B, 0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8, 0xE7, 0x56, 0x56,0xFA]
dec=""
for i in range(7,-1,-1):
    a=""
    for j in range(3):
        tmp=res[i*3+j]
        for w in range(i):
            tmp^=res[w]
        a+=chr(tmp)
    dec=a+dec
print(dec)
key="flag"+"\x00"*12
num=[2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]
n=[0 for i in range(24)]
for i in range(24):
    n[num[i]]=dec[i]
dec2="".join(n)
dec3=decrypt(dec2,key)
print(dec3)
buu 红帽杯 XX的更多相关文章
- buu 红帽杯easyre
		一.拖入ida静态分析 找到关键函数,然后 这步是可以得出前4个字符是flag,不知道为啥我这边的v15的内存地址为空,不然可以异或解出来的,ida日常抽风... 十次的base64加密,我用在线平台 ... 
- [BUUCTF]REVERSE——[2019红帽杯]easyRE
		[2019红帽杯]easyRE 附件 步骤: ida载入,没有main函数,就先检索了程序里的字符串 发现了base64加密的特征字符串,双击you found me跟进,找到了调用它的函数,函数很长 ... 
- 2019红帽杯部分wp
		xx 程序首先取输入的前4个字符作为xxtea加密的密钥之后进行xxtea加密.接着进行位置置换操作,然后又进行了以3个为一组的异或 首先逆向解出xxtea加密之后的结果 #include<st ... 
- 2019 红帽杯 Re WP
		0x01 xx 测试文件:https://www.lanzous.com/i7dyqhc 1.准备 获取信息 64位文件 2.IDA打开 使用Findcrypt脚本可以看到 结合文件名是xx,因此猜测 ... 
- 红帽杯-MISC-Advertising for Marriage
		convert -flip screenshot.png screensho1.png 本篇结合我上一博客https://www.cnblogs.com/qq3285862072/p/11869403 ... 
- [转+自]关于PHP7的新特性(涉及取反和disabled_functions绕过)
		PHP7和PHP5上的安全区别 preg_replace()不再支持/e修饰符 利用\e修饰符执行代码的后门大家也用了不少了,具体看官方的这段描述: 如果设置了这个被弃用的修饰符, preg_repl ... 
- web赛题2
		@上海赛wp 微信 和 https://www.ctfwp.com/articals/2019unctf.html 后续公告https://unctf.buuoj.cn/notice.html 必看! ... 
- Misc题目
		@freebuff教程https://www.freebuf.com/column/196815.html @巅峰极客wp https://www.anquanke.com/post/id/18914 ... 
- SQLi —— 逗号,空格,字段名过滤突破
		前言 出于上海大学生网络安全大赛的一道easysql,促使我积累这篇文章.因为放了大部分时间在Decade和Babyt5上,easysql一点没看,事后看了WP,发现看不懂怎么回事,于是了解了一番. ... 
随机推荐
- Java安全之Cas反序列化漏洞分析
			Java安全之Cas反序列化漏洞分析 0x00 前言 某次项目中遇到Cas,以前没接触过,借此机会学习一波. 0x01 Cas 简介 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用 ... 
- Centos 重置root密码
			# cat /etc/system-release #查看版本 开机后在内核grub.2上敲击 e 在linux16 行(倒数第二行)末加入 " ... 
- 原型和原型链 prototype和proto的区别
			原型 原型是function对象下的属性,它定义了构造函数的共同祖先,也就是一个父子级的关系,子对象会继承父对象的方法和属性 prototype是函数下的属性,对象想要查看原型使用隐式属性__Prot ... 
- jackjson学习2+CVE-2019-14379漏洞分析
			最近想着分析jackson,jackson和fastjson有点相似,浅蓝大神的文章很好,个人受益匪浅 昨天简单说了下jackson的用法,现在继续拓扑,补充前置知识,前置知识补充的足够多,那么漏洞分 ... 
- 微星msi B450M+i5-8500+1060成功黑苹果
			经过几天的努力,终于成功装上黑苹果! N卡1060目前只能装10.13.6(17G65),10.14版本N卡是没有驱动的,即便装上后也是8M的显存 详细教程网上一大堆,我就不做一份了.推荐大家看一下黑 ... 
- Redis限制一键登录次数
			一.产生背景 之前的随笔提到过项目中写了一键登录功能.上线后除了有时候网络波动会导致登陆失败,其他情况一直稳如老狗 しかし,邮件看到有人恶意刷一键登录,这年头闲的人可真闲啊, 只能思考如何搞一搞 二. ... 
- nginx的请求处理
			nginx的请求处理¶ nginx使用一个多进程模型来对外提供服务,其中一个master进程,多个worker进程.master进程负责管理nginx本身和其他worker进程. 所有实际上的业务 ... 
- 适用于AMD ROC GPU的Numba概述
			适用于AMD ROC GPU的Numba概述 Numba通过按照HSA执行模型将Python代码的受限子集直接编译到HSA内核和设备功能中,从而支持AMD ROC GPU编程.用Numba编写的内核似 ... 
- 深度学习调用TensorFlow、PyTorch等框架
			深度学习调用TensorFlow.PyTorch等框架 一.开发目标目标 提供统一接口的库,它可以从C++和Python中的多个框架中运行深度学习模型.欧米诺使研究人员能够在自己选择的框架内轻松建立模 ... 
- python_request 使用jsonpath取值结果,进行接口关联
			一.jsonpath的安装 pip install jsonpath 二.使用举例 import jsonpath d1={"token":"hjshdsjhdsj ... 
