And Hypothetically Speaking About ASN.1…
Thomas Ptacek | January 30th, 2006 | Filed Under: Bitching About Protocols, Development, Matasano
If you had yourself a program “asn1 int” that consumed its arguments and printed to standard output the binary BER representation of an ASN.1 integer, like so:
$ asn1 int 0 | hexify 020100
and you had yourself a program “asn1 seq” that consumed its standard input and printed to standard output that data wrapped in a BER ASN.1 sequence, like so:
$ asn1 int 0 | asn1 seq | hexify 3003020100
then you could generate yourself a random RSA private key block on the command line, like this:
$ ( asn1 int 0 ; asn1 int 1 ; asn1 int 11 ; asn1 int 2 ; asn1 int 3 ; asn1 int 3 ; asn1 int 3 ; asn1 int 3 ; asn1 int 3 ) | asn1 seq | hexify 301b02010002010102010b020102020103020103020103020103020103
Of course, that’s not very realistic. So you’d extend “asn1 int” to consume its own standard input when needed:
$ dd if=/dev/random bs=1 count=50 | asn1 int -r 020a807321825fa8a1c87516
And now it’s starting to get interesting:
#!/bin/sh # randkey.sh r8() { dd if=/dev/random bs=1 count=$1 2>/dev/null } echo "-----BEGIN RSA PRIVATE KEY-----" ( asn1 int 0 ; r8 256 | asn1 int -r ; asn1 int 11 ; r8 256 | asn1 int -r ; r8 128 | asn1 int -r ; r8 128 | asn1 int -r ; r8 128 | asn1 int -r ; r8 128 | asn1 int -r ; r8 128 | asn1 int -r ; ) | asn1 seq | b64 echo "-----END RSA PRIVATE KEY-----"
So we can do:
$ ./randprivkey | openssl rsa -text Private-Key: (2048 bit) modulus: 00:87:49:f1:dd:33:4c:45:aa:fa:62:bd:a6:c5:65: # and so on
and we’d start to be a little impressed by the Unix shell. Of course, we wouldn’t need to stop there; we could add another parameter to the “asn” commands, “-L” to specify, not sense, the BER length. Then our “randkey” might look like:
#!/bin/sh r8() { dd if=/dev/random bs=1 count=$1 2>/dev/null } r8r() { j=`random` r8 `expr $j % $1` } echo "-----BEGIN RSA PRIVATE KEY-----" ( asn1 int 0 ; r8r 1000 | asn1 int -r ; asn1 int -L `random` 11 ; r8 256 | asn1 int -r ; r8r 128 | asn1 int -r ; r8r 1280 | asn1 int -r ; r8r 1280 | asn1 int -r ; r8r 1280 | asn1 int -r ; r8r 128 | asn1 int -r ; ) | asn1 seq -L `random` | b64 echo "-----END RSA PRIVATE KEY-----"
and we’re fuzzing DER private key parsers on the command line.
But why would we stop there? We could add support for OIDs:
$ asn1 oid 1.2.3.4 06032a0304
and for strings:
$ asn1 string helu world 040a68656c7520776f726c64
and then we could write this script:
#!/bin/sh # snmpget.sh snmpget() { asn1 seq -T cC0 } ( asn1 int 0 ; asn1 string private ; ( asn1 int 12131415 ; asn1 int 0 ; asn1 int 0 ; ( ( asn1 oid 1.2.3.4 ; asn1 null ) | asn1 seq ) | asn1 seq ) | snmpget ) | asn1 seq
and run it like this:
$ snmpget.sh | nc -u 1.2.3.4 161
and, if we were watching in tcpdump, we’d see this:
10.0.1.5.53456 > 1.2.3.4.snmp: [udp sum ok] { SNMPv1 C=private { GetRequest(23) R=12131415 .iso.2.3.4 } }
and we’d start to wonder if there wasn’t something to this whole ASN.1 thing after all.
Right before we started hurling random bizarre SNMP GETs all over the place and watching what broke.
We’ll race you. Who can write “asn1 int,string,oid,seq” in AWK first?


Anonymous
January 30th, 2006 11:26 pmthrow in
| asn1 explicit
and
| asn1 implicit
to wrap up LDAP and Kerberos 5 PDUs and
aim higher
Adam
January 31st, 2006 9:50 amRace me? But Oulu University Secure Programming group already finished!
tqbf
January 31st, 2006 11:30 am@anonymous: IIRC, there’s no BER encoding for “explicit” and “implicit”. It just changes the tag numbers. Most “high level” BER types are just ASN.1 “sequence” with special tags. So I’m not sure you can’t do LDAP already (though I haven’t tried).
@adam: Oulu did NOT write their SNMP fuzzer in Bourne Shell and Awk. In fact, I can’t even pronounce “Oulu”. I don’t even have evidence that there is such a place. “Oulu”? Sounds made up to me.
Anonymous
February 2nd, 2006 8:37 am@tqbf
my bad about the implicit and explicit
things; i’d neglected to notice you had
the -T option to rewrite the tags for
your universal types already
and i do understand sorta what you’re
getting at. your ASN.1 shelltools for
generating BER (DER, actually, i sup-
pose, but, hmm, now wouldn’t it be fun
to start throwing arcane but valid BER
encodings at things. appropos of no-
thing, one thing i notice about Micro-
soft LDAP PDUs is that their integers
are always encoded as 4 octets. wonder
if that gets shoved into a signed or
unsigned?) are every bit as lucid as
the original ASN.1 specification, if
not more so, just bottom up (or maybe
bottom left)
yeah, i’ll shut up now
Leave a reply