Download - Digging for Android Kernel Bugs
About us
• Keen Team
• Pwn2Own Mobile 2013
• Pwn2Own 2014, 2015
• 0ops and Blue-Lotus members
• Multiple CVE affecting major
SoC solutions
• Also contribute root tools to
community for fun
• Huawei Ascend Mate 7
• User-mode exp of giefroot (by
zxz0O0)
Agenda
• Binary Analysis
• Benefits
• Disassembling kernel
• Fuzzing
• Case study
• Suggestions
• SoC vendors
• Phone/ROM mgfr
• Source Analysis
• Tools and methods
• Analyzer internals
• Case study
Agenda
• Binary Analysis
• Benefits
• Disassembling kernel
• Fuzzing
• Case study
• Suggestions
• SoC vendors
• Phone/ROM mgfr
• Source Analysis
• Tools and methods
• Analyzer internals
• Case study
Benefits of Binary Kernel
• Exact piece of code running on actual devices
• Critical security features
• …with many options
• SEAndroid
• TIMA, etc
• Offset, offset, offset…
• Important for constructing args
• Fuzzing
Preparing Kernel
1. Extract zImage
2. Decompress zImage
3. Flat, plain binary
• Code + Data
• No structure
IDA’s best guess ==>
Preparing Kernel
• Solution: IDA loader
1. Extract address table
• Also determine arch by
address length (64 or 32)
2. Extract (compressed) symbol
name table
3. Create symbols
Fuzzing Targets (1) - mmap
• Call mmap on dev fd
• Create VA => PA mapping in user space
• Boundary check?
• remap_pfn_range
• Fixed or variable start
• PA overlapping
• Long lasting…
• Framaroot (2013)
• Mate 7 root (2015)
Case Study – audio drv mmap overflow
seg000:C059ACE4 vul_mmapseg000:C059ACE4seg000:C059ACE4 var_14 = -0x14seg000:C059ACE4seg000:C059ACE4 MOV R12, SPseg000:C059ACE8 STMFD SP!, {R11,R12,LR,PC}seg000:C059ACEC SUB R11, R12, #4seg000:C059ACF0 SUB SP, SP, #8seg000:C059ACF4 LDR R2, =(dword_C0048C38 - 0xC059AD0C)seg000:C059ACF8 MOV R3, R1seg000:C059ACFC LDR R12, =(unk_C0047244 - 0xC059AD14)seg000:C059AD00 MOV R0, R1seg000:C059AD04 LDR R2, [PC,R2] ; dword_C0048C38seg000:C059AD08 LDR R1, [R1,#4] <== startseg000:C059AD0C LDR R12, [PC,R12] ; unk_C0047244seg000:C059AD10 LDR R3, [R3,#8] <== endseg000:C059AD14 LDR R2, [R2]seg000:C059AD18 LDR R12, [R12]seg000:C059AD1C RSB R3, R1, R3seg000:C059AD20 MOV R2, R2,LSR#12seg000:C059AD24 ORR R12, R12, #0x300seg000:C059AD28 STR R12, [SP,#0x14+var_14]seg000:C059AD2C BL remap_pfn_range
int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn,unsigned long size, pgprot_t prot
);
pfn: constantbefore kernel code
size: ove
rflow
cove
r cod
e and
data
Fix:1. Restrict ACL on devfs node (666 -> 600)2. Add boundary check
Fuzzing Targets (2) - ioctl
• Manipulate underlying device
params.
• ioctl(fd, cmd, args)
• File descriptor
• Command
• Arguments
• Problem: missing spec
document
Fuzzing Targets (2) - ioctl
• Command code
• Specify request type
• Differs from device to device
• Coverage!!!
• Argument
• Structure pointer
• Length, type, etc…
• Digging from binary
Hex-Rays Decompiler
• Assembly => Pseudo C
• API interface:• AST: ctree
• Nodes: citem_t
• 80+ types of node
• 9 types commonly used
enum ctype_t
{
cot_asg = 2, ///< x = y
cot_add = 35, ///< x + y
cot_sub = 36, ///< x – y
cot_cast = 48, ///< (type)x
cot_ptr = 51, ///< *x, access
size in 'ptrsize'
cot_call = 57, ///< x(...)
cot_idx = 58, ///< x[y]
cot_memref = 59, ///< x.m
cot_memptr = 60, ///< x->m,
access size in 'ptrsize'
};
Variable Propagation
• Lack of optimization
• Semi-SSA pseudo code
• int xxx_ioctl(a1, a2, a3)
• a1: fd
• a2: ioctl command
• a3: arg
• We need to track both a2 and
a3
Variable Propagation
• Propagation rules
• cot_asg nodes
• Straight forward
• Affecting both cmd and arg
• cot_call nodes
• Kernel specific
• copy_from/to_user
• memcpy
• Affecting arg only
Variable Propagation
• Inter-procedure propagation
• copy_from/to_user is a
special case
• memcpy
• For non-special case
propagation, decompile the
sub-routine recursively to
proceed
https://android.googlesource.com/kernel/mediatek/+/58a89abc8fc05796b12fd8829dac415c9e3f01e2/drivers/misc/mediatek/mmc-host/mt6582/mt_sd_misc.c
Type Re-construction
• cot_add & cot_sub
• Result of var propagation leads to a3
• Offset can be calculated
• Length can be assumed (accurately)
• Handling inter-procedure scenarios
• Just like variable propagation
Case Study – sdcard driverstatic int simple_mmc_erase_partition_wrap(
struct msdc_ioctl* msdc_ctl){
unsigned char name[25];
if (copy_from_user(name, (unsigned char*)msdc_ctl->buffer, msdc_ctl->total_size))
return -EFAULT;
return simple_mmc_erase_partition(name);}
static int vulnerable_func(struct vul_ioctl* vul_ctl){
unsigned char name[25];
if (copy_from_user(name, (unsigned char*)vul_ctl->buffer, vul_ctl->total_size <== overflow char name[] array))
return -EFAULT;
return other_func(name);}
- Discovered by constructing illegal total_size value- Actually needed bigger total_size as a inlined routine- Impacting almost every phone using that brand of SoC when discovered
Fix:1. Restrict access to the devfs node (bypassed by another configuration bug :-S)2. Check total_size before calling copy_from_user
Agenda
• Binary Analysis
• Benefits
• Disassembling kernel
• Fuzzing
• Case study
• Suggestions
• SoC vendors
• Phone/ROM mgfr
• Source Analysis
• Tools and methods
• Analyzer internals
• Case study
Secure Android with Dragon Wings
• 1. Android Kernel Source
• http://www.cyanogenmod.org/
• 2. Kernel Source Preprocessing
• http://llvm.linuxfoundation.org/
• 3. Apply Clang-Analyzer to Kernel Source
• http://clang-analyzer.llvm.org/
• 4. Review the Clang-Analyzer Report
Clang-Analyzer Internals - A Node
ProgramPoint
• Execution Location
• Pre-statement
• Post-statement
• Entering a call
• …
• Stack Frame
ProgramState
• Environment
• Expr -> Values
• Store
• Memory Location -> Values
• GenericDataMap
• Constraints on symbolic values
Android Kernel Source Preprocessing
• Android ARM Toolchain
• -target arm-none-linux-gnueabi -gcc-toolchain
• Clang compatibility processing
• BUILD_BUG_ON
• sbcccs in __range_ok()
• Checker compatibility processing
• copy_from_user / copy_to_user etc.
• remove the “inline” keyword
• Kernel Source Building/Pruning
• only care about 3rd party drivers
• make C=1 CHECK="arm-eabi-gcc" CHECKFLAGS="-E -o $<.i" V=1 –j8
• Actually there is still a lot can be done...
Clang-Analyzer - AST Checker
• 1. FuncInfo->isStr(“remap_pfn_range”) ?
• 2. TheCall->getNumArgs() == 5 ?
• 3. arg3->isEvaluatable() ?
• 4. foreach variable in arg3:
• visit the ASTBody to decide whether it is
constrained.
• 5. Are all the variables in arg3 not
constrained ?
• 6. report the potential bug.
Clang-Analyzer - Path-Sensitive Checker
• Checker Events• checkPreCall / checkPostCall
• checkLocation
• checkBind
• …
• Checker States• REGISTER_MAP_WITH_PROGRAMSTATE(ExampleDataType, SymbolRef, int)
• int currentlValue = state->get<ExampleDataType>(Sym);
• ProgramStateRef newState = state->set<ExampleDataType>(Sym, newValue);
Building a Checker in 24 Hours: http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf
Agenda
• Binary Analysis
• Benefits
• Disassembling kernel
• Fuzzing
• Case study
• Suggestions
• SoC vendors
• Phone/ROM mgfr
• Source Analysis
• Tools and methods
• Analyzer internals
• Case study
Suggestions
• SoC vendors
• Establish security response team
• Build in-house vulnerability research capabilities
• Acknowledge security researchers
• Qualcomm security team is great
• Phone manufacturers / ROM makers
• Keep tracking latest security advisories from SoC vendor
• Audit custom code, involve 3rd party when needed
• Hot patching?
• Contact us
• Twitter: @K33nteam
• Email:
Thank you
• And we are HIRING!
• Vulnerability & exploitation
• Kernel, app, etc
• Location
• Shanghai (HQ)
• Beijing (Subsidiary)