Alleged RC4

这个算法是在阅读 shc 项目里面发现的,我为这个项目fork了一个注释 版本

shc项目是可以将shell command编译成为C代码,最终编译成为可执行文件,用于漏洞攻击使用的。

既然是攻击漏洞,那么可执行文件需要:1. 在用户没有防备的情况下面执行,如果发现当前执行环境 是安全人员构造的沙盒的话,那么就自动退出;2. 提高安全人员反编译的难度,比如我们不会直接把 shell command以明文的方式写在text里面。shc来提供了许多额外的选项来限制可执行程序只能运行在 更加安全的环境中而不被反编译。

ARC4这个算法就是在生成C代码阶段将shell command混淆并且加速随机数据,而在运行阶段将这些 混淆的数据反解析回来用于执行。代码的要点在于,混淆和反混淆的操作必须是对称的。

我仿照下面的C代码自己测试了一下Python的 实现

/**
 * This software contains an ad hoc version of the 'Alleged RC4' algorithm,
 * which was anonymously posted on sci.crypt news by cypherpunks on Sep 1994.
 *
 * My implementation is a complete rewrite of the one found in
 * an unknown-copyright (283 characters) version picked up from:
 *    From: allen@gateway.grumman.com (John L. Allen)
 *    Newsgroups: comp.lang.c
 *    Subject: Shrink this C code for fame and fun
 *    Date: 21 May 1996 10:49:37 -0400
 * And it is licensed also under GPL.
 *
 *That's where I got it, now I am going to do some work on it
 *It will reside here: http://github.com/neurobin/shc
 */


/* 'Alleged RC4' */
// TODO(yan): 这个算法值得好好研究一下
static unsigned char stte[256], indx, jndx, kndx;

/*
 * Reset arc4 stte.
 */
void stte_0(void)
{
    indx = jndx = kndx = 0;
    do {
        stte[indx] = indx;
    } while (++indx);
}

/*
 * Set key. Can be used more than once.
 */
void key(void * str, int len)
{
    unsigned char tmp, * ptr = (unsigned char *)str;
    while (len > 0) {
        do {
            tmp = stte[indx];
            kndx += tmp;
            kndx += ptr[(int)indx % len];
            stte[indx] = stte[kndx];
            stte[kndx] = tmp;
        } while (++indx);
        ptr += 256;
        len -= 256;
    }
}

/*
 * Crypt data.
 */
void arc4(void * str, int len)
{
    unsigned char tmp, * ptr = (unsigned char *)str;
    while (len > 0) {
        indx++;
        tmp = stte[indx];
        jndx += tmp;
        stte[indx] = stte[jndx];
        stte[jndx] = tmp;
        tmp += stte[indx];
        *ptr ^= stte[tmp];
        ptr++;
        len--;
    }
}

/* End of ARC4 */