Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

Exploring Reverse Engineering Symptoms in Android Apps

今天要介绍的一篇论文Exploring Reverse Engineering Symptoms in Android apps来自EuroSec’15,是一篇讨论Android app 重打包检测的论文,介绍了一个简单有效的实用小技巧。

摘要

作者提出AndroidSOO,一种轻量级的对Android app重打包的检测方法,依赖于一种叫String Offset Order的,这是个对每个dex文件都有的可提取特征。这种方法异常简单,效果优良。

背景

Android APP重打包现象严重,过去的方法,如RiskRanger,DroidRanger,Drebin,DroidScope,ViewDroid等等都依赖非常复杂的特征提取以及需要使用app互相对比这种非常耗时耗资源的操作。而作者提出一种利用dex文件本身特性的方法来甄别重打包的app,不需要有训练集,标准原始库,也不需要互相对比。

SOO

这个神奇的方法就叫String Offset Order。就是原始dex的常量字符串是按首字节的顺序排序的,而重打包工具则一般为了方便起见,不会按顺序排列,所以只要检测下这个就OK了,对,就是这么简单。

效果

Fig

Fig

Fig

原始程序使用不同的方式打包,然后用apktool dalvik-obfuscator和人工重打包的方式,发现准确率非常高。其中使用AdobeAir的原始程序打包的本身SOO就是随机的,不是排序的。 然后对恶意程序也做了下实验,以重打包著名的恶意程序家族检测出SOO随机性的很高,play上检测出随机的除了Adobe Air以外,57个里面有30被virustotal报毒。 这个方法的效率很高,overhead几乎可以忽略不计。

讨论

如果人工重打包,则无法检测,但是因为这个方法基本没人采用,可以忽略不计。

修改APKTOOL的源代码可以让这个方法失效。

Gyrophone: Recognizing Speech From Gyroscope Signals

今天要介绍的一篇论文来自USENIX Security 14,是一篇讨论智能手机中陀螺仪这个不起眼却不可或缺的小部件造成的信息泄漏的问题。

项目网站:Link: http://crypto.stanford.edu/gyrophone/

1 介绍

在现在的智能手机上,我们大多数人知道麦克风、摄像头和GPS这些传感器存在暴露隐私风险的问题。然而,加速仪和陀螺仪这些传感器也同样暴露用户的隐私。在这篇文章中,作者提出了利用手机里的陀螺仪来实现窃听,获取声音信息的方法。

2 攻击原理

主要原理在于,陀螺仪对于声学的振动敏感。陀螺仪的声音的敏感度大约为70dB, 而70dB相当于大声的说话。同时,陀螺仪对声音的到达角度敏感,它相当于具有方向的麦克风。

手机上的陀螺仪的采样速率最高为200Hz。 根据那奎斯特采样定律,尽管200HZ的速率仅仅允许采样最高为100HZ的声音信号,作者发现仍然可以从陀螺仪的数据中恢复出高于100Hz的语音。尽管出现了频率混叠(aliasing)现象,他们仍然可以从陀螺仪的数据中提取更多的信息。

Figure 1

3 实验

根据陀螺仪的测量数据,作者从中提取特征,再结合机器学习的办法来完成语音识别。他们分别采用了Nexus和Samsung两种手机进行实现,这是因为这两部手机的陀螺仪的生产商并不相同。实验之前,他们先对数据进行预处理:将数据转换为音频文件WAV格式,提高采用速率为8KHZ,再去除没有声音的部分。接下来,他们完成了三类测试实验:区分说话者性别,区分说话者,区分语音的数字。

区分说话者的性别,他们可达到80%以上的成功率。对10位说话者,他们可达到50%的成功率来区分说话者。对于数字的语音识别,他们在与说话者有关的测试下可达到65%的成功率,在与说话者无关的测试下可达到26%的成功率。在多部手机同时采集语音信息的情况下,他们在说话者有关的测试下对数字的语音识别成功率为77%。

Figure 2

Figure 3

最后,作者提出对该类型攻击的一些防御方法:对采样数据进行低通滤波,以及对获取高采样速率设置高权限等等。

Achieving Accuracy and Scalability Simultaneously in Detecting Application Clones on Android Markets

论文下载

1 Introduction

本论文定义了一个图的几何特征 —— centdroid,用于测量两个APP的methods的相似度,根据相似度得出是否为APP克隆的结论,有较高的精确度(accuracy)及较大的应用规模(scalability)。

Unique Characteristics of App Clones

  • A billion opcode problem:opcode量大
  • code fragment clones and app clones: code fragment相似不代表是克隆APP,可能是相同三方库。只有核心代码相同才算克隆
  • Type 2 and Type 3 clones are prevalent on Android markets: 目前市场的APP clone大多是2,3类型的。

四种克隆类型:

  1. 大部分代码完全相同
  2. 大部分代码语义完全相同
  3. 代码有改动,增添或删减部分代码
  4. 相同的算法,但应用的形式有变化

现状分析

很多方法只能区分1类型,对于2,3类型的分析准确度不足,例如String-based, token-basedand AST (Abstract Syntax Tree)-based等等

