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}

待复现

2023NepCTF-RE部分题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. 2022-10-16:以下go语言代码输出什么?A:timed out;B:panic;C:没有任何输出。 package main import ( “context“ “fmt“

    2022-10-16:以下go语言代码输出什么?A:timed out:B:panic:C:没有任何输出. package main import ( "context" &quo ...

  2. 2021-02-01:Redis 集群会有写操作丢失吗?

    福哥答案2021-02-01: 以下情况可能导致写操作丢失:1.过期 key 被清理.2.最大内存不足,导致 Redis 自动清理部分 key 以节省空间.3.主库故障后自动重启,从库自动同步.4.单 ...

  3. 2021-08-08:自由之路。电子游戏“辐射4”中,任务“通向自由”要求玩家到达名为“Freedom Trail Ring”的金属表盘,并使用表盘拼写特定关键词才能开门。给定一个字符串 ring,表

    2021-08-08:自由之路.电子游戏"辐射4"中,任务"通向自由"要求玩家到达名为"Freedom Trail Ring"的金属表盘,并 ...

  4. 二次封装Element UI Table实现动态列

    开发中是否会遇见在一个页面中加载的table的列是不固定的,列名需要根据后台数据而动态加载:so element ui 的table 已经不再满足需求,我们得在他的基础上再次封装 增加 refacto ...

  5. 搭建自动化 Web 页面性能检测系统 —— 设计篇

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值.. 本文作者:琉易 liuxianyu.cn 页面性能对于用户体验.用 ...

  6. 代码随想录算法训练营Day44 动态规划

    代码随想录算法训练营 代码随想录算法训练营Day44 动态规划|完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ 完全背包 有N件物品和一个最多能背重量为W的背包.第i件物品的重量是weig ...

  7. karyoploteR: 基因组数据可视化 R 包

    karyoploteR,是一个适用于所有基因组数据(any data on any genome)非圆环布局(non-circular layouts)的可视化 R/Bioconductor 包.开发 ...

  8. 驱动开发:内核扫描SSDT挂钩状态

    在笔者上一篇文章<驱动开发:内核实现SSDT挂钩与摘钩>中介绍了如何对SSDT函数进行Hook挂钩与摘钩的,本章将继续实现一个新功能,如何检测SSDT函数是否挂钩,要实现检测挂钩状态有两种 ...

  9. 6 种方式读取 Springboot 的配置,老鸟都这么玩(原理+实战)

    大家好,我是小富- 从配置文件中获取属性应该是SpringBoot开发中最为常用的功能之一,但就是这么常用的功能,仍然有很多开发者在这个方面踩坑. 我整理了几种获取配置属性的方式,目的不仅是要让大家学 ...

  10. AB实验:科学归因与增长的利器

    第一章 AB实验的基本原理和应用 AB实验的相关概念: 3个基本参数:实验参与单元.实验控制参数.实验指标 2个核心价值:验证因果关系.量化策略效果 2个关键特性:先验性.并行性 基本流程:分流 -& ...