叮当东东当当 发表于 2020-8-3 21:05

XCTF题目easy-apk答题

将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;
      byte tmp = 0;
      int k;
      for(k = 0; k <= 2; ++k)
      {
            if(i + k <= arg9.length - 1)
            {
                enBytes = (byte)((arg9 & 0xFF) >>> k * 2 + 2 | tmp);
                tmp = (byte)(((arg9 & 0xFF) << (2 - k) * 2 + 2 & 0xFF) >>> 2);
            }
            else
            {
                enBytes = tmp;
                tmp = 0x40;
            }
      }

      enBytes = tmp;
      int v2_1;
      for(v2_1 = 0; v2_1 <= 3; ++v2_1)
      {
            if(enBytes <= 0x3F)
            {
                res.append(Base64New.Base64ByteToStr]);
            }
            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)); //取对应字符
      }
    }
    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 charoldc[] = {'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;
    newstr ='\0';
    for(int i = 0 ; i < clen ; i++)
    {
      int nnum = getcindex(oldstr);
      if(nnum!= -1)
            newstr = newc;
      else
            newstr = oldstr;
    }

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


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

对apk中的字符串转换之后



再找个标准base64解密


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

叮当东东当当 发表于 2020-8-4 01:20

搜索了下知道了,是要加flag{}

半梦半醒半浮生~ 发表于 2020-8-4 03:12

可惜我是个web狗

1372_7 发表于 2020-8-4 16:22

是将正常的Base64加密函数替换了代码APK中Base64Encode()函数,然后再打包是吗?

TS1 发表于 2020-8-4 16:49

pwn狗报道

quyun0517 发表于 2020-8-4 16:56

向技术大佬致敬{:1_893:}

叮当东东当当 发表于 2020-8-4 19:20

1372_7 发表于 2020-8-4 16:22
是将正常的Base64加密函数替换了代码APK中Base64Encode()函数,然后再打包是吗?

不是,apk提供一个新64字符表的base64加密方法和加密后的字符串,要你解密出原字符串。

wtlight 发表于 2020-8-13 16:46

这边可能还是一层加密
页: [1]
查看完整版本: XCTF题目easy-apk答题