PDG(program dependence graph)等依靠图的同态来分析的方法,对于2,3类型的准确度足够,但存在效率不足的问题。

结论:

  • 依靠图来分析方法,如果能够避免利用图的同态性(graph isomorphism)来分析,会大大提高效率
  • 分辨app clone需要比较不同市场中的APP,代码量巨大。一对一比较的复杂度为C(2,M),M为method个数。需要降低这个复杂度

特点

  • 在保证针对2,3类型的准确率的同时,不用同态性比较,大大提高了效率。
  • 在比较之前进行分类,不需要一对一的比较,复杂度降低,提升效率。
  • 只比较core functionalities,可以有效针对添加库和广告的克隆

2 Detail

centroid

PDG(program dependence graph) ->  CFG(control flow graph) -> 3D-CFG ->  centroid(重心坐标)

centroid相同,method一定相同,同时具有单调性,centroid相差大,method相差一定大。

ASD

定义了Application Similarity Degree

Clone Group

定义了可能是克隆的分组规则,将centroid相近的分在一起,用于比较。

流程

  • 在不同市场下载APP,转化为smali
  • 转化为centroid,存入数据库,包含market name,app file name, class name, method name and centroid
  • 将每个method只与Clone Group中的method相比较,复杂度为 M*c, c << M

3 Evaluation

Five typical third-party Android markets:

  • two American markets (Pandaapp and Slideme)
  • two Chinese markets (Anzhi and Dangle)
  • one European market (Opera).

Figure 1

  • 误报率:<1%
  • 漏报率:0.4—0.7%
  • 同时具有较高的效率,一个小时可以处理150145个APP,每个method只需同组内小于8个其他的method进行比较。
  • 如果有新的APP与数据库中已有数据比较,效率也是很快。。

Automatically Detecting SSL Error-Handling Vulnerabilities in Hybrid Mobile Web Apps

  • 作者:Chaoshun Zuo, Jianliang Wu, Shanqing Guo
  • 单位:Shandong University
  • 出处:AsiaCCS’15

Abstract && Introduction

  • 本文主要讨论自动化检测App中WebView对SSL的错误处理
  • 与以前研究的区别在于:既要分析native app activities,还要分析web page。因此本文采取了静态分析和动态分析结合的方法
  • 测试了第三方市场的13,820个app,645个确认有漏洞

Figure 1

System Overview

  • Problem Statement:WebView校验证书时,如校验失败,而客户端没有重写错误处理过程,则WebView会屏蔽当前page;因此开发者通常重写错误处理过程,包括忽略该错误、处理错误并返回结果给WebView。
  • Challenges and Solutions:
    • Is the potential vulnerable code reachable:
      • 先找到潜在漏洞代码,再确认这种代码是否可达。
      • 假设继承自WebViewClient并重写了错误处理方法OnReceiveSsLError的类中,包含忽略错误代码的是有漏洞的。
      • setWebViewClient->WebViewClient->Activity,target activity可达则问题代码可达。
    • How to record Activity jump relations with trigger events:
      • 为确认app是否有漏洞,需要能从launcher Activity触发一些事件后能跳转到target activity。
      • 基于launcher activity到target activity的一条路径建立ACG来实现跳转。ACG的顶点是activity,边是能触发activity的event和相关view。
      • MCG->method->event->ACG. 建立MCG来寻找ACG中的边,遍历MCG找到引起activity跳转的method,以及跳转到哪个activity,识别出该方法所属的事件方法(如OnClick),拥有该实践方法的view和该事件就是这个ACG中的边。
    • How to simulate human operations to both native Android UI and WebView UI:
      • 通过修改Android框架开发了Android Tester:能找到与activity相关的view,触发特定event
      • 利用Robotium为目标app开发了一个通用测试脚本app:当默认page不是https时,能利用test script跳转到https页面。类似爬虫,找出默认page的所有链接,选出其中的https链接。
  • System Overview:
    • 静态分析出潜在问题app
    • 动态分析确认问题app

Figure 2

Detailed Design

  • Static Analysis Module:
    • Static Detection:反编译,找继承自WebViewClient的类;分析收集到的类是否重写了onReceivedSsLError方法。分析发现大部分app选择信任所有证书,部分错误校验,部分直接放弃当前page。
    • Build MCG:MCG表示方法间的调用关系。顶点表示method,边表示method A可以调用B。
    • Locate Target Activities:查找包含问题代码的method,回溯MCG找到对应的activity,回溯在进入系统回调方法时停止因为没有方法会显示调用这些方法。检查activity集,删掉没有在Manifest文件里声明的。
    • Build ACG:
      • 找到target activity后再找从launcher activity跳转到这些activity的路径。
      • startActivity和startActivityForResult这两个系统调用会导致Activity跳转。
      • 建立ACG时,顶点是Manifest里声明的Activity,边根据以上两个系统调用回溯,找到它的起始Activity来建立边。
  • Dynamic Analysis Module:
    • Dynamic Test Environment:
      • 需求:
        • Being able to understand the UI states
        • Being able to get UI objects
        • Being able to perform actions
        • Being able to get return value
      • 实现:
        • 修改了Android系统工具instrumentation,绕过签名验证过程,以能用测试脚本app测试具有不同签名的app
        • 用静态分析阶段得到的配置文件开发了一个测试脚本app用于测试目标app,根据脚本读取配置文件测试app,驱使app跳转到target Activity
        • native Android UI driving跳转到目标Activity,WebView UI driving加载https页面
    • Confirm vulnerability:WebView拒绝问题cert会显示空白page,否则显示正常page即错误处理由app代码完成。所以只要检查是否加载了空白page就可以判断app是否有漏洞。

