Tuesday, 2 August 2016

TAOSSA Chapter 5-6

Ch 5 - Memory corruption

All memory corruption vulnerabilities should be treated as exploitable until proved otherwise

Buffer overflows

Process memory layout
Stack overflows
The runtime stack, activation records (function frames). Stack usually grows downward (Full Descending?). ESP / EBP. Calling conventions
Exploiting stack overflows
SEH attacks. Convenient method for exploiting stack overflows on a Windows system b/c the exception handler registration structures are located on the stack. Stack overflow followed by any exception
Off-by-one errors. Often in dealing with C strings NUL byte is not accounted for correctly. Easy to exploit on x86 by overwriting LSB of saved EBP (also little-endianness combined with FD stack)
Heap overflows. Heap management. malloc(). Exploiting via marking the next block as free and causing a single controlled fixed size value to be written to a controlled location

Popular targets of heap overwrites

  • Global Offset Table (GOT), process linkage table (PLT)
  • Exit handlers (Unix)
  • Lock pointers (Win) in process environment block PEB
  • Exception handling routines in PEB (Win)
  • Function pointers
  • Global and static data overflows. Usually result in application-specific attacks. No runtime structures to control

Shellcode

Writing the code
Finding your code in memory. Shellcode must be position-independent

Protection mechanisms

Stack cookies (canary values). Does not prevent against overwriting adjacent local vars, only saved frame pointer and return address; or against SEH overwrite (so SEH-based exploitation was developed because of stack cookies?)
Heap implementation hardening. Header cookie related to a global cookie and chunk’s address. Or additional checks on unlink operation. Similar deficiencies
Non-executable stack and heap. ROP bypasses this
Address space layout randomisation. Limitations: find something in memory that’s in a static location; or bruteforce where possible
SafeSEH. When exception is triggered, EH target addresses are checked. Bypasses depend on specific implementation. Function pointer obfuscation. Obfuscate any sensitive pointers stored in globally visible data structures. Limitations - can still overwrite app-specific pointers.

Assessing memory corruption impact

Where is the buffer located in memory?
What other data is overwritten? Pay special attention to any variables in the overflow path that mitigate exploit attempts (e.g. pointers that are freed before return)
How many bytes can be overwritten?
What data can be used to corrupt memory? Sometimes attacker does not control what data is used to overwrite memory. Often happens with off-by-ones
Are memory blocks shared? Determining whether memory-block-sharing vulnerabilities are exploitable is usually complicated and application specific
What protections are in place?

Ch 6 - C language issues

Background

Data storage overview

Chars are usually signed in implementations
Integers, floats, bit fields
Integers have precision and width, for signed ints width = precision + 1
Typedef as aliasing Signed representations: sign+magnitude; one’s complement; two’s complement (the most common) Byte order - big endian (RISC various), little endian (x86)
Common lengths: char type - signed by default and take up 1 byte. The short type takes 2 bytes, and int takes 4 bytes. The long type is also 4 bytes, and long long is 8 bytes. Also known as ILP32LL
64 bit architectures tend to be LP64 (long, long long, and pointer are 64 bit)

Arithmetic boundary conditions

Numeric overflow / underflow (wrapping). Used to manipulate length checks
NB: chars and shorts in arithmetic expressions are converted to ints first

Unsigned integer boundaries

In a typical case memory is allocated after multiplying user controlled values, then for loop is used to fill the memory x86 detects integer overflows but C cannot access the mechanism (OF flag)

Signed integer boundaries

In C spec, the result of under/overflow with signed integers is implementation defined and could include a machine trap. Usually though it is well defined, predictable and does not lead to exceptions
2’s complement used very commonly

Type conversions

Explicit vs. implicit type conversions. Conversions of integers are most interesting

Conversion rules

  • These rules are two’s complement specific
  • Value-preserving vs value-changing conversions
  • Widening - zero extension (unsigned source) and sign extension (signed source). If a narrow signed type is converted to a wider unsigned type, sign extension occurs(!).
  • Narrowing - only truncation.
  • Converting signed to unsigned of the same width does not modify bit pattern

