The relative costs depend very much on what the vulnerability is. To demonstrate this, I'm going to refer to two semi-recent vulnerabilities: the Bash "Shellshock" bug, and the glibc "Ghost" gethostbyname()
bug.
Shellshock
The Shellshock bug was caused by an intricate flaw in Bash's function parsing that could be used to make Bash execute code directly out of environment variables. The bug existed for roughly 22 years before it was publicly found.
A check for whether the bug exists looks like this:
$ env X="() { :;} ; echo vulnerable" /bin/sh -c ":"
Now, finding that bug takes either careful scrutiny of the source code, or a good session with a code fuzzer. But as soon as it's reduced to a test case like this, exploits come easily. For instance, if you know a target server is running a CGI shellscript:
$ nc vulnerable.example.com 80 <<__END
GET /path/to/cgi.sh HTTP/1.1
Host: localhost
User-Agent: () { x; }; printf "%s\n\n" "Content-type: text/plain"; /usr/bin/id
Accept: */*
__END
So Shellshock was hard to find, but once found, it was trivial to exploit.
Ghost
The glibc gethostbyname()
vulnerability, on the other hand, is a buffer overflow vulnerability that can only happen under certain very specific conditions. An attacker can overwrite at most 8 bytes of memory on 64-bit machines, or 4 on 32-bit machines. The attacker has to set up a specially crafted DNS entry, then trick the target into requesting it.
This bug went unfixed for around 13 years, and when it was fixed it was not recognized as a security vulnerability. The Qualys security researchers who did report it as a vulnerability spent a large amount of time testing individual programs for exploitability. A large majority were not, due to the 8-byte limitation and the particulars of how gethostbyname()
is typically used. Note too that simply triggering the bug will generally cause the program to crash: more a denial of service than an exploit.
Their coup de grace, a full remote exploit of the Exim mailserver, is a meticulously engineered Rube Goldberg chain that managed to work around the limitations using specific properties of how Exim happens to organize its memory in specific situations. It's described fully in the security advisory from Qualys, and is too complicated to go into here.
Comparison
I will admit I'm not sure which bug was harder to find. Both sat latent in the code for a long time. Qualys found the Ghost bug "during a code audit"; Stéphane Chazelas found the Shellshock bug by extrapolating from things he already knew about Bash behavior, and an entire series of related bugs were found very quickly once people knew where to look, some with the help of fuzzing tools.
However, the question of which was harder to exploit is much easier to answer. I think it's clear that a very high level of engineering went into finding a way to turn the Ghost bug into a working Exim exploit. Much more work was required than the Shellshock exploit above, which took about 10 minutes to write and test.