Evaluation

Figure 3

A Messy State of the Union: Taming the Composite State Machines of TLS

作者:Benjamin Beurdouche, Karthikeyan Bhargavan, Antoine Delignat-Lavaud, Cedric Fournet, Markulf Kohlweiss, Alfredo Pironti, Pierre-Y ves Strub, Jean Karim Zinzindohoue

单位:INRIA Paris-Rocquencourt, Microsoft Research, IMDEA Software Institute

Introduction:

  1. 设计了一个综合状态机能处理多种TLS协议模式(版本、扩展、认证模式、密钥交换方法的不同组合);
  2. 基于综合状态机测试了主流TLS开源实现,并发现若干严重漏洞,分析认为它们源自不同正确状态机的错误组合;
  3. 给出第一个C语言写的验证过的TLS综合状态机实现,可嵌入OpenSSL;
  4. 密码协议库的核心组件需要形式化验证,这能通过本文方法实现。

  5. TLS的安全性可以分解到组成模块的安全性:密钥交换算法(Ephemeral DH)、传输加密方案(AES-GCM with SHA256)

  6. Composite State Machines:SSL链接建立过程的状态机没有标准化,且不同实现的状态机也不同。
  7. 有时为了代码复用将状态机简单组合会带来问题序列: Figure 1

order of message: distinguish between truly optional messages, and messages whose presence if fully prescribed not prematurely calculate session parameters and secrets

Figure 2

Testing implementations with FlexTLS

文章提出了一种protocol-aware state machine fuzzing.

  • generate arbitrary sequences of valid TLS messages to test
  • implementations. 定义偏移序列,利用偏移序列来确定检测状态机错误。 Figure 3

State machine flaws in TLS implementations

  • OpenSSL:

    • Early CCS: OpenSSL 1.0.1g, CCS严格意义上不是handshake message,不出现handshake log中,不受客户端或服务器端状态机控制,可以出现在ServerHello后的任意位置。Receiving a CCS message triggers the setup of a recore key derived from the session key. CVE-2014-0224.
    • DH Certificate: client忽略ClientKeyExchange,可能导致client impersonation。
    • Server-Gated Crypto(SGC): SGC允许客户端收到serverhello后重新握手,但是表明某些extension是否被使用的信息会在新握手中消失。
    • Export RSA: 512 bit RSA modulus.
    • Static DH: 使用DHE或者ECDHE时,如果证书包含ECDH公钥,而且客户端不接受ServerKeyExchange,则会回滚到static ECDH,用服务器证书的公钥,导致前向安全性丢失。
  • JSSE: OpenJDK 6,7,8都存在下列问题。

    • Client Flaws: 消息序号检测,可以skip消息。会导致server impersonation attack。
      • 允许服务器skip ServerCCS,从而记录层不加密;
      • 允许服务器skip any combination of the ServerCertificate, ServerKeyExchange, ServerHelloDone.
    • Server Flaws: 消息序号检测,或上一条是CKE,或ClientcertificateVerifiy。
      • 允许skip ServerCCS,从而记录层不加密;
      • skip any combination of the ServerCertificate, ServerKeyExchange, ServerHelloDone.
      • CKE后可以发任意数量clienthello,clientcertificate,CKE,CCV等。这些行为会破坏Server状态。
  • Other implementations:
    • NSS:
      • DHE 或 ECDHE中允许skip ServerKeyExchange,会导致Static DH等,影响前向安全性。
      • renegotiation时,Server CCS和ServerFInished之间接收Allication Data,如果certificate换了会出错。
    • Mono:MS .NET framework
      • skip CCS message
      • skip ClientCertificateVerify。可能导致客户端伪造。
      • ServerKeyExhange后还可以发送ServerCertificate。证书替换攻击。
    • CyaSSL:
      • skip CCS
      • skip serverKeyExchange和ServerHelloDone
      • Skip ClientCertificateVerify
    • GnuTLS: skip ClientCertificate
    • miTLS and others: miTLS is a verified implementation. no deviant trace.

Attacks on TLS implementations

Early Finished: Server impersonation(Java, CyaSSL)

构造一个场景:

Figure 4

这种情况在JSSE中可行,即(4)中略过密钥协商的过程直接ServerFinished,导致所有通信全部明文。JSSE中,ServerFinished内容是前面通信内容的MAC,key是master secret。 对于CyaSSL,情况类似,除了ServerFinished是12个0. client接收ServerCCS时就生产MAC存在本地,收到ServerFinished后在将它和ServerCCS匹配。这个攻击依赖于未初始化的内存。

Skip verify:Client impersonation(Mono,CyaSSL, OpenSSL)

Figure 5

  • Mono中,步骤(5)略过了对client身份的验证。
  • CyaSSL:类似,只是(6)的信息M也要略过。
  • OpenSSL:(5)(6)略过了客户端身份验证。

Skip ServerKeyExchange:Forward Secrecy Rollback(NSS,OpenSSL):

Figure 6

  • ServerKeyExchange被攻击者拦截了,理论上client应该拒绝后续信息,NSS和OpenSSLim会降级到不支持前向安全性的密钥交换方式。
  • Inject ServerKeyExhange: RSA_Export flash-back 略。

A Verified State Machine for OpenSSL

系统化状态机测试能发现漏洞,但是不能保证所有漏洞被发现。形式化验证一个给定的状态机实现是否匹配TLS标准是有价值的,建立自动化验证框架更有价值。本文试图对OpenSSLim的full state machine进行证明。

  • OpenSSL Clients and Servers:消息处理异常复杂
  • A new state machine:提出一个新的状态机结构让OpenSSL消息序列更容易理解。

把状态机形式化为一个逻辑不变量isValidState

Figure 7

Summary and responsible disclosure:

8个TLS实现中6个有严重的状态机问题,并能利用它们发起9个不同的攻击。3个实现允许略过CCS信息。这篇论文提到的漏洞已报,已修复或修复中。

What the App Is That? Deception and Countermeasures in the Android User Interface

本次介绍的论文What the App is That? Deception and Countermeasures in the Android User Interface发表在2015年的SP安全会议上,这篇文章主要讨论了目前Android平台上存在的一种GUI attack,GUI attack是指恶意应用通过伪装成知名应用程序GUI或是在知名应用程序打开时在界面上覆盖透明的控件的方法来迷惑用户,从而达到窃取用户输入的隐私数据的目的。

论文下载:http://www.cs.ucsb.edu/~chris/research/doc/oakland15_uideception.pdf

本文就GUI attack的技术细节进行了研究,发现了多种已知、未知的GUI attack攻击方法。

此外,作者开发了两个不同工具来帮助用户对抗这样的攻击。一个是App静态分析工具,用于在应用市场中筛选出可能发起此类攻击的恶意程序。另一个是运行在Android设备上的动态防御工具,能够提醒用户正在和他们发生交互的App的身份。

作者原来是做web安全的,所以这篇文章里可以看到很多的安全设计都和web上的安全设计有着类似的想法。

Introduction

本文主要的贡献在于:

  1. 系统性的研究了Android平台上能够被用于实现GUI attack的多种技术。并以此设计了能够静态检测GUI attack的静态分析工具。
  2. 设计了一种部署在Android设备上的GUI attck防御工具,能够很好的覆盖现有的攻击方式。
  3. 实验

Background

一些有关Android GUI的介绍

GUI Confusion Attacks

GUI confusion attack的主要目的就是通过各种方法使得自己构造的仿造的恶意GUI替代正常应用程序的GUI来和用户进行交互,以此进行钓鱼,获取用户的敏感信息。作者通过分析,发现了很多可以用来实施GUI confusion attack的API,并进行了分类,如下图所示:

pic1

之后对不同的攻击方式进行了具体分析。除了通过上述的API来在不同的场景下使得自己的恶意API取信于用户,实施GUI attack的另一个要素就是如何正确的把握正常应用关键GUI弹出的时间。文章中同样对这些方法进行了分析总结:

  1. 读取系统log
  2. 使用getRunningTasks API(需要GET_TASKS权限,并且5.0之后对该API进行了限制,只能读取自己Activity的状态)
  3. 读取/proc/self/cgroups的内容(“/apps”表示处于最上层正在和用户交互,否则是”/apps/bg_non_interactive”)

最后作者表示一般会通过重打包来构造一个恶意的应用程序。

State exploration of the Android GUI API

分析了上述API在被用来实施GUI attack的时候,各项参数的选择,为下文的静态分析做准备。

Detection via static analysis

通过静态的程序分析技术,针对上一节总结出的各种API以及对应的参数,检测存在进行GUI attack隐患的App。

作者搜集了4种不同的app进行实验:

  1. 500个来自Google Play的随机应用
  2. 500个来自Google Play的热门应用
  3. 20个锁屏软件(作者认为这类应用很符合GUI attack恶意应用的特征)
  4. 1260个来自Android Malware Genome project的恶意程序

分析结果如下:

pic2

pic3

可以看出这样的恶意程序样本还不是很多。

UI defence mechanism