Simple conversions

  • Casts (to the specified type)
  • Assignments (to the type of the left operand)
  • Function prototypes (to the types in the prototype; if not prototype, default argument promotion)
  • Return statement (to the type in the function definition)

Integer promotions

Each integer data type is assigned an integer conversion rank (top to btm):
  1. long long int, unsigned long long int
  2. long int, unsigned long int
  3. unsigned int, int
  4. unsigned short, short
  5. char, unsigned char, signed char
  6. _Bool
You can substitute higher rank by lower rank types. Bit fields are narrower than their base type
Variables of integer types higher than int do not get promoted. Smaller (lower rank/narrower type) ones get taken to an int. If a value-preserving transformation to an int can be done, it is; otherwise a value-preserving conversion to an unsigned int is performed
Almost everything is converted to an int. To unsigned int - only unsigned int fields with 32 bits or some implementation specific integer types
In K&R days promotions were unsigned-preserving (e.g. unsigned char -> unsigned int)

Integer promotion applications

  • Unary + operator promotes
  • Unary - operator promotes first then does negation by 2’s complement, regardless whether the promoted operand is signed
  • Unary ~ operator - 1’s complement after promotion
  • Bitwise shifts promote both operands; result is the same type as promoted left operand
  • Switch statements: controlling expression is promoted, then all switch constants converted to the resulting promoted type
  • Function invocations: for functions w/o prototypes - when called, default argument promotions apply. Each argument is promoted, and any floats converted to doubles

Usual arithmetic conversions

Transforming 2 operands in an expression into a common real type
  1. Floating point takes precedence (int -> float, less precise -> more precise)
  2. Apply integer promotions (when neither is float). => Types narrower than int are promoted to an int
  3. If both operands are the same type after int promotions, done
  4. If operands are same signedness, different type, converted to the wider type (these will be always wider than int)
  5. If the unsigned type is wider than or same width as a signed type - signed is converted to the type of the unsigned operand
  6. If the signed type wider than unsigned type & value-preserving conversion is possible - transform everything into the signed integer
  7. It the signed type wider than unsigned type & value-preserving conversion is impossible - take the type of the signed integer type, convert it into a corresponding unsigned integer type, then convert both operands to that type. E.g. unsigned int and long int (if long int width is the same as int) converts to unsigned long int

Usual arithmetic conversion applications

  • Addition (when both arguments are of arithmetic type)
  • Subtraction between 2 arithmetic types
  • Multiplicative - always arithmetic types, always converted
  • Comparison - always converted, result is an int = 0 or 1
  • Binary bitwise operators require integer operands, conversion applies
  • Questions mark operator - compiler decides on the type of the operand based on the types of 2nd and 3rd arguments, first arg does not affect

Type conversion summary

In addition to the above, sizeof is of type size_t which is unsigned integer type
Auditing tip: check assembly for conversions, beware of optimisations.

Type conversion vulnerabilities

Implicit type conversions are the source of vulnerabilities

Signed/Unsigned conversions

The most common case is simple conversions b/w signed and unsigned integers, esp. in assignments, function calls, or typecasts
Calling a function that expects an unsigned int with a negative parameter is a common case. Negative value gets interpreted as a huge positive int
Many libc routines use an argument of type size_t which is unsigned int the same width as pointer.
Important not to get a negative parameter into read(), recvfrom(), memcpy(), memset(), bcopy(), snprintf(), strncat(), strncpy(), and malloc()

Sign extension

Can occur:
  • because of typecast, assignment, or function call
  • if a signed type smaller than an integer is promoted via the integer promotions
  • as a result of the usual arithmetic conversions applied after integer promotions because a signed integer type could be promoted to a larger type, such as long long
In some cases sign extension is value changing (e.g. a negative value from char to unsigned int) and has an unexpected result
Programmers often forget that char and short types are signed, especially in network code that deals with signed integer lengths or code processing binary or text data one char at a time
Another place where programmers forget whether small types are signed occurs with use of the ctype libc functions
Programmers rarely intend for their smaller data types to be sign-extended when they are converted, and the presence of sign extension often indicates a bug
Sign extension is somewhat difficult to locate in C, but it shows up well in assembly code as the movsx eax, [XXX] instruction; zero extension is xor eax, eax / mov al, [XXX]

