[攻防世界]mobile新手练习区easy-apk

6 篇文章 1 订阅

[攻防世界]mobile新手练习区easy-apk

easy-apk最佳Writeup由129师386旅独立团 • devi1提供

难度系数: 7.0

题目来源: 暂无

题目描述:无

题目场景: 暂无

题目附件: 附件1

反编译后有用的附件内容:

MainActivity.class

Base64New.class

package com.testjava.jack.pingan1;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity
  extends AppCompatActivity
{
  protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2130968603);
    ((Button)findViewById(2131427446)).setOnClickListener(new View.OnClickListener()
    {
      public void onClick(View paramAnonymousView)
      {
        paramAnonymousView = ((EditText)MainActivity.this.findViewById(2131427445)).getText().toString();
        if (new Base64New().Base64Encode(paramAnonymousView.getBytes()).equals("5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=")) {
          Toast.makeText(MainActivity.this, "验证通过!", 1).show();
        }
        for (;;)
        {
          return;
          Toast.makeText(MainActivity.this, "验证失败!", 1).show();
        }
      }
    });
  }
}
package com.testjava.jack.pingan1;

public class Base64New
{
  private static final char[] Base64ByteToStr = { 118, 119, 120, 114, 115, 116, 117, 111, 112, 113, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 121, 122, 48, 49, 50, 80, 81, 82, 83, 84, 75, 76, 77, 78, 79, 90, 97, 98, 99, 100, 85, 86, 87, 88, 89, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 56, 57, 43, 47 };
  private static final int RANGE = 255;
  private static byte[] StrToBase64Byte = new byte['?'];
  
  public String Base64Encode(byte[] paramArrayOfByte)
  {
    StringBuilder localStringBuilder = new StringBuilder();
    for (int i = 0; i <= paramArrayOfByte.length - 1; i += 3)
    {
      byte[] arrayOfByte = new byte[4];
      int j = 0;
      int k = 0;
      if (k <= 2)
      {
        if (i + k <= paramArrayOfByte.length - 1) {
          arrayOfByte[k] = ((byte)(byte)((paramArrayOfByte[(i + k)] & 0xFF) >>> k * 2 + 2 | j));
        }
        for (j = (byte)(((paramArrayOfByte[(i + k)] & 0xFF) << (2 - k) * 2 + 2 & 0xFF) >>> 2);; j = 64)
        {
          k++;
          break;
          arrayOfByte[k] = ((byte)j);
        }
      }
      arrayOfByte[3] = ((byte)j);
      j = 0;
      if (j <= 3)
      {
        if (arrayOfByte[j] <= 63) {
          localStringBuilder.append(Base64ByteToStr[arrayOfByte[j]]);
        }
        for (;;)
        {
          j++;
          break;
          localStringBuilder.append('=');
        }
      }
    }
    return localStringBuilder.toString();
  }
}

解题

拿到附件989ca07c3f90426fa05406e4369901ff.apk,flag一定要反编译。博主用的ApkIDE进行反编译。先找到入口主类MainActivity,发现有很明显的比较函数,字符串是5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=,又看到Base64Encode(paramAnonymousView.getBytes()),立马进行Base64进行解码得到江썊꺍캢ʫ!쎒岠껢䐟葓滀,明显不是flag,仔细一看是new Base64New().Base64Encode(paramAnonymousView.getBytes()),所以找到Base64New(),果然码表不一样。拿到码表,可根据新的码表进行计算。具体如下。

题目:flag->ASCII->base编码->Unicode编码->base编码。
解题:base解码->Unicode解码->base解码->对照ASCII得出flag

 

 

 

 

代码的实现

博主也找了base64相关的代码实现,如下。

#查看码表
tables = [118, 119, 120, 114, 115, 116, 117, 111, 112, 113, 51, 52, 53, 54, 
55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 121, 122, 48, 49, 50, 80, 
81, 82, 83, 84, 75, 76, 77, 78, 79, 90, 97, 98, 99, 100, 85, 86, 87, 
88, 89, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 56, 57, 43, 47]

flag = ""

for i in tables:
	flag += chr(i);

print(flag)

//输出的码表

vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/

Golang版本,可编码表Base64

package main
 
import (
	"encoding/base64"
	"fmt"
)
 
const (
	base64Table = "vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/"
)
 
var coder = base64.NewEncoding(base64Table)
 
