buuctf_RE(第二页)

有点之前已经写过wp了,主要就写一下,该注意的点吧

xxor

主要考察的就是 XTEA

#include <stdio.h>

int main() {
	 __int64 a1[6];
	a1[5] = 0x84F30420;
	a1[1] = 0x20CAACF4;
	 __int64 a = 0x84A236FFLL, b = 0xFA6CB703LL, c = 0x42D731A8LL;
	a1[2] = (a + b + c) / 2;
	a1[3] = a1[2] - a;
	a1[0] = 0xDF48EF7E;
	a1[4] = a1[2] - c;
	for (int i = 0; i < 6; i++) {
		printf("%d ", a1[i]);
	}
	//__int64 a1[6] = { 3746099070, 550153460, 3774025685, 1548802262, 2652626477, 2230518816 };
	int a2[4] = { 2,2,3,4 };
	for (int j = 0; j <= 4; j += 2) {
		int v5 = 1166789954 * 64;
		unsigned int v3 = a1[j];
		unsigned int v4 = a1[j + 1];
		for (int i = 0; i <= 63; ++i)
		{
			v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
			v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
			v5 -= 1166789954;
		}
		a1[j] = v3;
		a1[j + 1] = v4;
	}
	for (int i = 0; i < 6; i++) {
		printf("%x", a1[i]);
	}
	printf("\n");
	for (int i = 0; i < 6; ++i) {
		printf("%c%c%c", *((char*)&a1[i] + 2), *((char*)&a1[i] + 1), *((char*)&a1[i]));
	}
	return 0;
}

要注意密文是 __int64, delta 是 int ,中间 v3,v4是 unsigned int
还有就是十六进制打印成字符。

for (int i = 0; i < 6; ++i) {
	printf("%c%c%c", *((char*)&a1[i] + 2), *((char*)&a1[i] + 1), *((char*)&a1[i]));
	//取a1第三,二,一字节(从低到高)
}

端序这个东西真是不太好理解

[羊城杯 2020]easyre

就是简单的 base64,打乱顺序,还有凯撒加密
打乱顺序哪里写脚本,卡了半天 0.0
···

import base64
# enc='EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
# l1=len(enc)
# enc=list(map(ord,enc))
# cipher=[0]*l1
# for i in range(l1):
#     tmp=enc[i]
#     if 47<tmp<=57:
#         enc[i]=(tmp-48-3)%10+48
#     elif 64<tmp<=90:
#         enc[i]=(tmp-65-3)%26+65
#     elif 96<tmp<=122:
#         enc[i]=(tmp-97-3)%26+97
#     else:
#         enc[i]=tmp
# for i in range(l1):
#     print(chr(enc[i]),end='')
# print()
# # for i in range(13):
# #     cipher.append(enc[13+i])
# # for i in range(13):
# #     cipher.append(enc[39+i])
# # for i in range(13):
# #     cipher.append(enc[i])
# # for i in range(13):
# #     cipher.append(enc[39+i])
# cipher.extend(enc[13:26])  # 取enc的第14到第26个字符,共13个字符
# cipher.extend(enc[39:52])  # 取enc的第40到第52个字符,共13个字符
# cipher.extend(enc[0:13])   # 取enc的前13个字符
# cipher.extend(enc[39:52])  # 取enc的第40到第52个字符,共13个字符
# cipher_str = ''.join(map(chr, cipher))
# print(cipher_str)
# # hhh=''
# # for i in range(l1):
# #     hhh+=chr(cipher[i])
# # print(hhh)
# enc='EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
# l1=len(enc)
# enc=list(map(ord, enc))
# cipher=[]
#
# # 解密过程
# for i in range(l1):
#     tmp = enc[i]
#     if 47 < tmp <= 57:  # 数字 '0'-'9'
#         enc[i] = (tmp - 48 - 3) % 10 + 48
#     elif 64 < tmp <= 90:  # 大写字母 'A'-'Z'
#         enc[i] = (tmp - 65 - 3) % 26 + 65
#     elif 96 < tmp <= 122:  # 小写字母 'a'-'z'
#         enc[i] = (tmp - 97 - 3) % 26 + 97
#     else:  # 其他字符保持不变
#         enc[i] = tmp
#
# # 生成cipher列表
# cipher.extend(enc[13:26])  # 取enc的第14到第26个字符,共13个字符
# cipher.extend(enc[39:52])  # 取enc的第40到第52个字符,共13个字符
# cipher.extend(enc[0:13])   # 取enc的前13个字符
# cipher.extend(enc[39:52])  # 取enc的第40到第52个字符,共13个字符
#
# # 将cipher列表转换为字符串并输出
# cipher_str = ''.join(map(chr, cipher))
# print(cipher_str)
#
# flag=base64.b64decode(cipher_str)
# print(flag)
import base64
data='EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
data1=''
for i in data:
	if ord(i)>=48 and ord(i)<=57:
		data1 += chr((ord(i)-3-48)%10+48)
	elif ord(i)>=65 and ord(i)<=90:
		data1 += chr((ord(i)-3-65)%26+65)
	elif ord(i)>=97 and ord(i)<=122:
		data1 += chr((ord(i)-3-97)%26+97)
	else:
		data1 += i