Truncation

When a larger type is converted into a smaller type - can only happen as a result of an assignment, a typecast, or a function call that has a prototype
A good place to look at - in structure definitions, especially in network-oriented code

Comparisons

In comparisons, the compiler first performs integer promotions on the operands and then follows the usual arithmetic conversions on the operands to get compatible types. These promotions and conversions might result in value changes (because of sign change), and the comparison screws up
gcc -Wall does not warn on impossible condition checks (e.g. unsigned < 0), but gcc -W does
Pay particular attention to comparisons that protect allocation, array indexing, and copy operations
Watch for unsigned integer values that cause their peer operands to be promoted to unsigned integers. sizeof and strlen() are classic examples

Operators

Each operator has associated type promotions that are performed on each of its operands implicitly which could produce some unexpected results

Sizeof operator

One of the most common mistakes with sizeof is accidentally using it on a pointer instead of its target (ok to use sizeof(array) but not sizeof(pointer))
Often shows up as a result of editing when a buffer is moved from being within a function to being passed into a function
Look for it in expressions that cause operands to be converted to unsigned values

Unexpected results

2 primary issues with arithmetic operators: boundary conditions related to storage of integer types and issues with conversions that occur in expressions
On 2’s complement machines there are only a few C operators where signedness of operands can affect the result of operations. Their underlying implementation is sign-aware
Comparisons plus right shift >>, division /, modulus %
Right shift - problems when the left operand is signed (and negative). Easy to locate in assembly, look for sar mnemonic Division - when one operand is negative, the result is also negative. Apps often of not account for this possibility
Modulus - same when negative dividend. Often used with fixed-size arrays (hash tables)
Look for div (unsigned) vs idiv (signed) mnemonic in the x86 assembly

Pointer arithmetic

When pointers are subtracted, the result is a signed integer type ptrdiff_t
When C does arithmetic involving a pointer, it does the operation relative to the size of the pointer’s target.
Pointer to an object is treated as an array composed of one element of that object
You can add an integer type to a pointer type or a pointer type to an integer type, but you can’t add a pointer type to a pointer type
E1[E2] is equivalent to (*((E1)+(E2)))
Resulting type of the addition between an integer and a pointer is the type of the pointer

Vulnerabilities

Plenty of vulnerabilities that involve manipulation of character pointers essentially boil down to miscounting buffer sizes
Also, developers mistakenly perform arithmetic on pointers without realising that their integer operands are being scaled by the size of the pointer’s target

Other C nuances

Order of evaluation

C doesn’t guarantee the order of evaluation of operands or the order of assignments from expression “side effects”.
Example is macros or functions with side effects used several times in an expression

Structure padding

Structure members don’t have to be laid out contiguously in memory.
The order of members is guaranteed to follow the order programmers specify, but structure padding can be used between members to facilitate alignment and performance needs.
More visible on 64bit structures.
Comparing memory of 2 “identical” structs with different padding content will lead to incorrect results, or lead to double-free errors

Precedence

Sometimes a precedence mistake is made but occurs in such a way that it doesn’t totally disrupt the program
Precedence of the bitwise & and | operators, especially when you mix them with comparison and equality operators
Same with assignment, but these usually result in a compiler warning

Macros / Preprocessor

Parenthesising of params is important Problems with order of evaluation and side-effects exist

Typos

Programmers can make many simple typographic errors that might not affect program compilation or disrupt a program’s runtime processes, but these typos could lead to security-relevant problems
= in comparisons instead of ==
== instead of = in for loop initial assignment
& instead of && - even if there isn’t an issue caused by the difference between bitwise and logical AND operations in some situations, there’s still the critical problem of short-circuit evaluation (for the logical &&) and guaranteed order of execution
Semi-columns at the end of an if(); statement
Accidental octal conversion. E.g. 040 is 32 decimal
Missing comment sign */ at the end of the line will hide code until the end of the next comment
Missing {} in if statements Commenting out an if’s “then” part together with its “;” will make the next operator “then” part.

