CSAW CTF - 100 - Rgexepire - Misc

Informations

Version

By Version Comment
noraj 1.0 Creation

CTF

  • Name : CSAW CTF Qualification Round 2016
  • Website : https://ctf.csaw.io/
  • Type : Online
  • Format : Jeopardy
  • CTF Time : link

Description

I thought I found a perfect match but she ended up being my regEx girlfriend.

nc misc.chal.csaw.io 8001

Solution

It was very similar with ISolve from BackdoorCTF 2016.

I made 3 scripts to solve this:

I flaged with the Python one, the Ruby one work well too and the Bash one work badly due to the dirty way exrex handle regex. Here a proof of success (after the end of the CTF) :

1
2
3
4
5
6
7
8
to solve = '(wolf|gazelle)*[V8xqjx0A8]+[AoqoYnDiu]i3b+[ukqUrDlf]xf+(tomato|elephant)*(clinton|tomato)'
solution = wolfgazellegazellegazellewolfwolfgazelle88xj8Ajx0xAjqx8xxAx8088AqVV0jV8Axjxx8qjV8x8qV0x8V0ii3bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbqxffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffftomatotomatoelephantelephanttomatoelephanttomatotomatoelephanttomatoelephanttomatoelephantelephantelephanttomatotomatotomatotomatoelephantelephanttomatotomatoelephantelephanttomatotomatoelephanttomatoelephantelephanttomatoelephanttomatotomato
D*[i-r]*(dolphin|sloth)(clinton|giraffe)[nNAUqCu]z4*\d+DM*v{9}[e-j](fish|cat)(penguin|sloth)+(chair|clinton){7}
to solve = 'D*[i-r]*(dolphin|sloth)(clinton|giraffe)[nNAUqCu]z4*1+DM*v{9}[e-j](fish|cat)(penguin|sloth)+(chair|clinton){7}'
solution = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDmkpkoijmnrniprlknjppmmrjnlqqpjilrnqjmimkkmrndolphinclintonqz444444444444444444444444444444444444444444111111111111111111111111111111111111111111111111111111111111111111111111DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMvvvvvvvvvhfishpenguinslothpenguinslothpenguinpenguinpenguinslothpenguinslothpenguinpenguinpenguinslothpenguinpenguinpenguinslothslothslothslothpenguinslothpenguinslothpenguinslothpenguinslothpenguinpenguinslothslothpenguinpenguinslothpenguinslothpenguinpenguinslothpenguinpenguinslothslothpenguinslothpenguinchairchairchairclintonchairclintonchair
flag{^regularly_express_yourself$}
to solve = 'flag{^regularly_express_yourself$}'
solution = flag{regularly_express_yourself}

Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env python
import rstr
import socket
import re
from time import sleep
def wrapper_reg(s):
s = re.sub('[\\\]{1}[W]{1}', ' ', s)
s = re.sub('[\\\]{1}[W]{1}', 'a', s)
s = re.sub('[\\\]{1}[d]{1}', '1', s)
s = re.sub('[\\\]{1}[D]{1}', '#', s)
return s
"""
def wrapper(s):
s = re.sub('\s+', '\t', s)
s = re.sub('[^0-9a-zA-Z\s]+', '#', s)
return s
"""
def recvuntil(s):
data = ""
for i in range(9999):
c = s.recv(1)
if(c == '\n'):
break
data += c
return data
def main():
url = "misc.chal.csaw.io"
port = 8001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((url, port))
i = 0
while True:
if i == 0:
task = recvuntil(s)
print(task)
i = 1
task = recvuntil(s)
print(task)
to_solve = task
if len(to_solve) == 0:
print(task)
elif(to_solve == 'Irregular' or to_solve == 'Timeout'):
break
else:
to_solve = wrapper_reg(to_solve)
print("to solve = '%s'" % to_solve)
solution = rstr.xeger(to_solve).replace('\n','')
#solution = wrapper(solution)
print("solution = %s" % solution)
s.sendall(solution + "\n")
sleep(0.1)
main()

Ruby:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env ruby
### Dependencies ###
require 'regexp-examples'
require 'socket'
### Functions ###
def wrapper(s)
s = s.gsub('\s+', '\t')
s = s.gsub('[^0-9a-zA-Z\s]+', '#')
return s
end
### Main ###
if __FILE__ == $0
hostname = 'misc.chal.csaw.io'
port = 8001
s = TCPSocket.open(hostname, port)
output = ""
exit_test = nil
# pass Can you match these regexes?
line = s.gets
puts line.chop
while not exit_test
line = s.gets # Read lines from the socket
puts line.chop # And print with platform line terminator
output = output.concat(line)
# stop = /Can you match these regexes?\s+(.*)/.match(output)
stop = true
if stop
reg_test = output.match(/(.*)/)
reg = /#{reg_test[1]}/
example = reg.random_example
example = wrapper(example)
if example != nil
puts "solution :" + example
end
s.puts(example.gsub('\n', ''))
s.flush
output = ""
end
exit_test = /Failed regex/.match(output)
if exit_test
exit(1)
end
end
s.close # Close the socket when done
end

Bash:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
#######
#Config
URL="misc.chal.csaw.io"
PORT=8001
#####
#Main
OUT=""
# Open socket
exec 3<>/dev/tcp/${URL}/${PORT}
read LINE <&3
echo $LINE >&1
while [ -z "$EXIT" ]
do
read LINE <&3
echo $LINE >&1
exrex -r "$LINE" >&3
OUT=""
EXIT=$( echo "$OUT" | awk '/Irregular/ { getline; print $0 }' )
done

My point of view: This kind of chanllenge is tricky due to bad implementation of regex server and/or regex solver so you always need to fix/wrap regex answers/solutions. I think it's better to put a short timeout (<1s) rather than a lot a steps (100+) to prevent humans to do it by hand because the more steps there are the more chances you have to get a bug. I think the goal of the challenge is to make user script, use regex and parsing, use socket but not to correct/complete other's tools.

Share