除了上文所述的静态检测工具,作者还开发了运行在Android设备上的实时防御系统。通过修改系统,实时的向用户提醒目前和他们交互的UI是属于哪个应用,哪个开发者。这里需要提到的是Android程序分析领域的一个经典问题:如何识别一个恶意的应用程序。由于Android的生态系统相对于iOS来说要开放很多,用户可以通过多种不同的渠道安装应用(Google Play,第三方市场,apk安装),除了来自Google Play的应用外,并没有可信的第三方为Android程序的签名做背书,也就是说任何人都可以伪造签名的内容,攻击者可以将自己的签名制作的和腾讯、阿里这种大公司一样,用户没有办法通过签名进行身份校验。本文作者在这里使用的了传统web领域的方法, 使用已有的CA对签名进行认证。

pic4

最后作者召集了300多名测试者来测试他们的系统,以此说明这个实时防御系统的有效性:

pic5

Surreptitiously Weakening Cryptographic Systems

本次介绍的论文Surreptitiously Weakening Cryptographic Systems,来自大名鼎鼎的Bruce Schneier,讨论的是如何“设计”一个弱密码学系统

论文下载:https://eprint.iacr.org/2015/097.pdf

1 概要介绍

密码系统在部署之前,要对其可靠性进行检测。本文作者站在一个破坏者的角度上,通过一些具体案例的分析,阐述了在密码学设计和执行部署方面,如何制造一些漏洞,并且对这些漏洞进行了评价,包括漏洞是否容易被发现,是否容易使用,影响范围,是否能被控制等等。

2 模型术语

作者设定了四种角色,包括Saboteur(破坏者,在密码系统设计和执行中,有意或者无意加入漏洞),Attacker(攻击者,利用漏洞实施攻击的人),Victim(受害者,主要是用户),Defender(防御者,密码系统的设计者)

Figure 1

对漏洞的评估,使用了下列参数:

  • secrecy:隐蔽性。
  • utility:实用性
  • scope:影响范围

并对每一项进行了细分:

Figure 2

3 漏洞实例

作者分析了几个比较知名的密码学漏洞:

  • Lotus Notes:同EXP类似,Lotus Notes软件使用64位密钥,其中24位使用NSA的公钥加密传输,只有NSA能破解信息。
  • Dual EC DRBG:椭圆曲线产生伪随机数的问题。
  • Debian OpenSSL PRNG:开发者增加了两行代码,用来为伪随机数发生器提供熵值,但是却违反了内存安全使用原则,导致TLS或者SSH产生的密钥是32767种可能之一。
  • Heatbleed:代码实现漏洞
  • Double Goto:证书验证出现问题。

针对每个实例,其漏洞性质的评价。

Figure 3

4 设计与执行

4.1 设计方面

破坏者可以从两个角度实现设计上的漏洞,一个拥有先进的知识,在系统被广泛熟知之前,后门不会被发现,另一种类似FREAK ATTACK,拥有修改标准的权利,制定一个不安全的规则。

4.2 执行方面

  1. Bad randomness:随机数用在密钥生成,初始向量,密钥管理,关键数生成等方面,在目前做一个弱的随机数发生器并不能,并且有些时候直观上看不出问题。
  2. key 数据泄露: subliminal channels and kleptography. 在密码系统中加入后门。
  3. 泄露敏感数据:一是利用旁路攻击,由于开发者滥用密码算法,例如google keyczar的设计中,根据错误响应返回的不同时间,可以获取明文的一些数据信息。二是处理明文和密钥方法错误,比如加密通信后密钥未销毁,电脑死机时用临时文件存储明文信息,密钥留在内存区。
  4. 不正确的错误处理方式:POA攻击
  5. 随机数和IV重用:cbc模式中重复使用IV导致第一块明文信息泄露,随机数产生,IV熵不足
  6. API使用不当

5 Case Studies

TLS

  1. 随机数如何被预测:设计一个弱的随机数产生方法,似的主密钥可预测;或者使用的熵不足;或者根据产生的随机数推测出规律。
  2. 修改证书和握手信息验证信息,进行中间人攻击。

Avatar: A Framework to Support Dynamic Security Analysis of Embedded Systems’ Firmwares

Abstract & Introduction

  • 作者设计并实现了一个动态分析框架,方便用户分析嵌入式设备
  • 作者讨论了一些可能用于该引擎的优化方式,说明复杂的动态分析可以应用在这个框架上
  • 作者在三个不同场景下(逆向分析,漏洞检测,后门检测)评估了这个框架

Dynamic Firmware Analysis

  • 嵌入式设备进行动态分析是有难度的,这主要是因为尝试模拟一个嵌入式系统不仅仅需要对CPU的模拟,还要很多模拟外围设备(DMA, 交换芯片)的行为。不能正确模拟这些外围设备的话,模拟执行的固件会经常挂起,crash,或者与物理设备的行为有很大差异。。。。
  • 目前已提出的分析方法包括:
    • 全硬件模拟: 模拟该设备上的所有硬件。 先不说复杂度,很多芯片的文档都是难以拿到的。
    • Hardware Over-Approximation: 作者举了几个例子,这种系统会假设CPU从IO端口可能读到任意的值,一个中断可能在任何时间发生,CPU从IO端口总是能读到数据,不需要等待。。
    • Firmware Adaptation: 固件的一部分是可以分离出来单独进行分析的,也就是固件本身是一个linux。。但是在低端设备上固件一般都一个是整体
  • 作者提出的是: 模拟CPU,然后把所有的IO中断都传给实际的物理设备。。

