# Patching proxmark3 to brute force HF tags


Patching and flashing
# git clone https://github.com/Proxmark/proxmark3.git
# cd proxmark3/armsrc
# sed '/#include "protocols.h"/ a #include "usb_cdc.h"' iso14443a.c
# sed -i 's/if(BUTTON_PRESS())/if(BUTTON_PRESS() || (usb_poll_validate_length() ))/g' iso14443a.c
# cd ..
# make
# client/flasher /dev/cu.usbmodem1421 armsrc/obj/fullimage.elf

Brute forcing

# for i in `seq 0 255`; do uid=`printf '%08x\n' $i`; echo "hf 14a sim 1 $uid" | client/proxmark3; sleep 3; done

References

http://www.proxmark.org/forum/viewtopic.php?id=2347
https://github.com/Proxmark/proxmark3/pull/77/files

# CodeGate 2017 CTF: EasyCrack 101 - rev - 325 pts



# cat easycrack101.py
import angr, claripy
import r2pipe

for i in xrange(1, 101 + 1):
 fn = 'prob' + str(i)
 r2 = r2pipe.open(filename = fn)
 to_find  = int(r2.cmd('/c mov edi~Good[0]'), 16)
 to_avoid = int(r2.cmd('/c mov edi~No[0]'), 16)
 #print to_find, to_avoid
 p = angr.Project(fn)
 key = claripy.BVS('key', 50 * 8)
 es = p.factory.entry_state(args=[fn, key])
 pg = p.factory.path_group(es)
 ex = pg.explore(find = to_find, avoid = to_avoid)
 found = ex.found[0]
 key = found.state.se.any_str(key).replace('\x00', '')
 print fn + ' = ' + key