func base64Encode(src []byte) []byte {
	return []byte(coder.EncodeToString(src))
}
 
func base64Decode(src []byte) ([]byte, error) {
	return coder.DecodeString(string(src))
}
 
func main() {
         str := "5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs="
	// decode	
	enbyte, err := base64Decode([]byte(str))
	if err != nil {
		fmt.Println(err.Error())
	}
 
	fmt.Println(string(enbyte))
}

python

#调用base64模型
import base64
 
table_tmp = [ 118, 119, 120, 114, 115, 116, 117, 111, 112, 113, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 121, 122, 48, 49, 50, 80, 81, 82, 83, 84, 75, 76, 77, 78, 79, 90, 97, 98, 99, 100, 85, 86, 87, 88, 89, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 56, 57, 43, 47 ]
table_original = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
table_tmp_str = ''
str1 = '5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs='
for i in table_tmp:
    table_tmp_str += chr(i)
print(table_tmp_str)
print(base64.b64decode(str1.translate(str.maketrans(table_tmp_str, table_original)).encode('utf-8')))
#实现了base64
#来自https://blog.csdn.net/qq_42967398/article/details/101778364

# coding:utf-8

s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#s = "vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/"

def My_base64_encode(inputs):
	# 将字符串转化为2进制
	bin_str = []
	for i in inputs:
		x = str(bin(ord(i))).replace('0b', '')
		bin_str.append('{:0>8}'.format(x))
	#print(bin_str)
	# 输出的字符串
	outputs = ""
	# 不够三倍数,需补齐的次数
	nums = 0
	while bin_str:
		#每次取三个字符的二进制
		temp_list = bin_str[:3]
		if(len(temp_list) != 3):
			nums = 3 - len(temp_list)
			while len(temp_list) < 3:
				temp_list += ['0' * 8]
		temp_str = "".join(temp_list)
		#print(temp_str)
		# 将三个8字节的二进制转换为4个十进制
		temp_str_list = []
		for i in range(0,4):
			temp_str_list.append(int(temp_str[i*6:(i+1)*6],2))
		#print(temp_str_list)
		if nums:
			temp_str_list = temp_str_list[0:4 - nums]
			
		for i in temp_str_list:
			outputs += s[i]
		bin_str = bin_str[3:]
	outputs += nums * '='
	print("Encrypted String:\n%s "%outputs)
	
def My_base64_decode(inputs):
	# 将字符串转化为2进制
	bin_str = []
	for i in inputs:
		if i != '=':
			x = str(bin(s.index(i))).replace('0b', '')
			bin_str.append('{:0>6}'.format(x))
	#print(bin_str)
	# 输出的字符串
	outputs = ""
	nums = inputs.count('=')
	while bin_str:
		temp_list = bin_str[:4]
		temp_str = "".join(temp_list)
		#print(temp_str)
		# 补足8位字节
		if(len(temp_str) % 8 != 0):
			temp_str = temp_str[0:-1 * nums * 2]
		# 将四个6字节的二进制转换为三个字符
		for i in range(0,int(len(temp_str) / 8)):
			outputs += chr(int(temp_str[i*8:(i+1)*8],2))
		bin_str = bin_str[4:]	
	print("Decrypted String:\n%s "%outputs)
	
print()
print("     *************************************")
print("     *    (1)encode         (2)decode    *")	
print("     *************************************")
print()


num = input("Please select the operation you want to perform:\n")
if(num == "1"):
	input_str = input("Please enter a string that needs to be encrypted: \n")
	My_base64_encode(input_str)
else:
	input_str = input("Please enter a string that needs to be decrypted: \n")
	My_base64_decode(input_str)

如此就可以得到flag

05397c42f9b6da593a3644162d36eb01

flag{05397c42f9b6da593a3644162d36eb01}

话说这个题目有点坑,就是没有提示flag的形式,必须裹上flag{}才可以。提交完成后看评论,都在说这题目坑。

 

什么是Base64呢(百度百科)

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。

Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。

博主认为对于base64的变种来说,就是转换表和填充符号的区别,基本原理都是大同小异的。所以拿到编码后,要搞清楚转换表才是关键。

 

附录:
https://baike.baidu.com/item/base64

https://blog.csdn.net/qq_42967398/article/details/101778364

https://blog.csdn.net/qq_41858371/article/details/103329919

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byzf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值