Avatar

  • 系统结构
    • 直觉的想法是直接连线,把cpu的所有引脚都抽出来,中断/IO相关的部分的引脚就是与外围相关的部分,然后虚拟CPU对应的针脚“连接”到物理设备的针脚上。。作者显然不想这么做。。而且实现难度无限大。。
    • 作者采用了一种比较通用的方式
    • 直接来看作者的整个系统框架图:Figure 1
      • 左边的Emulator就是一个带符号执行功能的ARM CPU模拟器:
        • qemu config和qemu gdb 是用来改变qemu的行为(在需要的时候修改CPU的寄存器状态)
        • S2E QMP/Lua 符号执行相关吧,不确定。。
        • RemoteMem plugin:是用来将获取VM中memory和修改memory用的
      • 右边是target device:
        • 两种方式获取/修改状态:
          • 在系统中植入gdb stub(Remote_Debugging)
          • 很多设备上可能有JTAG,那么可以直接访问寄存器和内存
        • 然后用户通过一个GDB adapter(或者别的adapter)访问,看起来就像是在调试一个普通的进程
  • Full-seperate mode
    • 所有指令都由Emulator执行,通过UART(38400bps)每秒只能传送5次内存写的请求(JTAG 应该会快一些)
    • 这根本慢的无法接受,况且很多执行过程还要求在一定时限内完成。。
      • 一些polling 的循环要跑好久。。
      • 一些来自时钟的中断不断触发,模拟器前一次的中断还没处理完,下一次的又来了。。。
    • 所以文章后面的部分作者都在尝试解决这个慢的问题。。
  • Context Switching
    • 我们可以先从某一特定位置开始才模拟执行
      • JTAG本来就是用来调试硬件的,可以下断点
      • debuger也可以下断点
    • 模拟执行完毕之后:
      • 我们也可以把控制权交回硬件,来看接下来硬件的执行效果。。

Overcoming the Limits of Full Separation

  • 内存访问:
    • 分析:
      • 首先,没有必要就不需要在每次取指令时通过adapter从物理内存中取,预先取好了之后在任何时候都不会变的。。
      • 其次,一个完整的函数进行模拟执行,整个栈也是不需要从物理内存中取的。。
      • 最后,自己想想的话,会被外围设备修改/访问的内存只会有特定的一些(内存映射),剩下所有的内存都是可以直接放到模拟器里的
    • 所以如果可以识别出那些地址空间是IO,哪些不是,然后在context switch到模拟器之前,将所有不是IO的部分都拷入模拟内存,然后在执行过程中将其他部分通过adapter传过去就好了。。
    • 下面是作者对硬盘的bootloader的内存访问的统计

      Access Type Read Write
      Code 61632 0
      Stack&Data 646 1795
      I/O 3614 2097
  • 自动迁移:
    • 首先是一个已经实现的,一个轮询的循环,等待某一个设备是否完成,只会访问某个IO,这个过程就不需要再模拟器上执行了,扔回到物理设备上执行,而且还不需要传输内存(因为这段代码完全不访问模拟内存)
    • 类似的,所有我们不关心的代码都可以这样做,如果他只访问很少的内存,那么迁移回到物理设备上执行,大幅提高效率(依赖静态分析,作者还没有完全实现)

Extending Avatar

  • 到此为止,宏观上看,作者已经有了一个模拟器,针对部分代码进行分析的话,执行效率不算差
  • 目前avatar拥有的符号执行相关的功能:
    • 检测PC是否是符号化的,读取内存,写入内存使用的地址是不是符号化的(其实看起来更像是污点分析)
    • 具体怎么实现的其实并不重要,模拟器都有了,符号执行就很自然了
    • (大不了把整个解释器放在一个符号执行引擎里跑也可以- –)
  • 目前的limitation
    • 局限性都在模拟器和target的状态同步上:
      • 有的设备上有DMA, 有些内存的修改并不通过CPU实现,而是通过CPU发送IO请求给DMA去做。。。。然而我们并不知道各种DMA具体的协议,所以我们不知道DMA做了什么。。。
      • 我们并不知道哪些内存被target访问过,因此如果迁移到target的代码的静态分析结果无法完全确定访问的内存,那么这段代码执行结束后,就需要把整个内存传输回模拟器
      • 符号执行只能在模拟器上实现,也就意味着target执行到分支点之后只能选择一个分支继续执行,执行之后难以再回到分支点(即使恢复了内存和寄存器,外围设备的状态也难以恢复。。)。。
        • 当然,我们可以尝试做重放。。。慢。。(而且不可靠。。)