Monday, 1 August 2016

TAOSSA Chapter 1-4 summary

I've recently dug up these old notes of mine - they are probably from around 2008. I was jotting down points from The Art of Software Security Assessment as I was going through the book. 
Don't expect this to be a perfect summary, rather a snapshot of things I thought were worth remembering at the time. So, minimal formatting and no fancy sentences :) 

Oh and I asked @mdowd if he would be terribly upset about me posting this, he said no.

Ch 1 - Software vulnerability fundamentals

Augment source audit with black-box testing for best results
Design / implementation / operational vulnerabilities

Common threads

  • Input and data flow. Tracing input is one of the main tasks
  • Trust relationships (between components on an interface). Often the transitivity of trust plays an important role
  • Assumptions and misplaced trust. Example - assumptions on the structure of input by developers
  • Interfaces. Misplaced trust e.g. in cases when the interface is more exposed to external access than developers think
  • Environmental attacks. OS, hardware, networks, file system etc
  • Exceptional conditions

Ch 2 - Design review

Something about software design fundamentals
Issues in algorithms. Errors in business logic or in the key algorithms
Abstraction and decomposition

Trust relationships

Trust boundaries
Simple and complex trust relationships. Chain of trust
Strong coupling: look out for any strong intermodule coupling across trust boundaries. Usually data validation issues and too much trust b/w modules
Strong cohesion: pay special attention to designs that address multiple trust domains within a single module. Modules should be decomposed along trust boundaries.

Design flaws examples

Shatter attacks in Windows - strong coupling
Automountd + rpc.statd - transitive trust

Authentication vulns

“Forgetting” to authenticate
Untrustworthy credentials, e.g verified on a client
Insufficient validation, e.g. in programmatic authN between systems only the client or only the server is authenticated

Authorisation vulns

Web apps often do authZ checks “at the front door” but the actual handler pages omit authZ checks
Often it is possible to authN as a low prig user, but access info from other users, higher privilege
Insecure authorities - inconsistent logic or leaves room for abuse

Other vulns

Accountability - log injection breaks nonrepudiation

Confidentiality

All sorts of crypto problems
CBC (cypher block chaining) is the only good mode for block cyphers
CTR (counter) mode is the best for stream cyphers. IV (init vector) reuse can lead to trouble
Key exchange can be subject to MITM
Storing more sensitive data than needed, or for longer period. Lack of encryption, obsolete algorithms, data obfuscation instead of encryption. Hash issues
Salt values
“Bait-and-Switch” attacks, or hash collision.

Threat modelling

Microsoft stuff. DFDs
Attack trees
DREAD ratings
Prioritising implementation review based on thread modelling

Ch 3 - Operational review

Insecure defaults - of the application and of the base platform or OS
Access control issues
Unnecessary services
Secure channels
Spoofing
Network profile exposure (unnecessary services)

Web-specific issues

  • HTTP request methods.
  • Directory indexing.
  • File handlers (server-side) leading to source disclosure. Uploads.
  • Misconfiguration of external auth.
  • Default site installed.
  • Verbose error messages.
  • Admin interface is public facing.

Development protective measures

  • Non-executable stack
  • Stack protection (canaries)
  • Heap protection
  • ASLR
  • Registration of function pointers (wrapping in a check for unauthorised modification)
  • Virtual machines (only prevent low-level vulnerabilities)

Host-based protective measures

  • Object (e.g. memory) and file system permissions. Permissions are difficult, can be screwed up
  • Restricted accounts. Details of access are important
  • Chroot jails (more effective when combined with a restricted account). Does not limit network access
  • System virtualisation
  • Kernel protections. System call gateway as a natural trust boundary. Additional checks by kernel modules, e.g. SELinux
  • Host based firewalls
  • Anti-malware applications
  • File and object change monitors. Reactive in nature
  • Host passed ID/PS

