CSAW CTF - 100 - Rgexepire - Misc

Information#

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) :

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:

#!/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:

#!/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:

#!/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