吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3958|回复: 23
收起左侧

[Android CTF] 学破解第192天,《攻防世界mobile练习区easy-apk》学习

  [复制链接]
小菜鸟一枚 发表于 2022-4-17 17:00

前言:

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1582287-1-1.html

立帖为证!--------记录学习的点点滴滴

0x1 静态分析

  1.下载apk安装,看一看业务逻辑,就是输入数据,点击check校验:

https://s1.ax1x.com/2022/04/17/LUpLB6.png

  2.jadx反编译一波,找到关键源码,也就是点击事件,可以看到将我输入的字符串base64加密,然后和5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=比较,相等就可以了:

public void onClick(View view) {
                if (new Base64New().Base64Encode(((EditText) MainActivity.this.findViewById(R.id.editText)).getText().toString().getBytes()).equals("5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=")) {
                    Toast.makeText(MainActivity.this, "验证通过!", 1).show();
                } else {
                    Toast.makeText(MainActivity.this, "验证失败!", 1).show();
                }
            }

  3.再找到Base64New这个类,似乎不是标准的。

package com.testjava.jack.pingan1;

/* loaded from: classes.dex */
public class Base64New {
    private static final int RANGE = 255;
    private static final char[] Base64ByteToStr = {'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', '+', '/'};
    private static byte[] StrToBase64Byte = new byte[128];

    public String Base64Encode(byte[] bytes) {
        StringBuilder res = new StringBuilder();
        for (int i = 0; i <= bytes.length - 1; i += 3) {
            byte[] enBytes = new byte[4];
            byte tmp = 0;
            for (int k = 0; k <= 2; k++) {
                if (i + k <= bytes.length - 1) {
                    enBytes[k] = (byte) (((bytes[i + k] & 255) >>> ((k * 2) + 2)) | tmp);
                    tmp = (byte) ((((bytes[i + k] & 255) << (((2 - k) * 2) + 2)) & 255) >>> 2);
                } else {
                    enBytes[k] = tmp;
                    tmp = 64;
                }
            }
            enBytes[3] = tmp;
            for (int k2 = 0; k2 <= 3; k2++) {
                if (enBytes[k2] <= 63) {
                    res.append(Base64ByteToStr[enBytes[k2]]);
                } else {
                    res.append('=');
                }
            }
        }
        return res.toString();
    }
}

  4.正好原来写的base64编码解码源码派上用场了,码表一换,然后把比较的字符串放进来。

#include <iostream>
#include <string>

using namespace std;

int decodeBase64(const char *cpystr, int cpystrLen, char *str, int strLen)
{
        //解密就是将加密的过程倒过来即可!

        char base64[65] = {'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', '+', '/'};//定义base64码表

        int i = 0;//密文下标
        int j = 0;//明文下标

        while (i < cpystrLen)//判断是否解密完毕
        {
                int index = 0;//码表下标
                int temp1 = -1;//保存第一个密文下标
                int temp2 = -1;//保存第二个密文下标
                int temp3 = -1;//保存第三个密文下标
                int temp4 = -1;//保存第四个密文下标

                if (j < strLen - 1)//判断下标是否超过明文可存储范围
                {
                        //通过码表反查密文对应的下标,然后分别获得十进制数字
                        for (; index < 64; index++) {
                                if (cpystr[i] == base64[index])
                                {
                                        temp1 = index;
                                }
                                if (cpystr[i + 1] == base64[index])
                                {
                                        temp2 = index;
                                }
                                if (cpystr[i + 2] == base64[index])
                                {
                                        temp3 = index;
                                }
                                if (cpystr[i + 3] == base64[index])//一轮密文4个字节已取出,退出循环
                                {
                                        temp4 = index;
                                }

                                //如果已经查到四个下标就退出循环!
                                if (temp1 != -1 && temp2 != -1 && temp3 != -1 && temp4 != -1) break;
                        }

                        if (temp3 != -1 && temp4 != -1)//完整的读取到了4个字节,直接解密
                        {
                                str[j] = (temp1 << 2) | (temp2 >> 4);//取第一个密文6个字符再加上第二个密文前2个字符
                                str[j + 1] = ((temp2 & 15) << 4) | (temp3 >> 2);//取第二个密文后4个字符再加上第三个密文前4个字符
                                str[j + 2] = ((temp3 & 3) << 6) | temp4;//取第三个密文后2个字符再加上第四个密文6个字符
                        }
                        else if (temp3 == -1)//只取到了2个字节
                        {
                                str[j] = (temp1 << 2) | (temp2 >> 4);//取第一个密文6个字符再加上第二个密文前2个字符
                                j -= 2;//下标前移2位,不然补‘\0’的位置不对
                        }
                        else if (temp4 == -1)//只取到了3个字节
                        {
                                str[j] = (temp1 << 2) | (temp2 >> 4);//取第一个密文6个字符再加上第二个密文前2个字符
                                str[j + 1] = ((temp2 & 15) << 4 | (temp3 >> 2));//取第二个密文后4个字符第三个密文前4个字符
                                j--;//下标前移1位,不然补‘\0’的位置不对
                        }
                        else
                        {
                                cout << "下标取值不对,程序逻辑错误!!!" << endl;
                                return 1;
                        }

                        i += 4;//密文每次循环向后移动4位
                        j += 3;//明文每次循环向后移动3位
                }
                else
                {
                        cout << "存储明文的内存不足,请重新分配!!!" << endl;
                        return 2;
                }
        }

        str[j] = '\0';//补一个字符串结束符
        return 0;
}

int main(int argc, char *argv[])
{ 
    char cpystr[] = "5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=";
    char str[100];

    decodeBase64(cpystr, 45,str, 100);

    cout<<"flag:"<< str <<endl;

    return 0;

}

  5.运行,成功得到flag:05397c42f9b6da593a3644162d36eb01。

https://s1.ax1x.com/2022/04/17/LUnLz6.png

0x2 总结

  1.可以把自己学的加密解密代码留下来,以备不时之需,免得用的时候到处去百度。

免费评分

参与人数 5威望 +1 吾爱币 +23 热心值 +5 收起 理由
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
haoe + 1 我很赞同!
18687321617 + 1 + 1 热心回复!
raycerlane + 1 + 1 用心讨论,共获提升!
Vardven + 1 + 1 热心回复!

查看全部评分

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

daxueba 发表于 2022-4-17 18:16
cy学习一下
fxxxysh010 发表于 2022-4-17 18:25
erkelee 发表于 2022-4-17 18:48
glorymusic 发表于 2022-4-17 19:43
学习参考了,感谢分享~!~!~!
头像被屏蔽
xiadongming 发表于 2022-4-17 20:00
提示: 作者被禁止或删除 内容自动屏蔽
amwquhwqas128 发表于 2022-4-17 23:36
记录的非常详细,适合我菜鸟学习
louischeung004 发表于 2022-4-18 00:34
参考参考一下
xkxx0001 发表于 2022-4-18 05:51
谢谢指导
ShanGuiOne 发表于 2022-4-18 07:21
学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 15:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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