Evaluation

  • 三个实验分别是对一块硬盘,一个zigbee传感器(zigbee是一种低功耗无线局域网协议)以及摩托罗拉C118的分析
    • 硬盘:
      • 硬盘的UART有一个用来升级的菜单
      • 硬盘的JTAG不具备调试功能,所以只能植入stub,
      • stub首先执行,然后才是bootloader,
      • 作者首先尝试模拟执行到UART输出menu并等待用户输入:
        • full-seperate执行了一天,太久了,放弃
        • 加上非IO内存访问的优化,花了8个小时
        • 由于大量的时间都花在了读取bootloader读取flash中的OS,解压到内存的过程中,作者虚拟了那块flash,现在就只需要4分钟就可以执行到menu了
      • 符号化menu的输入,并符号执行,用户就可以检测menu中是否有没有显示的隐藏命令。
      • 再作者的分析中并没有发现隐藏命令,不过发现一些命令参数解析的错误
    • zigbee 传感器:
      • 这个设备有JTAG
      • 直接再解析数据包的地方下断点,context switch 然后符号执行,发现有个地方可以控制返回地址为不合法的值
    • C118:
      • 有JTAG
      • 之前已经有关于畸形SMS导致错误的行为的报告,不过是fuzz出来的 * 作者这里使用自己的分析引擎断在接受到SMS数据之后,并将对应的内存标记为符号,开始符号执行:
        • 花了10个小时,。分支出120,000个状态。。。用尽了电脑的60G内存,没有跑出来。。。
        • 作者又尝试跑完了42个用来decode的subroutine,然后那个已知的问题也没能跑出来。。
        • 最后作者放弃了,说SMS的协议栈太过于复杂。。。符号执行的路径爆炸问题并不是本文的重点。。。

Conclusion

Avatar allows to analyze firmwares that rely on completely unknown peripherals.

  • 作者实现了模拟器和物理设备进行context switch的想法,
  • 通过最后的实验也论证了这种模拟执行的效率是可以接受的
  • 并且通过符号执行,证明再整个平台上去做已有的动态分析是可行的

Let’s GoSSIP 信息安全研究奖励计划

一、 介绍

Let’s GoSSIP 信息安全研究奖励计划(下称“奖励计划”)是上海交通大学计算机系密码与计算机安全实验室软件安全小组设立的一项本科生学术研究奖励计划。期待能够寻找未来软件安全领域的创新解决方案,发掘潜在的未来软件安全研究人员。

首届奖励计划将于2015年6月开始实施。

二、 项目申请

1. 申请人条件

2016年7月前未毕业的应届普通高校全日制大学本科生。

申请人可以单独申请课题,也可以组织3人以下(包括3人)的研究小组共同申报1个课题。

2. 课题范围

移动终端安全;程序逆向分析;密码工程应用分析或者其他软件安全相关课题。

课题研究期限:2015年6月1日-2016年5月31日

3. 奖励标准及名额

本次活动将从所有的项目申请书中挑选5个优秀项目入围,并进行技术指导和经费资助。项目申请人需要按照提出的设计完成一个完整的信息安全项目,每个项目会得到10000元的资助(具体项目工作可在承担者所在学校开展,承担者需要对项目进行阶段性报告,资助会按照项目进展逐步发放)。5个入围项目最终将评选出1-2个最佳项目,为入围的项目组的同学提供进入GoSSIP研究小组开展暑期实习或毕业设计的机会,并额外给予10000元的资助。

4. 申报方式

申请人按要求撰写申请书(下载),将电子版及附属材料发送至我们的邮箱:contact@securitygossip.com。申请截止日期为2015年5月31日(在此期限之前可以随时提交)。

四、 主办单位

上海交通大学 密码与计算机安全实验室 GoSSIP软件安全小组(下称“GoSSIP”)隶属的上海交通大学计算机系密码与计算机安全实验室(LoCCS),成立于2004年。GoSSIP成立于2012年,自成立之日起便开始承担大量国家和上海市重大科研项目,拥有非常优越的软硬件条件。GoSSIP小组多名同学为上海交大CTF战队0ops成员,在各类信息安全竞赛活动中取得过优异成绩,在国内程序分析和软件安全研究领域内享有很高声誉。GoSSIP在相关领域发表国际会议论文二十余篇,国际学术期刊论文十余篇(SCI)。LoCCS实验室和GoSSIP正处于快速发展的时期,希望能够为技术扎实,自驱动力强,具有团队精神的同学提供良好的研究和发展的空间。

  • 地址:上海市闵行区东川路800号交通大学电信群楼3-337
  • 电话:021-34204756

更多信息:

微信扫一扫

密码学误用分析实例:Cryptcat

0x0 背景

Cryptcat是经典网络工具netcat的加密版,使用twofish算法加密,其密钥协商过程基于发送、接收双发共享的一个password。

Cryptcat密码学模块的源文件主要为farm9crypt.cpptwofish.cppfarm9crypt.cpp作为netcat和twofish之间的接口,twofish.cpp实现了加解密算法。本次分析的源码来自其sourceforge项目主页 ,unix版的cryptcat密码学模块基本相同。

0x1 加解密流程

Cryptcat使用了CBC(密文分组链接)模式,大致流程如下:

  1. 发送端将待发送数据的size与一些“随机数”用password加密后发送,接收端解开后可以得知size
  2. 将第一步的密文与第一步的明文异或后,用password加密发送,密文作为后续CBC模式的IV
  3. 在CBC模式中,采用了ciphertext stealing技术,可以发送不是分组长度倍数的数据

