question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Strange Behaviour: Unconstrained Paths Not Found on Certain Buffer Sizes

See original GitHub issue

Describe the bug. When trying to use angr to find unconstrained paths in a simple scanf buffer overflow, angr can find unconstrained paths on certain buffer sizes (shown below), but not on other buffer sizes.

Environment Information.

Linux 3121919fa5f2 4.19.104-linuxkit #1 SMP PREEMPT Sat Feb 15 00:49:47 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
python3 -m angr.misc.bug_report
angr environment report
=============================
Date: 2020-12-29 09:08:49.280599
!!! runninng in global environment.  Are you sure? !!!
Platform: linux-x86_64
Python version: 3.6.9 (default, Oct  8 2020, 12:12:24) 
[GCC 8.4.0]
######## angr #########
Python found it in /usr/local/lib/python3.6/dist-packages/angr
Pip version angr 9.0.5171
Couldn't find git info
######## ailment #########
Python found it in /usr/local/lib/python3.6/dist-packages/ailment
Pip version ailment 9.0.5171
Couldn't find git info
######## cle #########
Python found it in /usr/local/lib/python3.6/dist-packages/cle
Pip version cle 9.0.5171
Couldn't find git info
######## pyvex #########
Python found it in /usr/local/lib/python3.6/dist-packages/pyvex
Pip version pyvex 9.0.5171
Couldn't find git info
######## claripy #########
Python found it in /usr/local/lib/python3.6/dist-packages/claripy
Pip version claripy 9.0.5171
Couldn't find git info
######## archinfo #########
Python found it in /usr/local/lib/python3.6/dist-packages/archinfo
Pip version archinfo 9.0.5171
Couldn't find git info
######## z3 #########
Python found it in /usr/local/lib/python3.6/dist-packages/z3
Pip version z3-solver 4.8.9.0
Couldn't find git info
######## unicorn #########
Python found it in /usr/local/lib/python3.6/dist-packages/unicorn
Pip version unicorn 1.0.2rc3
Couldn't find git info
######### Native Module Info ##########
angr: <CDLL '/usr/local/lib/python3.6/dist-packages/angr/lib/angr_native.so', handle 1815c70 at 0x4004152550>
unicorn: <CDLL '/usr/local/lib/python3.6/dist-packages/unicorn/lib/libunicorn.so', handle f472a0 at 0x400522deb8>
pyvex: <cffi.api._make_ffi_library.<locals>.FFILibrary object at 0x400426d048>
z3: <CDLL '/usr/local/lib/python3.6/dist-packages/z3/lib/libz3.so', handle 1185390 at 0x40077027f0>

Files used to reproduce.

With buffer size 48:

#include <stdio.h>

void vulnerable() {
   char buffer[48];
   scanf("%s",buffer);
}

int main(){
   vulnerable();
   return 0;

}

Buffer size 50

#include <stdio.h>

void vulnerable() {
   char buffer[50];
   scanf("%s",buffer);
}

int main(){
   vulnerable();
   return 0;

}
import angr
import sys
import claripy
from angr import sim_options as so
from pwn import * 

p = angr.Project(sys.argv[1],load_options={"auto_load_libs": False})
extras = {so.REVERSE_MEMORY_NAME_MAP, so.TRACK_ACTION_HISTORY}
elf = ELF(sys.argv[1])
p.hook(elf.plt["__isoc99_scanf"],angr.SIM_PROCEDURES["libc"]["scanf"]())
payload_chars = [claripy.BVS("byte%d" % i, 8) for i in range(512)]


payload_ast = claripy.Concat(*payload_chars+ [claripy.BVV(b"\n")])
es = p.factory.entry_state(args=[sys.argv[1]],add_options = extras,stdin=payload_ast)

pg = p.factory.simgr(es, save_unconstrained = True)

ep = None

while pg.active:
    pg.step()
    if len(pg.unconstrained) > 0:
        print("Found unconstrained path")
        sys.exit(0)

print("No unconstrained path")

Detailed Info

Compile the c program with:

gcc buf.c -o buf -z execstack -fno-stack-protector

Run python script against the vulnerable program with a buffer size of 48, this works as expected:

python3 bugreport.py ./buf
WARNING | 2020-12-29 09:13:18,284 | angr.simos.simos | stdin is constrained to 513 bytes (has_end=True). If you are only providing the first 513 bytes instead of the entire stdin, please use stdin=SimFileStream(name='stdin', content=your_first_n_bytes, has_end=False).
WARNING | 2020-12-29 09:13:31,192 | angr.engines.successors | Exit state has over 256 possible solutions. Likely unconstrained; skipping. <BV64 0x0 .. byte58_58_8 .. byte57_57_8 .. byte56_56_8>
Found unconstrained path

Recompile the program with a buffer size higher than 48, for example 50, 52, 56 60, 150, etc.

gcc buf.c -o buf -z execstack -fno-stack-protector 
python3 bugreport.py ./buf
WARNING | 2020-12-29 09:14:45,775 | angr.simos.simos | stdin is constrained to 513 bytes (has_end=True). If you are only providing the first 513 bytes instead of the entire stdin, please use stdin=SimFileStream(name='stdin', content=your_first_n_bytes, has_end=False).
No unconstrained path

I have tried raising the payload_chars to as many as 4096, which didn’t help.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
rhelmotcommented, Dec 29, 2020

first, I would try changing buf_symbolic_bytes too

then, I would debug by examining simulated memory and figuring out how many bytes of symbolic data are being written, and then trying to reverse engineer where that number came from

1reaction
rhelmotcommented, Dec 29, 2020

This is a built-in limit to help tractability.

https://github.com/angr/angr/blob/master/angr/state_plugins/libc.py#L189

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is a false_path constriaint the best option for control signals ...
I am working on a Zynq XC7Z030 design that has some control and low frequency signals that leave the FPGA and do not...
Read more >
Why does the Quartus II software report unconstrained ...
You may observe Quartus® II software report unconstrained paths while running quartus_sta with the --sdc option to perform timing analysis. This behavior ......
Read more >
Tut10-2: Symbolic Execution - CS6265: Information Security Lab
Generally, a program is "concretely" executed; it handles concrete values, e.g., an input value given by a user, and its behavior depends on...
Read more >
Nastran Dmap Error Message List
'PATH=' KEYWORD NOT FOUND ON NDDL DATA BLOCK STATEMENT FOR %1 ... YOU HAVE SELECTED A BUFFER SIZE OF %1 FOR THE MASTER...
Read more >
IC Compiler is for place and route and it is used after synthesis ...
memory, it loads the missing libraries as necessary. ... In the example above, the command lappend is used to “append” two paths to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found