Network-based protective measures

  • Network segmentation, on all levels of OSI
  • NAT
  • VPNs
  • Network ID/PS

Ch 4 - Application review process

Code review is a fundamentally creative process; it is also a skill, not strictly a knowledge problem
Some businesses focus on easy-to-detect issues (even of low risk) for the fear of issues found and published by someone else; not subtle complex ones
A good reviewer can do 100 to 1000 LoC an hour, depending on code. 100 kLoC takes less than double the time of 50 kLoC
Information gathering: dev interviews, dev docs, standards, source profiling, system profiling

Application review

Do not do a waterfall-like review. The time you’re best qualified to find more abstract design and logic vulnerabilities is toward the end of the review
Design review is not always the best to begin with - e.g. when there is no docs
Initial phase, then iterate the process 2-3 times a day: plan-work-reflect
Initial preparation: top-down (good only when the design docs are good, which is rare); bottom-up (could end up reviewing a lot of irrelevant code) or hybrid

Hybrid approach questions

  • General application purpose
  • Assets and entry points
  • Components and modules
  • Intermodule relationships
  • Fundamental security expectations
  • Major trust boundaries
Planning: consider goals (depending on the stage and level of understanding); pick the right strategy; create a master ideas list; pick a target/goal; coordinate
Work: keep good notes; don’t fall down rabbit holes (can be waste of time); take breaks
Reflect: status check; re-evaluate; peer review

Code Navigation

Code flow navigation - control-flow sensitive or data-flow sensitive. Surprisingly, not used much.
It is more effective to review functions in isolation and trace the code flow only when absolutely necessary (!)
Forward- and back-tracing. Back-tracing usually start from candidate points
Back-tracing examines fewer code flows - easier to do; but misses logic problems or anything not covered by candidate points

Code-auditing strategies

Code comprehension, candidate point, design generalisation

Code comprehension strategies

  • Trace malicious input - difficult in OO code, especially poorly designed. In these cases, do some module or class review to understand the design. “5 or 6 code files before the system manages to do anything with the input”
  • Analyse a module - reading code file line by line, not tracing or drilling-down. Very popular among experienced reviewers. Especially good for framework and glue code. Easy to go off-track
  • Analyse an algorithm. Less likely to go off-track. Focus on pervasive and security critical algorithms
  • Analyse a class or object. Study interface and implementation of an important object. Good for OO code (obviously). Less likely to go off-track than analysing a module
  • Trace black box hits. Fuzz then investigate crashes. Check Shellcoder’s Handbook - Fault Injection chapter

Candidate point strategies

  • General approach. Trace from potential vulnerabilities to user input.
  • Automated source code analysis tool. Similar. Limited to a set of potentially vulnerable idioms
  • Simple lexical candidate points
  • Simple binary candidate points
  • Black-box generated candidate points. Mostly crash analysis. Microsoft’s gflags is useful for heap overflows - “heap paging” functionality in the debugged process. LD_PRELOAD in Linux is useful. Corruption can happen in a buffer or an array (or heap)
  • Application-specific candidate points. Similarities to previously found vulnerable patterns

Design generalisation patterns

  • Model the system. Detailed modelling for security critical components
  • Hypothesis testing. Guess an abstraction and then test the validity of this guess
  • Deriving purpose and function. Somewhat similar; pick key programmatic elements and summarise them
  • Design conformity check. Look at the “grey areas” and common code paths. Look for discrepancies b/w spec and implementation

Code-auditing tactics

Internal flow analysis. Intra-procedural and intra-module analysis. Especially error-checking branches and pathological code paths
  • Error-checking branches - code paths that are followed when validity checks result in an error. Do not dismiss them
  • Pathological code paths - functions with many small and nonterminating branches - branches that don’t result in abrupt termination of the current function. Exponential explosion of similar code paths
Subsystem and dependency analysis
Re-reading code. At least 2 passes
Desk-checking (symbolic execution)
Test cases. Be wary of input data from other modules. Don’t assume the same level of danger as external input, but a be a bit suspicious about it. Boundary cases

Code auditor’s toolbox

