HackThisSite realistic 6

这次任务是关于密文的破译

ToxiCo_Watch 这个家伙发现了 ToxiCo 化学工厂向附近的河流里排放化学废料,这个工厂的CEO 给生态督查主任 Samuel Smith 发了一个加密的邮件,这个邮件估计是有什么猫腻,然而这个加密算法涉及到了这个家伙知识的盲区,所以希望大家能帮忙破解发给他。

密文分析

这个是加密后的密文
由上图可以简单的得出这个是有字符 ‘.’ 和三位数组成的密文,其中还附上了加密算法.

看看这个加密

这个是加密表单,待加密的文字和加密密码

试着加密一个字符 ‘a’ 并且不带密码

第一加密
加密后发现这个密文是有三个两位数组成的,并且每个数前缀了一个 ‘.’,然后试着多加密几次看看是不是还是这个结果。
第二次加密
当我点了很多次之后,我发现每次加密的结果都不一样,因此我记录下几次加密的结果,来分析一下。

  1. 第一次结果 .59.48.-10
  2. 第二次结果 .33.47.17
  3. 第三次结果 .8.54.35
    观察一下这几次的结果,感觉发现了什么,我们把每次的结果以’.’ 分割求个和
/*
59 + 48 + (-10) = 97
33 + 47 + 17 = 97
8 + 54 + 35 = 97
哎,每次加密后求和的结果相等,都是 97,这里如果有经验的同学
能立马想到这个不就是ASCII码么。
a: 97, b: 98, c: 99
不带密码加密 b
16 + 5 + 77 = 98
不带密码加密 c
30 + 52 + 17 = 99
哎,这下就发现了这个秘密了
1. 每个字符加密后会得到由三个数字组成的一个密文
2. 每次生成的密文都是不同的,但将这个三个数字求和会得到这个字符的ascii码的值 
*/

但是啊,我们发现邮件密文是三位数字,而我们测试的字符加密后都是两位数字,这次我们带密码加密试试。

试着加密一个字符 ‘a’ 并且带密码 123456
/*
哎,这次加密结果就有感觉了,还是求和试试
.111.123.172 sum = 406
.163.138.105 sum = 406
啧,这个结果就不对了,为什么不是 ascii码值了呢。远远的超过了,想想看,既然不带密码加密
后求和是ascii值带了密码就不对了,咋搞!猜测一下这个密码本与ascii码值有关,那么密码是不
是也经过了ascii码值得处理呢。
密码中每个字符对应ascii码中的值 1:49,2:50,3:51,4:52,5:53,6:54, 什么都别管先加起来看
看 49+50+51+52+53+54 = 309, 哎发现了没有 309 + 97 = 406。哎!是不是找到了。
我换了不同的密码又测了几次,结果都是由密码字符和密文字符的ascii码值求和的结果。
*/

经过了一系列分析得出以下结论:

  1. 密码本 ASCII码表
  2. 密文由三个数字带 . 组成;
  3. 密码字符和密文字符的ascii码值求和值等于密文求和值。

啧!结论有了,那么直接撸代码吧,用自己熟悉的语言 C语言 开撸。
本人撸代码注释都是尽量用英文注释(不喜勿喷)。

代码的思路

将邮件密文复制到本地,通过文件读写来解析密文。

  1. 将密文一个字符一个字符的解析,每组密文求和结果放到链表中;
  2. 以26个小写字母为字典【因为邮件是英文,所以以26个小写字母为字典,其实也可以直接以生态督查主任的名字 Samuel Smith 为字典(这种方式我还没试过,大家可以试一下,破解密文就是靠合理猜测)】,与密文求和值相减的得到的值出现频率最高的那个就是密码了;
  3. 将密文求和的值和得到的密码值相减得到最后的解密结果。

解密后的邮件

#include<stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define DIGITS 3 /* each of them have three digits */
#define GROUPS 3 /* each of a set of three */
#define DOT '.' /* each of them start with a dot */

typedef struct node* ptr_node;
struct node {
    int data;
    int frequency;
    ptr_node next;
};
typedef ptr_node list;

