2022年HGAME中REVERSE的Flag Checker

99 篇文章 33 订阅

2022年HGAME中REVERSE的Flag Checker

照例下载附件:
在这里插入图片描述
.
.
APK 文件,运行不了,照例扔入 JEB 中查看代码:
在这里插入图片描述
.
.
既然是 RC4 加密,那么直接搬上解密代码,结果发现解码错误:
在这里插入图片描述
.
.
那就修改编码为 Unicode-escape 编码,正确代码如下:(相关编码细节可以查看另一篇博客

# -*- coding: utf-8 -*-
import base64

def get_message():
	print("输入你的信息: ")
	s=input()
	return s

def get_key():
	print("输入你的密钥: ")
	key=input()
	if key=='':
		key="不要输入空的 key 值"
	return key

def init_box(key):
	"""
	S盒
	"""
	s_box=list(range(256))	#我这里没管秘钥小于256的情况,小于256应该不断重复填充即可,这里完成了 C 实现中的 for(i=0;i<256;i++) prc4->s_box[i] = i;
	j=0
	for i in range(256):
		j=(j+s_box[i] + ord(key[i % len(key)])) % 256	#这里把 C 实现中的 prc4->t_box[i] = key[i % keylen];和j=(j+prc4->s_box[i]+prc4->t_box[i])%256;合并在了一起。
		s_box[i],s_box[j] = s_box[j],s_box[i]
	#print(type(s_box)) #可以输出 s_box 来看是否随机混乱的
	return s_box

def ex_encrypt(plain,box,mode):
	"""
    利用PRGA生成秘钥流并与密文字节异或,加解密同一个算法
    """
	if mode == '2':
		while True:
			c_mode=input("输入你的解密模式:base64 or ordinary\n")
			if c_mode == 'base64':
				plain=base64.b64decode(plain)
				plain=bytes.decode(plain,'unicode-escape')				#因为返回的是解码过的  bytes,所以需要再用 decode 解码成字符串。
				break
			elif c_mode == 'ordinary':
				break
			else:
				print("输入不合法,请重新输入")
				continue
	
	res=[]
	i=j=0
	for s in plain:						#与 C 实现无太大差异
		i=(i+1)%256
		j=(j+box[i])%256
		box[i],box[j]=box[j],box[i]
		t=(box[i]+box[j]) % 256
		k=box[t]
		res.append(chr(ord(s)^k))

	cipher="".join(res)
    #print(cipher)

#根据选择进行输出,至于是明文还是密文得看用户决定
	if mode == '1':
        # 化成可视字符需要编码
		print("加密后的输出(没经过任何编码)")
		print(cipher)
        # base64的目的也是为了变成可见字符
		print("base64后的编码")
		print(str(base64.b64encode(cipher.encode('utf-8')),'utf-8'))
	if mode == '2':
		print("解密后的密文")
		print(cipher)

def get_mode():
	print("请选择加密或者解密")
	print("1.Encrypt")
	print("2.Decrypt")

	mode = input()

	if mode == '1':			#加密解密虽同源,但是由于不能直接用 =='1' or '2',所以还是得分开写
		message = get_message()
		key = get_key()
		box = init_box(key)
		ex_encrypt(message,box,mode)
	elif mode == '2':			#由于异或运算的对合性,RC4加密解密使用同一套算法。
		message = get_message()
		key = get_key()
		box = init_box(key)
		ex_encrypt(message,box,mode)
	else:
		print("输入有误! ")

if __name__ == '__main__':
	while True:
		get_mode()

在这里插入图片描述
.
.
涉及编码问题的都比较麻烦,上面的代码有缺陷,不可以反向加密,所以可以直接选择用 byte 流的方式加密解密,就不用涉及编码了.
.
.
第一种,直接用 python 封装库,正向反向都可以:

from Crypto.Cipher import ARC4 as rc4cipher
import base64

def rc4_algorithm(encrypt_or_decrypt, data, key1):
    if encrypt_or_decrypt == "encrypt":
        key = bytes(key1, encoding='utf-8')
        enc = rc4cipher.new(key)
        res = enc.encrypt(data.encode('utf-8'))
        res=base64.b64encode(res)
        res = str(res,'utf8')
        return res
    elif encrypt_or_decrypt == "decrypt":
        data = base64.b64decode(data)
        #print(data)
        #print(str(data,'utf-8'))
        key = bytes(key1, encoding='utf-8')
        enc = rc4cipher.new(key)
        res = enc.decrypt(data)
        res = str(res,'utf8')
        return res


if __name__ == "__main__":
    data = 'hgame{weLC0ME_To-tHE_WORLD_oF-AnDr0|D}'
    key = 'carol'
    print(rc4_algorithm('encrypt',data,key))
    res ='mg6CITV6GEaFDTYnObFmENOAVjKcQmGncF90WhqvCFyhhsyqq1s='
    print(rc4_algorithm('decrypt', res, key))

在这里插入图片描述
.
.
第二种,C 语言版,base64 解码后直接生成 byte 字节,然后进行解密:

import base64
c="mg6CITV6GEaFDTYnObFmENOAVjKcQmGncF90WhqvCFyhhsyqq1s="
c=base64.b64decode(c)
arr=[]
for i in c:
    arr.append(ord(i))
print(arr)
#[154, 14, 130, 33, 53, 122, 24, 70, 133, 13, 54, 39, 57, 177, 102, 16, 211, 128, 86, 50, 156, 66, 97, 167, 112, 95, 116, 90, 26, 175, 8, 92, 161, 134, 204, 170, 171, 91]

#include<stdio.h>
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{
	int i = 0, j = 0;
	char k[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i < 256; i++) {
		s[i] = i;
		k[i] = key[i % Len_k];
	}
	for (i = 0; i < 256; i++) {
		j = (j + s[i] + k[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}
}
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
	unsigned char s[256];
	rc4_init(s, key, Len_k);
	int i = 0, j = 0, t = 0;
	unsigned long k = 0;
	unsigned char tmp;
	for (k = 0; k < Len_D; k++) {
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		Data[k] = Data[k] ^ s[t];
	}
}
void main()
{
	unsigned char key[] = "carol";
	unsigned long key_len = sizeof(key) - 1;
	unsigned char data[] = { 154, 14, 130, 33, 53, 122, 24, 70, 133, 13, 54, 39, 57, 177, 102, 16, 211, 128, 86, 50, 156, 66, 97, 167, 112, 95, 116, 90, 26, 175, 8, 92, 161, 134, 204, 170, 171, 91 };
	rc4_crypt(data, sizeof(data), key, key_len);
	for (int i = 0; i < sizeof(data); i++)
	{
		printf("%c", data[i]);
	}
	printf("\n");
	return;
}
//hgame{weLC0ME_To-tHE_WORLD_oF-AnDr0|D}

.
.
解毕!
敬礼!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值