Code navigators: cscope, ctags, source navigator, code surfer (slicing!), understand (scripting)
Debuggers: gdb, OllyDbg, SoftICE (yeah right), (Immunity Debugger),
Binary navigation: IDA Pro, BinNavi Fuzzing: SPIKE, (Sulley)

Saturday, 5 March 2016

Fiddling with Nexus 4 boot image

TLDR; How to modify any system to set ro.debuggable=1 without rebuilding it from source. This setting will make any apk debuggable on the device.

Get the existing boot image off the phone

dd if=/dev/block/mmcblk0p6 of=/mnt/sdcard/boot.img # on the phone
adb pull /mnt/sdcard/boot.img # on your computer

/dev/block/mmcblk0p6 is Nexus 4's boot partition.

Install abootimg from https://github.com/coruus/abootimg. The rest of the process below is stolen from this page.

Extract and unpack initrd

mkdir boot 
cd boot
abootimg -x /tmp/boot.img

mkdir initrd
cd initrd
cat ../initrd.img | gunzip | cpio -vid


Edit default.prop, setting anything you want, including ro.debuggable=1.

Repack initrd and boot image

cd initrd
find . | cpio --create --format='newc' | gzip > ../myinitrd.img
 
cd ..
abootimg --create myboot.img -f bootimg.cfg -k zImage -r myinitrd.img

Flash to phone

adb reboot-bootloader
fastboot flash boot myboot.img

Android Studio for refactoring obscure decompiled code

"It's in Foreign" @thegrugq

A while ago, I've been experimenting with using Android Studio for refactoring decompiled code.

  1. Export Java sources, from whatever decompiler works 
  2. "Import project" from sources in Android Studio 
  3. Use Shift-Fn-F6 to rename classes, methods etc 
What's best is that Studio (hurray for IntelliJ IDEA) is sometimes intelligently estimates types of variables and offers reasonably meaningful names:


Friday, 4 March 2016

Using Proguard to deobfuscate code


TLDR; Optimisation features of Proguard can be useful for removing some "obfuscations" that add dead code and screw up control flow.

Proguard comes with Android Studio or can be installed from homebrew on Mac, that one version is newer:


$brew install proguard


Then use a generic script similar to this one:

-injars      <obfuscated jar>
-outjars     <result>
-libraryjars $HOME/Library/Android/sdk/platforms/android-19/android.jar ; or similar
-optimizationpasses 10 
-dontobfuscate
-dontpreverify
-printusage

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

-keepattributes *Annotation*

 
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.admin.DeviceAdminReceiver
-keep public class * extends android.view.View {
 public <init>(android.content.Context);
        public <init>(android.content.Context, android.util.AttributeSet);
 public <init>(android.content.Context, android.util.AttributeSet, int);
 public void set*(...);
}
-keepclasseswithmembers class * {
 public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
 public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.content.Context {
 public void *(android.view.View);
 public void *(android.view.MenuItem);
}
-keepclassmembers class * implements android.os.Parcelable {
 static ** CREATOR;
}
-keepclassmembers class **.R$* {
 public static <fields>;
}
-keepclassmembers class * {
 @android.webkit.JavascriptInterface <methods>;
}
-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-dontwarn android.support.**

Run as proguard @deob.conf and you'll end up with a more readable version of your obfuscated code.

Friday, 26 February 2016

Re-signing VirusTotal samples to install them on a non-jailbroken iPhone

Sir Leigh Teabing: In which year did a Harvard scholar outrow an Oxford man at Henley? 
Robert Langdon: [reluctantly] Surely such a travesty has never occurred.

Why would one even want to do this? Let's say, you're doing some sort of zomg malware research and you want to verify something. You can either use a jailbroken phone, code signing is kinda moot there, or a real phone :)

VT samples of iPhone apps are sometimes encrypted, tough luck then. Most of the time they are already stripped of DRM. So you can download one and rename it to *.ipa. Then the fun begins.
I'll assume you already have a working Xcode setup and can sign and run a test app on your device. If not, Google it, there are bazillions of how-tos on that topic.