ciphertext stealing

如上图,b为分组长度,b-d是最后一个分组的填充长度,默认用0填充。在传输密文时,倒数第二个分组(C_3)后半部分b-d长度的密文无需传输,因为C_4解密后可以得到这部分的值。所以利用Ciphertext Stealing技术,在无需扩展密文长度的情况下进行分组加密,减少了不必要的网络传输。

0x2 密码学安全问题

2.1 初始化

keystr为用户输入的password,此处使用了固定值的随机数种子。

extern "C" void farm9crypt_init( char* keystr ) {
       printf( "farm9crypt_init: %s\n", keystr );
       encryptor = new TwoFish( generateKey( keystr ), false, NULL, NULL );
       decryptor = new TwoFish( generateKey( keystr ), true, NULL, NULL );
       initialized = true;
       srand( 1000 );
}

2.2 密钥初始化

twofish2.cpp中的generateKey函数,功能是将用户提供的字符串password转换成twofish的128bit密钥。

static char key[32];
char* generateKey( char* s ) {
    int sIdx = 0;
    for ( int i = 0; i < 32; i++ ) {
        char sval = *( s + sIdx );
        if (( sval >= '0' ) && ( sval <= '9' )) {
            key[i] = sval;
        } else if (( sval >= 'a' ) && ( sval <= 'f' )) {
            key[i] = sval;
        } else {
            int q = sval%16;
            if ( q < 10 ) {
                key[i] = ('0' + q);
            } else {
                key[i] = ('a' + q - 10);
            }
        }
        sIdx++;
        if ( *( s + sIdx ) == 0 ) {
            sIdx = 0;
        }
    }
    return( &key[0] );
}

对password的每个字符,函数用取模的方式只取了4个bit,如果password过短的话函数就对passwrod进行循环,超过32个字符的话则会丢弃剩下的部分。造成多个字符串可以对应相同的twofish密钥,并且还存在默认密码metallica的情况。

p.s. 这个bug已经有人报告了,但开发者没有回复 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=715415

2.3 CBC模式

iv的产生与farm9crypt.cpp中的farm9crypt_write函数有关。

char tempbuf[16];
    char outbuf[16];
    sprintf( tempbuf, "%d %d", size, rand() );
    tempbuf[strlen(tempbuf)] = 'x';
    encryptor->setSocket( sockfd );
    encryptor->setOutputBuffer( (unsigned char*)&outBuffer[0] );
    encryptor->resetCBC();
    encryptor->blockCrypt( tempbuf, outbuf, 16 );
    encryptor->blockCrypt( tempbuf, outbuf, 16 );

tempbuf的取值来自传输数据的size和rand(),而rand的种子在farm9crypt_init中被设定为了1000,因此这里rand并没有产生随机意义。随机的来源还是开辟数组空间后栈上原来的值。

encryptor->blockCrypt( tempbuf, outbuf, 16 );

这一语句出现了两次,blockCrypt函数的作用是对输入进行加密或解密。 第一次将tempbuf加密后发送给接受端,接收端解密后可以获得待发送内容的size 第二次将tempbuf与第一次的密文异或后加密后发送,作为CBC模式的IV.

从接受端的函数farm9crypt_read也能看出这一过程,decryptor也调用了blockCrypt函数两次,第一次得到变量limit,就是所要接受数据的大小,atoi的调用对应了发送端的

sprintf( tempbuf, "%d %d", size, rand() );

第二次则是取得了IV的值。

decryptor->resetCBC();
    decryptor->setOutputBuffer( (unsigned char*)&outBuffer[0] );
    decryptor->blockCrypt( buf, outbuf, 16 );
    decryptor->flush();
    decryptor->setOutputBuffer( (unsigned char*)&outBuffer[0] );
    decryptor->blockCrypt( buf + 16, outbuf2, 16 );
    int limit = atoi( outbuf );
    total = 0;
    char* inbuf = &inBuffer[0];
    while ( total < limit ) {
        int result = recv( sockfd, inbuf + total, limit - total, 0 );
        if ( result > 0 ) {
            total += result;
        } else {
            break;
        }
    }

2.4 传输完整性问题

缺少mac验证。尤其是第一个包,包含了待收数据的大小,被攻击者修改后会导致后续的内容都无法解密。

0x3 总结

从cryptcat源码分析中看到了一些密码学的使用问题包括默认密码、固定随机数种子、IV随机性不足、缺少mac验证等。

我们从这个例子总结的一些密码学相关程序源码的审查方法:

  1. 从注释、头文件包含、函数名等确定各源文件的主要功能和关系,确定密码学实现部分和原语调用部分
  2. 特定的敏感函数,如srand
  3. 有老版本和历史bug的话,关注新版本的bug fix
  4. 加密逻辑与解密逻辑是对应的,可以对照着看
  5. 不能快速理解的源码,可以通过输出中间变量、抓包等方式,观察程序行为来理解