Skip to content

Python Bakhönnun verkefni

Python rev verkefni eru algeng fyrir byrjendur vegna þess að frumkóðinn er oft lesanlegur, en hann er viljandi gerður erfiður aflestrar (obfuscated) eða notar dulkóðun sem þú þarft að snúa við.

Algengar tegundir

Tegund Lýsing
Samanburður Forritið ber inntak við rétt svar: þú þarft að skilja hvernig
XOR dulkóðun Fáni er XOR-aður, þú XOR-ar aftur til að fá upprunalega
Sérsniðin kóðun Sérsniðin kóðun, t.d. stafaskipti (e. substitution cipher)
Obfuscation Kóðinn er vísvitandi ólesanlegur (óskiljanleg breytunöfn, base64 exec, osfrv.)

Dæmi 1: Beinn samanburður

# challenge.py
import sys

def check(flag):
    secret = [71, 71, 123, 115, 51, 99, 114, 51, 116, 125]
    if len(flag) != len(secret):
        return False
    for i in range(len(secret)):
        if ord(flag[i]) != secret[i]:
            return False
    return True

flag = input("Flag: ")
if check(flag):
    print("Correct!")
else:
    print("Wrong!")

Lausn: Breyta tölunum í stafi:

secret = [71, 71, 123, 115, 51, 99, 114, 51, 116, 125]
flag = ''.join(chr(c) for c in secret)
print(flag)   # GG{s3cr3t}

Dæmi 2: XOR dulkóðun

# challenge.py
encrypted = bytes([0x26, 0x24, 0x5a, 0x46, 0x13, 0x46, 0x07, 0x13, 0x46, 0x07])
key = 0x42

flag = input("Flag: ").encode()
if len(flag) != len(encrypted):
    exit("Wrong length")

result = bytes(b ^ key for b in flag)
if result == encrypted:
    print("Correct!")

Lausn: XOR er andhverfanlegt, XOR aftur til að fá fánann:

encrypted = bytes([0x26, 0x24, 0x5a, 0x46, 0x13, 0x46, 0x07, 0x13, 0x46, 0x07])
key = 0x42
flag = bytes(b ^ key for b in encrypted)
print(flag.decode())   # d"flag{...}

Dæmi 3: Stafaskipti

# challenge.py
table = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

def encode(s):
    return ''.join(table[alpha.index(c)] if c in alpha else c for c in s)

secret = "EE{zryyb_jbeyq}"
flag = input("Flag: ")
if encode(flag) == secret:
    print("Correct!")

Lausn: Búa til uppflettingartöflu:

table = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
secret = "EE{zryyb_jbeyq}"

reverse = {t: a for t, a in zip(table, alpha)}
flag = ''.join(reverse.get(c, c) for c in secret)
print(flag)   # GG{hello_world}

Dæmi 4: Obfuscated kóði

Stundum lítur kóðinn svona út:

exec(__import__('base64').b64decode(
    b'ZmxhZyA9IGlucHV0KCk7IHByaW50KCdDb3JyZWN0IScgaWYgZmxhZyA9PSAnR0d7dGVzdH0nIGVsc2UgJ1dyb25nIScpCg=='
))

Lausn: Ekki keyra, afkóðaðu base64 fyrst:

import base64
code = base64.b64decode(b'ZmxhZyA9IGlucHV0KCk7IHByaW50KCdDb3JyZWN0IScgaWYgZmxhZyA9PSAnR0d7dGVzdH0nIGVsc2UgJ1dyb25nIScpCg==')
print(code.decode())
# flag = input(); print('Correct!' if flag == 'GG{test}' else 'Wrong!')

Keyrðu aldrei óþekktan kóða beint

Þegar þú sérð exec(...) eða eval(...) með dulkóðuðum strengjum, afkóðaðu og lestu kóðann áður en þú keyrir hann.


Dæmi 5: Margskipt dulkóðun

Stundum eru mörg lög af dulkóðun:

import base64, codecs

def encode(flag):
    step1 = flag.encode()
    step2 = base64.b64encode(step1)
    step3 = codecs.encode(step2.decode(), 'rot_13').encode()
    step4 = step3[::-1]   # Snúa við
    return step4

target = b'=4JWZ6VWbhNmbhlGdlJFI'

Lausn: Snúa við í öfugri röð:

import base64, codecs

target = b'=4JWZ6VWbhNmbhlGdlJFI'

step3 = target[::-1]                              # Snúa við
step2 = codecs.decode(step3.decode(), 'rot_13')   # Afkóða ROT13
step1 = base64.b64decode(step2)                   # Afkóða base64
flag  = step1.decode()                             # UTF-8
print(flag)

Gagnleg Python tól

# Prenta alla stafi í streng
for c in b'\x41\x42\x43':
    print(chr(c), end='')

# Breyta á milli gagnagerða
int('ff', 16)          # hex → int: 255
hex(255)               # int → hex: '0xff'
bin(255)               # int → binary: '0b11111111'
bytes([65, 66, 67])    # list → bytes: b'ABC'
list(b'ABC')           # bytes → list: [65, 66, 67]

# XOR allt á móti lykli
key = 0x42
result = bytes(b ^ key for b in encrypted)

# Finna lykil ef við vitum hluta af fánanum (known plaintext)
# "GG{" er oft upphaf fánans
for key in range(256):
    attempt = bytes(b ^ key for b in encrypted[:3])
    if attempt == b'GG{':
        print(f"Lykill: {hex(key)}")

Algengar aðgerðir og hvernig á að snúa þeim við

Aðgerð Hvernig snúa við
XOR key XOR aftur með sama lykli
base64.b64encode base64.b64decode
rot13 codecs.decode(..., 'rot_13') aftur
s[::-1] (reverse) s[::-1] aftur
chr(ord(c) + n) chr(ord(c) - n)
sorted / permutation Nota upprunalega röðuna

Z3 (SMT Solver)

Fyrir flókin skilyrði getur z3 Python bókasafnið leyst jöfnur sjálfkrafa:

from z3 import *
x = Int('x')
s = Solver()
s.add(x * 3 + 7 == 100)
s.check()
print(s.model())  # x = 31