当前位置:网站首页>[CTF. Show. Reverse] reverse AK race easydse
[CTF. Show. Reverse] reverse AK race easydse
2022-04-21 08:42:00 【Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi】
After opening, the program is relatively simple , But looking at it carefully, it's still very difficult . Once wanted to see exp 了 , I haven't found it for a long time . Only a little bit . Watch it after you finish , It's not hard to find . What's the matter .
int __cdecl main(int argc, const char **argv, const char **envp)
{
char C[34]; // [rsp+20h] [rbp-60h] BYREF
int key_pre[64]; // [rsp+50h] [rbp-30h] BYREF
int m[128]; // [rsp+150h] [rbp+D0h] BYREF
int dest[16][48]; // [rsp+350h] [rbp+2D0h] BYREF
int i; // [rsp+F5Ch] [rbp+EDCh]
_main();
while ( 1 ) // Input 32 byte flag(16 Hexadecimal Numbers + Lowercase letters ) Press 16 Hexadecimal bits are saved in the first place
{
while ( getstr(m) )
;
getkey(key_pre);
exchangeIP(key, key_pre, PC_1, 56);
getroundkey((int *)dest, key); // Key generation dest
exchangeIP(mint, m, IP_first, 64); // The first half flag Change the order according to the table
encode(mint, dest); // The first half uses dest encryption
exchangeIP(m, mint, IP_last, 64); // The first half of the second 2 Secondary exchange
exchangeIP(mint, &m[64], IP_first, 64); // Second half 1 Secondary exchange
encode(mint, dest); // The second half is encrypted
exchangeIP(&m[64], mint, IP_last, 64); // Second half 2 Secondary exchange
for ( i = 0; i <= 127; i += 4 )
C[i / 4] = hex_re(&m[i]);
C[32] = 0;
puts(C);
if ( !strcmp(flag, C) )
break;
puts("flag is incorrect!");
}
puts("congratulation!!!");
getchar();
return 0;
}
Add a comment to each function , Basically understand .
Input flag yes 16 Hexadecimal characters ( Letter lowercase ) And turn it into 4 position 2 Base storage ( High in the former ), front 16 Bytes and after 16 Bytes are encrypted separately .
Before encryption, the matrix is generated by the key 8*65 byte . After the original key is converted into a digit group , First use PC_1 Rotation , Proceed again 16 Move the wheel left and use PC_2 The rotation of . This one doesn't have to be reversed , Just do it in the original order .
void __cdecl exchangeIP(int *d, int *s, int *IP_0, int n)
{
int i; // [rsp+Ch] [rbp-4h]
for ( i = 0; i < n; ++i )
d[i] = s[IP_0[i] - 1];
}
void *__cdecl getroundkey(int *dest, int *k)
{
int n; // [rsp+3Ch] [rbp-4h]
for ( n = 0; n <= 15; ++n )
{
shiftL(k, move_time[n]); // The first half cycle moves left , The second half of the cycle moves left
shiftL(k + 28, move_time[n]);
exchangeIP(&dest[48 * n], k, PC_2, 48);
}
return dest;
}
For each plaintext, use IP_first Rotate , Re encryption , And then use IP_last Rotation
The encryption process is 16 round encode_ground encryption , After each encryption, the left and right halves are exchanged .
encode_ground encryption : Generate the key with the second half and XOR the first half . This is the loophole , Because the back is not encrypted , Even though 16 The wheel has changed beyond recognition , But it's still possible to go back round by round .
replaceS Put each of the keys 6 Bit look-up table to 4 position
encode_ground This one doesn't have to be reversed , Copy directly .
void __cdecl encode(int *mint, int (*dest)[48])
{
int temp; // [rsp+24h] [rbp-Ch]
int j; // [rsp+28h] [rbp-8h]
int i; // [rsp+2Ch] [rbp-4h]
for ( i = 0; i <= 15; ++i )
{
encode_ground(mint, &(*dest)[48 * i]);
for ( j = 0; j <= 31; ++j )
{
temp = mint[j];
mint[j] = mint[j + 32];
mint[j + 32] = temp;
}
}
}
void __cdecl encode_ground(int *m, int *k)
{
int ec[32]; // [rsp+20h] [rbp-60h] BYREF
int temp[48]; // [rsp+A0h] [rbp+20h] BYREF
int i_1; // [rsp+164h] [rbp+E4h]
int i_0; // [rsp+168h] [rbp+E8h]
int i; // [rsp+16Ch] [rbp+ECh]
exchangeIP(temp, m + 32, E, 48);
for ( i = 0; i <= 47; ++i )
temp[i] ^= k[i];
for ( i_0 = 0; i_0 <= 47; i_0 += 6 )
replaceS(&ec[4 * (i_0 / 6)], &temp[i_0], i_0 / 6);
exchangeIP(temp, ec, P, 32);
for ( i_1 = 0; i_1 <= 31; ++i_1 )
m[i_1] ^= temp[i_1];
}
void __cdecl replaceS(int *dest, int *source, int n)
{
int i; // [rsp+8h] [rbp-8h]
int temp; // [rsp+Ch] [rbp-4h]
temp = S_Box[n][32 * *source + 16 * source[5] + 8 * source[1] + 4 * source[2] + 2 * source[3] + source[4]];
for ( i = 3; i >= 0; --i )
{
dest[i] = temp % 2;
temp /= 2;
}
}
The overall process is to do it step by step from the back to the front , But there's too much data involved , The steps are really troublesome . Yes 108 That's ok .
# Take data out of the file
def u32(v):
return v[0] | v[1]<<8 | v[2]<<16 | v[3]<<24
def get_val(s, p, n):
return [u32(data[p+i*4: p+i*4+4]) for i in range(n)]
data = open('DS.exe', 'rb').read()
move_time = get_val(data, 0x3880, 16)
IP_first = get_val(data, 0x38c0, 64)
IP_last = get_val(data, 0x39c0, 64)
PC_1 = get_val(data, 0x3ac0, 56)
PC_2 = get_val(data, 0x3bc0, 48)
E = get_val(data, 0x3c80, 48)
P = get_val(data, 0x3d40, 32)
S_Box = get_val(data, 0x3dc0, 8*65)
S_Box = [S_Box[i*65:i*65+65] for i in range(8)]
def getkey(key):
v = [0]*4*len(key)
for i in range(len(key)):
t = int(key[i], 16)
v[i*4+3] = t&1
v[i*4+2] = (t>>1)&1
v[i*4+1] = (t>>2)&1
v[i*4+0] = (t>>3)&1
return v
def r_getkey(c):
print(c, len(c))
v = [0]*(len(c)//4)
for i in range(len(c)//4):
v[i] = (c[i*4+0]<<3) + (c[i*4+1]<<2) + (c[i*4+2]<<1) + c[i*4+3]
return v
def getarr(t):
return [(t>>3)&1, (t>>2)&1, (t>>1)&1, t&1]
def exchangeIP(m,k,n):
#print(m,k,n)
return [m[k[i]-1] for i in range(n)]
def r_exchangeIP(s, ip, n):
t = [0]*n
for i in range(n):
t[ip[i]-1] = s[i]
return t
def replaceS(s,n):
temp = S_Box[n][32 * s[0] + 16 * s[5] + 8 * s[1] + 4 * s[2] + 2 * s[3] + s[4]]
d = [0,0,0,0]
for i in range(3,-1,-1):
d[i] = temp %2
temp //=2
return d
# Encrypt the first half with the second half , The second half is reserved
# Dispose of the second half and untie the first half
def encode_ground(m, k):
temp = exchangeIP(m[32:], E, 48)
for i in range(48):
temp[i] ^=k[i]
ec = []
for i in range(0,48,6):
ec += replaceS(temp[i:i+6], i//6)
temp = exchangeIP(ec, P, 32)
for i in range(32):
m[i] ^= temp[i]
return m
def r_encode(m):
for i in range(15,-1,-1):
m = m[32:]+m[:32]
m = encode_ground(m, dest[48*i:48*i+48])
return m
def getroundkey(k):
dest = []
for i in range(16):
k = k[move_time[i]:28]+k[:move_time[i]] + k[move_time[i]+28:] + k[28:28+move_time[i]]
#print(''.join([str(i) for i in k]))
dest += exchangeIP(k, PC_2, 48)
return dest
key = "aabb09182736ccdd"
c = 'c358ab3ca5fd6757b39c12a82cab8b8d'
#dest Initialize key
key_pre = getkey(key)
key = exchangeIP(key_pre, PC_1, 56)
dest = getroundkey(key)
m = getkey(c)
m1,m2 = m[:64],m[64:]
m1 = r_exchangeIP(m1, IP_last, 64)
m1 = r_encode(m1)
m1 = r_exchangeIP(m1, IP_first, 64)
m2 = r_exchangeIP(m2, IP_last, 64)
m2 = r_encode(m2)
m2 = r_exchangeIP(m2, IP_first, 64)
m = r_getkey(m1+m2)
print(m)
for i in m:
print(hex(i)[2:], end='')
#123456abcd132536aabb09182736ccdd
#flag{123456abcd132536aabb09182736ccdd}
版权声明
本文为[Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210841116115.html
边栏推荐
- Leetcode0824. 山羊拉丁文(simple,字符串处理)
- L2-026 小字辈 (25 分)
- 渗透实战-无回显Rce-thinkphp5-Getshell
- Workerman给Timer定时器里的方法传参数
- 曾经有望挑战苹果的魅族,如今靠为苹果用户提供配件而生存
- 内网渗透-代理穿透-提权-注入-msf-中间件-域渗透-日志清除-学习资源
- Static insertion and dynamic traversal of linked list
- 渗透实战-挖掘某学校站点漏洞(APP漏洞)
- sql 一般模糊查询语句,查询表T , 表T2的SEQ是条件,请问模糊查询 如何 能够匹配表T2的SEQ多个字符?
- idea连接SqlServer报错
猜你喜欢

6. 堪比JMeter的.Net压测工具 - Crank 实战篇 - 收集诊断跟踪信息与如何分析瓶颈

2022茶艺师(初级)考题及在线模拟考试
![[GYCTF2020]Blacklist](/img/23/14236d426700925f2da86119b2e4f7.png)
[GYCTF2020]Blacklist

多线程小抄集(新编二)

Count the number of linked lists and look up linked lists

Comprehensive case: pinyougou project (pinyougou project process, SEO optimization, TDK three labels and codes) will be gradually optimized in the later stage

Insert a new node after the linked list node

渗透测试-获取系统FOFA关键字来刷洞

神经网络学习之Opencv使用记录

初识UI自动化(inspect.exe + uiautomation)
随机推荐
[ctf.show.reverse] 逆向AK赛 EasyDSE
Analysis of VoIP technology of network telephone
TX2 install ROS melody opencv3 4.5 ceres1. 14.0 Eigen3. 3.9 gtsam cv_ bridge
实战渗透-fofa-dirBrute-代码审计-构造poc-ueditor-解密-过waf-Godzilla
Overview of VoIP technology development and its relationship with outbound call system
Static insertion and dynamic traversal of linked list
[ctf.show.reverse] 月饼杯 re1_西北望乡、re2_归心、re3_若无月
2022年上海市安全员C证考试模拟100题及模拟考试
Common file types and content type of Apache Tika
sql 一般模糊查询语句,查询表T , 表T2的SEQ是条件,请问模糊查询 如何 能够匹配表T2的SEQ多个字符?
电网企标B接口接入记录(一):注册
JVM——》常用参数
方格分割【dfs】
[nodejs] nodejs basic learning (II) - module mechanism
规划自己的健康问题
js或jq怎么操作单选框,设置选中某个值
Signalr console as server
The problem of reading configuration file in feign request interceptor
Insert a new node before the linked list node
Apache Tika 常用的文件类型与content-type