首页 > 其他分享 >2023NepCTF-RE部分题解

2023NepCTF-RE部分题解

时间:2023-08-14 22:16:21浏览次数:51  
标签:enc v1 题解 2023NepCTF value v0 RE key uint32

2023NepCTF-RE部分题解

九龙拉棺

过反调试

很容易发现

void __stdcall sub_401700() 

里面有tea的痕迹
接出来发现只是前半部分

#include <stdio.h>
#include <stdint.h>
#include"defs.h"
#include <stdio.h>

#include <stdio.h>  
#include <stdint.h>  

//加密函数  
void encrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0, i;           /* set up */
    uint32_t delta = 0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];   /* cache key */
    for (i = 0; i < 32; i++) {                       /* basic cycle start */
        sum += delta;
        v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
        v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
    }                                              /* end cycle */
    v[0] = v0; v[1] = v1;
}
//解密函数  
void decrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;//0xc6ef3720  /* set up */
    uint32_t delta = 0x61C88647;                     /* a key schedule constant */
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];   /* cache key */
    for (i = 0; i < 32; i++) {                         /* basic cycle start */
        v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
        v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
        sum += delta;
    }                                              /* end cycle */
    v[0] = v0; v[1] = v1;
}
int main() {


    uint32_t enc[17] = {
    0x88AFD2D6, 0x3FBE45A7, 0x27AAD1B9, 0x8CB3E51E, 0x09348FFA, 0xE19F3C42, 0xFFDD0D86, 0xEDB97383,
    0x12C4C0BF, 0x1B67BD19, 0xF7A514D6, 0x18F95254, 0xAB100CB0, 0x00CBA137, 0x02A91712, 0xC58D0D9E,0
    };
    int sum = 0;
    uint32_t v[2] = { 1,2 }, k[4] = { 1,2,3,4 };

    for (int i = 0; i < 16; i += 2)
    {
        decrypt(&enc[i], k);
    }
    puts((char*)enc);//NepCTF{c9cdnwdi3iu41m0pv3x7kllzu8pdq6mt9n2nwjdp6kat8ent4dhn5r158
    return 0;
}

卡在找后半段flag校验的地方很久,

这里其实有优先级
按创建顺序开始
tea后面的函数是根据密文直接校验的结果进行判断

慢慢看

void __usercall StartAddress(int a1@<ebp>)

里面

断点下在这,明显在内存看到MZ标识
这里使用idapython没把数据提取出来
纯shift+f12拉出来的

#include <stdio.h>
#include <stdint.h>
#include"defs.h"
#include <stdio.h>


//加密函数  
void encrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0, i;           /* set up */
    uint32_t delta = 0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];   /* cache key */
    for (i = 0; i < 32; i++) {                       /* basic cycle start */
        sum += delta;
        v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
        v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
    }                                              /* end cycle */
    v[0] = v0; v[1] = v1;
}
//解密函数  
void decrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;//0xc6ef3720  /* set up */
    uint32_t delta = 0x61C88647;                     /* a key schedule constant */
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];   /* cache key */
    for (i = 0; i < 32; i++) {                         /* basic cycle start */
        v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
        v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
        sum += delta;
    }                                              /* end cycle */
    v[0] = v0; v[1] = v1;
}
int main() {
    

    uint32_t enc[17] = {
   0 };

    enc[0] = 0x1DC74989;
    enc[1] = 0xD979AF77;
    enc[2] = 0x888D136D;
    enc[3] = 0x8E26DB7F;
    enc[4] = 0xC10C3CC9;
    enc[5] = 0xC3845D40;
    enc[6] = 0xC6E04459;
    enc[7] = 0xA2EBDF07;
    enc[8] = 0xD484388D;
    enc[9] = 0x12F956A2;
    enc[10] = 0x5ED7EE59;
    enc[11] = 0x43137F85;
    enc[12] = 0xEF43F9F0;
    enc[13] = 0xB29683AA;
    enc[14] = 0x8E3640B4;
    enc[15] = 0xc2d36177;
    int sum = 0;
    uint32_t v[2] = { 1,2 }, k[4] = { 18,52,86,120 };
    
    for (int i = 0; i < 16; i += 2)
    {
        decrypt(&enc[i],k);
    }
    puts((char*)enc);
    return 0;
}

