做了点简单的题目。
【春节】解题领红包之一
扫码关注即可。
【春节】解题领红包之二
查壳是 upx,ESP 定律法找到 OEP 脱壳。然后放进 ida 里:
HWND main_func()
{
HWND result; // eax
char *input; // esi
char *key; // edi
int enc_1; // [esp+0h] [ebp-14h]
int enc_2; // [esp+4h] [ebp-10h]
int enc_3; // [esp+8h] [ebp-Ch]
int enc_4; // [esp+Ch] [ebp-8h]
char v7; // [esp+10h] [ebp-4h]
result = GetDlgItem(0, 1000);
if ( result )
{
if ( GetWindowTextLengthA(result) == 16 )
{
input = (char *)malloc(0x11u);
key = (char *)malloc(0x11u);
*(_DWORD *)input = 0;
*((_DWORD *)input + 1) = 0;
*((_DWORD *)input + 2) = 0;
*((_DWORD *)input + 3) = 0;
input[16] = 0;
*(_DWORD *)key = 0;
*((_DWORD *)key + 1) = 0;
*((_DWORD *)key + 2) = 0;
*((_DWORD *)key + 3) = 0;
key[16] = 0;
GetDlgItemTextA(0, 1000, input, 17);
enc_3 = 'udhY';
enc_1 = 'ssdH';
enc_2 = 'zhNb';
enc_4 = '9102';
v7 = 0;
encrypt((const char *)&enc_1, (int)key, 3);
if ( !strcmp(key, input) )
result = (HWND)MessageBoxA(0, aOye, Caption, 0);
else
result = (HWND)MessageBoxA(0, aAuey, Caption, 0);
}
else
{
result = (HWND)MessageBoxA(0, &Text, Caption, 0);
}
}
return result;
}
看下来应该就是把 16 位的 enc
加密了一下,然后和 input
比较。看看 encrypt()
函数:
signed int __cdecl encrypt(const char *enc, int key, int num_3)
{
const char *enc_0; // edx
unsigned int length; // kr04_4
int v5; // esi
int i; // edi
char c; // al
char alphabet[29]; // [esp+Bh] [ebp-1Dh]
char tmp; // [esp+30h] [ebp+8h]
strcpy(&alphabet[1], "abcdefghijklmnopqrstuvwxyz");
if ( !key )
return -1;
enc_0 = enc;
if ( !enc )
return -1;
if ( num_3 <= 0 )
return -1;
length = strlen(enc) + 1;
if ( (signed int)(length - 1) <= 0 )
return -1;
v5 = key - (_DWORD)enc;
tmp = alphabet[num_3 + 1];
i = length - 1;
do
{
c = *enc_0;
if ( *enc_0 < tmp || c > 122 )
{
if ( c >= 97 && c <= alphabet[num_3] )
c = c - num_3 + 26;
}
else
{
c -= num_3;
}
(enc_0++)[v5] = c;
--i;
}
while ( i );
return 0;
}
就是对字符串判断是否为字母,然后根据字母表 alphabet
做映射和加减。正向实现一下脚本就得到口令了:
#!/usr/bin/env python
enc = ('9102' + 'udhY' + 'zhNb' + 'ssdH')[::-1]
print enc
alpha = 'abcdefghijklmnopqrstuvwxyz'
num = 3
t = alpha[num + 1]
i = len(enc)
j = 0
res = ''
while i != 0:
c = enc[j]
if ord(c) < ord(t) or ord(c) > 122:
if ord(c) >= 97 and ord(c) <= ord(alpha[num]):
c = chr(ord(c) - num + 26)
if ord(c) > ord(alpha[-1]):
c = chr(ord(c) - 26)
else:
c = chr(ord(c) - num)
res += c
j += 1
i -= 1
print res
# HappyNewYear2019
【春节】解题领红包之三
这道题我查了壳然后不会脱就一直没做。看了 writeup 居然是直接进 ida 就分析了。搜索到 main 函数:
int main_main()
{
int v0; // ST04_4
_DWORD *v1; // ST04_4
_DWORD *v2; // ST04_4
int v3; // ST04_4
_DWORD *v4; // ST04_4
int v5; // ST10_4
int v6; // ST14_4
int base64_check; // ST18_4
int v8; // ST04_4
int result; // eax
char v10; // ST0C_1
int v11; // [esp+0h] [ebp-7Ch]
int v12; // [esp+4h] [ebp-78h]
int v13; // [esp+4h] [ebp-78h]
int v14; // [esp+8h] [ebp-74h]
int v15; // [esp+Ch] [ebp-70h]
int v16; // [esp+Ch] [ebp-70h]
int v17; // [esp+Ch] [ebp-70h]
char v18; // [esp+Ch] [ebp-70h]
int v19; // [esp+10h] [ebp-6Ch]
int v20; // [esp+10h] [ebp-6Ch]
int v21; // [esp+10h] [ebp-6Ch]
int v22; // [esp+14h] [ebp-68h]
int v23; // [esp+14h] [ebp-68h]
int v24; // [esp+14h] [ebp-68h]
int v25; // [esp+14h] [ebp-68h]
unsigned int v26; // [esp+18h] [ebp-64h]
int v27; // [esp+18h] [ebp-64h]
int v28; // [esp+1Ch] [ebp-60h]
int v29; // [esp+1Ch] [ebp-60h]
int v30; // [esp+20h] [ebp-5Ch]
int aes_check; // [esp+24h] [ebp-58h]
int v32; // [esp+28h] [ebp-54h]
int v33; // [esp+2Ch] [ebp-50h]
int v34; // [esp+2Ch] [ebp-50h]
_DWORD *v35; // [esp+30h] [ebp-4Ch]
_DWORD *v36; // [esp+34h] [ebp-48h]
_DWORD *v37; // [esp+38h] [ebp-44h]
int *v38; // [esp+3Ch] [ebp-40h]
int v39; // [esp+40h] [ebp-3Ch]
int *v40; // [esp+44h] [ebp-38h]
void *v41; // [esp+48h] [ebp-34h]
int *v42; // [esp+4Ch] [ebp-30h]
void *v43; // [esp+50h] [ebp-2Ch]
int *key; // [esp+54h] [ebp-28h]
_DWORD *v45; // [esp+58h] [ebp-24h]
int *v46; // [esp+5Ch] [ebp-20h]
void *v47; // [esp+60h] [ebp-1Ch]
int *uid; // [esp+64h] [ebp-18h]
_DWORD *v49; // [esp+68h] [ebp-14h]
int *v50; // [esp+6Ch] [ebp-10h]
void *v51; // [esp+70h] [ebp-Ch]
int *v52; // [esp+74h] [ebp-8h]
void *v53; // [esp+78h] [ebp-4h]
void *retaddr; // [esp+7Ch] [ebp+0h]
if ( (unsigned int)&retaddr <= *(_DWORD *)(*(_DWORD *)__readfsdword(0x14u) + 8) )
runtime_morestack_noctxt();
v52 = dword_4A04E0;
v53 = &main_statictmp_0;
fmt_Println(&v52, 1, 1);
runtime_newobject(dword_4A04E0, v0);
v36 = v1;
runtime_newobject(dword_4A04E0, v1);
v37 = v2;
v50 = dword_4A04E0;
v51 = &main_statictmp_1;
fmt_Print(&v50, 1, 1);
uid = dword_498EE0;
v49 = v36;
fmt_Scanln(&uid, 1, 1); // input uid
v46 = dword_4A04E0;
v47 = &main_statictmp_2;
fmt_Print(&v46, 1, 1);
key = dword_498EE0;
v45 = v37;
fmt_Scanln(&key, 1, 1); // input key
runtime_newobject(dword_4A90C0, v3);
v35 = v4;
*v4 = 0x67452301;
v4[1] = 0xEFCDAB89;
v4[2] = 0x98BADCFE;
v4[3] = 0x10325476;
v4[4] = 0xC3D2E1F0;
v4[21] = 0;
v4[22] = 0;
v4[23] = 0;
runtime_stringtoslicebyte(0, *v36, v36[1]);
crypto_sha1___digest__Write(v35, v15, v19, v22, v19, v22);
crypto_sha1___digest__Sum(v35, 0, 0, 0, v5, v6);// get uid's sha1 digest
if ( v26 < 0x10 )
runtime_panicslice(
v11,
v12,
v14,
v16,
v20,
v23,
v26,
v28,
v30,
aes_check,
v32,
v33,
v35,
v36,
v37,
v38,
v39,
v40,
v41,
v42,
v43,
key,
v45,
v46,
v47,
uid,
v49,
v50,
v51,
v52,
v53);
v34 = v20;
encoding_base64___Encoding__DecodeString(encoding_base64_StdEncoding, *v37, v37[1], v16, v20, v23, v26);
if ( base64_check )
{
v42 = dword_4A04E0;
v43 = &main_statictmp_3;
result = fmt_Println(&v42, 1, 1);
}
else
{
main_AesDecrypt(v17, v21, v24, v34, 16, 16, 0, v28);
if ( aes_check )
{
v40 = dword_4A04E0;
v41 = &main_statictmp_4;
result = fmt_Println(&v40, 1, 1);
}
else
{
if ( v29 == 26 && (runtime_memequal(v27, MEMORY[0x4B8A80], 26, v18), v10) )
fmt_Printf(aSuccess, 73, 0, 0, 0, v25, v27, 26);
else
fmt_Printf(&aFailed, 24, 0, 0, 0, v25, v27, v29);
runtime_newobject(dword_4A04E0, v13);
v38 = dword_498EE0;
v39 = v8;
result = fmt_Scanln(&v38, 1, 1);
}
}
return result;
}
大概看了一遍之后,可以推测,先分别输入 uid 和 key,然后先进行 base64 解密(如果解密失败则报错),然后用 uid 的 sha1 摘要作为 key 来进行 aes 解密(如果解密失败则报错),最后和数据段中一串长度为 26 的字符串比较。具体字符串我们可以 dump 出来:
data = [0x48, 0x61, 0x70, 0x70, 0x79, 0x4E, 0x65, 0x77, 0x59, 0x65, 0x61, 0x72, 0x46, 0x72, 0x6F, 0x6D, 0x35, 0x32, 0x50, 0x6F, 0x4A, 0x69, 0x65, 0x2E, 0x43, 0x6E, 0x4C, 0x69, 0x6E, 0x65, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x4E, 0x65, 0x77, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69]
output = ''
for i in range(26):
output += chr(data[i])
print output
# HappyNewYearFrom52PoJie.Cn
可以使用 IDA 进行动态调试来验证 AES 的密钥。先输入 uid 和一个可以被成功解码的 base64 字符串,然后在 AES 函数中设下断点,可以看到密钥即为 uid 的 sha1 摘要:
调试中可以从内存里 dump 得到 3f2481363378f23964b9977ab8bad974de108eee
其实这一串数据就是 uid 对应的 sha1 散列值,取前 16 位作为 AES 的密钥。 AES 加密方式为 CBC
(main_AesDecrypt()
函数中可以直接看出),补码方式为 PKCS5Padding
(AES 解密错误时,会退出程序,但是有异常信息一闪而过,给报错函数下断点即可查看异常信息)。只需要把密钥转化成字节数组,使用 AES/CBC/PKCS5Padding
方式加密 HappyNewYearFrom52PoJie.Cn
,最后进行 base64 加密就可得到口令。go 语言实现代码:
package main
import (
"fmt"
"bytes"
"crypto/cipher"
"crypto/sha1"
"crypto/aes"
"encoding/base64"
)
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
func AesEncrypt(origData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = PKCS5Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
func AesDecrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(crypted))
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
return origData, nil
}
func main() {
uid := "975446"
h := sha1.New()
h.Write([]byte(uid))
bs := h.Sum(nil)
var aeskey = bs[0:16]
fmt.Println("AES Key: ", aeskey)
pass := []byte("HappyNewYearFrom52PoJie.Cn")
xpass, err := AesEncrypt(pass, aeskey)
if err != nil {
fmt.Println(err)
return
}
pass64 := base64.StdEncoding.EncodeToString(xpass)
fmt.Printf("Ciphertext: %v\n",pass64)
bytesPass, err := base64.StdEncoding.DecodeString(pass64)
if err != nil {
fmt.Println(err)
return
}
tpass, err := AesDecrypt(bytesPass, aeskey)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Plaintext: %s\n", tpass)
}
【春节】解题领红包之番外篇
番外篇个人感觉应该算是一道 ctf 里的 misc 题了。压缩包里给了一个大部分文字被加密的 md 文件:
# ȐĆŅƃȓƇńƃȒċƝÞɌÇńßɌĉŇƅŕƇŃbȒȼȵßȒĆȵƁȓĉnƁɌćǸß
ƦćƝƁȓĉnƅȓčƞÞɌćÑbȒČŃbȒċÑbŕƇŃþȒČNƃȒĈÑƄȓĊÑƄŕƇņÞȓčƞÞɌćÑbȒċƝÞŘcǸÞȐĆŅBƦĊȵþřÇȵƅȐċŇbɌcńþȓČŇƁŕƇNƀȒČŃBɌćÑBɌċnƄȓĈƝbŗƇƞÞŗčnBŕƇnþȒȻŃBȓĉnƅȒČNƅȒƈŇþŕčȠßŕƇŃƃřčȠbřċȵƀ
ȐčNƄŕƇņƃɌcŅƄɌċnþŕƇŇƁȓƇńƁŕƇńþɌcńƄŕƇńþɌCňƀƦȻƝƃŕƇńþɌCňƀȐĉņþŗcŅƅȒĈÑƄȓĊǸƅȓĈȵþɌćƞßŕƇņÞȒȻŃþɌCňƀɌćǸbȒȼǹßȓĈƝB
[ƦĉņƃŖċŅþŕƇŅƀȒCŅƀȒƈŇþɌcŅƄɌĉŇßŕƇņÞȓčƞÞȒƈňþŕƇńþȓĉnþȓČŇBŗcŅƅɌćƞƁȓćŅƁŕƇņÞȒȻŃþɌCňƁ](//rcnb.xyz)
řĊÑbȒĉȠƀɌćÑbȒċƝÞȓćŅƁɌƈȠƃŕƇŃþȒȻŃþȒĈƞÞȑÇǹƄɌCȠƄƦȻŇƅɌćƞBȐčnÞŗÇÑBřĊÑbɌĆnþŗÇǹb
ȐȼŃßɌćÑbŕƇņÞȒȻŃƄŕƇņÞɌcńþȒCŅbŕȻ
ŘĈÑƀƝƄŘȻŖĊǸƀrcnƃňßɍĉƞƀRČņbRÇrcnbrcnbrcnbŖĊƝƃrcnbrcnbrcnbrČNþȓĉƞƁnƅŔƇńÞrćǹƁȓĆÑƅŔȼŕÇƞƅƞßȐCŅƁȐƇŖĆňƁɌƇȵƃȑĈȠƃNƃƦčƝƄȓĉŕČňƃŇbȐĆȑćnƅŘȼȵßƞßRĆǸƄɌCƞBȑĊŅÞŗĊɌȼŃßŇƁŔcŔƈǹÞȠƁɌĆńƅɍĉƝÞŖÇɌcŇƅŖĆnþńƁȓČňƄŘȻȓȻnƃǸƁɌCȒćȵƁȵƄɌCŅƅȐčŃƀřCřƇŇƁǸþřÇƞbƦČnbRCƝßȐćǹƁŔȻřȻņBǹBȑċŗÇƞƃȠBɌĆÑƃŕčņƃȓƇńbŖčÑbɌĊŗƈÑBRcƞƁȑƇńÞƦČǹƀǸƀŘcŘȻnƅRCņƃŅƄȐĉNÞŘĈÑƄŕčȐćǹbŇÞȓćǹßɌĈŔȻňƀƝbȐÇrCǹÞȓȻŃBńƄɍċńbɌČŗƇnƅȵƀŗċņßRCŇbřČřćÑƀȐĊŃbǸƅɍcȑCȵbǸßȑƇȑCǹƅŘȻŃƃřċŃþnƄRċǹBrƇńƃŖĈȑĉņbƞƅƦĆrCƝÞƦĆÑBņƄrćȑƇÑƅńƄƦƇŗĆnƀŔĆȠƄȐćNƀÑƅƦȼȓĉŇƄȵßȑCǹƄȐȼŗćȠƃŅBȓCȠƁŔċƝßřcŘčŅbƦĊƝƃɌċƞƀnƁŘȻÑbŖčŗCnþȒȻÑƅNþřȼrƈNƁŕĆƝBȐÇňƅȐCŃßŅƄrćƞƀȓĊńƃŖƇǸƁřċŘćŃƁŘȼÑƅȑċȵƀŃþrƇŃßŕĉrćNþȒȻƝƁɌƈȠbƦĊNƅŔCƝßȓČńÞƦċŇbŖƈņƃŖĉȵþnƃɍĉɌƈňÞřčǹBȠbŕĉřċńþņƄȑÇƞƁȒcŘĉǸƅňƃȒcŔĈńßǹƁƦćȓȼǹƁÑƁƦCȑċŇƄȓƈnƄȵƄrcŘčnƃȵßRčȑcNƁrĊNƅȐÇŇƁņƁȒčnƀɌČňbɌĆrȼƞÞŇƃɌCřÇnþňƅȒȼƝBȑcȐȻnBňƁȑċȓcȠbǹþȑƇǹƁrĈŖƈňƁŗcȵbňþřȼƦĈŃƅňßŗcŃƀƦĊŔcńÞŖĉȠƅŃƁȑĊȐÇȠþƞÞɌƇȵƅȐȼɍĉÑBrƇŇƅŔčƞßnƅŗĈɍĆȵƅŖČņbŖĆȠÞȒċÑƃŗċNƃŕȻŃÞNÞŔčŕĆƞƃNƃRČȐĆņƁŃƀřċŃbȓčƝƃȑcŔĆNþȑčȠbŗĆNþŇƁȓčrčŃƄȑĉnþŅþȓȻřcÑƄŖƇÑßȐĆńbŅbŕĊŃßŕČŇÞȒcÑƁȑĆŘÇńƃRƈǸƅŕcȠbņÞȑċRƈŇƀȐcňþńÞƦĈɍCȠƀÑBRĉǸƁŗȼȑƇnƁȵßŕƇŖċƞƅřƇǹþŇƄŖÇȠƃRĈǸƅŕƇņþŔĊřƈňbƝßrƈŕÇǸþŃÞȐĆnbȑĉȑȻǸƃǹƀRƇrƈNbnƄrċrĉŅBƦcňþRċňƁnBŗȼÑƁŕċƞßɍĈŗćņƀǹƁȑĈŅþŔƇňƅŗƇrĊǹƄǸßȒƈǹßŕȻȠBŔćƝþŔȻÑBȓĆǸÞȑċŕĉŃþŃƀŘcřȻÑBŅƀɌƈńƄŔĊÑÞƦĈƞƃȓȼņƁŘȻnƄŔćŖċǸƄŅBŖÇȓĉŅBňƄȐȼŖÇņbǹƅrȻÑÞŔČŅßŔĊNþɌƇȠÞRĉnþřčŕċNþȠþƦȼȠƅRĆÑƄŗćŘčŃƄŖÇÑƄǹbȑĆŖÇǹþƞƄȓcƞƁRCǸƄɍćȒČNƅȓȻňÞņBRĆƞbřƇŖcȠbřȻńƄŗĆŃÞŃBƦĉŗĊNþřĊņßȒĆȠƁȑĊŅBȐƈȵBǹƁřcrĉƞbnƀƦċŘȼÑƀȒÇńƁŗCȠƁƝßrĊǹþŗȻŃƀȒȻɍċNßŖĉǸßŃÞrƇȒȼȠƃřƇŃƃNbŘċƦČňƅŔČnBŗČƞbƞßŔȼŔĊȠƀnƅŖċŕčŇƄǹBŔCřċǹƅȐČňƀƝƀřĈŖČȵßńÞɌCǹƃŔćȓċÑþŕȼƝƄȒcńbǹbȓƈƝƅɌĆȠƄŖćǹBŖƈŘÇƝƅƦĉŃƁŃßŖĉNƃŔĉÑƄŖĈƞþȑČȑČnBŃƁŔČnƃȒĈȓĈNBǸßȐCȠßȐčŅbɍĉƞþƦĉrȻŅBŇßȒȻǸƁŘȼŘċńBňbŘčnƄŘÇȒƈŇƅǹÞřćȐćŅÞƦċŇƄŇbɌƇƦƇńƀňƁrČRČņbȑÇŅßȵƅřȼŖĆǸƀŔCƝƀņÞȓƇrĊŇþňbŕÇŃƄŔƈńÞŘČȐĊƝbřȻǹƃɌČȠBńƄȒƇNþřĊɌćņBŕȼȠƃŖƇňþÑßȓȼȑČÑƅnƄɍĉnÞŗcŘƈňßȓĉȵƄȑcNbȠßƦÇŅƃɍĈƦĊnƁŖÇŅBŔcŃƁńƁɌċňÞŕĉƦCņƅƦȻȵƅȓÇǹƃȓĆȠƃRȻňƃřćǸƀŗƈǹßřĉňbȐČńƁɍĈŇÞÑÞŘćŗÇNbŗȻÑÞRƈǸƃǹƀŕȻRĉƞBńþŘȻŔĆƝƁņBŕȻNBRĉņƃȓČƝƁȐċÑƀRČŕƈňƀrčŇƅȐĊŅÞƦȼǹƁňƃȓĊnþřĈŘCnþȠƀȒcƞƃɌćɌĊȵƅŕƇňƃnƄŔčńÞRČřȼńbŇßŕĊňþŘCǹbŔĈnbŕĊńþȑcŃƄŔĈŔčńbȐčȠBřĉŅƃņƃŘƈɌÇÑÞŇƄȓĉɍċňƅńþŗCřČƝƄRCņÞƝƁŔĈRȼNƅȒCnƃɌƇǹßńÞŕƈŇBŘCŕȼÑBȒÇŃÞǸƁȓȼŕČȠþȵƁȑƈńƀŔcȑƇÑßrƈǸÞrcŃÞŇƅȓćɌćńƀɍćňƀȠƅŘȼǸƁɍĊřčƞÞņƃrĊǸƀŗcȓƈńƀŇƀȐcrĊŅBȓĈȠƁɍćnƁnÞɌƇÑƃȐȼƞßŔCɍćƞbƝBȒcņƁrċnBŗƈȓȻńƃɌCÑBƞƀȒČňßŔƇřƇǹbŖcņƃŕĆňþŕČņƅȒĉŇƅȐĈŇƁȠƃRĉŔƇǸþŘĊȵßŔȼńbȑƈȠBǹBɌčȵƃrčǹƄŔȻƞƅŗȼȒĆƞƀŖĉȵbŕcƝÞȒȼńBrċǸƅŘcȠÞȐčƝbȓĊŅbŘCȠƀɍĆȠƅŕĉNƀȠÞŖćřċńƁńþȓĉȠƁƦȻnƀȓÇɍĈŅƅǸƀȓčȒȻņƀǹÞɍcȑĆȵƃrȻƝƀɌCŃþɍĈȵþŖČņßňƅŗĉÑÞŕƈȑcŃƁǸßȒƇȐÇƞßńbŕƈȵBŕƇnƄȓċȑȼȠBɍċŅÞŗċŅƃƦčńƄňÞRÇrcŅƄȐÇȠÞřčȠÞƞBɌȼɍĈŇþɍĉÑƅǸBrĆňƃŖȻŕčȵbņßŘĊƞƀȐƈnþŘčȓȻÑÞŕcńþņbŔȼɌČÑBɌčȵbȑĈŅBŕĉƞƄÑþȒÇȓȻNƀÑßŘĈÑƀȐȼƝBŔĈȵþɍĊÑßŕĉȒȼnþŕÇņbńþɍĆŅÞŗĊŃƃRċņƅŘcNþȑĆŅƁrƈǸƄȒCƝþŖȻrÇŇbřĊŅƅȑƈŃBƦċnßňƅƦĉÑþȓĈřȼŃƀɍcŃƄȵþɌCřĆNƄǹƄƦȻŔčŅƃnƅrċrCǸƄȓƈŃƀrÇnƁrCÑƅrCȵƀrƈǹßrƈȵƁRĆƞƁrÇŇÞȵßƦČȑȼǸƁǹBȑcɌƈƝÞȒĆŅÞrĆňƃRćŇƁȠƅȓcrc
这里给了一个网站,上面可以解密,得到明文 md 文件:
# Prove your Niubility
Hello there, Welcome to the 52PoJiE Spring Festival 2019 Challenge - RCNB.
To prove you are as NB as RC, complete this trial!
[It's dangerous to go alone, take this!](//rcnb.xyz)
And the key: Which_is_N0t_Th3_Answ3r
With the trial:
7z��'�G�'�l×v����2!���!$�x�Z�ˤ�XЂY�=��W�K�ï�z���������r�$]�I��q�Ib��iԎ�2C���Z�`�3��EW�w3X�� ��*2� ']�Kz�,<` ��5�&�
QT�~�z�rq+�I�1����r?�R���Y�5X�<rA���U��[���G��^*�O- GP���l��
��.:�7�3��:*J(v��]��,�h����nOˁ��X�&�6�=Z\����g�h�y6I��nNJ�)�&���yCE��A��#�
8��ȍr'�M\?o:��W��Va�)����D��.�5V��Gi��A��)�,~� H¬?���&��V�����~*;�P|�(
\$�e00"�� 荈{�����8�]�-1��_Z��G=�)oPd�
�)���w;����8zOi��|&���]à�'�C�q�����SD>��!��b��*� |�F�
-�'����-�ڷ��� 畢{�ٙ�� �ti��E��ޕ;��
���['��Yl�י*b����G�1�B�����~�:�و����Aenqd�)ü#�EG-:�S/�ACb*[�V�H�l=Vg�-
�۴�b7&���ihCz��KLE0��)��H 咣 BT�0(k����m�"�`��b�ĥq�<IU�1������\��[� k��%���"ɡ� 菽 a8��H��gb��Q J��ZLL�� �*�\$�|�ɡ����R�E�wu��t7#)S�\�����;{l�W�����I�*Y��}��GN�p�k\*�?�2�@�S�}���33���v ���/���^Ӈ��!�R�N��F��5[�2�bvX ��ߍ�E؞%���d��� ��T�@��dy��r��B� ��?aHx�����"�g���� 呴^+��|t$}�x�C.���bp �X�lU|��&��}(���O�eq8s=店 �C�#^�c�Q��>�8��^���֙���b6&��i�5FT�m$5�|�X�tA���s��}��.h���Y��r�}�(�,�<W���V�����`�V08K�� -V�CV��}�~d��� 0�y��
q����wWxZe��#q"�״�=�%��h�!��_�������#��ᷫDA8^kJqɊ�=E�{%�m>��k� p
\$�
SL˓`��]y
b
v
��
最后面给出的 trial 看开头显然是个 7z,那上面的 key 应该就是密码了。我把它存为一个新文件,然而这个字符�
严重干扰了我好几个小时,让懵逼的我一度以为这是题目设计的加密。一开始我 xxd
了一下文件,发现有三个字节 efbfbd
频繁出现 505 次:
根据 7z 文件头 377a bcaf 271c 0004
尝试过替换,一度以为掉进了脑洞的陷阱。直到我看到这篇文章,才知道这串字节就是那个字符。
后来在 github 上找到了 rcnb 的源码,修改 js,将明文每个字节以 int 的形式输出,再用 python 一跑拿到压缩包:
function printRes(str) {
var res = rcnb.decode(str);
for (var i = 0; i < res.length; i++) {
console.log(res[i]);
}
// console.log(res)
}
printRes("ŘĈÑƀƝƄŘȻŖĊǸƀrcnƃňßɍĉƞƀRČņbRÇrcnbrcnbrcnbŖĊƝƃrcnbrcnbrcnbrČNþȓĉƞƁnƅŔƇńÞrćǹƁȓĆÑƅŔȼŕÇƞƅƞßȐCŅƁȐƇŖĆňƁɌƇȵƃȑĈȠƃNƃƦčƝƄȓĉŕČňƃŇbȐĆȑćnƅŘȼȵßƞßRĆǸƄɌCƞBȑĊŅÞŗĊɌȼŃßŇƁŔcŔƈǹÞȠƁɌĆńƅɍĉƝÞŖÇɌcŇƅŖĆnþńƁȓČňƄŘȻȓȻnƃǸƁɌCȒćȵƁȵƄɌCŅƅȐčŃƀřCřƇŇƁǸþřÇƞbƦČnbRCƝßȐćǹƁŔȻřȻņBǹBȑċŗÇƞƃȠBɌĆÑƃŕčņƃȓƇńbŖčÑbɌĊŗƈÑBRcƞƁȑƇńÞƦČǹƀǸƀŘcŘȻnƅRCņƃŅƄȐĉNÞŘĈÑƄŕčȐćǹbŇÞȓćǹßɌĈŔȻňƀƝbȐÇrCǹÞȓȻŃBńƄɍċńbɌČŗƇnƅȵƀŗċņßRCŇbřČřćÑƀȐĊŃbǸƅɍcȑCȵbǸßȑƇȑCǹƅŘȻŃƃřċŃþnƄRċǹBrƇńƃŖĈȑĉņbƞƅƦĆrCƝÞƦĆÑBņƄrćȑƇÑƅńƄƦƇŗĆnƀŔĆȠƄȐćNƀÑƅƦȼȓĉŇƄȵßȑCǹƄȐȼŗćȠƃŅBȓCȠƁŔċƝßřcŘčŅbƦĊƝƃɌċƞƀnƁŘȻÑbŖčŗCnþȒȻÑƅNþřȼrƈNƁŕĆƝBȐÇňƅȐCŃßŅƄrćƞƀȓĊńƃŖƇǸƁřċŘćŃƁŘȼÑƅȑċȵƀŃþrƇŃßŕĉrćNþȒȻƝƁɌƈȠbƦĊNƅŔCƝßȓČńÞƦċŇbŖƈņƃŖĉȵþnƃɍĉɌƈňÞřčǹBȠbŕĉřċńþņƄȑÇƞƁȒcŘĉǸƅňƃȒcŔĈńßǹƁƦćȓȼǹƁÑƁƦCȑċŇƄȓƈnƄȵƄrcŘčnƃȵßRčȑcNƁrĊNƅȐÇŇƁņƁȒčnƀɌČňbɌĆrȼƞÞŇƃɌCřÇnþňƅȒȼƝBȑcȐȻnBňƁȑċȓcȠbǹþȑƇǹƁrĈŖƈňƁŗcȵbňþřȼƦĈŃƅňßŗcŃƀƦĊŔcńÞŖĉȠƅŃƁȑĊȐÇȠþƞÞɌƇȵƅȐȼɍĉÑBrƇŇƅŔčƞßnƅŗĈɍĆȵƅŖČņbŖĆȠÞȒċÑƃŗċNƃŕȻŃÞNÞŔčŕĆƞƃNƃRČȐĆņƁŃƀřċŃbȓčƝƃȑcŔĆNþȑčȠbŗĆNþŇƁȓčrčŃƄȑĉnþŅþȓȻřcÑƄŖƇÑßȐĆńbŅbŕĊŃßŕČŇÞȒcÑƁȑĆŘÇńƃRƈǸƅŕcȠbņÞȑċRƈŇƀȐcňþńÞƦĈɍCȠƀÑBRĉǸƁŗȼȑƇnƁȵßŕƇŖċƞƅřƇǹþŇƄŖÇȠƃRĈǸƅŕƇņþŔĊřƈňbƝßrƈŕÇǸþŃÞȐĆnbȑĉȑȻǸƃǹƀRƇrƈNbnƄrċrĉŅBƦcňþRċňƁnBŗȼÑƁŕċƞßɍĈŗćņƀǹƁȑĈŅþŔƇňƅŗƇrĊǹƄǸßȒƈǹßŕȻȠBŔćƝþŔȻÑBȓĆǸÞȑċŕĉŃþŃƀŘcřȻÑBŅƀɌƈńƄŔĊÑÞƦĈƞƃȓȼņƁŘȻnƄŔćŖċǸƄŅBŖÇȓĉŅBňƄȐȼŖÇņbǹƅrȻÑÞŔČŅßŔĊNþɌƇȠÞRĉnþřčŕċNþȠþƦȼȠƅRĆÑƄŗćŘčŃƄŖÇÑƄǹbȑĆŖÇǹþƞƄȓcƞƁRCǸƄɍćȒČNƅȓȻňÞņBRĆƞbřƇŖcȠbřȻńƄŗĆŃÞŃBƦĉŗĊNþřĊņßȒĆȠƁȑĊŅBȐƈȵBǹƁřcrĉƞbnƀƦċŘȼÑƀȒÇńƁŗCȠƁƝßrĊǹþŗȻŃƀȒȻɍċNßŖĉǸßŃÞrƇȒȼȠƃřƇŃƃNbŘċƦČňƅŔČnBŗČƞbƞßŔȼŔĊȠƀnƅŖċŕčŇƄǹBŔCřċǹƅȐČňƀƝƀřĈŖČȵßńÞɌCǹƃŔćȓċÑþŕȼƝƄȒcńbǹbȓƈƝƅɌĆȠƄŖćǹBŖƈŘÇƝƅƦĉŃƁŃßŖĉNƃŔĉÑƄŖĈƞþȑČȑČnBŃƁŔČnƃȒĈȓĈNBǸßȐCȠßȐčŅbɍĉƞþƦĉrȻŅBŇßȒȻǸƁŘȼŘċńBňbŘčnƄŘÇȒƈŇƅǹÞřćȐćŅÞƦċŇƄŇbɌƇƦƇńƀňƁrČRČņbȑÇŅßȵƅřȼŖĆǸƀŔCƝƀņÞȓƇrĊŇþňbŕÇŃƄŔƈńÞŘČȐĊƝbřȻǹƃɌČȠBńƄȒƇNþřĊɌćņBŕȼȠƃŖƇňþÑßȓȼȑČÑƅnƄɍĉnÞŗcŘƈňßȓĉȵƄȑcNbȠßƦÇŅƃɍĈƦĊnƁŖÇŅBŔcŃƁńƁɌċňÞŕĉƦCņƅƦȻȵƅȓÇǹƃȓĆȠƃRȻňƃřćǸƀŗƈǹßřĉňbȐČńƁɍĈŇÞÑÞŘćŗÇNbŗȻÑÞRƈǸƃǹƀŕȻRĉƞBńþŘȻŔĆƝƁņBŕȻNBRĉņƃȓČƝƁȐċÑƀRČŕƈňƀrčŇƅȐĊŅÞƦȼǹƁňƃȓĊnþřĈŘCnþȠƀȒcƞƃɌćɌĊȵƅŕƇňƃnƄŔčńÞRČřȼńbŇßŕĊňþŘCǹbŔĈnbŕĊńþȑcŃƄŔĈŔčńbȐčȠBřĉŅƃņƃŘƈɌÇÑÞŇƄȓĉɍċňƅńþŗCřČƝƄRCņÞƝƁŔĈRȼNƅȒCnƃɌƇǹßńÞŕƈŇBŘCŕȼÑBȒÇŃÞǸƁȓȼŕČȠþȵƁȑƈńƀŔcȑƇÑßrƈǸÞrcŃÞŇƅȓćɌćńƀɍćňƀȠƅŘȼǸƁɍĊřčƞÞņƃrĊǸƀŗcȓƈńƀŇƀȐcrĊŅBȓĈȠƁɍćnƁnÞɌƇÑƃȐȼƞßŔCɍćƞbƝBȒcņƁrċnBŗƈȓȻńƃɌCÑBƞƀȒČňßŔƇřƇǹbŖcņƃŕĆňþŕČņƅȒĉŇƅȐĈŇƁȠƃRĉŔƇǸþŘĊȵßŔȼńbȑƈȠBǹBɌčȵƃrčǹƄŔȻƞƅŗȼȒĆƞƀŖĉȵbŕcƝÞȒȼńBrċǸƅŘcȠÞȐčƝbȓĊŅbŘCȠƀɍĆȠƅŕĉNƀȠÞŖćřċńƁńþȓĉȠƁƦȻnƀȓÇɍĈŅƅǸƀȓčȒȻņƀǹÞɍcȑĆȵƃrȻƝƀɌCŃþɍĈȵþŖČņßňƅŗĉÑÞŕƈȑcŃƁǸßȒƇȐÇƞßńbŕƈȵBŕƇnƄȓċȑȼȠBɍċŅÞŗċŅƃƦčńƄňÞRÇrcŅƄȐÇȠÞřčȠÞƞBɌȼɍĈŇþɍĉÑƅǸBrĆňƃŖȻŕčȵbņßŘĊƞƀȐƈnþŘčȓȻÑÞŕcńþņbŔȼɌČÑBɌčȵbȑĈŅBŕĉƞƄÑþȒÇȓȻNƀÑßŘĈÑƀȐȼƝBŔĈȵþɍĊÑßŕĉȒȼnþŕÇņbńþɍĆŅÞŗĊŃƃRċņƅŘcNþȑĆŅƁrƈǸƄȒCƝþŖȻrÇŇbřĊŅƅȑƈŃBƦċnßňƅƦĉÑþȓĈřȼŃƀɍcŃƄȵþɌCřĆNƄǹƄƦȻŔčŅƃnƅrċrCǸƄȓƈŃƀrÇnƁrCÑƅrCȵƀrƈǹßrƈȵƁRĆƞƁrÇŇÞȵßƦČȑȼǸƁǹBȑcɌƈƝÞȒĆŅÞrĆňƃRćŇƁȠƅȓcrc");
#!/usr/bin/env python
f = open('plain_array.txt', 'rb')
t = f.read()
f.close()
data = t.split('\n')[:-1]
print len(data)
# print data
f = open('trial.7z', 'wb')
for i in range(len(data)):
f.write(chr(int(data[i])))
f.close()
解压后拿到一个新文件 nb
,还是被加密了的:
ȐȼŃƁȓĉnƅŕƇŅƀȓƇŃƅȒċƝþŕƇNƄɌćŃÞɌCȵBȒČNƄɌCňƀɌćÑbȒCŅÞŕƇŇƁȓƇńƁŕƇŅƅȒCņbȒċƝÞȒƈƝƀȒČnƁɌćŃÞȓƈȠƅȓƇNþɌcńBȓĊǸƁȒȼȵbȒƈnbɌCȵßȒȼȠÞȓĉNƁŗćƝƅRćŇbƞƅRȻÑßŘȻŇƁrĊńßŕčȠþRĉNƁƦĈņBƦcǹÞƦćŃbƦĈNƁƦĈȒćƝÞnƅŔĆņÞrȼȒćƝþǸßRĊńþrȻNþrČńßŕčǸÞRĊȵÞrȼȵbŕƇŇÞrĊnÞŔĆnBŘÇƝƃrĉǹþƦćņƅƦcȵƀƦćņBƦcǹÞƦćŃbƦĈNƁƦĈȒćƝÞnƃŔĆǸþRĊƝƃrĉňÞƦĉřƇƞþȵƅrȼņbrCnƃŔĆņßRćńßrȻńßŕčŃBRĊƞƅřȻƞƀřƇǹþƦćȵÞřƈƞþřȻŅþƦcǸƁřȻņƄƦcƞÞřȻŇbřƇǹÞƦćNþƦĈƞƄřȻņƀƦcǸƁřȻņƄƦcƞßřȻņƁƦcǹþƦćņƄƦcƞƄřȻņBƦcǹÞƦćŃbƦĈȵƀƦćȒćƝÞŃƄŔCƞÞřȻŅþƦcňÞƦĉřƇƞþȵƅrȼņbrCŃƄŔCƞßřȻŅÞƦcǹÞƦćȵƄřƈȵƀƦćŅÞƦcňÞƦĉȵƁřƈŅßřƇȒćƝþŃBRĊƞßřȻņƀƦcňÞƦĉȵƄřƈƞÞřȻņƀƦcǹÞƦćNþƦĈƞƅřȻņƀƦcňÞƦĉȵƄřƈƞþřȻŇbřƇǸƁřȻņƄƦcƞÞřȻŇbřƇǹÞƦćNþƦĈƞƄřȻņƀƦcǸƁřȻņƄƦcƞƄřȻȒćƝÞnƃŔĆǸþRĊŇƅrĊŃBrČŃƃŔċńþrȻŅbrċǹÞƦćȵÞřƈȓčnÞnƅrćǸƃŔćÑþŘȻȠBŘĊȵƅŕċRćņßƝƃŔƇȵƅrƇŅÞƦcǹÞƦćȵƁřƈȓčnƄNþřĆŃƃŔċÑƀrÇƞƀřƇǹþƦćņƄƦcƞƅřȻņƁƦcňÞƦĉņƄƦcňßƦcņƀƦcǸßřȻȵƃřƈňßƦcŇBřƇǸƄřȻņƄƦcȵƀƦćȒćƝÞǸbŔćňÞRČNƅŘCǹÞƦćŃbƦĈňÞƦcƞƀřƇǸƄřȻȒĉŅBǹÞrčȠbrčŅÞŔcÑƃRCȵbŕƇnƅrćŃƄŔCƞßřȻŅÞƦcňÞƦĉȵƁřƈƞƄřȻŇbřƇňÞƦĉȵƁřƈŅßřƇŇBřƇǸƁřȻņƄƦcƞßřȻƞƀřƇǹþƦćȵÞřƈÑbřȻřČȵßǸÞRĊǸþRĊǹÞrčȠbrčǸbŔćņþRćȠƃŘĊŃƄrČŃBRĊƞƅřȻņƀƦcǸƁřȻņƄƦcƞƅřȻƞƀřƇǹÞƦćȵƀřƈNƁƦĈƞƀřƇňÞƦĉȵƄřƈƞþřȻŇbřƇǸƁřȻņƄƦcƞƄřȻņBƦcǸßřȻȵþřƈȵƀƦćȒćƝƄȵƅŔȻNƅRĉǸƅŘCņbrCȠBŔĆŅßřƇřČȵƁȵƅŔȻńþrȻƝƃrĉǸƃřȻȵÞřƈNƁƦĈņBƦcňÞƦĉȵƁřƈŇbƦĆŅÞƦcǹþƦćņƅƦcȵƀƦćŇBřƇǸƅřȻȵþřƈƞßřȻņƀƦcǸƄřȻȵƄřƈȵƀƦćņƀƦcǹÞƦćŃbƦĈNƁƦĈņƁƦcǹÞƦćNþƦĈƞßřȻřČȵƅnƃŔĆƝƃrƈǹƀŕĉŇÞrĊnƃŔĆȵƁrȼņbŔcŃƃrČǸbŔćņßRćÑƀrƇǸßřȻņƄƦcƦȼŇƅnßrćǹbRĊŅbrȻǹÞŕĊňÞƦĉřƇÑbǸþŕĉńƅŕčƞƀRȻÑBRCƝBrƈŃbřĆŃÞŖĊnƀŘÇǹƀŕĉŇƄrĊƝƃŔƇȵƄrȼŃƀrČņBrCȠþRĉňßƦcřċÑƅRĆŇþŖƇŃÞǹƅƦćȒĉŅBȵƁrȼňßŕċȠßŔčƞßřȻņƁƦcǹÞƦćřƇƞþǹÞrčņbrCnƃŔĆÑƃRCȵbŕƇņbrCnÞŔĆnBŘÇŇƅrĊŃƄrČŃBRĊƞƅřȻņƀƦcǸƃřȻȵßřƈƞßřȻƞƀřƇǸƁřȻņƄƦcƞÞřȻŇbřƇǹÞƦćNþƦĈƞƄřȻņƀƦcǸƁřȻņƄƦcƞßřȻƞƀřƇǹÞƦćȵÞřƈƞƄřȻŇBřƇǸƅřȻȵþřƈƞƅřȻȒćƝƅŃÞŖĊnBŘÇŅbrȻȠBrčǸÞRĊǸßRĊŅßŔcŃƁřĆǹbRĊȵßrȼƞbŘČŇþrĊǸÞRĊÑBRCǹƄrčńƅŕčŃƄŔCƞßřȻņƁƦcǹÞƦćȵÞřƈȓČŃƅƝƅƦcNþƦĈňßƦcņBƦcǹßƦćńßřƇňßƦcņƀƦcǸƅřȻřčȠbŅþƦcǹƅƦćȵƄřƈƞÞřȻƞƀřƇ
然后一层层解密拿到 key:
Well done! It seems that you have great programming skills.
ȐȼŃßɌCȵƃȒȼȵbȒƈnbɌÇńßɌĈȠƃȒȻŃBȓƈȠƃȒȼȵbȒČŃBɌCňƀȒĊŇßɌcńþȓČŇƁŕƇņÞȒȻŃƄŕƇŅƅȓƇŃƃȒȼȠbȒCņƁɌCňƀȒCŅƀȒĉȠƀɌćÑbɌcŅƄɌĉņƄȒȻńƄɌĉŇÞŕƇņÞȒȻŃƄŕƇŃbȒČŃƄŕƇńBȒČnƁȓȼǸß
ŗĆnƀȒćnþŕƇnþȓƇńƅɌƇƝƄřĈƝßŗƇȠbȓčȵbȒȼƞþŗcŅƅȑĉȠƁȒCŅƀɌćŃÞɌćÑßŕƇŅþȓČňBɌČŅƅȓĊǸƄɌcńƄŕƇńþȒĆȵþɌĉŇÞŕƇŃƃřčȠbřċȵƀȓCÑBřćŃBŖČȵƃɌćǸƀȓƈȠßŘčŅƄŗĉȠƄȒȼȵƅȒȻŅBȒĆƝƃȒĈÑƄȓĊņBřƇNƁɌƇƞbɌCƝßȐĉņþƦȻƝƃŗĈńƀɌCƝB
;) ȐcňÞŗcŅƅȒCŅƀȒĉȠƀȒȻŃƄɌcńƄŖċŅþŕƇņÞȒȻŃƄŕƇŅþȒČŃßŘčńbƦȻŇƅɌČÑþɌƈǹƃɌĉŅßȒCŅƅȒČnBƦȻƝƃȑÇƝƄŘCNƁȐĉņþ
Well done! It seems that you have great programming skills.
Wishing you happiness during the holidays and throughout the New Year!
- by Coxxs@52PoJiE, [Want to know more about RCNB.js?](https://github.com/Coxxs/RCNB.js)
;) Oh, and here's the key: N0w_y0u_are_NB_A5_RC
感谢的话
最后感谢吾爱破解大佬们的辛勤付出!
参考网站
https://github.com/Coxxs/RCNB.js
https://travis-ci.com/Coxxs/RCNB.js
https://liudanking.com/golang/utf-8_replacement_character/
https://www.52pojie.cn/thread-873265-1-1.html
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!