# python easycrack101.py
prob1 = T}gTRvNZAK_Exv^vqpDwCW
prob2 = }hGafk~acCtypkaEoi||f}tzsr
prob3 = ELFT[^MYLINQMI_FQFYKOOZ^U
prob4 = <D8;F9G?:0A01?E8@A92
prob5 = JI^pYCXpFZuS[STOZWqvVJFWW
prob6 = 0:B3:91[Y&7913F_30OZ
prob7 = WIVT|ANQCKACJLPRWJ}RRBA
prob8 = 1:5=926;:7696040678854
prob9 = WUYUYYSYQPSMURTWRVPWVRSXXSZY
prob10 = MSTBCCMSWNMTMMDO@UJSOLLMSAT
prob11 = BD92A76;@D>>6E8FG05?F?G6C
prob12 = DEEEDDEDEDDEDEEEEDDDEDEEEED
prob13 = I@P}Y|mB|x@MuXAl|u_RoxCn|jD
prob14 = 5??;>>:<95;>845?9;:8:?4
prob15 = GAGA@GGAG@@G@AAA@A@A@AAAG
prob16 = LDLFDBNLALGOCDFOCAMGLDFJMBO
prob17 = ELZyoZRiERGGxpSNH~R]qtwWEo@o
prob18 = FEB{E{zBFFD}DFEB@@zzCF{xB
prob19 = ;;:;;:;:;:;:;;;::::;:;;:;::
prob20 = vnbcwgqsuefggl|mpqboic
prob21 = HLLLILJHHJJHIKHJMMHK
prob22 = RQyBKyODWSDIEGQNSMSOTFHO
prob23 = 5676;13=;+;5+=0;<><6:859>:08
prob24 = ^<.:Q%.)W,.><VS,$8:7X55=*U/%
prob25 = >:?<:<??>?>>=>>>=<:=
prob26 = ===9=<:=><=<=?=;89?8::??<
prob27 = Kptq~HqIIwKrHrprs~vw
prob28 = SSPRWPkVRkRkRkQRVSPVU
prob29 = J464=D>5.OAGRJ472*)TIT:J=
prob30 = ALMNBBOJqNDODKBrHO__GrIqMOMK
prob31 = 5+0356*=3?5=+2=>5>67845
prob32 = 161=5=?32<?2=211?><3:;11
prob33 = ppvqppqvppqvvqpqqqqvqpqvqvpvq
prob34 = @RxjcJkdpO}[pIJiFGUtnhKTvay
prob35 = hSZFDatdwHvTo_hbhMEMHN[
prob36 = VO^AP_EUSSR@VLANHQSMCTKANWT@A
prob37 = CFCAFKLLFCAMMFNAOEBLAEL@E
prob38 = xmo~zclqi}mdgwf{oovqmbpucto
prob39 = MJEQFIRDRLKOJIEPIOOGWQFN
prob40 = uwsuptquzwzzqwxp~zzu~y
prob41 = )+*/,*)-.,..)+,-).-)-
prob42 = HOHOOOHHHOOOOHHOOOOOHOHHHHOOO
prob43 = YMNJMGFOFODYAJDOL@OAMMNYBJDGO
prob44 = -)--,.(*)/)..*.-,)-(..-
prob45 = bskndsifjscahcklhppaq
prob46 = CGFGGCFHCFEFCEEDGGEFDFCH
prob47 = DTOIFLYFUD@OZPGPRDLXT
prob48 = WtFGGP^^@LuCCE^YuKAYIO
prob49 = 0q7a>>>B<gDwPFpi_5AbxwX
prob50 = TB@YZKTYYEPSNP@OAK@YHG
prob51 = 5?254=5822<??8=43556826<834
prob52 = NMIIJMMKHOKMMLOMKLLMKLNOJKLNM
prob53 = 792<=>75=9=4<52;=6219:9:;9=<
prob54 = :4(&>)3+;3&.15=3?%=6
prob55 = NLGDGJOHLMLEKFHEHMDFLNMKIFMNI
prob56 = uwuuvwuwvvvwwvuvuwwvwvuuvvuv
prob57 = @DRS@UBRPWXUIJPBNK{WOyAZWZFSX
prob58 = NIAFK{HBJ|qNC|CzDCzNpNTTKpM
prob59 = jroo|zniylzuxs}rtymoqkr
prob60 = ;8::<<=:;;:8;<;>;;;=<<;:
prob61 = TTKUUTKKKTUUTKUTKTKUUUTKUTKKT
prob62 = uOlWq^~nQN^crr@hXShtOD
prob63 = bNw~_z}~AHbrk{XBeH_}
prob64 = EDEDDEEDEDEDDEEEDDDEDEEDEDE
prob65 = SfhUoj[PkRhlVSQVZRhhS[PQVe
prob66 = rsrqiqooolilnqmqnnmonmho
prob67 = -15w(=b(a{lok2vTh>j-Ho
prob68 = SSRQSSSRQSSSSSSRQSRQQRSSQR
prob69 = hiihhihihihiiihhhhhi
prob70 = qtqtohp}}rijjwvr|qr|}nrq
prob71 = ?SYRE]CP2UDOH/k46N5J#
prob72 = <#lf-7,=H#172t.Yye2)Fl_Vh&
prob73 = Wbov~zqg[IZ}jxwvf}FYR[aY
prob74 = cccccccccccccccccccccc
prob75 = NFPiOYZvKYEW^bgRmBAM
prob76 = UjJb,U+)**UzF1pj2bx{ls
prob77 = HNEMpINJzGJHYLnHbYzMqNKO
prob78 = IIIOHONOHOOHIOHOOHOIHI
prob79 = MLOOLLNONNOOMOLNILNNOM
prob80 = deba5:Jnv|Eb?4>kBXnRf[L|?I
prob81 = _XON^]LNO^CLD[[LJZZL]]MFO
prob82 = nhimninlmnmmlonionnmlhloolnh
prob83 = SYVK]YOGvSCrOCuR_FTQ@qu]w^wX
prob84 = GGNDAFAD@D@EODMNGNBOGLFMMO
prob85 = 6(1:*2<9=37>.)7788+97/41
prob86 = 8E3>4/3K2=AKF+-*G91,9/
prob87 = WTRUUTU]RWW_]S]]PRQQV
prob88 = LJ@XFL^ETLC_Y@UMZWQ@Z_AYTMZP
prob89 = ckakcocoldcnocaeoejjk
prob90 = QTRUQ^QTUUUUQTUTQTQSTSSRP
prob91 = C@KE@N@FGKDG@AAMCLONN
prob92 = CMISDCN@@G@HIPKBRPP@PPNHC
prob93 = DGDGEFDDGGDDGDFEEEFFEEFG
prob94 = vvvvvvvvvvvvvvvvvvvvvvvvvv
prob95 = x]zweUnmcDEFyVbyF|SWlU
prob96 = TTU_U__T[^YUY[_^U[XT^T^__[Z[
prob97 = 10111010011101110010111101010
prob98 = qtuqtvwtqtvtqpwwttqutvttut
prob99 = W(,T,*V),(URW-W-UT*,,R+*
prob100 = m9-9r9/VA4&8BM=R*+OMrgf
prob101 = ttvwtjivikitiivjvsuisjukthki

# HTTP security headers


X-XSS-Protection

X-XSS-Protection: 0; // no protection
X-XSS-Protection: 1; // filters xss but renders the page
X-XSS-Protection: 1; mode=block // blocks the page

Protection against reflected xss.

Content Security Policy

Content-Security-Policy: <policy>

Protection against xss. Controls what resources are allowed to load.

HTTP Strict Transport Security (HSTS)

Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; preload // Use a preload list

Connections to the site will use HTTPS, except the first one, if preload is not used.

HTTP Public Key Pinning (HPKP)

Public-Key-Pins: pin-sha256=<base64>; max-age=<expireTime>;
Public-Key-Pins: pin-sha256=<base64>; max-age=<expireTime>; includeSubDomains
Public-Key-Pins: pin-sha256=<base64>; max-age=<expireTime>; report-uri=<reportURI>

Dynamic pinning. Check if the certificate matches the pins stored.

X-Frame-Options

X-Frame-Options: DENY // No one can put the page in an iframe
X-Frame-Options: SAMEORIGIN // Only from the same site
X-Frame-Options: ALLOW-FROM https://example.com/

Avoids clickjacking attack.

X-Content-Type-Options

X-Content-Type-Options: nosniff;

Solves the "MIME sniffing" problem.

Referer-Policy

Referrer-Policy: <policy>

Allows you to specify when the browser will set a referer header

Cookies Options

Set-Cookie: <key>=<value>; Expires=<expiryDate>; Secure; HttpOnly; SameSite=strict
// Secure: only sent over HTTPS
// HttpOnly: can not be accessed from javascript
// SameSite: lax or strict. Defends against Cross-Origin Request Forgery (CSRF)

References

https://blog.appcanary.com/2017/http-security-headers.html
https://securityheaders.io

# AlexCTF: CR5: Bring weakness - 300 pts


Get random numbers

# cat get.py 
from pwn import *

host = '195.154.53.62'
port = 7412

def give_me_the_next_number():
 r.sendlineafter('2: Give me the next number\n', '2')
 number = int(r.recvline())
 return number

r = remote(host, port)

for i in xrange(4):
 print give_me_the_next_number()

r.close()
# python get.py
855109115
895402096
2391280583
300480802

Linear congruential generator

random_n+1 = ((a * random_n) + c) % m
a = multiplier
c = increment
m = modulus

Get modulus

# cat get_modulus.py
from pwn import *

host = '195.154.53.62'
port = 7412

def give_me_the_next_number():
 r.sendlineafter('2: Give me the next number\n', '2')
 number = int(r.recvline())
 return number

def egcd(a, b):
 if a == 0:
  return (b, 0, 1)
 else:
  g, y, x = egcd(b % a, a)
 return (g, x - (b // a) * y, y)

results = []

for i in xrange(20):
 r = remote(host, port)
 last = give_me_the_next_number()
 current = give_me_the_next_number()
 tn = current - last
 last = current
 current = give_me_the_next_number()
 tn1 = current - last
 last = current
 current = give_me_the_next_number()
 tn2 = current - last
 u = abs(tn2*tn - tn1**2) # Important
 r.close()
 results.append(u)

print results

for i in xrange(0, 19):
 print egcd(results[i], results[i+1])[0]

# python get_modulus.py
[312571317250000395, 2949916660717308525, 640738713015133065, 435603004762385760, 2439656571633178950, 11411209872061185300L, 6407385815891338380, 610020832043386185, 1779427408702485555, 149150577634188375, 3371733426053132880, 402697709832197265, 2394242682672509175, 854013216788180865, 829159057095801915, 2030937970488420525, 9719562562552278360L, 4544082617950022895, 157160975107204845, 5385743285459484420L]
12884901885
12884901885
4294967295
8589934590
42949672950
17179869180
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
55834574835
4294967295
30064771065
4294967295
12884901885
244813135815
12884901885

Modulus = 4294967295 == 2**32 -1

Solve the equation with Wolfram Alfa and get (a, c)

r0 = 855109115
r1 = 895402096
r2 = 2391280583
r3 = 300480802
m = 4294967295
r1 = ((a*r0) + b) mod m
r2 = ((a*r1) + b) mod m
r3 = ((a*r2) + b) mod m

a = 6771334847
c = 6621298821

Get the flag

# cat get_flag.py
from pwn import *

host = '195.154.53.62'
port = 7412

def give_me_the_next_number():
 r.sendlineafter('2: Give me the next number\n', '2')
 number = int(r.recvline())
 return number

def guess_the_next_number(number):
 next = lcg(number)
 r.sendlineafter('2: Give me the next number\n', '1')
 r.sendlineafter('Next number (in decimal) is\n', str(next))
 return next

def lcg(seed):
 a = 6771334847
 c = 6621298821
 m = 4294967295
 return ((seed * a) + c) % m

r = remote(host, port)

seed = give_me_the_next_number()

for i in range(10):
 print seed
 seed = guess_the_next_number(seed)

print r.recvline()
r.close()

# python get_flag.py
604672456
322278383
3842182927
2626463750
2042127376
830485493
3402655117
2936071940
3380135806
3463756493
flag is ALEXCTF{f0cfad89693ec6787a75fa4e53d8bdb5}

References

https://en.wikipedia.org/wiki/Linear_congruential_generator
http://security.stackexchange.com/questions/4268/cracking-a-linear-congruential-generator

# AlexCTF: CR4: Poor RSA - 200 pts


Get modulus and exponent from public key

# openssl rsa -pubin -inform PEM -text -noout < key.pub
Public-Key: (399 bit)
Modulus:
    52:a9:9e:24:9e:e7:cf:3c:0c:bf:96:3a:00:96:61:
    77:2b:c9:cd:f6:e1:e3:fb:fc:6e:44:a0:7a:5e:0f:
    89:44:57:a9:f8:1c:3a:e1:32:ac:56:83:d3:5b:28:
    ba:5c:32:42:43
Exponent: 65537 (0x10001)

Factor the modulus with factordb

# python -c 'print 0x52a99e249ee7cf3c0cbf963a009661772bc9cdf6e1e3fbfc6e44a07a5e0f894457a9f81c3ae132ac5683d35b28ba5c324243'
833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
863653476616376575308866344984576466644942572246900013156919
965445304326998194798282228842484732438457170595999523426901

Generate a private key and decrypt the flag

# ipython

In [1]: import gmpy

In [2]: p = 863653476616376575308866344984576466644942572246900013156919

In [3]: q = 965445304326998194798282228842484732438457170595999523426901

In [4]: e = 65537L

In [5]: d = long(gmpy.invert(e,(p-1)*(q-1)))

In [6]: n = p * q

In [7]: from Crypto.PublicKey import RSA

In [8]: key = RSA.construct((n,e,d))

In [9: f = open('flag.b64')

In [10]: edata = f.read()

In [11]: f.close()

In [12]: import base64

In [13]: key.decrypt(base64.b64decode(edata))
Out[13]: 'ALEXCTF{SMALL_PRIMES_ARE_BAD}'

# AlexCTF: RE4: unVM me - 250 pts


Decompilation

# uncompyle unvm_me.pyc > source.py
# cat source.py
import md5
md5s = [174282896860968005525213562254350376167L, 137092044126081477479435678296496849608L, 126300127609096051658061491018211963916L, 314989972419727999226545215739316729360L, 256525866025901597224592941642385934114L, 115141138810151571209618282728408211053L, 8705973470942652577929336993839061582L, 256697681645515528548061291580728800189L, 39818552652170274340851144295913091599L, 65313561977812018046200997898904313350L, 230909080238053318105407334248228870753L, 196125799557195268866757688147870815374L, 74874145132345503095307276614727915885L]
print 'Can you turn me back to python ? ...'
flag = raw_input('well as you wish.. what is the flag: ')
if len(flag) > 69:
    print 'nice try'
    exit()
if len(flag) % 5 != 0:
    print 'nice try'
    exit()
for i in range(0, len(flag), 5):
    s = flag[i:i + 5]
    if int('0x' + md5.new(s).hexdigest(), 16) != md5s[i / 5]:
        print 'nice try'
        exit()

print 'Congratz now you have the flag'

Generate the wordlist

# crunch 5 5 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz{} > md5.txt

Get the flag

# cat crack.py
import md5

imd5 = [174282896860968005525213562254350376167L, 137092044126081477479435678296496849608L, 126300127609096051658061491018211963916L, 314989972419727999226545215739316729360L, 256525866025901597224592941642385934114L, 115141138810151571209618282728408211053L, 8705973470942652577929336993839061582L, 256697681645515528548061291580728800189L, 39818552652170274340851144295913091599L, 65313561977812018046200997898904313350L, 230909080238053318105407334248228870753L, 196125799557195268866757688147870815374L, 74874145132345503095307276614727915885L]

hmd5 = []
for i in imd5:
 r = hex(i)[2:-1]
 if len(r) != 32:
  r = '0' + r
 hmd5.append(r)

with open("md5.txt", "r") as ins:
 for line in ins:
  line = line[:-1]
  m = md5.new(line).hexdigest()
  if m in hmd5:
   print line, hmd5.index(m)
for i in hmd5:
 print i

# python crack.py
1n52n 8
28n4b 11
43s8d 4
5d4s2 2
6v3k} 12
81h3d 10
8l6m1 5
ALEXC 0
TF{dv 1
ds9v4 7
n5l67 6
v37j4 9
vj8nk 3
ALEXCTF{dv5d4s2vj8nk43s8d8l6m1n5l67ds9v41n52nv37j481h3d28n4b6v3k}