吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4887|回复: 7
收起左侧

[Android CrackMe] XCTF题目easy-apk答题

[复制链接]
叮当东东当当 发表于 2020-8-3 21:05
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

将apk拖入JEB查,查看入口:
 <activity android:name="com.testjava.jack.pingan1.MainActivity">



进入MainActivity,查看发现关键位置代码
if(new Base64New().Base64Encode(strIn.getBytes()).equals("5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs="))
{
    Toast.makeText(MainActivity.this, "验证通过!", 1).show();
    return;
}

Toast.makeText(MainActivity.this, "验证失败!", 1).show();



是通过Base64New类的Base64Encode()函数,对用户输入的字符串进行处理后与"5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs="进行比较。
那么就进去Base64New类查看Base64Encode()函数是如何对字符串进行处理的,处理函数如下。
public String Base64Encode(byte[] arg9)
{
    StringBuilder res = new StringBuilder();
    int i;
    for(i = 0; i <= arg9.length - 1; i += 3)
    {
        byte[] enBytes = new byte[4];
        byte tmp = 0;
        int k;
        for(k = 0; k <= 2; ++k)
        {
            if(i + k <= arg9.length - 1)
            {
                enBytes[k] = (byte)((arg9[i + k] & 0xFF) >>> k * 2 + 2 | tmp);
                tmp = (byte)(((arg9[i + k] & 0xFF) << (2 - k) * 2 + 2 & 0xFF) >>> 2);
            }
            else
            {
                enBytes[k] = tmp;
                tmp = 0x40;
            }
        }

        enBytes[3] = tmp;
        int v2_1;
        for(v2_1 = 0; v2_1 <= 3; ++v2_1)
        {
            if(enBytes[v2_1] <= 0x3F)
            {
                res.append(Base64New.Base64ByteToStr[enBytes[v2_1]]);
            }
            else
            {
                res.append('=');
            }
        }
    }

    return res.toString();
}


处理有点复杂,如果不是实在没办法我是不愿意慢慢分析如何处理的。鉴于对base64不太了解,先去找找资料。

理解理念后,自己尝试写一个base64加密,由于对最后不足3个字符加‘=’的处理形式还不理解,就先写个函数处理前面的。
const char *basedd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
QString MainWindow::getBase(char *ch)
{
    int chleng = strlen(ch);  //原字符串长度
    int fnum = chleng/3;      //可进行几个完整3转4
    QString retstr;           //生成字符串

    for(int i = 0 ; i < fnum ; i++)       //每次循环进行一次3转4
    {
        int tmp = *((int*)(ch+i*3));      //取前四字节放入tmp中
        tmp = getreorder(tmp);            //校正字节顺序
        for(int j = 0 ; j < 4 ;j ++)      //循环生成四个字符
        {
            int ch1 = (tmp>>(26-6*j))&0x3f;    //将要取的6位移动到最后,其他位置0
            retstr.append(QChar(basedd[ch1])); //取对应字符
        }
    }
    return retstr;
}

int MainWindow::getreorder(int value)
{
    int byte_1=(value&0xff000000)>>24;
    int byte_2=(value&0x00ff0000)>>16;
    int byte_3=(value&0x0000ff00)>>8;
    int byte_4=value&0x000000ff;
    int result=(byte_4<<24)+(byte_3<<16)+(byte_2<<8)+byte_1;
    return result;
}


方法是先取字符串下标0、1、2、3的四个字节当成int类型,并将4个字节逆序(大小端对齐的问题),然后根据规律循环取6Bit生成新的字符,取够4个6位刚好是前三个字节的内容。
再取3、4、5、6下标的字节,用同样方法循环处理。这里仅处理3个一组的字符,多余的我没有处理,仅为了测试。

写完代码后再看Base64New类,发现应该是把64个字符对应的字符顺序换了。
找个解码base64的代码,将64位字符替换掉就可以。
这里我直接将apk中NEWbase64加密后的字符转换成正常base64加密后的,代码如下
const char  oldc[] = {'v', 'w', 'x', 'r', 's', 't', 'u', 'o', 'p', 'q', '3', '4', '5', '6', '7', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'y', 'z', '0', '1', '2', 'P', 'Q', 'R', 'S', 'T', 'K', 'L', 'M', 'N', 'O', 'Z', 'a', 'b', 'c', 'd', 'U', 'V', 'W', 'X', 'Y', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', '8', '9', '+', '/'};
const char *newc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void MainWindow::on_pushButton_clicked()
{
    char* oldstr = ui->lineEdit->text().toLatin1().data();
    int clen = strlen(oldstr);
    char newstr[clen+1];
    newstr[clen+1] ='\0';
    for(int i = 0 ; i < clen ; i++)
    {
        int nnum = getcindex(oldstr[i]);
        if(nnum!= -1)
            newstr[i] = newc[nnum];
        else
            newstr[i] = oldstr[i];
    }

    ui->lineEdit_2->setText(QString(newstr));
}

int MainWindow::getcindex(char cc)
{
    for(int i = 0 ; i < 64 ; i++)
    {
        if(cc == oldc[i])
            return i;
    }
    return -1;
}


对apk中的字符串转换之后



再找个标准base64解密


但是提交的时候提示错误,不知道原因?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 叮当东东当当 发表于 2020-8-4 01:20
搜索了下知道了,是要加flag{}
半梦半醒半浮生~ 发表于 2020-8-4 03:12
1372_7 发表于 2020-8-4 16:22
是将正常的Base64加密函数替换了代码APK中Base64Encode()函数,然后再打包是吗?
TS1 发表于 2020-8-4 16:49
pwn狗报道
quyun0517 发表于 2020-8-4 16:56
向技术大佬致敬
 楼主| 叮当东东当当 发表于 2020-8-4 19:20
1372_7 发表于 2020-8-4 16:22
是将正常的Base64加密函数替换了代码APK中Base64Encode()函数,然后再打包是吗?

不是,apk提供一个新64字符表的base64加密方法和加密后的字符串,要你解密出原字符串。
wtlight 发表于 2020-8-13 16:46
这边可能还是一层加密
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-27 03:10

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表