# strncpy(a3, a1 + 26, 0xDui64);
# strncpy(a3 + 13, a1, 0xDui64);
# strncpy(a3 + 26, a1 + 39, 0xDui64);
# strncpy(a3 + 39, a1 + 13, 0xDui64);
flag = data1[13:26] + data1[39:] + data1[:13] + data1[26:39]
print(base64.b64decode(flag).decode('utf-8'))

受不了了
还有一个比较好理解的

int main(){
    string flag = "BjYjM2Mjk4NzMR1dIVHs2NzJjY0MTEzM2VhMn0=zQ3NzhhMzhlOD";
    string flag1 = "";
    string flag2 = "";
    string flag3 = "";
    string flag4 = "";
    int cn = 0;
    for (int i = 13; i < 26; i++) {
        flag1 += flag[i];
    }
    for (int i = 39; i < flag.size(); i++) {
        flag2 += flag[i];
    }
    for (int i = 0; i < 13; i++) {
        flag3 += flag[i];
    }
    for (int i = 26; i < 26+13; i++) {
        flag4 += flag[i];
    }
    string ans = flag1+flag2+flag3+flag4;
    cout << ans << endl;
    return 0;
}

crackMe

在这里插入图片描述
还是忘记了
在这里插入图片描述
在这里插入图片描述
这个函数看似改变了 enc,但解密的时候没管,?
这个想到了可以通过动调来看
但确实改变了啊,0xA5–>0xD2 ?想不到了
在这里插入图片描述
动调把 S_Box 调出来,然后异或得到 password
还有一个问题就是 ida 和 dbg 调出来的值不一样?
最后写脚本:

data=[0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63]
print(''.join(list(map(chr,data))))
byte=[0x2A, 0xD7, 0x92, 0xE9, 0x53, 0xE2, 0xC4, 0xCD]
flag=[]
for i in range(len(data)):
    flag.append(data[i]^byte[i])
for i in range(len(flag)):
    print(hex(flag[i])[2:],end='')
# dbappsec
# 4eb5f3992391a1ae

[GUET-CTF2019]number_game

检查二维数组元素是否重复
在这里插入图片描述
在这里插入图片描述
那这怪多重复的啊
有几个函数中用到了递归
0.0
看了看 wp 大致明白了:
其实看到那个检查重复的就可以猜是数独了
那几个递归函数也是在给变量赋值
在这里插入图片描述
在这里插入图片描述

解完还不对,因为这是最后结果,是经过上面两个函数得到的,
而这两个函数是二叉树的遍历好像,还没学 0.0 先记着

[网鼎杯 2020 青龙组]jocker

在这里插入图片描述
要先修复,不能直接修smc,patch代码
选中call __Z7encryptPc这行指令,按alt+k,将新旧sp偏移值改成0;
call 是属于虚函数
通过ALT + P 来确认下变量起始地址,清除个数与保存个数是否正常(0.0)

在这里插入图片描述
上面那个看似正常的 call 也要改,然后再 f5 就没有报错了
然后解 smc
在这里插入图片描述
这个 jocker 真是,怎么说每次写都要遇到一些新问题,
我简单总结一下:
1,需要假flag过 wrong和omg函数
2,sp指针修复,要用到调用约定知识
3,smc修复,finally可能和encrypt连在一起,两个都被smc修改了
4,最后一部分flag,需要推测(猜)‘}’=c^x
也有在 smc 那里自解后 dump 出来,但我的太丑了,还是算了

[2019红帽杯]xx

撕,也是一道很令人头疼的题,代码也很长
看 wp 是知道了大致的流程,不过一些代码还是需要自己去理解,再看看。

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值