A presentation in NanoSec Conference 2020 held virtually with topic Revisiting Software Security.
Security - State the
Special interest group located in Malaysia with
passion in bug hunting, software security, fuzzing,
reverse engineering and exploits.
We called ourselves TomatoDuck Fuzzing Group.
Some of our notable work can be found here:
➔ Overview of Software Security
➔ Our Approach on Hunting
➔ Modern Exploitation
➔ Vulnerability Disclosure - Best
Defense is Oﬀense
What Makes It Failed?
3rd party software developer do not follow mitigations built
by Microsoft, e.g. compiler options.
Lack of Secure Development Lifecycle.
Ignorance from vendor by trying to avoid ﬁxes.
Security is expensive.
What’s Happening Here?
Microsoft has improved so many things including killing bug
Finding vulnerability is SUPER hard.
Exploit mitigations on different aspects, vulnerability become
Exploit development costly.
Our Approach on
Usually we’ll go from low hanging fruit to the complex part.
Our previous work on hunting vulnerability in Antivirus
covering various security issue and methods.
The methods are almost similar, it’s just depends on your
Sometimes we studied other researchers’ bugs, we analyzed
from scratch to understand how it works. We used the case
studies for different test case.
Easiest way to hunt for vulnerability is the access to source
However it is impossible to have access to source code when
it comes to closed source program. Heavily involved in
One way to approach is to fuzz. Fuzzing is hard!
We still rely on traditional method such as ﬁle format fuzzing
- Byte and Bit mutation FTW!
We perform variant hunting
- APIs, Functions, etc.
Dumb & Smart Fuzzing
- Custom & Public
Our resources, 128GB of memory
- Split into multiple VMs, can up to 8 VMs running parallel
- Tweak Windows VM to get a better performance
- Pipe out results to external disk for easy access
- Depends on target, e.g. PDF, DOC
- Hundreds to thousands ﬁles, from 1KB up to 30MB+
We got number of CVEs
For custom fuzzer, we built a fuzzer that speciﬁc to work on
the target ONLY!
- Limited to the target itself
Public fuzzer, we used any available fuzzers such as WinAFL
and CERT BFF
- WinAFL supports coverage guided, APIs
- CERT BFF only ﬁle format, support custom Python plugin
Overall Stats / Results
Our Custom Fuzzer (½)
File format fuzzing still effective these days, although it slow
but we do found numbers of vulnerabilities.
- Mutation on input ﬁle
- e.g. ﬁle.exe input.test
- Covering bit ﬂip
- Random, Range values
- 0x0 to 0xFFFFFFFFFFFFFFFF
- Strings, special characters
- Detecting crashes via debugger, slow but it works :)
- cdb, PyKD or WinAppDBG
- Page Heap enabled
Our Custom Fuzzer (2/2)
Detecting crashes could trigger false alarm
- Split out the result by performing a better ﬁltering
- Check last exceptions e.g. address NULL or has something on
memory / register
- Important info
- Access violation
- Last crash disassembly code, Register value, Stack trace
- At some cases, this required manual veriﬁcation.
Results from Custom Fuzzer
Remote Code Execution:
CVE-2020-0980 - Microsoft Word
CVE-2020-16957 - Microsoft Access
CVE-2020-25291 - WPS Oﬃce
Some don’t assign with CVE, e.g. Foxit PDF Software
We still have pending from vendors. Stay tuned!
Effective but hard to use
- Originally from AFL, now implemented on Windows
- It supports instrumentation, this giving advantage for
coverage guided fuzzing
- Doesn’t work on all environment, our test case only
works on Windows 10 1511
- You can port a custom mutator
- We found numbers of vulnerabilities using WinAFL
- At some cases it required reverse engineering and code
- Writing harness
- Ideally you fuzz on assembly level, you have to extract
that disassembly path and turn it into code
- e.g. If the API available on MSDN, easy to write the harness
- Much more faster however input ﬁle only max to 1MB
- Minimum resources available on Internet, but you can get
the idea how it works :)
Example Results of WinAFL
MSRC Case 58680 - Windows GDI
MSRC Case 58593 - Windows GDI
MSRC Case 58745 - Windows GDI
MSRC Case 58843 - Windows GDI
CERT BFF (½)
- Perform mutational fuzzing on software that consumes
- Easy to use, just conﬁgure the YAML plugin
- Our member found out that you can plugin your own
fuzzer engine scripts (Python)
- e.g. Using another public fuzzer such as Radamsa to call the speciﬁc
parameter to perform mutational. Radamsa will responsible
perform this mutation and the results still pipe to the BFF for triage
CERT BFF (2/2)
- We found numbers of vulnerabilities using this fuzzer
- We tested out the custom scripts that we ported and the
default fuzzer scripts.
- We found out if it is running more than 48 hours, the
performance will turn slow
- The option is to reboot VM for every 2-3 days and restart the
process based on the last execution
- No limit on the ﬁle size but can turn the program to load
- At some cases, it will crash due to several factors such as fail fast,
out of memory, etc.
Example Results of CERT BFF
Remote Code Execution:
CVE-2020-10222 - Nitro PDF Software
CVE-2020-10223 - Nitro PDF Software
CVE-2020-25290 - Nitro PDF Software
CVE-2019-19817 - Nitro PDF Software
CVE-2019-19818 - Nitro PDF Software
CVE-2019-19819 - Nitro PDF Software
Some don’t have CVE - Multiple software
State the Art
Memory corruption exploitation used to be easy
Historically been exploited for decades
Past mitigations not powerful enough to prevent exploitation
Control Flow Guard
GS (Buffer Security
Case Study - Windows GDI
Out-of-Bounds Read vulnerability found in Windows GDI
Reported to MSRC (58593) with the potential exploitation
that leads to info leak. No ﬁx due to by design.
We couldn’t demonstrate full behavior of the exploitation due
to limitation of vulnerability that we had, which requires
Vulnerability was found via fuzzing with WinAFL.
An invalid pointer read error inside GDI32!CreateDIBitmap
API function was found when it tries to copy specially crafted
Further analysis found the vulnerability could be exploited to
achieve information leakage.
An access violation
occurred when harness
triggered crash on
Backtrace shows the
memcpy() was called in
Bug Analysis (½)
The 4th argument was passed
as a pointer to an array of
uninitialized data which later
passed as source for memcpy
to an allocated heap of ﬁxed
6fd67ae is 4th argument
Before reaching to the part
where the input is copied,
there is a check to test if the
3th bit of the pointer
address is set or not.
Bug Analysis (2/2)
Once the check is satisﬁed,
the CreateDIBitmap copies
the uninitialized data to the
allocated heap of size
0x200 and then triggers
the Invalid Pointer Read
With this information, we
could achieve info leak.
To achieve info-leak,
CBM_INIT must be set so that
the system would use the
data pointed by the 4th
argument because we are
going to spray it with the
index of the color table data
and the color table must not
The heap allocation must be
large enough to make sure
the masked pointer still
points to our sprayed data.
Modern exploitation is hard.
To achieve powerful exploitation, one has to chain to multiple
Costs of exploit development will continue grow.
Vuln Disclosure - General (½)
Vulnerability disclosure debate has been there for many
Some people like it, some against.
Painful process for both party, researchers and vendors.
Most vendors these days came with vulnerability disclosure
Vuln Disclosure - General (2/2)
Vendors give feedback, appreciate the work, give bounty.
Some vendors don’t really have proper channel to disclose
vulnerability, e.g. no PGP
Delay in response and sometimes silent ﬁxes has been
shipped to customer.
When disclosing vulnerability, try to provide as much info.
Use all the medium for contact e.g. social media, general email.
Reach to people / researchers out there if you need help.
You can go as Anonymous if you want, Full Disclosure might
Get CERTs involved.
Just never disclose anything not until things are settle.
Most vendors co-operate these days, they might slow or you
need to push a bit.
Before you post anything, make sure to inform vendor and get
their opinion. If it doesn’t work, get your peers to help you.
Seek for advice :)
Vuln Disclosure - Malaysia (½)
Disclosing vulnerability to vendor in Malaysia is pain.
Vendors / Companies trying to avoid those, just don’t care
Past years we saw case(s) vendor tend to sue. Vendor keeps
ignore / deny.
Poor vulnerability management, remediation and security
Vuln Disclosure - Malaysia (2/2)
No one knows you, probably you go as anonymous so no one
Vendors think they do better than you. Ignorance is bliss.
Its 2020, security should be prioritize.
Real World example -
Case Study: Kyrol Labs
We started to look into Kyrol Internet Security product
somewhere end of 2018. Tooks us total 5 days to ﬁnd 12
vulnerabilities, with severity Informational to Critical.
Our ﬁrst email to them on January 2, 2019 and they
responding 2 days after.
The conversation via email until May 2, 2019. Nothing works.
We were looking for alternative before we about to do full
disclosure. Let’s take a look into the timeline of disclosure :)
Jan - Apr May Jun Aug Oct Nov
2 Jan - Sending ﬁrst email to Kyrol Labs
4 Jan - Follow up and vendor respond
8 Jan - They informed us the product is obsolete, we
asked for further update like ﬁxes, etc.
10 Jan - We told them we’ll go full disclosure and they
try to deny. We gave 90 days standard disclosure.
15 Jan - Vendor told us they will ﬁx and expect on April.
16 Apr - Follow up with vendor as the 90 days has
reach. They told us they can’t ﬁx the issue.
18 Apr - We told them we couldn’t wait. We seek for
advice from local community before full disclosure.
18 Apr - Friend from local community help to liaise with
NACSA. We sent vulnerability report to them. NACSA
responding the same day saying that they’ll look into it.
29 Apr - NACSA invite us for discussion over video
conference on May 3.
2 May - Seek update from vendor.
No reply at all.
3 May - Video conference with
NACSA. Presented 12 vulnerabilities
to them. NACSA coordinated the
case to vendor.
13 Jun - Seek update from
NACSA. They have followed
up via call and email.
28 Jun - NACSA invite for
video conference with
vendor. We made a choice
by giving them surprise with
12 vulnerabilities we found.
They said will look into it
and will try to ﬁx the highest
16 Aug - Seek update from vendor.
They told us they manage to
identiﬁed the vulnerability
22 Aug - Our paper in POC Seoul
got accepted and presenting Kyrol
security issue to public in Nov.
23 Aug - We informed vendor and
NACSA we’ll be discussing the
vulnerability to public.
26 Aug - We were told by vendor
they will be releasing new product
29 Oct - NACSA invite us for ﬁnal
discussion with vendor,
face-to-face meeting on Nov 1.
1 Nov - Face-to-face meeting.
Vendor told us they can’t
deliver the ﬁx nor ship new
product in Nov. During
discussion, we told NACSA
that we’ll be disclosing the
issue public due to disclosure
timeline has exceeded (almost
a year). We discuss the matter
of impact. NACSA agree with
our decision and they required
vendor to ﬁx the issue no
matter any constraint.
Vuln Disclosure in Malaysia
We seen that agencies like NACSA and MyCERT slowly
getting better at it. If you found vulnerability, report to
NACSA or MyCERT. CNII prioritized by them.
- NACSA usually drive the process and can help you to hide
- Don’t publish to public, not until you get things settle
with the agencies.
- We can help you if you need help to work closely with
You can contact
➔ Best defense is oﬀense
➔ We help the community to eliminate
➔ Engage with vendors for bugs ﬁx
➔ Future works in planned, fuzzing
hypervisor and custom fuzzer with
➔ Feel free to ping us at twitter
➔ We are open for new blood to join us on
Thank You & Stay Safe!