

Exploiting a Go Binary - fabriceleal
http://codearcana.com/posts/2013/04/23/exploiting-a-go-binary.html

======
laumars
This is what should happen in IT. Someone looks for a vulnerability; find it.
Determine if the project owners need prior warning; then go public. Everyone
becomes aware of the issue and upgrades their systems accordingly. Problem
solved.

Criminalizing those who are only looking to harden the security of public
facing infrastructures from those who don't have good intentions doesn't help
anyone. And while I'm sure that Geohot and Reece took on this challenge as
more of a fun exercise, we've all benefited from the results.

So I look forward to reading more articles where hackers attempt to exploit Go
binaries; and subsequently how to avoid my own Go binaries from being
exploited the same way.

(i should add, this is a more generalized comment. I'm aware that this
specific attack isn't a practical real-world vulnerability)

~~~
StavrosK
Well, to be fair, if you don't want your binaries exploited, don't write the
exploit into them. I can't see a case where this could be used, unless you're
letting people execute arbitrary code on your system, in which case you're
screwed anyway.

~~~
_ak
> Well, to be fair, if you don't want your binaries exploited, don't write the
> exploit into them.

That's a bit naive and not the point of this PoC. The exploit used a bug in
the code generator. Normally, guard code would have been generated that would
have caught that issue, but it just wasn't, and that's why the exploit worked.

So in theory, every program with that particular programming bug and the
missing guard code (due to the code generator bug) is vulnerable.

~~~
StavrosK
Vulnerable to what? As far as I can see, it will crash or corrupt memory when
it tries to read/write to it. An actual _exploit_ of this requires intent.

~~~
_ak
"Never ascribe to malice that which is adequately explained by incompetence"

Imagine a programmer has a shitty day, lacks concentration, and adds code like
this to his internet-facing server app:

    
    
        type Embedded struct {
           offset [0x400100]byte
           address uint32
        }
    
        type Struct struct {
           *Embedded
           bar int
        }
    
        var instance Struct
    

Later in the code, he forgets to initialize instance.Embedded.

When handling an HTTP request that comes from the internet,
instance.Embedded.address is filled from a GET parameter. Et voila, anyone who
can do a GET request can overwrite memory, possibly leading to code execution.

The bug in the code was unintentional, because programmers (like all humans)
make mistakes, the HTTP request was intentional (it was done by the attacker),
and the exploit worked because of a bug in the code generation.

That's what I meant by vulnerable.

~~~
StavrosK
Ah, okay. I think this particular exploit falls a bit too far into the "you
have to work to make it useful" spectrum (the "offset [0x400100]byte" part),
but I see how it might be exploitable, thanks.

~~~
saidajigumi
It's also worth remembering that a complete exploit can often compose numerous
"small" vulnerabilities into the realized breach. As such, it's easy to
discount a seemingly hard-to-exploit vulnerability until you see it in action.
It may be used in concert with other weaknesses or "widened" by an unforeseen
technique.

As a specific example, check out the two-part wrap-up of the Pwnium browser
hacking competition[1] [2]. It's a great illustration of chaining weaknesses
together to achieve a desired exploit.

[1] [http://blog.chromium.org/2012/05/tale-of-two-pwnies-
part-1.h...](http://blog.chromium.org/2012/05/tale-of-two-pwnies-part-1.html)

[2] [http://blog.chromium.org/2012/06/tale-of-two-pwnies-
part-2.h...](http://blog.chromium.org/2012/06/tale-of-two-pwnies-part-2.html)

~~~
StavrosK
Oh wow, that guy exploited 14 bugs to craft the exploit. That's some work...

------
tptacek
To be clear: this is an attack that works if you're compiling and executing
malicious Golang code, as if it were Javascript.

~~~
NateDad
Or if you happen to have some fairly odd code in your executable. All that
this really needs is really big array of bytes in one struct of your code.
While anything that big should be unusual, you never know what crazy stuff
people will write.

~~~
tptacek
Odd code like that will crash your executable, and may set up the conditions
for some other exploit, but this one requires the code to be very specifically
written to maliciously overwrite a function pointer.

~~~
pcwalton
What if, instead of a function pointer, an interface happened to be at that
address? Given that interfaces are extremely common in Go, it seems plausible
to me that many addresses in the heap could contain interfaces (and if they
don't, then it may be possible to manipulate an application to create many
interfaces so that they do). An attacker could overwrite the vtable pointer to
point to attacker-supplied memory, and then an indirect call through the
vtable could jump to shellcode.

~~~
tptacek
Sure, that's a plausible vulnerability concept for Go. Someone just has to
find a way to do that. :)

------
onlydnaq
If we are writing programs to write to arbitrary memory, wouldn't it be easier
to write them in C? :)

    
    
      int main(int argc, char *argv) {
        *((char *)addr_to_write) = val_to_write;
      }
    

On a more serious note: this is a fun compiler bug, but I wouldn't call it a
valid exploit. If you have the power to run your own binary on a system, then
of course you can write to any memory the process has access to.

~~~
tptacek
It's valid in the sense of, if you tried to use an in-language sandbox to keep
people from running arbitrary code on your machine, this would bypass it.

------
bishop_mandible
Non-executable heap and stack in Go 1.1 - nice!

~~~
gngeal
Huh, there goes my plan to write a dynamic assembler in Go...

~~~
cthom06
You can still use mmap/equivalent to allocate executable memory and package
unsafe to use it; the difference is that the memory allocated normally by the
runtime won't be executable.

Or I missed the sarcasm.

~~~
gngeal
What sarcasm? Well, if I could mmap it, that would be fine, although it would
mean that I'd have to manage the memory for the machine code fragments by
hand, as opposed to having them as part of GCd values.

------
mvzink
I'm really excited to see people working on security in Go. Security by
default is supposed to be one of Go's "features" at some level. (The typical
example: your first several C programs probably had many buffer overflow
vulnerabilities, but it's very likely none of your Go programs ever will.)
Still, Go hasn't been very thoroughly tested and security hardened, so I'm
hoping to see many more exploits like this discovered and ironed out in the
near future.

------
AYBABTME
For some reason, the website is not loading here and Google's cache dates from
before the release of the exploit, so the post is hidden.

Anybody has a mirror or some way to access the post?

~~~
_ak
It was accidently deleted. [https://groups.google.com/d/msg/golang-
nuts/wZILkqFbbus/j9Wq...](https://groups.google.com/d/msg/golang-
nuts/wZILkqFbbus/j9WqQZQdaGwJ)

------
ancarda
I'm a little confused, does this work on 64-bit binaries too?

