当前位置:主页>产 业>业界新闻>

颤抖了吗?九步逆向破解银行安全令牌(3)

不过我接下来发现数据blob(binary large object)在carragar函数中被aa.a(和上文中的a.a不是一码事)这个函数加密了,这个函数接收blob数据,和一串16个字符的密钥。

在研究aa.a这个函数之前。我们先研究一下解密Blob的密钥,他作为carregar的一个参数传递进来。由PersistenciaUtils这个类产生。下面是这个类的入口。

public class PersistenciaUtils {

public static byte[] getChave(Context paramContext, byte[] paramArrayOfByte) {

try {

byte[] arrayOfByte = MessageDigest.getInstance("SHA-1").digest(getId(paramContext).getBytes());

return arrayOfByte;

} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {

}

return new byte[20];

}

public static String getId(Context paramContext) {

String str = Settings.System.getString(paramContext.getContentResolver(), "android_id");

if (str == null)

str = "";

return str;

}

}

从代码可以看出,先取得android_id的SHA-1摘要,如果获取失败就是用一个默认的16进制hash字符串。

使用adb看看我的android_id

$ ./adb shell

shell@hammerhead:/$ content query --uri content://settings/secure --projection name:value --where "name='android_id'"

Row: 0 name=android_id, value=0123456789abcdef

shell@hammerhead:/$ exit

a.aa把blob分成很多段,96位的头,16位的随机数,16位的标签和为加密数据预留的空间。

进一步研究aa这个类,我们的到了,如下的信息。

类a实现了 EAX AEAD(Authenticated Encryption with Associated Data)

类f实现了 CMAC (Cipher-based Message Authentication Code)

类h实现了 CTR (counter) mode 广告计费的功能

以上三个类的算法实现都取自JAES库

类l实现了 SHA-1 哈希算法 ,有趣的是类PersistenciaUtil并没有使用它,而是使用了MessageDigest这个函数来替代它。

类m实现了 HMAC (keyed-Hash Message Authentication Code) 算法

类n,包装了l和m,提供了HMAC-SHA1接口

最重要的我发现,aa.a函数是通过CMAC标签进行加密的,写出python的解密代码。

def decodeBlob(datablob, android_id):

header = datablob[:96]

nonce = datablob[96:112]

tag = datablob[112:128]

cryptotext = datablob[128:]

key1 = SHA1(android_id)[:16]

aes = AES(key1)

cmac = CMAC(aes)

cmac.update(header)

key2 = cmac.getTag()

eax = EAX(key2, aes)

(validTag, plaintext) = eax.checkAndDecrypt(cryptotext, tag)

if validTag:

return plaintext

如果EAX验证成功,aa.a返回解密的内容给PersistenciaDB使用。

再来看PersistenciaDB这个类,其中的a方法可以解析明文数据并把它变成一个perfil对象,并反序列化之,把其变成一个包含着bool,short,byte的数组。

其中以下3个,是关键的数据,根据偏移量反推出偏移。

pin = int(blob[82:86])

key = blob[38:70]

timeOffset = long(blob[90:98])

这就是密钥所需要的三个数据,只要三个都正确,程序就可以正常运行。

第七步:深度理解代码

上文中得到的秘钥在OPT 类中被截取到20个字节,并和时间戳一起传送到o.a方法中,这个方法引用了上文提到的很多类,所以,比较轻松的就写出了python代码~

def generateToken(key, timestamp):

message = [0] * 8

for i in xrange(7, 0, -1):

message[i] = timestamp &0xFF

timestamp >>= 8

hmacSha1 = HMAC_SHA1(key)

hmacSha1.update(message)

hash = hmacSha1.getHash()

k = 0xF &hash[-1]

m = ((0x7F &hash[k]) <<24 | (0xFF &hash[(k + 1)]) <<16 | (0xFF &hash[(k + 2)]) <<8 | 0xFF &hash[(k + 3)]) % 1000000;

return "%06d" % m

基本时间戳是一个占8字节的长整形,手动把它转换成大端的byte数组,接着使用HMAC-SHA1,取得hash最后四位作为整数读取的索引。使用这个整形,mod 1000000,就是我们的随机密码了,简单的超乎我的想象~~

马上我在google的TOTP认证的实现代码中,发现了很相似的一段。

public String generateResponseCode(byte[] challenge)

throws GeneralSecurityException {

byte[] hash = signer.sign(challenge);

// Dynamically truncate the hash

// OffsetBits are the low order bits of the last byte of the hash

int offset = hash[hash.length - 1] &0xF;

// Grab a positive integer value starting at the given offset.

int truncatedHash = hashToInt(hash, offset) &0x7FFFFFFF;

int pinValue = truncatedHash % (int) Math.pow(10, codeLength);

return padOutput(pinValue);

}

其实他们使用了基本相同的算法。

第九步:克隆

现在一个德州出品的Stellaris LaunchPad正躺在我面前,我准备了如下的库~

Cryptosuite

Arduino的加密算法库 (包括 SHA and HMAC-SHA)

RTClib

JeeNodes and Arduinos所使用的轻量级时间日期库.

2x16LCD_library

A library for 2x16 LCD (like JDH162A or HD44780) written for Energia and Stellaris Launchpad (LM4F).

RTC有一部分需要改进。由于Stellaris LaunchPad没有板载实时时钟,内部时钟需要在每次启动时设置,而且需要一台电脑来辅助,这是很麻烦的事情。

完整代码如下。

#include

#include

#include

RTC_Millis RTC;

void setup() {

RTC.begin(DateTime(__DATE__, __TIME__));

LCD.init(PE_3, PE_2, PE_1, PD_3, PD_2, PD_1);

LCD.print("Token");

LCD.print("valverde.me", 2, 1);

delay(1000);

LCD.clear();

}

char token[6];

uint8_t message[8];

long timestamp = 0;

long i = 0;

uint8_t key[] = {};

void showToken() {

long now = RTC.now().get() - 228700800 + 7200;

i = now / 36;

int timeLeft = now % 36;

for(int j = 7; j >= 0; j--) {

message[j] = ((byte)(i &0xFF));

i >>= 8;

}

Sha1.initHmac(key, 20);

Sha1.writebytes(message, 8);

uint8_t * hash = Sha1.resultHmac();

int k = 0xF &hash[19];

int m = ((0x7F &hash[k]) <<24 | (0xFF &hash[(k + 1)]) <<16 | (0xFF &hash[(k + 2)]) <<8 | 0xFF &hash[(k + 3)]) % 1000000;

LCD.print(m, 2, 1);

LCD.print(36 - timeLeft, 2, 15);

}

void loop() {

LCD.clear();

LCD.print("Current token:");

showToken();

delay(1000);

}

最后作者还分享了一个,解决Arduino时间问题的小技巧~这里省略啦~感兴趣的同学可以去原文看。

(责任编辑:安博涛)

分享到:

更多
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
  • 微笑/wx
  • 撇嘴/pz
  • 抓狂/zk
  • 流汗/lh
  • 大兵/db
  • 奋斗/fd
  • 疑问/yw
  • 晕/y
  • 偷笑/wx
  • 可爱/ka
  • 傲慢/am
  • 惊恐/jk
用户名: 验证码:点击我更换图片
资料下载专区
图文资讯

中国重启银行业安全新规 下月征集意见

中国重启银行业安全新规 下月征集意见

8月19日,路透社今日援引知情人士的消息称,中国将重启银行业安全新规。在此之前,该...[详细]

网络安全准则还需“下一步”

网络安全准则还需“下一步”

近日,联合国信息安全问题政府专家组召开会议,并向联合国秘书长提交报告。专家组包括...[详细]

用大数据为互联网金融保驾护航

用大数据为互联网金融保驾护航

近日,在2015上海新金融年会暨外滩互联网金融外滩峰会上,中国人民银行条法司司长张涛...[详细]

互联网深刻变革:世界正向黑客帝国演进

互联网深刻变革:世界正向黑客帝国演进

2015年中国互联网大会于7月23日在北京国家会议中心闭幕了,很显然,由于去年办过一次...[详细]

《网络安全法》有望在三季度出台

《网络安全法》有望在三季度出台

2015年,第十二届全国人大常委会第十五次会议初次审议了《中华人民共和国网络安全法(...[详细]

返回首页 返回顶部