序:最近学习信息安全技术的习题,发现了一个很有意思的题,怎么个有意思,是因为他把一个死循环,硬是写成了信息安全漏洞,好啦,废话不多说了

0x0 题目

拿到一堆电子书,其中有“2019年上半年信息安全工程师真题(下午案例分析试题与答案”,其中一个题目是这样的
算法学习:那些奇形怪状的软考题之搞笑系列_第1张图片
算法学习:那些奇形怪状的软考题之搞笑系列_第2张图片
算法学习:那些奇形怪状的软考题之搞笑系列

他的答案是这样的:
算法学习:那些奇形怪状的软考题之搞笑系列

0x1 复现

鄙人菜鸟一个,代码敲得不好勿喷:

#include 
#include 
#include 
#include 
#pragma warning(disable:4996)
#define PASSWORD "1234567"

int verify_password(char* password)
{
    int authenticated;
    char buffer[8];
    authenticated = strcmp(password,PASSWORD);
    strcpy(buffer, password);
    return authenticated;

}

int main(int argc,char* argv[])
{
    int valid_flag = 0;
    char password[13];
    while (1)
    {
        printf("please input password:\n");
        scanf("%s",password);
        printf("%s", password);
        valid_flag = verify_password(password);//验证口令
        if (valid_flag)//口令无效
        {
            printf("incorrect password\n\n");
        }
        else//口令有效
        {
            printf("Congratulation!you have passed the verifications\n");
            break;
        }
    }
    return 0;
}

于是我就复现,嗯,没问题,输入密码确实会重新输入:

算法学习:那些奇形怪状的软考题之搞笑系列_第3张图片

因此,代码是复现了,于是针对题目所说的问题,进行深入测试

0x2 满足条件后进行执行

        条件: 1.password数组长度大于等于12个字符;
                 2.password[8]~password[11]这部分每个字符均为空字符
#include 
#include 
#include 
#include 
#pragma warning(disable:4996)
#define PASSWORD "1234567"

int verify_password(char* password)
{
    int authenticated;
    char buffer[8];
    authenticated = strcmp(password,PASSWORD);
    strcpy(buffer, password);
    return authenticated;

}

int main(int argc,char* argv[])
{
    int valid_flag = 0;
    char password[13];
    while (1)
    {
        printf("please input password:\n");
        /*scanf("%s", password);
        memset(password,1024,NULL);
        password[0] = '1';
        password[1] = '1';
        password[2] = '1';
        password[3] = '1';
        password[4] = '1';
        password[5] = '1';
        password[6] = '1';
        password[7] = '\0';
        password[8] = '\0';
        password[9] = '\0';
        password[10] = '\0';
        password[11] = '\0';
        */
        sprintf(password,"abcdefgh%c%c%c%c11111111111111",'\0', '\0', '\0', '\0');
        printf("%s\n", password);
        printf("password[7] = %c\n", password[7]);
        valid_flag = verify_password(password);
        if (valid_flag)
        {
            printf("incorrect password\n\n");
        }
        else
        {
            printf("Congratulation!you have passed the verifications\n");
            break;
        }
    }
    return 0;

}

在代码中我把scanf输入注释掉了,取而代之的直接使用我指定的字符串进行输入输出,这样更符合答案所需要的条件

执行后如图:
算法学习:那些奇形怪状的软考题之搞笑系列_第4张图片

执行后他并没有绕过验证,而是重新进行循环,再次验证:

算法学习:那些奇形怪状的软考题之搞笑系列_第5张图片

0x3 小结

我发现,在verify_password中,有两行注释掉也完全没什么问题,代码一样的执行,毕竟没有代入到return里,因此大家可以尝试尝试
算法学习:那些奇形怪状的软考题之搞笑系列_第6张图片

总的来说,这个题,即使照着他的答案来,也不过是有域验证失败而进入循环而已,根本就不存在什么漏洞,信息安全的软件考试,这个《信息安全工程师历年真题》里面的东西,真正跟技术沾边的,没发现什么有用的,基本上都是一些理论、故事之类的。你给我说蠕虫,结果是说发生蠕虫事件的时间,哈哈

参考:
https://blog.csdn.net/luyan1992/article/details/49306885
https://jingyan.baidu.com/article/6fb756ec5bf9c8241858fb29.html
https://blog.csdn.net/bjbz_cxy/article/details/80388908
https://www.cnblogs.com/lidabo/p/12170728.html