Strikamerki, QR-kóðar og textagreining
Ferningur úr svörtum og hvítum reitum getur geymt vefslóð, texta eða næstu vísbendingu. Röð af strikum getur falið tölur. Óskýr ljósmynd af miða getur orðið að leitanlegum texta með stafakennsl.
Í CTF-verkefnum eru þessi form oft aðeins eitt lag:
mynd → QR-kóði → vefslóðarkóðun → Base64 → fáni
Markmiðið er því ekki bara að „skanna kóðann“. Við þurfum að skoða afkóðuðu gögnin áður en við notum þau.
QR-kóði er ótraust inntak
Kóði getur innihaldið skaðlega vefslóð, greiðslubeiðni, Wi-Fi-stillingu eða texta sem forrit reynir að framkvæma. Afkóðaðu fyrst í texta. Ekki opna slóð eða samþykkja aðgerð sjálfkrafa.
Strikamerki og QR-kóðar
Strikamerki (e. barcode) geymir upplýsingar í mynstri sem vél getur lesið. Einvíð strikamerki nota yfirleitt breidd strika og bila eftir einni stefnu. Tvívíðir kóðar nota flöt og geta geymt meiri gögn.
QR-kóði (e. Quick Response code) er tvívíður kóði úr litlum einingum, oft svörtum og hvítum ferningum.
Auðþekkjanlegu stóru ferningarnir í þremur hornum hjálpa lesara að finna stefnu kóðans. Minni mynstur hjálpa með röðun, útgáfu og villuleiðréttingu.
Vissir þú?
QR-kóðinn var þróaður árið 1994 af Denso Wave til að rekja íhluti í japanskri bílaframleiðslu. Quick Response vísar til þess að kóðinn átti að vera fljótlesinn úr ólíkum áttum.
Byrjum á óbreyttri mynd
Við skoðum fyrst snið og stærð:
file kodi.png
magick identify kodi.png
exiftool kodi.png
Síðan reynum við staðbundinn lesara. zbarimg styður meðal annars QR og mörg einvíð strikamerki:
zbarimg kodi.png
Til að fá aðeins hráa nytjahlassið:
zbarimg --raw kodi.png
Mögulegt úttak:
https://ctf.example/next?data=%67%67%7Bqr_er_texti%7D
Við opnum ekki slóðina strax. Við vistum hana eða sendum í textagreiningu.
zbarimg --raw kodi.png > afkodad.txt
file afkodad.txt
Prófaðu einföldustu útgáfuna fyrst
Góður lesari sér oft um 90° snúning og villuleiðréttingu sjálfur. Ekki skerpa, þröskulda og spegla mynd sem lesst þegar óbreytt.
Æfing: hvað kemur næst?
Æfing 1
QR-lesari skilar:
https://example.invalid/login?user=nemandi&token=abc123
Hvert er öruggasta næsta skrefið?
- Opna slóðina í venjulegum vafra og skrá sig inn.
- Skoða textann og þáttun slóðarinnar án nettengingar.
- Keyra textann sem skeljaskipun.
Lausn við æfingu 1
Svar 2 er öruggast. Við getum greint slóðina sem gögn:
from urllib.parse import parse_qs, urlparse
slod = "https://example.invalid/login?user=nemandi&token=abc123"
hlutar = urlparse(slod)
print(hlutar.scheme) # https
print(hlutar.hostname) # example.invalid
print(hlutar.path) # /login
print(parse_qs(hlutar.query))
Lénið .invalid er frátekið fyrir dæmi og á ekki að virka. Hvorki innskráning né keyrsla í skel er nauðsynleg til að lesa nytjahlassið.
Afkóðum vefslóðarkóðun án þess að heimsækja slóð
Prósentur í slóð geta táknað bæti. Python getur afkóðað þær:
from urllib.parse import unquote
texti = "%67%67%7Bqr_er_texti%7D"
print(unquote(texti))
Úttak:
gg{qr_er_texti}
Við greindum aðeins textann. Engin vefbeiðni var send.
Kóðinn gæti líka skilað:
WIFI:T:WPA;S:...fyrir Wi-Fi-stillingu,BEGIN:VCARDfyrir tengilið,otpauth://...fyrir auðkennislykil,mailto:eðatel:fyrir aðgerð,- Base64, hex eða JSON,
- annarri mynd eða skrá.
Þessi forskeyti segja forriti hvað það gæti gert. Við meðhöndlum allt fyrst sem texta.
Þegar QR-kóðinn lesst ekki
Algengar ástæður:
- kóðinn er of lítill eða óskýr,
- hann er skorinn við brún,
- hvíta jaðarsvæðið vantar,
- birtuskil eru lítil,
- myndin er spegluð,
- sjónarhornið skekkir ferninginn,
- hluti kóðans er skemmdur,
- myndin var vistuð sem tapsþjappað JPEG.
Við búum til afleidd afrit og breytum einu atriði í einu.
Stækkum án mýkingar
QR-kóði samanstendur af skörpum einingum. Næsti nágranni heldur köntunum:
magick kodi.png -filter point -resize 400% nidurstodur/kodi-stor.png
Bætum við hvítum jaðri
Hvíta svæðið utan um kóða kallast kyrrt svæði (e. quiet zone). Lesari þarf það til að aðgreina kóðann frá bakgrunni.
magick kodi.png -bordercolor white -border 40 nidurstodur/kodi-jadar.png
Snúum og speglum
magick kodi.png -rotate 90 nidurstodur/kodi-90.png
magick kodi.png -flop nidurstodur/kodi-spegill.png
magick kodi.png -flip nidurstodur/kodi-lodrett.png
-flop speglar lárétt en -flip lóðrétt.
Grátónar og þröskuldur
magick kodi.png \
-colorspace Gray \
-threshold 55% \
nidurstodur/kodi-svart-hvitt.png
Þröskuldurinn getur hjálpað þegar bakgrunnur er ójafn, en rangt gildi getur eytt einingum. Við prófum fá gildi kerfisbundið og berum saman.
Skerum kóðann úr stærri mynd
magick mynd.png -crop 600x600+120+80 +repage nidurstodur/kodi-skordur.png
Merkingin er:
breidd x hæð + x-hliðrun + y-hliðrun
600 600 120 80
Við skiljum eftir smá hvítan jaðar ef mögulegt er.
Ekki vista vinnuafritið sem JPEG
JPEG getur búið til óskýra kanta og litlar sveiflur við hverja einingu. PNG er betra vinnusnið fyrir svarta og hvíta kóða.
Æfing: röð umbreytinga
Æfing 2
QR-kóði er aðeins 80×80 dílar, snýr á hlið og snertir brún myndarinnar. Hvaða þrjár einfaldar aðgerðir eru skynsamlegar áður en við reynum flókna viðgerð?
Lausn við æfingu 2
Skynsamleg röð er:
- snúa myndinni um 90°,
- stækka með
-filter point, - bæta við hvítum jaðri.
Til dæmis:
magick kodi.png \
-rotate 90 \
-filter point -resize 400% \
-bordercolor white -border 40 \
nidurstodur/kodi-lagadur.png
zbarimg --raw nidurstodur/kodi-lagadur.png
Við gætum prófað lesara eftir hvert skref. Þá vitum við hvaða breyting var nauðsynleg.
Villuleiðrétting er ekki töfrar
QR-kóðar geyma umframupplýsingar svo lesari geti endurheimt gögn þótt hluti kóðans sé skemmdur. Stigin eru L, M, Q og H. Þeim er oft lýst þannig að hægt sé að endurheimta um 7%, 15%, 25% og 30% skemmdra kóðaorða (e. codewords), en raunhæf geta fer eftir staðsetningu og eðli skemmdarinnar.
Skemmdir á staðsetningarferningum, sniði eða stórum samfelldum hluta geta verið verri en dreifðir blettir. Við megum því ekki álykta að „30% af myndfletinum megi vanta“.
Í CTF getum við stundum:
- endurgert augljóst staðsetningarmynstur,
- sameinað tvo kóða sem skemmast á ólíkum stöðum,
- rétt sjónarhorn,
- nýtt villuleiðréttingu eftir að jaðar og einingastærð eru rétt.
Við gerum breytingar á afriti og skráum nákvæmlega hvað var teiknað eða afritað.
Einvíð strikamerki
Algeng snið eru meðal annars:
- EAN-13 á vörum,
- Code 128 fyrir fjölbreyttan texta,
- Code 39 fyrir einfalt stafasett,
- UPC-A.
zbarimg getur greint mörg þeirra:
zbarimg strikamerki.png
Einvítt strikamerki þarf oft:
- nægilega lárétta upplausn,
- skýra kanta,
- autt svæði við báða enda,
- rétta stefnu,
- öll strikin óskorin.
Vartala í EAN-13
Síðasti tölustafur EAN-13 er vartala (e. check digit). Hún greinir margar algengar innsláttar- og lesvillur en er ekki dulritunarvörn.
Fyrir fyrstu tólf tölurnar:
5 9 0 1 2 3 4 1 2 3 4 5
leggjum við saman tölur í oddasætum og þrefalt summu talna í jafnsætum, talið frá vinstri:
oddasæti: 5 + 0 + 2 + 4 + 2 + 4 = 17
jafnsæti: 9 + 1 + 3 + 1 + 3 + 5 = 22
summa: 17 + 3×22 = 83
Vartalan fyllir upp í næsta tug:
(10 - (83 mod 10)) mod 10 = 7
Heili kóðinn er því:
5901234123457
Æfing: staðfestu vartölu
Æfing 3
OCR les EAN-kóða sem:
5901234123451
Samræmist síðasti tölustafurinn vartölunni sem við reiknuðum?
Lausn við æfingu 3
Nei. Fyrstu tólf tölurnar 590123412345 gefa vartöluna 7, ekki 1.
Þetta bendir til OCR- eða lesvillu. Við skoðum myndina aftur og prófum strikamerkjalesara. Réttur kóði samkvæmt útreikningnum er:
5901234123457
Vartalan segir ekki hvaða af fyrri tölunum væri röng ef fleiri villur eru til staðar; hún segir aðeins að runan stenst ekki þessa athugun.
Ljóskennsl stafa
Ljóskennsl stafa (e. optical character recognition, OCR) breytir mynd af texta í stafi sem við getum leitað í og unnið með.
Tesseract er opið OCR-tól:
tesseract texti.png stdout
Fyrir eina textalínu getur síðuskipanarhamur 7 hentað:
tesseract texti.png stdout --psm 7
Fyrir þéttan textablokk er hamur 6 algeng byrjun:
tesseract texti.png stdout --psm 6
Tungumál eru valin með -l ef viðeigandi tungumálagögn eru uppsett:
tesseract texti.png stdout -l isl+eng --psm 6
Undirbúum mynd fyrir OCR
magick texti.jpg \
-colorspace Gray \
-resize 300% \
-contrast-stretch 1%x1% \
nidurstodur/texti-skyr.png
Við gætum einnig prófað þröskuld eða skorið textasvæðið úr. Aftur breytum við einu í einu og berum úttakið saman við myndina.
Algengar ruglingar
OCR ruglar meðal annars:
| Mynd | Mögulegir stafir |
|---|---|
0 |
núll eða O |
1 |
einn, I eða l |
5 |
fimm eða S |
8 |
átta eða B |
{ |
slaufusvigi eða ( |
_ |
undirstrik eða eyða |
Fánasnið og annað samhengi hjálpar okkur að staðfesta, en við eigum ekki að „leiðrétta“ allt sem passar ekki fyrirfram ákveðinni hugmynd.
Æfing: OCR-frambjóðendur
Æfing 4
OCR skilar:
gg(0CR_l3s_ekkl_a11t}
Myndin virðist hins vegar hafa slaufusviga eftir gg, og tveir óskýrir stafir gætu verið I, l eða 1.
Hvernig staðfestum við fánann án þess að giska blint?
Lausn við æfingu 4
- Skerum hvert óskýrt svæði út og stækkum með skörpum köntum.
- Berum saman lögun sömu stafa annars staðar í myndinni.
- Prófum annan OCR-ham og mögulega
isl+engtungumálagögn. - Athugum fánasniðið: upphafið ætti líklega að vera
gg{, svo(er líkleg lesvilla. - Skráum möguleikana fyrir óskýru stafina í stað þess að skipta þeim strax út.
Mjög líklegur texti gæti verið:
gg{OCR_les_ekki_allt}
En við skila aðeins þeirri útgáfu þegar sjónræn skoðun styður O á móti 0, l á móti 1 og lokasvigann. Fánasniðið er staðfesting, ekki heimild til að finna upp stafi.
Mörg lög af kóðum
Afkóðað nytjahlass getur sjálft verið kóðað:
QR → `R0d7a29kaSBvZyB0ZXh0aX0=` → Base64 → texti
Eða QR-kóði getur innihaldið slóð á mynd með öðru strikamerki. Við spyrjum eftir hvert lag:
file nidurstada
wc -c nidurstada
head -c 100 nidurstada
Fyrir texta skoðum við:
- stafasett,
- þekkt forskeyti,
- vefslóðarkóðun,
- Base64 eða hex,
- JSON eða XML,
- hvort textinn sé í raun skráarauðkenni í kóðuðu formi.
Eitt lag, ein staðfesting
Skráðu QR → slóðarafkóðun → Base64 → PNG í stað þess að skrifa bara „notaði CyberChef“. Þá má endurtaka lausnina og sjá hvar röng forsenda gæti hafa komið inn.
Búum til skaðlaust æfingadæmi
qrencode getur búið til QR-mynd úr texta:
qrencode -o aetfing.png 'gg{eg_bjo_til_qr}'
zbarimg --raw aetfing.png
Við getum síðan búið til skemmt afrit, til dæmis snúið og minnkað, en höldum upprunalega kóðanum svo hægt sé að bera saman:
magick aetfing.png -rotate 90 -resize 25% aetfing-skemmd.png
Þetta er örugg leið til að æfa verkfæri án þess að skanna ókunnan kóða af götu eða senda mynd í vefþjónustu.
Persónuvernd og OCR-þjónustur
Skýjaþjónusta fyrir OCR eða QR sendir myndina til annars aðila. Myndin gæti innihaldið:
- nöfn,
- heimilisföng,
- skjöl í bakgrunni,
- staðsetningarlýsigögn,
- aðgangslykla í kóðum.
Við notum staðbundin tól fyrir viðkvæm gögn og aðeins tilbúnar CTF-myndir í utanaðkomandi þjónustum.
Lokaverkefni: miðinn á veggnum
Æfing 5
Verkefnið gefur ljósmyndina veggur.jpg. Hún sýnir lítinn, speglaðan QR-kóða og óskýra handskrifaða línu fyrir neðan.
Eftir QR-afkóðun fæst:
data=%52%30%64%37%61%32%39%6b%61%53%42%76%5a%79%42%30%5a%58%68%30%61%58%30%3D
Skrifaðu skipulega leið frá mynd að lokaúttaki og nefndu öryggisathuganir.
Möguleg lausn við æfingu 5
- Halda óbreyttu afriti af
veggur.jpgog búa tilnidurstodur/. - Skera QR-svæðið út með smá jaðri.
- Spegla afritið með
-flop, stækka með-filter pointog bæta við hvítum jaðri ef þarf. - Afkóða í texta, ekki sjálfvirka aðgerð:
zbarimg --raw nidurstodur/qr-lagadur.png > nidurstodur/qr.txt
- Þáttum
data=og afkóðum prósenturnar án netbeiðni:
from urllib.parse import parse_qs, unquote
texti = open("nidurstodur/qr.txt").read().strip()
gildi = parse_qs(texti)["data"][0]
print(unquote(gildi))
parse_qs afkóðar prósenturnar sjálft, svo niðurstaðan verður Base64-lík runa.
- Afkóða Base64 og skoða textann:
printf '%s' 'R0d7a29kaSBvZyB0ZXh0aX0=' | base64 -d
Niðurstaðan er:
GG{kodi og texti}
- OCR-greina handskrifuðu línuna sérstaklega, en staðfesta hana sjónrænt. Hún gæti sagt hvort breyta eigi hástöfum, eyðum eða svigum í fánasniðið.
- Ekki opna slóðir, keyra afkóðaðan texta eða hlaða ljósmyndinni í skýjaþjónustu án heimildar.
Athugum að úttakið er ekki enn á venjulega gg{...} sniðinu. Ef handskrifaða línan segir „allt með lágstöfum, bil verða undirstrik“ verður lokafáninn:
gg{kodi_og_texti}
Við gerum þessa breytingu aðeins ef vísbendingin segir það.
Samantekt
Í þessum kafla lærðum við að:
- strikamerki og QR-kóðar eru gagnasnið, ekki sjálfkrafa öruggar aðgerðir,
zbarimg --rawafkóðar í texta án þess að opna slóð,- við getum stækkað, snúið, speglað, þröskuldað og skorið kóða á afritum,
- hvítur jaðar og skarpir einingakantar skipta lesara máli,
- QR-villuleiðrétting þolir sumar skemmdir en ekki hvaða 30% myndarinnar sem er,
- vartala strikamerkis greinir villur en sannar ekki uppruna eða heilleika,
- OCR breytir mynd í textaframbjóðanda sem þarf sjónræna staðfestingu,
- afkóðað nytjahlass getur verið vefslóð, Base64, JSON eða annað lag,
- við skoðum afkóðaðar slóðir án þess að heimsækja þær,
- við sendum ekki viðkvæmar myndir í utanaðkomandi OCR- eða QR-þjónustur.
Í næsta kafla skoðum við Unicode, stafi sem líta eins út, núllbreiddarstafi, stefnustýringu og skilaboð sem fela sig í bilum.