ptr_node malloc_space();
void free_spaces(list lst);
void print_list(list lst);
void list_append(list lst, int data);
int get_password(list lst);
void decrypt(list lst, int passwd);

int main()
{
    FILE *fp = NULL;
    list lst_character, lst_password;
    char code, *digits;
    char letter[26] = {'a','b','c','d','e','f','g',
         'h','i','j','k','l','m','n',
         'o','p','q','r','s','t',
         'u','v','w','x','y','z'};
    int num_dot = 0,
        index,
        index_digits = 0,
        sum = 0,
        index_groups = 0,
        passwd;
    fp = fopen("encrypted", "r");
    if (fp == NULL)
        exit(0);
    lst_character = malloc_space();
    lst_password = malloc_space();
    digits = malloc(DIGITS);
    printf("format encrypt message...");
    while((code = fgetc(fp)) != EOF)
    {
        if (num_dot && isdigit(code))
            *(digits + index_digits++) = code;
        if (code == DOT)
            num_dot++;
        if (index_digits == DIGITS)
        {
            num_dot = index_digits = 0;
            sum += atoi(digits); /* cumulative three-digit integer*/
            index_groups++;
        }
        if (index_groups == GROUPS)
        {
           list_append(lst_character, sum); 
           for(index = 0; index < 26; index++)
               list_append(lst_password, sum - letter[index]);
           index_groups = sum = 0;
        }

    }
    printf("done.\n");
    passwd = get_password(lst_password);
    decrypt(lst_character, passwd);

    free_spaces(lst_character);
    free_spaces(lst_password);
    fclose(fp);
    
    return 0;
}


/*void free_spaces {{{*/
void free_spaces(list lst)
{
    ptr_node ptrnode;
    
    while(lst!= NULL) 
    {
        ptrnode = lst->next;
        free(lst);
        lst = ptrnode;
    }
}
/* }}} */

/*list malloc_space() {{{*/
ptr_node malloc_space()
{
    ptr_node ptrnode;

    ptrnode = (ptr_node)malloc(sizeof(struct node));
    if (ptrnode == NULL)
    {
        printf("out of space\n");
        exit(1);
    }
    return ptrnode;
}
/*}}}*/

/*void print_list(list lst) {{{*/
void print_list(list lst)
{
    printf("list: \n");
    lst = lst->next;
    while(lst!= NULL)
    {
        printf("%5d", lst->data);
        lst = lst->next;
    }
    printf("\n");
}
/*}}}*/

/*void list_append(list lst, int data) {{{*/
void list_append(list lst, int data)
{
    while(lst->next != NULL)
        lst = lst->next;

    lst->next = malloc_space();
    lst->next->data = data;
}
/*}}}*/

/* int get_password(list lst) {{{ */
int get_password(list lst)
{
    ptr_node first_head, second_head, passwd_node;
    list lst_frequency = malloc_space();
    printf("get encrypt password...");
    /* count the number of each letter */
    first_head = lst->next;
    while(first_head != NULL)
    {
        first_head->frequency = 0;
        second_head = lst->next;
        while(second_head != NULL)
        {
            if(first_head->data == second_head->data)
                first_head->frequency++;
            second_head = second_head->next;
        }
        first_head = first_head->next;
    }

    /* the most of frequent is the password */
    first_head = lst->next;
    passwd_node = first_head;
    while(first_head != NULL)
    {
        if (passwd_node->frequency < first_head->frequency)
            passwd_node = first_head;
        first_head = first_head->next;
    }
    printf("done.\n");
    return passwd_node->data;
}
/* }}} */

/* void decrypt(list lst, int passwd) {{{*/
void decrypt(list lst, int passwd)
{
    ptr_node head;
    head = lst->next;
    printf("decrypt...\n\n");
    printf("---------------------------------------\n\n");
    while(head != NULL)
    {
        printf("%c", head->data - passwd);
        head = head->next;
    }
    printf("\n\n---------------------------------------");
    printf("\n\ndecrypted.\n");
}
/* }}} */


将解密后的邮件发给 ToxiCo_Watch 就可以完成这次任务。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值