后64位flag
拼凑一下

Review

这里有反调试,patch就好

需要对aes的key进行爆破,有2位根据相等位置生成,xxtea加密后,有个异常处理,里面进行~操作

from Crypto.Cipher import AES
from ctypes import *


def MX(z, y, total, key, p, e):
  temp1 = (z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value << 4)
  temp2 = (total.value ^ y.value) + (key[(p & 3) ^ e.value] ^ z.value)

  return c_uint32(temp1 ^ temp2)


def encrypt(n, v, key):
  delta = 0x9e3779b9
  rounds = 6 + 52 // n

  total = c_uint32(0)
  z = c_uint32(v[n - 1])
  e = c_uint32(0)

  while rounds > 0:
    total.value += delta
    e.value = (total.value >> 2) & 3
    for p in range(n - 1):
      y = c_uint32(v[p + 1])
      v[p] = c_uint32(v[p] + MX(z, y, total, key, p, e).value).value
      z.value = v[p]
    y = c_uint32(v[0])
    v[n - 1] = c_uint32(v[n - 1] + MX(z, y, total, key, n - 1, e).value).value
    z.value = v[n - 1]
    rounds -= 1

  return v


def decrypt(n, v, key):
  delta = 0x9e3779b9
  rounds = 6 + 52 // n

  total = c_uint32(rounds * delta)
  y = c_uint32(v[0])
  e = c_uint32(0)

  while rounds > 0:
    e.value = (total.value >> 2) & 3
    for p in range(n - 1, 0, -1):
      z = c_uint32(v[p - 1])
      v[p] = c_uint32((v[p] - MX(z, y, total, key, p, e).value)).value
      y.value = v[p]
    z = c_uint32(v[n - 1])
    v[0] = c_uint32(v[0] - MX(z, y, total, key, 0, e).value).value
    y.value = v[0]
    total.value -= delta
    rounds -= 1

  return v

Aeskey=[  0x19, 0x28, 0x6E, 0x04, 0x19, 0x28, 0x6E, 0x04, 0x46, 0x55,
  0xC8, 0x04, 0x46, 0x55, 0xC8, 0x04]

for i in range(47):
  v17=i+4
  Aeskey[3]=v17
  Aeskey[11]=v17
  enc = [0xF4, 0x9C, 0xDD, 0x41, 0x03, 0xDD, 0x5A, 0x13, 0x2E, 0x55, 0x97, 0x9E, 0xFF, 0xD5, 0x08, 0xD9, 0xF6, 0xD1,
         0x09, 0x8C, 0x68, 0x9E, 0x92, 0xFF, 0x75, 0x0F, 0x80, 0x95, 0x4B, 0x16, 0xB9, 0xC6, 0x7F, 0x54, 0x2E, 0x20,
         0x35, 0xFC, 0x1B, 0x46, 0x14, 0xAA, 0xDA, 0x5E, 0x4F, 0xBD, 0x59, 0x71]
  aes = AES.new(bytes(Aeskey), AES.MODE_ECB)  # 创建一个aes对象
  den_text = aes.decrypt(bytes(enc))  # 解密密文
  x=[i for i in den_text]
  for i in range(len(x)):
    x[i] = ~x[i]
    x[i]&=0xff

  enc1 = [int.from_bytes(x[i*4:i*4+4],'little') for i in range(12)]
  xxteakey = [0x00000019, 0x00000000, 0x0000006E, 0x00000003]
  m=decrypt(12,enc1,xxteakey)
  import libnum
  try:
    x=[libnum.n2s(i).decode()[::-1] for i in m]
    for i in x:
      print(i,end='')#NepCTF{tEA_with_AES_by_mixing_antiDebug_hahaHah}
  except :
    pass
# flag='NepCTF{'+'11112222'*5+'}'
# print(flag)
#NepCTF{1111222211112222111122221111222211112222}