The best and most fool-proof application for re-signig is iReSign, or you can do the signing manually, using commands similar to ones here (codesign is the main one, duh) or here. IReSign requires you to chose the application to resign, the certificate and the profile. Entitlements can be usually omitted, the app will attempt it best at recovering the ones required. The ID field can be left unchanged if your certificate allows for * to be signed, otherwise change it to something that you can actually sign for.

Tips

  • If in the process of re-signing VT ipas you get "Getting certificate ID's failed" from iReSign and the cert list is empty, don't worry, this is temporary after 16 Feb 2016 because Apple's root cert has expired. To save you some googling - http://stackoverflow.com/a/35399656 ("Show expired certificates" in keychain, then delete the old ones, install the new one).
  • iReSign needs the correct provisioning profile that applies both to the ipa file being re-signed and your iPhone. It looks like setting them is a little contrived, what finally worked for me was using “iOS Team Provisioning Profile: *” from Xcode. Download it, or a similar one from developer centre. It massively depends on your particular setup, though. The simplest way to test yours is to create a base iOS project with Xcode, fiddle with settings (do not leave them on "Automatic") in "Build Settings"->"Code Signing" and try "Project"->"Run" for your dummy project. If it does install and run, use the same identity and provisioning profile for iReSign.



  • You are likely to get (if you install via Xcode, iTunes install will silently fail) "Can't install application. The Info.plist for application at... specifies a CFBundleExecutable of ..., which is not executable" at some stage. This is because VirusTotal samples do not maintain Unix file permissions and the main executable needs to be, well, executable. Unpack and "chmod +x" then repack the ipa, either before or after re-signing: https://github.com/maciekish/iReSign/issues/45.
  • Sometimes troubles with signing are due to a mismatch of the certificate in the provisioning profile and the keys you have. See here for how to check the DeveloperCertificates in the provisioning profile (and don't forget to split lines in your .pem to 63 char lengths). Then again, overall signing is described in a million places on the Internet :)

Thursday, 11 February 2016

More Meta Than Regehr

Context

This is another meta-meta-meta-meta-model page to show up in Google search. John, you're welcome :D
 

Thursday, 4 February 2016

More IDA Pro plugins for OS X - HexRaysCodeXplorer

Another little thing I did. Compiling was rather painless - mostly changing __LINUX__ to __MAC__ and recovering a few files from pre-6.9 version. It looks like the format of "custom view handlers" in Hex-Rays SDK has changed between IDA 6.8 and 6.9.

So the diff is here and the (IDA 6.8) plugin is here (32bit) + here (64bit).

IMMV - I have only tested that it compiles, displays context menu and C-Tree graph.

I'll maintain a branch for IDA Pro 6.8 OS X for a brief while at https://github.com/agelastic/HexRaysCodeXplorer/tree/OSX_IDA68

Tuesday, 26 January 2016

Compiling non-OSX IDA pro plugins on OS X, or sanity ala Einstein

"Insanity: doing the same thing over and over again and expecting different results." - Albert Einstein

Recently I was looking at more IDA Pro on OS X than normally, so I experimented with themes a bit, e.g. Consonance. Then I found IDASkins. Lo and behold, there are tons of Windows IDA versions for which it has been already precompiled in the github repo, but no OS X ones.

OS X compilation in cmake files in IDASkins is marked "untested" and it is, in fact, a bit buggy. After some fiddling I got the compilation to work, although one of the resulting plugins (one for Ida 64) crashes everything, no idea why :). I'm mostly looking at 32bit ARM anyways, so one plugin is good enough for me.

The diff that made the build work is in this gist. It contains mostly cosmetic changes, plus a weird fact that "if(APPLE)" didn't work properly in the cmake I had (from homebrew?). Plus I haven't used make before :) YMMV

Plugin for 32bit OS X IDA Pro 6.8 is here.

Oh and while I am compiling plugins, here are the two precompiled WWDC plugins for the same version of IDA Pro. No tricks in compiling it from source, just stick it into "plugins" dir of IDA SDK and have a universal or i386 libcapstone.a (the one from home-brew is x64 only, I believe).