How do exploit developers counter control-flow integrity (CFI) used to prevent ROP-based buffer overflow attacks?

Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
How do exploit developers counter control-flow integrity (CFI) used to prevent ROP-based buffer overflow attacks?
Originally, return-oriented programming (ROP) was invented to counter the no-execute (NX) protection of the stack, by jumping from different memory locations (executable) to execute code (gadgets).
However, control-flow integrity (CFI) is meant to prevent ROP-based execution by dynamically checking the destinations of jumps for validity, i.e., it is no longer possible to jump to arbitrary locations in executable code (only to the beginning of functions etc.)
How does exploit developers counter CFI to exploit NX-protected programs using buffer overflows?
exploit exploit-development
add a comment |Â
up vote
2
down vote
favorite
How do exploit developers counter control-flow integrity (CFI) used to prevent ROP-based buffer overflow attacks?
Originally, return-oriented programming (ROP) was invented to counter the no-execute (NX) protection of the stack, by jumping from different memory locations (executable) to execute code (gadgets).
However, control-flow integrity (CFI) is meant to prevent ROP-based execution by dynamically checking the destinations of jumps for validity, i.e., it is no longer possible to jump to arbitrary locations in executable code (only to the beginning of functions etc.)
How does exploit developers counter CFI to exploit NX-protected programs using buffer overflows?
exploit exploit-development
@forest - I wasn't aware that there were different types of CFI. Although there is no way to bypass it for ROP, has something entirely different been invented that make buffer-overflows feasible? Or are buffer-overflows impossible, given that the CFI protecting is good enough.
â user111854
3 hours ago
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
How do exploit developers counter control-flow integrity (CFI) used to prevent ROP-based buffer overflow attacks?
Originally, return-oriented programming (ROP) was invented to counter the no-execute (NX) protection of the stack, by jumping from different memory locations (executable) to execute code (gadgets).
However, control-flow integrity (CFI) is meant to prevent ROP-based execution by dynamically checking the destinations of jumps for validity, i.e., it is no longer possible to jump to arbitrary locations in executable code (only to the beginning of functions etc.)
How does exploit developers counter CFI to exploit NX-protected programs using buffer overflows?
exploit exploit-development
How do exploit developers counter control-flow integrity (CFI) used to prevent ROP-based buffer overflow attacks?
Originally, return-oriented programming (ROP) was invented to counter the no-execute (NX) protection of the stack, by jumping from different memory locations (executable) to execute code (gadgets).
However, control-flow integrity (CFI) is meant to prevent ROP-based execution by dynamically checking the destinations of jumps for validity, i.e., it is no longer possible to jump to arbitrary locations in executable code (only to the beginning of functions etc.)
How does exploit developers counter CFI to exploit NX-protected programs using buffer overflows?
exploit exploit-development
exploit exploit-development
edited 3 hours ago
asked 4 hours ago
user111854
12819
12819
@forest - I wasn't aware that there were different types of CFI. Although there is no way to bypass it for ROP, has something entirely different been invented that make buffer-overflows feasible? Or are buffer-overflows impossible, given that the CFI protecting is good enough.
â user111854
3 hours ago
add a comment |Â
@forest - I wasn't aware that there were different types of CFI. Although there is no way to bypass it for ROP, has something entirely different been invented that make buffer-overflows feasible? Or are buffer-overflows impossible, given that the CFI protecting is good enough.
â user111854
3 hours ago
@forest - I wasn't aware that there were different types of CFI. Although there is no way to bypass it for ROP, has something entirely different been invented that make buffer-overflows feasible? Or are buffer-overflows impossible, given that the CFI protecting is good enough.
â user111854
3 hours ago
@forest - I wasn't aware that there were different types of CFI. Although there is no way to bypass it for ROP, has something entirely different been invented that make buffer-overflows feasible? Or are buffer-overflows impossible, given that the CFI protecting is good enough.
â user111854
3 hours ago
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
There are many types of CFI. However, CFI that supports both forward and backward edge protection, is deterministic, and is also fine-grained is very rare to come by (the only concrete example I know of is the commercial version of PaX RAP). Most CFI is coarse-grained, which means that a function can return not to only that one function, but to a number of functions with the same function signature (that is, the same return type and exact same arguments). Forward edges come from jumps and calls, whereas backward edges come from returns. The vast majority of CFI only supports one or the other (such as Microsoft's CFG or Clang's CFI), vastly limiting its capabilities.
Another issue with CFI is that it is often probabilistic, using some secret value. Any infoleaks that expose that secret value could be used to break the CFI. Deterministic CFI does not suffer from this, but most deterministic CFI is very coarse-grained. In summary:
Most CFI is not both forward and backward edge, severely limiting its capabilities.
Most CFI is probabilistic, making it vulnerable to infoleaks that can break it.
Most CFI is coarse-grained, letting you return to groups of functions with the same signature.
You can learn a lot more about actual CFI implementations by checking out kCFI and PaX RAP, the only two which I know of that provide full forward and backward edge protection. Unfortunately, since CFI is such a complex topic and there's no one implementation or even technique for CFI, there's no way to answer exactly how an attacker can bypass it without specifying the implementation.
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
There are many types of CFI. However, CFI that supports both forward and backward edge protection, is deterministic, and is also fine-grained is very rare to come by (the only concrete example I know of is the commercial version of PaX RAP). Most CFI is coarse-grained, which means that a function can return not to only that one function, but to a number of functions with the same function signature (that is, the same return type and exact same arguments). Forward edges come from jumps and calls, whereas backward edges come from returns. The vast majority of CFI only supports one or the other (such as Microsoft's CFG or Clang's CFI), vastly limiting its capabilities.
Another issue with CFI is that it is often probabilistic, using some secret value. Any infoleaks that expose that secret value could be used to break the CFI. Deterministic CFI does not suffer from this, but most deterministic CFI is very coarse-grained. In summary:
Most CFI is not both forward and backward edge, severely limiting its capabilities.
Most CFI is probabilistic, making it vulnerable to infoleaks that can break it.
Most CFI is coarse-grained, letting you return to groups of functions with the same signature.
You can learn a lot more about actual CFI implementations by checking out kCFI and PaX RAP, the only two which I know of that provide full forward and backward edge protection. Unfortunately, since CFI is such a complex topic and there's no one implementation or even technique for CFI, there's no way to answer exactly how an attacker can bypass it without specifying the implementation.
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
add a comment |Â
up vote
2
down vote
There are many types of CFI. However, CFI that supports both forward and backward edge protection, is deterministic, and is also fine-grained is very rare to come by (the only concrete example I know of is the commercial version of PaX RAP). Most CFI is coarse-grained, which means that a function can return not to only that one function, but to a number of functions with the same function signature (that is, the same return type and exact same arguments). Forward edges come from jumps and calls, whereas backward edges come from returns. The vast majority of CFI only supports one or the other (such as Microsoft's CFG or Clang's CFI), vastly limiting its capabilities.
Another issue with CFI is that it is often probabilistic, using some secret value. Any infoleaks that expose that secret value could be used to break the CFI. Deterministic CFI does not suffer from this, but most deterministic CFI is very coarse-grained. In summary:
Most CFI is not both forward and backward edge, severely limiting its capabilities.
Most CFI is probabilistic, making it vulnerable to infoleaks that can break it.
Most CFI is coarse-grained, letting you return to groups of functions with the same signature.
You can learn a lot more about actual CFI implementations by checking out kCFI and PaX RAP, the only two which I know of that provide full forward and backward edge protection. Unfortunately, since CFI is such a complex topic and there's no one implementation or even technique for CFI, there's no way to answer exactly how an attacker can bypass it without specifying the implementation.
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
add a comment |Â
up vote
2
down vote
up vote
2
down vote
There are many types of CFI. However, CFI that supports both forward and backward edge protection, is deterministic, and is also fine-grained is very rare to come by (the only concrete example I know of is the commercial version of PaX RAP). Most CFI is coarse-grained, which means that a function can return not to only that one function, but to a number of functions with the same function signature (that is, the same return type and exact same arguments). Forward edges come from jumps and calls, whereas backward edges come from returns. The vast majority of CFI only supports one or the other (such as Microsoft's CFG or Clang's CFI), vastly limiting its capabilities.
Another issue with CFI is that it is often probabilistic, using some secret value. Any infoleaks that expose that secret value could be used to break the CFI. Deterministic CFI does not suffer from this, but most deterministic CFI is very coarse-grained. In summary:
Most CFI is not both forward and backward edge, severely limiting its capabilities.
Most CFI is probabilistic, making it vulnerable to infoleaks that can break it.
Most CFI is coarse-grained, letting you return to groups of functions with the same signature.
You can learn a lot more about actual CFI implementations by checking out kCFI and PaX RAP, the only two which I know of that provide full forward and backward edge protection. Unfortunately, since CFI is such a complex topic and there's no one implementation or even technique for CFI, there's no way to answer exactly how an attacker can bypass it without specifying the implementation.
There are many types of CFI. However, CFI that supports both forward and backward edge protection, is deterministic, and is also fine-grained is very rare to come by (the only concrete example I know of is the commercial version of PaX RAP). Most CFI is coarse-grained, which means that a function can return not to only that one function, but to a number of functions with the same function signature (that is, the same return type and exact same arguments). Forward edges come from jumps and calls, whereas backward edges come from returns. The vast majority of CFI only supports one or the other (such as Microsoft's CFG or Clang's CFI), vastly limiting its capabilities.
Another issue with CFI is that it is often probabilistic, using some secret value. Any infoleaks that expose that secret value could be used to break the CFI. Deterministic CFI does not suffer from this, but most deterministic CFI is very coarse-grained. In summary:
Most CFI is not both forward and backward edge, severely limiting its capabilities.
Most CFI is probabilistic, making it vulnerable to infoleaks that can break it.
Most CFI is coarse-grained, letting you return to groups of functions with the same signature.
You can learn a lot more about actual CFI implementations by checking out kCFI and PaX RAP, the only two which I know of that provide full forward and backward edge protection. Unfortunately, since CFI is such a complex topic and there's no one implementation or even technique for CFI, there's no way to answer exactly how an attacker can bypass it without specifying the implementation.
edited 3 hours ago
answered 3 hours ago
forest
24.9k127893
24.9k127893
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
add a comment |Â
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
Thank you @forest for a very good answer. Why don't Microsoft use PaX RAP then? Is it because the program suffers to much w.r.t. time and size?
â user111854
1 hour ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f196980%2fhow-do-exploit-developers-counter-control-flow-integrity-cfi-used-to-prevent-r%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password

@forest - I wasn't aware that there were different types of CFI. Although there is no way to bypass it for ROP, has something entirely different been invented that make buffer-overflows feasible? Or are buffer-overflows impossible, given that the CFI protecting is good enough.
â user111854
3 hours ago