待复现

标签:enc,v1,题解,2023NepCTF,value,v0,RE,key,uint32
From: https://www.cnblogs.com/maffy/p/17629888.html

相关文章

  • CodeForces-1798#B 题解
    正文开个数组\(last_k\)统计\(a_{i,j}\)最后买彩票的时间,再开一排桶\(day_t\)记录该天最后买彩票的有哪些人(即:有\(p\)满足\(last_p=t\)的集合)。将\(last_k\)放入\(day_t\)中,判断\(day_t\)中是否存在空桶,若有则无解(因为没有人在当天是最后买彩票的)。因为本题是......
  • 题解 CF379D New Year Letter
    思路提供一种比较容易想到的做法。拿到题看数据范围发现都很小,所以放心大胆地暴力。容易发现\(s_i\)中AC的个数等于\(s_{i-2}\)中AC的个数加\(s_{i-1}\)中AC的个数再加上两者拼接处可能有的一个AC。所以\(s_1\)和\(s_2\)从第二个字符到倒数第二个字符这之间......
  • asp.net core配置验证
    在开发asp.netcore时,通常会在appsettings.json中配置信息,这些信息都是以一个json的格式存储,在程序中通过Options的方式来绑定实体类使用,如下面的APIConfig和实体类。配置文件:{"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNet......
  • asp.net core配置验证
    在开发asp.netcore时,通常会在appsettings.json中配置信息,这些信息都是以一个json的格式存储,在程序中通过Options的方式来绑定实体类使用,如下面的APIConfig和实体类。配置文件:{"Logging":{"LogLevel":{"Default":"Information","Microsoft.As......
  • P4412 题解
    P4412题解传送门更好的阅读体验简化题意:一张无向图,给定一棵生成树,求最小的修改边权的代价使得这棵生成树是最小生成树,代价定义为修改前后一条边的边权变化量的绝对值。思路首先,发现让这棵树成为最小生成树不好直接处理,但是判定是否为最小生成树却相对更容易。判定的思路......
  • Paper Reading: A pareto-based ensemble of feature selection algorithms
    目录研究动机文章贡献相关概念集成特征选择帕累托最优非支配排序拥挤距离本文方法实验结果数据集和实验设置与FS方法比较与集成FS方法比较优点和创新点PaperReading是从个人角度进行的一些总结分享,受到个人关注点的侧重和实力所限,可能有理解不到位的地方。具体的细节还需要......
  • asp.net core配置验证
    在开发asp.netcore时,通常会在appsettings.json中配置信息,这些信息都是以一个json的格式存储,在程序中通过Options的方式来绑定实体类使用,如下面的APIConfig和实体类。配置文件:{"Logging":{"LogLevel":{"Default":"Information","Microsoft.As......
  • GCC options: compare -nostartfiles, -nodefaultlibs, -nolibc
    GNU不同编译选项的区别nostartfiles不使用启动文件,默认使用库nodefaultlibs不使用默认库,默认使用启动文件nostdlib不使用启动文件,不使用默认库nolibc不使用启动文件,不使用与系统库紧耦合的库-nostartfiles-nodefaultlibs-nolibc-nostdlib/usr/lib/Scrt1.o......
  • CF1845D Rating System 题解
    题面给定一个长度为\(n\)数列\(a\),保证每项都不为\(0\)。初始时\(x=0\),然后对于\(1\lei\len\),按顺序进行如下操作:如果\(x\gek\),则\(x\rightarrow\max(k,x+a_i)\),否则\(x\rightarrowx+a_i\)。你需要求出\(k\),使得\(x\)的值尽量大。题解如果我们不考虑\(k......
  • ASP.NET Core Identity 系列之四
    这节我们主要介绍ASP.NETCoreIdentity认证,认证是决定用户是否能够成功登录应用程序的一个过程,用户通过提供自己的用户名和密码来证明他们自己是真实用户,当登录成功时,Identity认证用户并且赋予访问ASP.NETCore应用程序安全资源1、ASP.NETCoreIdentity如何认证我们创建AS......