Lazy Project
Published on

Pwnium CTF 2014 - ROT

Rot 90, Rot -90, Rot 90, Rot -90... nc 41.231.53.40 9090

題目名稱是 ROT,但跟 ROT 加解密完全沒關係,只是簡單的圖片操作題

連上題目後會得到一大串編碼,然後問 Answer
每一次的編碼內容都不同,必須在約 3 至 4 秒內回傳答案: code

base64 decode 後內容是一張 png png

可以看出其中有被切割過的文字,而題目名稱的 ROT 其實指的是 Rotate
(在解這題的時候腦袋不清楚跑去切三角形...轉了半天,寫這篇的時候才發現只要垂直切一半再旋轉就好了...)

知道圖片怎麼拼後,剩下就是做 OCR ,得到圖中的文字,回傳給 Server
找了一些 library 後,最後決定用 pyocr 配合 tesseract 做 OCR
切圖及疊圖交給 PIL 處理

結果大概長這樣,辨識度挺不錯的 result

完整的 script:

#!/usr/bin/python
import base64
import socket
import pyocr
import pyocr.builders
from PIL import Image

def removecolor(img, color):
    img = img.convert("RGBA")
    datas = img.getdata()

    newData = []
    for item in datas:
        if item[0] == color[0] and item[1] == color[1] and item[2] == color[2]:
            newData.append((255, 255, 255, 0))
        else:
            newData.append(item)

    img.putdata(newData)
    return img

# Prepare OCR
tool = pyocr.get_available_tools()[0]
lang = tool.get_available_languages()[0]

# Download png
print "Connecting..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("41.231.53.40", 9090))
d = s.recv(102400)
d += s.recv(102400)
d += s.recv(102400)
d += s.recv(102400)
d += s.recv(102400)
d = d[:d.find("Answer:")]

print "Saving..."

with f.open("1.png", "w"):
    f.write(base64.b64decode(d))

img = Image.open('1.png')

# Remove background
img = removecolor(img, (255, 255, 0))
img = removecolor(img, (0, 255, 255))
img = removecolor(img, (0, 255, 0))
img = removecolor(img, (255, 255, 255))
rst = Image.new("RGBA", (200,100), "white")

# Crop and rotate
left = img.crop((0, 0, 100, 200))
left = left.transpose(Image.ROTATE_90)
rst.paste(left, (0,0), left)

right = img.crop((100, 0, 200, 200))
right = right.transpose(Image.ROTATE_270)
rst.paste(right, (0,0), right)

# OCR
answer = tool.image_to_string(rst, lang=lang, builder=pyocr.builders.TextBuilder()).replace(" ","")
print "OCR Result: %s" % answer

s.send(answer + "\n")

# Recv flag
print s.recv(1024)

flag