|
|
Log in / Subscribe / Register

Security quotes of the week

I started working on this exploit on a build of the upcoming Android N release, and anyone sitting near my desk will testify to the increased aggravation this caused me. A lot of general hardening work has gone into N, and the results are impressive. That’s not to say that exploiting this bug was impossible on N - but a full chain would be significantly more complex. The initial steps to get control of the program are identical; the only significant change is that instead of mediaserver, the target process is a new one - mediaextractor, which runs in a more restrictive sandbox and no longer has the ‘execmem’ privilege, ruling out the mprotect route to shellcode, and meaning that a privilege elevation direct from ROP would be required.

A day or two later I had a fairly complicated self-modifying ROP chain to make the necessary C++ virtual calls to interact with other services from the new, heavily sandboxed, mediaextractor and I was ready to start working on the privilege elevation into system_server. However, every time I tested, attempts to lookup the system_server services failed - and looking in the logs I realised that I’d misunderstood the selinux policy. While the mediaextractor was allowed to make binder calls; it wasn’t permitted to lookup any other binder services! Privilege elevation on N would instead require exploiting an additional, distinct vulnerability.

Mark Brand

Snatching the login credentials of a locked computer just got easier and faster, thanks to a technique that requires only $50 worth of hardware and takes less than 30 seconds to carry out.

Rob Fuller, a principal security engineer at R5 Industries, said the hack works reliably on Windows devices and has also succeeded on OS X, although he's working with others to determine if it's just his setup that's vulnerable. The hack works by plugging a flash-sized minicomputer into an unattended computer that's logged in but currently locked. In about 20 seconds, the USB device will obtain the user name and password hash used to log in to the computer. Fuller, who is better known by his hacker handle mubix, said the technique works using both the Hak5 Turtle ($50) and USB Armory ($155), both of which are USB-mounted computers that run Linux.

Dan Goodin

to post comments

Security quotes of the week

Posted Sep 9, 2016 3:03 UTC (Fri) by wahern (subscriber, #37304) [Link] (7 responses)

There are two functions in libutils/Unicode.cpp that need to match up; the first,
utf16_to_utf8_length is used to compute the size of buffer needed to hold the UTF8 string that will be
the result of converting the source UTF16 string, and utf16_to_utf8 performs the conversion. These
functions are intended to be used together, to first allocate a buffer of the required size and then convert, and
so it is obviously important that they agree on how many bytes of output are needed…

Classic example for why depending on a separate verification or sanity-checking routine is usually a bad idea:

  1. it's too easy for the routines to get out of sync, and
  2. you have double the opportunities to introduce bugs.
This is especially true when parsing is involved and you're not using a parser generator, but more generally when there's no automated way to ensure equivalence between the two routines. Far better to implement constraint checking inline.

I get that it arguably makes memory management easier for the caller while not incurring a performance penalty for speculative output a la strlcpy. I disagree with both parts, but even if so the benefits are far outweighed by the cost. Separating constraint checking from the meat of the code is a security anti-pattern, in C or any other language.

Security quotes of the week

Posted Sep 9, 2016 6:34 UTC (Fri) by alonz (subscriber, #815) [Link] (6 responses)

I suspect at least part of the problem are programmers attempting to be frugal with resources (either because it looks more “cool” or “right”, or because they have learned habits from older / embedded systems). I know I have at least the second symptom here (as I learned to program on a 2KB computer, when 16KB was quite a lot).

In a security-oriented mindset, you would usually allocate either the maximum possible output size or a “reasonable” size—and you would then cautiously track the actual output, either aborting or reallocating if you reach the end of the buffer. This way you indeed never have to estimate the output size[*]; but you will usually waste resources (e.g. in the example given – you would allocate (3*#codepoints) bytes for the UTF8 output, even though this is guaranteed to be 66% wasted if the input is in the Latin1 Unicode block).

[*] You will still need simple estimators, such as arithmetic operations on the input buffer size…

Security quotes of the week

Posted Sep 9, 2016 19:29 UTC (Fri) by dskoll (subscriber, #1630) [Link] (5 responses)

Actually, a UTF-8 codepoint might take up to 4 octets (not 3) according to RFC 3629

Security quotes of the week

Posted Sep 10, 2016 15:46 UTC (Sat) by flussence (guest, #85566) [Link]

Worth noting that 4-byte UTF-8 (the ones above U+10000) are becoming increasingly common due to emoji being there.

(This has the positive side-effect of hastening UCS-2's demise - if you try to put that in your software in the wild today, people *will* notice!)

Security quotes of the week

Posted Sep 10, 2016 15:55 UTC (Sat) by alonz (subscriber, #815) [Link] (3 responses)

Yes, but such codepoints are encoded by two UTF-16 code units… so (3*#codeunits) is still an upper bound.

Security quotes of the week

Posted Sep 10, 2016 21:56 UTC (Sat) by excors (subscriber, #95769) [Link]

That sounds like exactly the kind of subtle logic that is going to lead to security bugs (perhaps when someone adapts your UTF-16 code to work on UTF-32 and now U+10000 is only one code unit, or perhaps when your invalid-UTF-16 error handling code produces more code points per code unit than you expected based on the RFC).

In a security-oriented mindset, you should avoid designs that require you to "cautiously track" anything, because that implies that a momentary lack of caution would result in bugs. You should just append bytes to a dynamically-reallocating string class that eliminates all possibility of buffer overflows so you don't even have to think about it.

Security quotes of the week

Posted Sep 10, 2016 23:59 UTC (Sat) by tialaramex (subscriber, #21167) [Link] (1 responses)

Er. Saying it's "still" true but changing what it is you're claiming to be true is a lousy way to argue AND a bad way to write code

I think you've illustrated exactly the sort of error you're claiming to defend against, by at first saying " (3*#codepoints)" and now saying "(3*#codeunits)" when code units and code points are different things and of different sizes.

In UTF-8, the code units are bytes, and for examples U+1F600 😀 would be F0 9F 98 80, in UTF-16 the code units are 16-bit signed integers. In both cases the code points are integers from zero to 1114111 (0x10FFFF) by fiat, integers outside that range are not valid Unicode code points and needn't have any representation in a valid encoding. Although of course you also need to write code to ensure you don't try to make one...

In an Internet argument you get to say "Well that's what I _really_ meant all along". In code, what you wrote is what counts, and what you wrote was wrong and would result in an overflow, possibly a stack or heap smash that could be a remotely exploitable code execution...

Security quotes of the week

Posted Sep 13, 2016 20:16 UTC (Tue) by barryascott (subscriber, #80640) [Link]

UTF 16 is UNSIGNED 16 bit integer code units I think you will find.


Copyright © 2016, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds