20160501: Hacky Easter 2016 - writeup

tags: netsec, ctf, hacking-lab, hacky, easter, 2016, he2016
QR code decoder
all keys in lowercase only
  1. Easy One
  2. As always, the first challenge is very easy. Even babies can solve this one!
    
    Find the code and enter it in the Egg-O-Matic™ below! One word, all lowercase.
    
    xt   hex   yhi   dde   nyy   str
    in   gyy   isy   ymo   lly   cod
    dl   exy   sox   xsi   mpl   ey🚼
    
    • remove whitespace => xthexyhiddenyystringyyisyymollycoddlexysoxxsimpley
    Need a holiday? Book a cruise on our new flag ship!
    
    Seek out the promotion code below (lowercase only, no spaces) and get a free welcome package!
    




    • @ //en.wikipedia.org/wiki/International_maritime_signal_flags
    • download <img> URLs (list via Chrome DevTools console): console.log.apply(console, $("a.image>img", $("table.wikitable")[0]).map((_,el)=>"https:"+$(el).attr("src").replace("/thumb/","/").split("/").slice(0,-1).join("/")+"\n"))
    • https://upload.wikimedia.org/wikipedia/commons/7/71/ICS_Alpha.svg
      https://upload.wikimedia.org/wikipedia/commons/f/f7/ICS_Bravo.svg
      https://upload.wikimedia.org/wikipedia/commons/e/e7/ICS_Charlie.svg
      https://upload.wikimedia.org/wikipedia/commons/e/eb/ICS_Delta.svg
      https://upload.wikimedia.org/wikipedia/commons/0/0b/ICS_Echo.svg
      https://upload.wikimedia.org/wikipedia/commons/a/a8/ICS_Foxtrot.svg
      https://upload.wikimedia.org/wikipedia/commons/f/fb/ICS_Golf.svg
      https://upload.wikimedia.org/wikipedia/commons/0/0f/ICS_Hotel.svg
      https://upload.wikimedia.org/wikipedia/commons/8/8e/ICS_India.svg
      https://upload.wikimedia.org/wikipedia/commons/a/a0/ICS_Juliet.svg
      https://upload.wikimedia.org/wikipedia/commons/a/a8/ICS_Kilo.svg
      https://upload.wikimedia.org/wikipedia/commons/7/76/ICS_Lima.svg
      https://upload.wikimedia.org/wikipedia/commons/7/73/ICS_Mike.svg
      https://upload.wikimedia.org/wikipedia/commons/2/21/ICS_November.svg
      https://upload.wikimedia.org/wikipedia/commons/c/c9/ICS_Oscar.svg
      https://upload.wikimedia.org/wikipedia/commons/d/d0/ICS_Papa.svg
      https://upload.wikimedia.org/wikipedia/commons/d/d4/ICS_Quebec.svg
      https://upload.wikimedia.org/wikipedia/commons/b/bf/ICS_Romeo.svg
      https://upload.wikimedia.org/wikipedia/commons/3/36/ICS_Sierra.svg
      https://upload.wikimedia.org/wikipedia/commons/1/1e/ICS_Tango.svg
      https://upload.wikimedia.org/wikipedia/commons/e/e2/ICS_Uniform.svg
      https://upload.wikimedia.org/wikipedia/commons/e/ef/ICS_Victor.svg
      https://upload.wikimedia.org/wikipedia/commons/8/88/ICS_Whiskey.svg
      https://upload.wikimedia.org/wikipedia/commons/b/ba/ICS_X-ray.svg
      https://upload.wikimedia.org/wikipedia/commons/2/23/ICS_Yankee.svg
      https://upload.wikimedia.org/wikipedia/commons/c/c6/ICS_Zulu.svg
      d30dad6a23a294b9f210d216d59473d253e91be7	a
      d9bf326a6f0d0f00a7d1d8b400507e62d29483ed	b
      c11941f79c5500728d0dc7425fe9bb124446079c	c
      4f166789cf42b599a7f4f3060d8b6e25f7727e13	d
      753cc7b14eff2227d7dac636011a9ac0f5f8c85d	e
      e14699d3d770644c8573605ffbc8d4f4aa5f7029	f
      dda74b1b698bc28c0cf306c6da9f25050fa3d350	g
      069e17c90baaebe58f353e74ce5fb7b1c652be5a	h
      0a68cb42def843d4248bced813e0c841ba6e8e5c	i
      2195ef95677fc1e704feae58fe9c2b3a2e97ccae	j
      3a236df89d94c52b46f6cf749dc09154cc84b08a	k
      995e3d13a4caa01bf857401627e14cdb5d8de7b2	l
      08863662b355d3b53553c8e514d4ba0a972526f5	m
      ecbe3f1de440a2291c6b8179aa66642ea2bc741f	n
      9f0ecff5283aa1860b5f398d138540e2cf71d994	o
      67b2119bedff230ed0cbff46e5976fd39a6808f0	p
      4ce3f408ba42ca2bffee85facd1cb0fe6ecbe11a	q
      96c008b70347a138f1c903b3375b942011d61498	r
      6d959e1753fdf0367f0595a74346ef2f89984a5f	s
      e8b76378e7f17abdc5c0833e2bcd98df0912d049	t
      2e3842ba3f23bef3c46e6b8c2bd1097a0500d447	u
      327bafff04f8b6b4383a915d277b3e50bc06a9eb	v
      9aa58d041d01df5e0f9e3742bda88824a132d352	w
      ce959e05c85362c2942472e8f34e8889e9c17d59	x
      d6a88534fdb4e978d2f1e1f0e963fcd660ab69bb	y
      517cac1d9150b6258e8a82b614711864bb9fb3e1	z
    • some of the given flags are invalid "International Maritime Signal Flags"; only those 600x600 ones are valid, so filter: for f in flag*.svg; do if fgrep -q 'width="600"' "${f}"; then if fgrep -q 'height="600"' "${f}"; then sha1sum "${f}"; fi; fi; done >2-hash-to-flag.txt
    • 753cc7b14eff2227d7dac636011a9ac0f5f8c85d	flag01.svg
      ecbe3f1de440a2291c6b8179aa66642ea2bc741f	flag02.svg
      2195ef95677fc1e704feae58fe9c2b3a2e97ccae	flag04.svg
      9f0ecff5283aa1860b5f398d138540e2cf71d994	flag05.svg
      fcd4d10bdc43277b3ccbba71382bf0fbfc5bc494	flag06.svg
      0ddbf603ef28c81e359e7ba64308990d6f4a214e	flag07.svg
      52df748402bccf3c7e8c381fbde0bb34dbda8948	flag08.svg
      83f3eec8fb51a3ec4bba76c6be635513fa951fb0	flag09.svg
      96c008b70347a138f1c903b3375b942011d61498	flag10.svg
      8409911c83fe9df49344dfd34c0434ac7756f0d0	flag12.svg
      069e17c90baaebe58f353e74ce5fb7b1c652be5a	flag13.svg
      ebccda6096bed11e237d7c40ca3f1ba1ef6124bc	flag14.svg
      bbcb27098a0b3174143c44e2d907c72a1fdb7cd8	flag15.svg
      517cac1d9150b6258e8a82b614711864bb9fb3e1	flag16.svg
      753cc7b14eff2227d7dac636011a9ac0f5f8c85d	flag01.svg	e
      ecbe3f1de440a2291c6b8179aa66642ea2bc741f	flag02.svg	n
      2195ef95677fc1e704feae58fe9c2b3a2e97ccae	flag04.svg	j
      9f0ecff5283aa1860b5f398d138540e2cf71d994	flag05.svg	o
      fcd4d10bdc43277b3ccbba71382bf0fbfc5bc494	flag06.svg
      0ddbf603ef28c81e359e7ba64308990d6f4a214e	flag07.svg
      52df748402bccf3c7e8c381fbde0bb34dbda8948	flag08.svg
      83f3eec8fb51a3ec4bba76c6be635513fa951fb0	flag09.svg
      96c008b70347a138f1c903b3375b942011d61498	flag10.svg	r
      8409911c83fe9df49344dfd34c0434ac7756f0d0	flag12.svg
      069e17c90baaebe58f353e74ce5fb7b1c652be5a	flag13.svg	h
      ebccda6096bed11e237d7c40ca3f1ba1ef6124bc	flag14.svg
      bbcb27098a0b3174143c44e2d907c72a1fdb7cd8	flag15.svg
      517cac1d9150b6258e8a82b614711864bb9fb3e1	flag16.svg	z
    • to solve the remaining:
      1. convert all un-mapped ICS_*.svg => ICS_*.png and flag[0-9]*.svg => flag[0-9]*.png
      2. transparent background => white
        using Inkscape & ImageMagick
        for f in {ICS_,flag[0-9]}*.svg; do inkscape -z -e "${f%%.svg}.png" "${f}"; convert "${f%%.svg}.png" -background white -alpha remove -flatten -alpha off "${f%%.svg}.png"; done
      3. some of the <img> contain extra borders, causing an exact hash match to fail
        …so find closest match, in terms of pixel similarity
        threshold @ <100k/(600*600)~27.8%
        COLOR=black; for flag in flag[0-9]*.png; do for ics in ICS_*.png; do compare "${flag}" "${ics}" -compose src -highlight-color black cmp.tmp.png; L=$(basename "${ics}"); echo -ne "${(L)L:4:1}\t"; convert cmp.tmp.png -fill black +opaque "${COLOR}" -fill white -fuzz 0 -opaque "${COLOR}" -print "%[fx:int(w*h*mean)]" null:; echo; done | sort -n -k2 | head -1 | while read letter cnt; do if [ "${cnt}" -lt 100000 ]; then echo -e "${flag%%.png}.svg\t${letter}"; fi; done; done; rm -f cmp.tmp.png
      4. flag06.svg	y
        flag08.svg	a
        flag09.svg	f
        flag12.svg	s
        flag14.svg	b
        flag15.svg	m
      5. it turns out that flag07.svg doesn't match any of the "International Maritime Signal Flags", even though it is of the expected dimensions 600x600
    • consolidated list
    • flag01.svg	e
      flag02.svg	n
      flag04.svg	j
      flag05.svg	o
      flag06.svg	y
      flag08.svg	a
      flag09.svg	f
      flag10.svg	r
      flag12.svg	s
      flag13.svg	h
      flag14.svg	b
      flag15.svg	m
      flag16.svg	z
      flag01.svg
      flag02.svg
      flag03.svg
      flag04.svg
      flag05.svg
      flag06.svg
      flag07.svg
      flag08.svg
      flag09.svg
      flag10.svg
      flag11.svg
      flag01.svg
      flag12.svg
      flag13.svg
      flag12.svg
      flag01.svg
      flag08.svg
      flag14.svg
      flag10.svg
      flag15.svg
      flag01.svg
      flag01.svg
      flag16.svg
      flag17.svg
      flag01.svg
    • matched consolidated list with seq of flags given: while read f; do fgrep "${f}" 1; done <2 | cut -f2 | tr -d '\n'
    • enjoyafreshseabreeze (removed an extraneous `m`)
    @ /assets/www/challenge03.html:
    The little bird has hidden an egg in its nest. Can you find it?
    
    
    
    @ /assets/www/challenge04.html:
    The new sound system needs a check. Sharpen your ears and listen carefully!
    
    
    
    • @ ps.hacking.hackyeaster.android.SoundActivity:
      …
      byte[] woozle = Base64.decode(this.val$activity.getString(C0174R.string.woozle), 0);
      for (int i = 0; i < woozle.length; i++) {
      	woozle[i] = (byte) (woozle[i] ^ i);
      }
      …
      
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      import sys
      import struct
      
      data = bytearray(open("egg04-woozle.in", "rb").read())
      key = map(int, list(xrange(len(data))))
      o = [(data[i]^key[i])%256 for i in xrange(len(data))]
      with open("egg04-woozle.png", "wb") as f: f.write(bytearray(o))
      print "egg04-woozle.in => egg04-woozle.png"
    Do you know Paul? If not, it's about time to get to know him! Check out his video below!
    Ĉu vi scias Paŭlo? Se ne, ĝi estas pri tempo ekkoni lin! Kontroli lian video sube!
    
    • hint to look in Esperanto subtitle file, since given translation (second line) is in Esperanto
    • 1
      00:01:00.000 --> 00:01:03.000
      passphrase is "youtubelotitis"
    Time for an elevator ride. Guess the right floor, and find the hidden easter egg!
    
    Nope! Click the image to try again!
    Wise Rabbit says:
    
    The solution is in the solutions!
    Go back and scroll to 123!
    
    @ /assets/www/challenge08.html:
    var solved = false;
    var hist = "";
    …
    function rotFeedback(jsonString) {
    	if (json) {
    		hist = json.h;
    		if (json.k) {
    			solved = true;
    		} else if (json.s > 1) {
    			$("#rotImg").attr("src", "images/rot/rot"+json.s+".png");
    		} else {
    			$("#rotImg").attr("src", "images/egg_gray.png");
    		}
    	}
    }
    
    setInterval(function () {
    	if (!solved) {
    		document.location.href = "ps://rot?h="+hist;
    	}
    }, 1000);
    • @ ps.hacking.hackyeaster.android.Activity:
    • private String handleRot(String s) {
      	char c;
      	switch (((WindowManager) getSystemService("window")).getDefaultDisplay().getRotation()) {
      		case SwipeRefreshLayout.LARGE /*0*/:
      			c = 'r';
      			break;
      		case SwipeRefreshLayout.DEFAULT /*1*/:
      			c = 'n';
      			break;
      		case WearableExtender.SIZE_MEDIUM /*3*/:
      			c = 'x';
      			break;
      		default:
      			c = 'l';
      			break;
      	}
      	if (!s.startsWith(BuildConfig.VERSION_NAME + c)) {
      		s = c + s;
      	}
      	if (s.length() > 8) {
      		s = s.substring(0, 8);
      	}
      	int steps = 0;
      	String key = BuildConfig.VERSION_NAME;
      	String h = sha1(s);
      	if (h.startsWith("4692bd56dd3070f74b7e")) {
      		key = h;
      	} else if (s.length() >= 7 && "1ab9a97066f747c25d9c6a6b0fda647fae98cb98".equals(sha1(s.substring(0, 7)))) {
      		steps = 7;
      	} else if (s.length() >= 6 && "58192f7d1263bd420efb788cc884a84f871239cf".equals(sha1(s.substring(0, 6)))) {
      		steps = 6;
      	} else if (s.length() >= 5 && "e8f235e79be9f8b13598b285a6fdaf2ac70a66ca".equals(sha1(s.substring(0, 5)))) {
      		steps = 5;
      	} else if (s.length() >= 4 && "3daee0c0bada99f5bf0866728fd78299acaafa15".equals(sha1(s.substring(0, 4)))) {
      		steps = 4;
      	} else if (s.length() >= 3 && "f11fa81c0b72716bba0536dd34b9b0987af69b03".equals(sha1(s.substring(0, 3)))) {
      		steps = 3;
      	} else if (s.length() >= 2 && "a8643e0e26d5ead82e73aae64966ca144f152d8a".equals(sha1(s.substring(0, 2)))) {
      		steps = 2;
      	} else if (s.length() >= 1 && "4dc7c9ec434ed06502767136789763ec11d2c4b7".equals(sha1(s.substring(0, 1)))) {
      		steps = 1;
      	}
      	return "{ \"s\": " + steps + ", \"h\":\"" + s + "\", \"k\":\"" + key + "\" }";
      }
    • crack SHA1 hashes using cudaHashcat; charset: `rnxl`
      • 4692bd56dd3070f74b7e81c6b2f69339b0fd6062: nrxrxrnr
      • 1ab9a97066f747c25d9c6a6b0fda647fae98cb98:  rxrxrnr
      • 58192f7d1263bd420efb788cc884a84f871239cf:   xrxrnr
      • e8f235e79be9f8b13598b285a6fdaf2ac70a66ca:    rxrnr
      • 3daee0c0bada99f5bf0866728fd78299acaafa15:     xrnr
      • f11fa81c0b72716bba0536dd34b9b0987af69b03:      rnr
      • a8643e0e26d5ead82e73aae64966ca144f152d8a:       nr
      • 4dc7c9ec434ed06502767136789763ec11d2c4b7:        r
    • $(document).ready(function () {
      	var o = {k: "4692bd56dd3070f74b7e81c6b2f69339b0fd6062"};
      	var s = CryptoJS.enc.Latin1.stringify(
      		CryptoJS.AES.decrypt(scrambledEggCipher, o.k)
      	);
      	// var png_magic_s = "iVBORw0KGgoAAAANSUhEUgAAA";
      	// s.startsWith(png_magic_s);
      	// s.substring(0,26) === png_magic_s;
      	document.getElementById("rotImg").src = "data:image/png;base64,"+s;
      });
    What about a little brain game?
    
    
    
    1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 Bc5 5. O-O d6 6. Nbd2 O-O 7. Bxc6 bxc6 8. h3 h6 9. Re1 Re8 10. Nf1 a5 11. Ng3 Rb8 12. b3 Bb4 13. Bd2 Ra8 14. c3 Bc5 15. d4 Bb6 16. dxe5 dxe5 17. c4 Nh7 18. Qe2 Nf8 19. Be3 c5 20. Rad1 Qf6 21. Nh5 Qe7 22. Nh2 Kh7 23. Qf3 f6 24. Ng4 Bxg4 25. Qxg4 Red8 26. Qf5+ Kh8 27. f4 Rxd1 28. Rxd1 exf4 29. Bxf4 Qe6 30. Rd3 Re8 31. Nxg7 Kxg7 32. Qh5 Nh7 33. Bxh6+ Kh8 34. Qg6 Qg8 35. Bg7+ Qxg7 36. Qxe8+ Qf8 37. Qe6 Qh6 38. e5 Qc1+ 39. Kh2 Qf4+ 40. Rg3 1-0
    
    • each term in the string of the white-on-red part encodes a row of the state of the chessboard, from top to bottom
    • `0` indicates absence of a piece in that particular grid cell, while `1` indicates presence
    • interpret each row of `0`s and `1`s formed this way in binary, and convert it to decimal
    • play out the given sequence of moves from the initial state, as given:
    • encode the final state of the chessboard similarly:
    • 00000001
      00100001
      01001100
      10101000
      00100100
      01000011
      10000011
      00000000
    • 1-33-76-168-36-67-131-0
    Time for some math! Find the number which produces the plot on the bottom!
    Try these two samples: sample 1, sample 2.
    Your plot:
    Target plot:
    You found a secret disc which conceals a secret password. Can you crack it?
    
    Hint: Each ring of the disc holds one letter. The first letter sits on the outermost ring.
    
    
    
    • letters that appear once only (i.e. unique) in each ring
      • h
      • a
      • n
      • i
      • e, l, s
      • h
      • o
    • hanisho
    Version control is a powerful tool. Thinking she was oh so smart, Fluffy used it to hide an easter egg. Can you pull out the egg from her file?
    
    Hint: If you get stuck, go one step back.
    
    
    
    • nested `.git` repo
    • _PWD="${PWD}"; for i in $(seq -f %04g 1000 -1 1); do git checkout ${i}.zip; mv ${i}.zip "${_PWD}"; cd "${_PWD}"; 7za x ${i}.zip; cd ${i}; done
    • #722: 0722-trunk.jpg
    • commit dcf4797deccfbeaea0e3bcd12d2b32b1185326f6 <-- <trunk.jpg>
      Author: Fluffy <fluffy@bunnymail.net>
      Date:   Thu Nov 26 21:12:51 2015 +0100
      
      	Change committed
      
      commit 44dc75110bf3139dca7aa156cfe11781971887bd
      Author: Fluffy <fluffy@bunnymail.net>
      Date:   Thu Nov 26 21:12:51 2015 +0100
      
      	Change committed
      
      commit 93d630215b9c5c49f2c7f3c6b9fe1b55efd93cd1
      Author: Fluffy <fluffy@bunnymail.net>
      Date:   Thu Nov 26 21:12:51 2015 +0100
      
      	Commit committed
    • git reset 93d630215b9c5c49f2c7f3c6b9fe1b55efd93cd1
    • #396: 0396-scooter.jpg
    • commit a0c43441f52a5ff4362156a2f8db1d16a4f8bb3b <-- <scooter.jpg>
      Author: Fluffy <fluffy@bunnymail.net>
      Date:   Thu Nov 26 21:10:08 2015 +0100
      
      	Commit committed
      
      commit 27dbde667908b19d59eb6d8e3ed8802ebf34ab9b
      Author: Fluffy <fluffy@bunnymail.net>
      Date:   Thu Nov 26 21:10:08 2015 +0100
      
      	Commit committed
    • git reset 27dbde667908b19d59eb6d8e3ed8802ebf34ab9b
    • #46: passwd-prot archive 0045.zip
    • commit 37f69df62069e4d98e60986aa5d4b4b21e66ccc3
      Author: Fluffy 
      Date:   Thu Nov 26 21:08:52 2015 +0100
      
      	Commit committed. Pass is fluffy99 <-- for 0045.zip
    Do you need a new wallpaper? What about a fancy fractal?
    
    Find the password hidden in the wallpaper image, and enter it in the Egg-O-Matic below.
    
    
    • extract QR codes individually from given image
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      import os
      import sys
      from PIL import Image
      
      if __name__ == "__main__":
      	im = Image.open("wallpaper.jpg")
      	w, h = im.size
      	pix = im.load()
      	qr_w, qr_h = 21, 21
      	m = 0
      	for y in xrange(0,h,qr_h):
      		for x in xrange(0,w,qr_w):
      			top_left = (x,y)
      			btm_right = (x+qr_w-1,y+qr_h-1)
      			im_qr = Image.new("RGB", (qr_w,qr_h), "white")
      			pix_qr = im_qr.load()
      			for c in xrange(qr_w):
      				for r in xrange(qr_h):
      					pix_qr[c, r] = pix[x+c, y+r]
      			folder = "img"
      			if not os.path.exists(folder):
      				os.makedirs(folder)
      			fp = "%s/egg13-out-%d.png" %(folder,m)
      			im_qr.save(fp)
      			print>>sys.stderr, "=>", fp
      			m += 1
    • process using zxing:
      • either "No barcode found"
      • or QR code txt == xx*
      • except #58608 : fractalsaresokewl
    Folks at HOBO Authentication Systems implemented a new authentication system named P.A.L.M. ™
    
    Prove that you can break it and find a pair of username and passcode to log on.
    
    

    P.A.L.M. Authentication ™

    • decoy js
    • function checkEntries() {
      	var u = document.getElementById("puser").value;
      	var p = document.getElementById("ppass").value;
      	if (u === "yolo" &amp;&amp; p === "1337") {
      		document.location.href = "challenge14_" + u + "_" + p + ".html";
      	} else {
      		alert("nope");
      	}
      }
      var _0x549b = ["value", "puser", "getElementById", "ppass", "rolo", "length", "charAt", "href", "location", "challenge14_", "_", ".html", "nope"];
      function checkEntries() {
      	var u = document[_0x549b[2]](_0x549b[1])[_0x549b[0]];
      	var p = document[_0x549b[2]](_0x549b[3])[_0x549b[0]];
      	var ok = false;
      	if (u === _0x549b[4]) {
      		if (p > 0 &amp;&amp; p[_0x549b[5]] == 10) {
      			ok = true;
      			for (i = 0; i <= 9; i++) {
      				var digit = p[_0x549b[6]](i);
      				if (digit != 9 - i) {
      					ok = false
      				}
      			}
      		}
      	};
      	if (ok) {
      		document[_0x549b[8]][_0x549b[7]] = _0x549b[9] + u + _0x549b[10] + p + _0x549b[11]
      	} else {
      		alert(_0x549b[12])
      	}
      };
    • @ btm of webpage HTML src
    • eval(atob("ZXZhbChmdW5jdGlvbihwLGEsYyxrLGUsZCl7ZT1mdW5jdGlvbihjKXtyZXR1cm4gYy50b1N0cmluZygzNil9O2lmKCEnJy5yZXBsYWNlKC9eLyxTdHJpbmcpKXt3aGlsZShjLS0pe2RbYy50b1N0cmluZyhhKV09a1tjXXx8Yy50b1N0cmluZyhhKX1rPVtmdW5jdGlvbihlKXtyZXR1cm4gZFtlXX1dO2U9ZnVuY3Rpb24oKXtyZXR1cm4nXFx3Kyd9O2M9MX07d2hpbGUoYy0tKXtpZihrW2NdKXtwPXAucmVwbGFjZShuZXcgUmVnRXhwKCdcXGInK2UoYykrJ1xcYicsJ2cnKSxrW2NdKX19cmV0dXJuIHB9KCdyIHEoKXsyIHU9Ny44KFwnd1wnKS5iOzIgcD03LjgoXCd2XCcpLmI7MiA0PVswLDAsMCwwLDAsMCwwLDAsMCwwXTsyIDU9YzszKHU9PT1cJ2dcJyl7MyhwPjAmJnAuaD09OSl7NT1qO2YoaT0xO2k8PTk7aSsrKXsyIDY9cC5rKGktMSk7MiBhPXAuZSgwLGkpOzMoNFs2XSE9MHx8YSVpIT0wKXs1PWN9Myg0WzZdPT0wKXs0WzZdPTF9fX19Myg1KXs3Lm0ubj1cJ29cJyt1K1wneFwnK3ArXCcuc1wnfXR7ZChcJ2xcJyl9fScsMzQsMzQsJ3x8dmFyfGlmfHVzZWR8b2t8ZGlnaXR8ZG9jdW1lbnR8Z2V0RWxlbWVudEJ5SWR8MTB8cGFydHx2YWx1ZXxmYWxzZXxhbGVydHxzdWJzdHJpbmd8Zm9yfGVsc2F8bGVuZ3RofHx0cnVlfGNoYXJBdHxub3BlfGxvY2F0aW9ufGhyZWZ8Y2hhbGxlbmdlMTRffHxjaGVja0VudHJpZXN8ZnVuY3Rpb258aHRtbHxlbHNlfHxwcGFzc3xwdXNlcnxfJy5zcGxpdCgnfCcpLDAse30pKQ=="));
    • ...becomes...
    • eval(eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('r q(){2 u=7.8(\'w\').b;2 p=7.8(\'v\').b;2 4=[0,0,0,0,0,0,0,0,0,0];2 5=c;3(u===\'g\'){3(p>0&&p.h==9){5=j;f(i=1;i<=9;i++){2 6=p.k(i-1);2 a=p.e(0,i);3(4[6]!=0||a%i!=0){5=c}3(4[6]==0){4[6]=1}}}}3(5){7.m.n=\'o\'+u+\'x\'+p+\'.s\'}t{d(\'l\')}}',34,34,'||var|if|used|ok|digit|document|getElementById|10|part|value|false|alert|substring|for|elsa|length||true|charAt|nope|location|href|challenge14_||checkEntries|function|html|else||ppass|puser|_'.split('|'),0,{})))
    • @ //jsbeautifier.org
    • function checkEntries() {
      	var u = document.getElementById("puser").value;
      	var p = document.getElementById("ppass").value;
      	var used = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
      	var ok = false;
      	if (u === "elsa") {
      		if (p > 0 && p.length == 10) {
      			ok = true;
      			for (i = 1; i <= 10; i++) {
      				var digit = p.charAt(i - 1);
      				var part = p.substring(0, i);
      				if (used[digit] != 0 || part % i != 0) {
      					ok = false;
      				}
      				if (used[digit] == 0) {
      					used[digit] = 1;
      				}
      			}
      		}
      	}
      	if (ok) {
      		document.location.href = "challenge14_"+u+"_"+p+".html";
      	} else {
      		alert("nope");
      	}
      }
    • elsa / 3816547290
    Three little pigs have hidden in their house. You're the big, bad wolf, and your stomach is growling. Huff and puff and blow the pigs' house in! Get that juicy bacon!
    
    Hints:
    • the pigs have hidden in three different media types (image, sound, text)
    • no password cracking is necessary
    
    
    
    • file listing:
      • piglet.jpg
      • pigs.jpg
      • song.mp3
      • story.pdf
      • story.txt
      • wolf.jpg
    • pig 1: Filbert @ SNOW story.txt
    • pig 2: Cassadee $ exiftool wolf.jpg | fgrep "XP Comment"
    • pig 3: Wynchell @ MP3Stego $ decode song.mp3
    Egg coloring is fun!
    
    Can you get the yellow egg?
    
    
    
    Wannabe programming guru Hazel B. Easterwood created a new programming language called "Bunny Hop". You suspect Hazel to have cheated, because the language looks very familiar to you.
    
    Download the following code and complete it! It will yield the QR code for egg 17.
    
    
    
    • 1-1 mapping from Logo programming language, replace:
      • `hop` = `fd`
      • `backhop` = `bk`
    • missing subroutine: egg
    • to egg
      	pd
      	fd 1
      	bk 1
      	pu
      end
    • online tool: //logo.twentygototen.org
    • ...in ASCII, becomes egg17-qrcode.txt:
      xxxxxxx..x.....xx.xxxxxxx
      x.....x.xx.xxxxxx.x.....x
      x.xxx.x..xxx..xx..x.xxx.x
      x.xxx.x.xx.x.xxx..x.xxx.x
      x.xxx.x...x.xx.xx.x.xxx.x
      x.....x.x.x..xxxx.x.....x
      xxxxxxx.x.x.x.x.x.xxxxxxx
      ............x.xxx........
      xxxxx.xxxxx.x.x..x.x.x.x.
      .x.xxx...x...x.xx.xx.x...
      .xx...x.xx.xx.xx..x....xx
      xx.x.x.xxxxx..xx.xxx.x.xx
      xxx...x.xx.x....xxxx..x..
      x..x...x.xx.xx..xxxx.x.xx
      x.x.x.x...x..xxxx.xxx.xxx
      x..x...xx.x.xx.x.xxxx....
      x...x.x.....x.x.xxxxxxxx.
      ........x.......x...xxx..
      xxxxxxx.xx.xx...x.x.x.xxx
      x.....x...xx..x.x...x...x
      x.xxx.x.x.xx...xxxxxx.xxx
      x.xxx.x.x...xxxxxxx.x..xx
      x.xxx.x.x.x..xx....x.x..x
      x.....x.xx..xx..x.xx....x
      xxxxxxx.x...x.xx.x...x.xx
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      import sys
      import codecs
      from PIL import Image
      
      sys.stdout = codecs.getwriter("utf8")(sys.stdout)
      sys.stderr = codecs.getwriter("utf8")(sys.stderr)
      
      if __name__ == "__main__":
      	w, h = 75, 75
      	im = Image.new("RGBA", (w, h), "white")
      	pix = im.load()
      	grid = []
      	with codecs.open("egg17-qrcode.txt", "r", "utf-8") as f:
      		for r, line in enumerate(f):
      			line = line.strip()
      			if not line: continue
      			row = []
      			for c, ch in enumerate(line):
      				color = (0,0,0,255) if ch == "x" else (255,255,255,255)
      				row.append(color)
      			grid.append(row)
      	for r in xrange(w):
      		for c in xrange(h):
      			pix[r,c] = grid[r/(w/25)][c/(h/25)]
      	im.save("egg17-qrcode.png")
    Lacking of time, you were not able not complete your DeggCryptor program. In an act of desperation, you instructed Sammy, the junior programmer, to implement the missing key generation function.
    
    As always, Sammy miserably failed. Can you fix his code? It's the KeyGen class. Pay attention to the comments!
    
    
    
    • file listing:
      • DeggCryptor.sln
      • DeggCryptor/AesHelper.cs
      • DeggCryptor/App.config
      • DeggCryptor/DeggCryptor.csproj
      • DeggCryptor/KeyGen.cs
      • DeggCryptor/MainForm.cs
      • DeggCryptor/MainForm.Designer.cs
      • DeggCryptor/MainForm.resx
      • DeggCryptor/Program.cs
      • DeggCryptor/Properties/AssemblyInfo.cs
      • DeggCryptor/Properties/Resources.Designer.cs
      • DeggCryptor/Properties/Resources.resx
      • DeggCryptor/Properties/Settings.Designer.cs
      • DeggCryptor/Properties/Settings.settings
      • DeggCryptor/Resources/egg_gray.png
    • @ DeggCryptor/KeyGen.cs (original commented + fixed)
    • public static string generateKey()
      {
      	// Init the four seed values. 1111 and multiples of it.
      	int h1 = /*0x*/1111;
      	int h2 = /*0x*/2222;
      	int h3 = /*0x*/3333;
      	int h4 = /*0x*/4444;
      
      	// Init variables.
      	int a = h1;
      	int b = h2;
      	int c = h3;
      	int d = h4;
      
      	// 1k iterations.
      	//for (int i = 1; i < 1000; i++)
      	for (int i = 0; i < 1000; i++)
      	{
      		// If c is greater than d, double c and d.
      		// if (c > d)
      		// 	c *= 2;
      		// 	d *= 2;
      		if (c > d) {
      			c *= 2;
      			d *= 2;
      		}
      
      		// Calculate new values.
      		// a: Take sum of a and b, and c and d. Then, multiply the two values.
      		// a = a + b * c + d;
      		a = (a + b) * (c + d);
      
      		// b: multiply with 3. Using two additions instead of multiplying -> performance booooost!
      		// b = b + b;
      		// b = b + b;
      		b *= 3;
      
      		// c, d: Swap c and d
      		// c = d;
      		// d = c;
      		int tmp = c;
      		c = d;
      		d = tmp;
      
      		// Take last four digits (modulo 10000)
      		a %= 10000;
      		b %= 10000;
      		c %= 10000;
      		// d %= 100000;
      		d %= 10000;
      	}
      	// Password: a,b,c and d with "X" in between
      	return a + "X" + b + "X" + c + "X" + d;
      }
    • key = 5792X2222X9104X5472
    • encryptedEgg @ DeggCryptor/MainForm.cs
    • public void egg18() {
      	string key = KeyGen.generateKey();
      	System.IO.MemoryStream streamBitmap = new System.IO.MemoryStream(
      		AesHelper.Decrypt(Convert.FromBase64String(encryptedEgg), key)
      	);
      	Bitmap bitImage = new Bitmap((Bitmap)Image.FromStream(streamBitmap));
      	String outputFilename = "egg18.png";
      	bitImage.Save(outputFilename);
      	Console.WriteLine("=> "+outputFilename);
      }
    In this challenge you must crack a server-side program. Lucky for you, you got the assembly file of the program. First, reverse-engineer the program and find a valid code! Then, submit the code to the server.
    
    The server is located at:
    hackyeaster.hacking-lab.com:1234
    
    Important: Do not launch brute-force attacks on the server - you'll not be lucky with it!
    
    
    
    • used Hopper & IDE Pro v6.6
    • code not obfuscated; just highly optimised
    • first few lines == preamble (gnu asm)
    • can strip all lines beginning with `.cfi_*`~instrumentation, and `.p2align*`~alignment
    • followed by `const` str
    • then `main` subroutine
      1. initial fgets() from `stdin` of 20 chars
      2. first main code block == optimised strlen()
        • [chk]: 16 < strlen(usr input str) ≤ 20 char (cmp rdx, 16; jbe .L2)
        • incl. bit-twiddling hack
        • [ref]: C-like pseudocode
        • v3 = &v19;
          do
          {
          	v4 = *(_DWORD *)v3;
          	v3 += 4;
          	// @ //graphics.stanford.edu/~seander/bithacks.html
          	// #define haszero(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL)
          	v5 = ~v4 & (v4 - 16843009) & 0x80808080; //16843009=0x1010101
          }
          while (!v5);
          if (!(~v4 & (v4 - 16843009) & 0x8080))
          	LOBYTE(v5) = v5 >> 16;
          if (!(~v4 & (v4 - 16843009) & 0x8080))
          	v3 += 2;
        • compare with @ //security.cs.pub.ro/hexcellents/wiki/writeups/pctf2014_bronies1, esp. magic `const` like 0x1010101
      3. infinite `while` loop containing main components:-
        • one if-check
        • one sort of if-else check
        • a bunch of expr stmts with the same fmt/patt, involving `shr` i.e. `>>31`, followed by `>>24`
        • another if-check that might `break` out of the loop
        • two more code sections
        v6 = v19;
        v12 = v19;
        v7 = 0; //'\0';
        v8 = 0;
        v9 = 0;
        v10 = 0;
        v11 = 0;
        while ( 1 )
        {
        	if ( v8 == 3 * (v8 / 3) ) // i.e. v8 % 3 == 0
        		v10 += v6;
        
        	v13 = v9 + v6;
        	if ( (v8 & 3) == 2 ) // i.e. (v8-2) % 4 == 0
        		v9 = v13; // v9 += v6
        
        	++v8; // v8:idx
        
        	// 8-bit ASCII value
        	v14 = (unsigned __int8)(((unsigned int)(v12 >> 31) >> 24) + v12) - ((unsigned int)(v12 >> 31) >> 24);
        	v15 = (unsigned __int8)(v11 + ((unsigned int)(v11 >> 31) >> 24)) - ((unsigned int)(v11 >> 31) >> 24);
        	v10 = (unsigned __int8)(((unsigned int)(v10 >> 31) >> 24) + v10) - ((unsigned int)(v10 >> 31) >> 24);
        	v9 = (unsigned __int8)(((unsigned int)(v9 >> 31) >> 24) + v9) - ((unsigned int)(v9 >> 31) >> 24);
        
        	if ( v8 == 16 ) // last char: idx 0-16; total len == 17
        		break;
        
        	// v7 = ptr to the curr pos into input str
        	// v6 holds actual value
        	// so, this line basically means: save, to v6, actual value stored @ addr v7
        	v6 = *(_BYTE *)v7;
        
        	v12 = v14 + v6; // no if-check here
        
        	v11 = v15 + v6; // odd pos: v11=v15+v6;
        	if ( !(v8 & 1) ) // i.e. v8 even
        		v11 = v15; // even pos: v11=v15
        
        	++v7;
        }
        • notice loop termination/exit condition v8 == 16, and increment statement ++v8;
        • => `v8`: loop counter variable
        • some sort of char chk by pos idx into usr input str happening
        • also another loop counter variable `v7` in the bottom half of the loop (hint: ++v7;), although this won't terminate the loop
        • notice `v7` "lags" behind `v8` by one
        • v6 = *(_BYTE *)v7; means `v6` == ASCII value corresponding to the char @ index `v7`
        • lines of the form v14 = (unsigned __int8)(((unsigned int)(v12 >> 31) >> 24) + v12) - ((unsigned int)(v12 >> 31) >> 24); convert a char to its equivalent 7-bit ASCII value
        • unsigned __int8: 8-bit type-cast (i.e. range 0-255) => %256
        • first if-check involving magic constant 0x55555556 ~ fancy way of division by 3
          @ //stackoverflow.com/questions/25782270/is-this-how-a-compiler-divides-just-by-using-bit-wise-operations
      4. final condition: v14 == 133 && v15 == 67 && v10 == 79 && v9 == 176
        • pseudocode: if(success) {print flag in secret.txt} else {print failure message "nope" (with a little `usleep()` distraction)}
    • instrumented asm
      • added `const` str: .LC1-5
        • with corresponding `jmp`s
      • split individual terms of final condition
      • added "discriminator"
        • cycling through ASCII range 1-127 for each term
        • except null terminator byte '\0', and line feed '\n'
      • e.g. v9 == 176:
      • …
        cmp     esi, 176 # v9~esi
        jb      .LL # <
        jl      .LL
        je      .LE # ==
        ja      .LG # >
        jg      .LG
        jne     .L2 # !=
        jmp     .L35 # catch-all jmp
        …
      	.intel_syntax noprefix
      	.section .rodata.str1.1,"aMS",@progbits,1
      .LC1:
      	.string "yep ✓"
      .LC2:
      	.string "nope ✗"
      .LC3:
      	.string "<"
      .LC4:
      	.string "=="
      .LC5:
      	.string ">"
      
      	.section .text.startup,"ax",@progbits
      	.globl  main
      	.type   main, @function
      main:
      	push    rbx
      	sub     rsp, 32
      
      	mov     esi, 20
      	mov     rdx, QWORD PTR stdin[rip]
      	mov     rdi, rsp
      	mov     rbx, rsp
      	call    fgets #fgets(input, 20, stdin)
      	test    rax, rax
      	je      .L2
      
      	mov     rdx, rsp
      .L3:
      	# 0x4004f8
      	mov     ecx, DWORD PTR [rdx]
      	add     rdx, 4
      
      	# @ //bits.stephan-brumme.com/null.cpp
      	lea     eax, [rcx-16843009] #v3-0x01010101
      	not     ecx
      	and     eax, ecx
      	and     eax, -2139062144 #0x80808080
      	je      .L3
      
      	mov     ecx, eax
      	shr     ecx, 16 #>>16
      	test    eax, 32896 #0x8080
      	cmove   eax, ecx
      	lea     rcx, [rdx+2]
      	cmove   rdx, rcx
      	add     al, al
      	sbb     rdx, 3
      	sub     rdx, rbx
      	cmp     rdx, 16 #0x10
      	jbe     .L2
      
      	# 16 < input str len <= 20 #
      
      	# 0x400537
      	#mov     bx, 0C3EEh  ;Sign bit of bl is now 1: BH == 1100 0011, BL == 1110 1110
      	#movsx   ebx, bx     ;Load signed 16-bit value into 32-bit register and sign-extend
      	#                    ;EBX is now equal FFFFC3EEh
      	movsx   r8d, BYTE PTR [rsp] #v7
      	lea     r10, [rbx+1]
      	xor     edi, edi #v8
      	xor     esi, esi #v9
      	xor     ecx, ecx #v10
      	xor     ebx, ebx #v11
      	mov     r11d, 1431655766 #0x55555556
      	mov     r9d, r8d
      	# 0x400551
      	jmp     .L13
      
      .L9:
      	# 0x400553
      	movsx   r8d, BYTE PTR [r10]
      	lea     ebx, [rdx+r8]
      	add     r9d, r8d
      	test    dil, 1
      	cmove   ebx, edx
      	add     r10, 1
      
      .L13:
      	# 0x400569
      	mov     eax, edi
      	imul    r11d # 0x40056b
      	mov     eax, edi
      	sar     eax, 31 #0x1f
      
      	sub     edx, eax
      	lea     eax, [rcx+r8]
      	lea     edx, [rdx+rdx*2]
      	cmp     edi, edx
      
      	cmove   ecx, eax
      	mov     eax, edi #v8~edi
      	add     r8d, esi
      	and     eax, 3 #v8 & 3
      	cmp     eax, 2 #(v8&3) == 2?
      
      	mov     eax, r9d
      	cmove   esi, r8d
      	sar     eax, 31
      	add     edi, 1
      	shr     eax, 24 #0x18
      	add     r9d, eax
      	movzx   r9d, r9b #sign-extend w/ 0
      	sub     r9d, eax
      
      	mov     eax, ebx
      	sar     eax, 31
      	shr     eax, 24
      	lea     edx, [rbx+rax]
      	movzx   edx, dl
      	sub     edx, eax
      
      	mov     eax, ecx
      	sar     eax, 31
      	shr     eax, 24
      	add     ecx, eax
      	movzx   ecx, cl
      	sub     ecx, eax
      
      	mov     eax, esi
      	sar     eax, 31
      	shr     eax, 24
      	add     esi, eax
      	movzx   esi, sil
      	sub     esi, eax
      
      	cmp     edi, 16  #edi == 16 (0x10)?
      	jne     .L9
      
      	# cmp     esi, 176
      	# jb      .LL
      	# jl      .LL
      	# je      .LE
      	# ja      .LG
      	# jg      .LG
      	# jne     .L2
      	# jmp     .L35
      
      	# v14 == 133 && v15 == 67 && v10 == 79 && v9 == 176 #
      	cmp     ecx, 79  #v10~ecx
      	jne     .L2
      	cmp     esi, 176 #v9~esi
      	jne     .L2
      	cmp     r9d, 133 #v14~r9d
      	jne     .L2
      	cmp     edx, 67  #v15~edx
      	jne     .L2
      	jmp     .L35
      
      .LL: #<
      	mov     edi, OFFSET FLAT:.LC3
      	call    puts
      	jmp     .LX
      .LE: #==
      	mov     edi, OFFSET FLAT:.LC4
      	call    puts
      	jmp     .LX
      .LG: #>
      	mov     edi, OFFSET FLAT:.LC5
      	call    puts
      	jmp     .LX
      
      .L2: #nope
      	mov     edi, OFFSET FLAT:.LC2
      	call    puts
      	jmp     .LX
      .L35: #yep
      	mov     edi, OFFSET FLAT:.LC1
      	call    puts
      	jmp     .LX
      
      .LX: #cleanup
      	add     rsp, 32
      	pop     rbx
      	ret
    • [USAGE]: rm -f egg19; gcc -c egg19.S -o egg19.o && gcc egg19.o -o egg19; for i in {1..255}; do echo -n "$i: "; python -c "import sys; sys.stdout.write(hex($i)+' ')"; python -c "import sys; sys.stdout.write(''.join(map(chr,[0x2c if (i-2)%4==0 else (${i} if i%2==0 else p) for i,p in enumerate(xrange(91,108))])))" | ./egg19; done
    • which char pos idx in str is incl. in which term(s) of the final condition?
    • for i in xrange(0,17):
      	xs = []
      	if i%3==0: xs.append(1)
      	if (i&3)==2: xs.append(2)
      	if i<16:
      		xs.append(3)
      		if i%2==1: xs.append(4)
      	print str(i)+":", " ".join(map(str,xs))
    • validate proposed solution:
    • xs = [49, 24, 44, 52, 25, 32, 44, 34, 19, 84, 44, 21, 53, 23, 44, 53, 21]
      f1 = sum(map(int, [p for i,p in enumerate(xs) if i%3==0]))%256
      f2 = sum(map(int, [p for i,p in enumerate(xs) if (i&3)==2]))%256
      f3 = sum(map(int, [p for i,p in enumerate(xs[:16])]))%256
      f4 = sum(map(int, [p for i,p in enumerate(xs[:16]) if i%2==1]))%256
      print (f1, f2, f3, f4), (79, 176, 133, 67), (f1, f2, f3, f4)==(79, 176, 133, 67)
    • exploit to profit
    • #!/usr/env/env python
      #-*- coding: utf-8 -*-
      
      import sys
      from pwn import *
      
      data = "".join(map(chr, [49, 24, 44, 52, 25, 32, 44, 34, 19, 84, 44, 21, 53, 23, 44, 53, 21]))
      conn = remote("hackyeaster.hacking-lab.com", 1234)
      conn.sendline(data)
      print conn.recvall()
      conn.close()
    • ida.lo\/es.you
    You got hold of a dump of Humpty Dumpty's secret egg database.
    
    Search and extract the egg hidden in the dump!
    
    Hints
    • The `puzz` is not more than 8 chars, letters only.
    • The decryption of the file can be done using AES_DECRYPT().
    
    
    
    • `dump2.zip` contains:
      • humpty_fyle.sql
      • humpty_kee.sql
      • humpty_routines.sql
      • humpty_uzr.sql
    • docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=P@ssw0rd -d mysql:latest
    • mysql> CREATE DATABASE humpty;
    • mysql> SHOW TABLES;
    • +------------------+
      | Tables_in_humpty |
      +------------------+
      | fyle             |
      | kee              |
      | uzr              |
      +------------------+
    • mysql> DESCRIBE fyle;
    • +-------+------------+------+-----+---------+-------+
      | Field | Type       | Null | Key | Default | Extra |
      +-------+------------+------+-----+---------+-------+
      | id    | bigint(10) | NO   | PRI | NULL    |       |
      | keeid | bigint(10) | NO   | MUL | NULL    |       |
      | blahb | longblob   | YES  |     | NULL    |       |
      +-------+------------+------+-----+---------+-------+
    • mysql> SELECT id, keeid FROM fyle;
    • +------+-------+
      | id   | keeid |
      +------+-------+
      | 5182 |  1293 |
      | 3475 |  1493 |
      | 3492 |  2332 |
      | 1374 |  4327 |
      | 3481 |  7465 |
      +------+-------+
    • mysql> SELECT * FROM kee;
    • +------+-------+------------------------------------------------------------------+
      | id   | uzrid | kee                                                              |
      +------+-------+------------------------------------------------------------------+
      | 1293 |  1342 | 16B1917E3DC15E94D5956807F89874F0F90D2C778F1574F40E2DC75FA241CD15 |
      | 1493 |  8944 | 8758597E209E6716877463D7605CB489DD0E62A61332CD022F5C07F5FD339A53 |
      | 2332 |  3443 | 1ABF4B7CD25C61FDF0E74EC2BFB43BD1C2D8ECD803AFA3AA376F4C0000052813 |
      | 4327 |  1875 | 4ED525F310E7A530D0BAA8FE3D54A5CF102D6AE8E9529289F664730FB248EF9A |
      | 7465 |  5420 | A14EA5BDA9360D9E790B0935FFD21FA9B6BEBCDEAAFC8AADBD8A3A13643D5583 |
      +------+-------+------------------------------------------------------------------+
    • mysql> SELECT * FROM uzr;
    • +------+--------+------------------------------------------+-------+
      | id   | neighm | puzz                                     | sawlt |
      +------+--------+------------------------------------------+-------+
      | 1342 | stuart | de2278f5bcafcbb097ecc1fb54e5ab8a9e912c55 | efgh  |
      | 1875 | beaver | 943f9ecbbd91306a561d0e3c15e18ee700007083 | abcd  |
      | 3443 | chuck  | 0cf32f8f418659f23f8968d4f63ea5c98b39f833 | zyxw  |
      | 5420 | yogo   | 1742ae4507fc480958e2437104e677e70aa5e857 | jklm  |
      | 8944 | flint  | 915d253cb5ba6f0a220bca83e2d6d3258af15e68 | nmlk  |
      +------+--------+------------------------------------------+-------+
    • mysql> SELECT name FROM mysql.proc WHERE db=database() ORDER BY name;
    • +-----------------+
      | name            |
      +-----------------+
      | DeekryptKee     |
      | GetPuzzMishMash |
      | KryptKee        |
      +-----------------+
    • mysql> SHOW CREATE PROCEDURE DeekryptKee \G;
    • PROCEDURE `DeekryptKee`(
          IN  p_puzz  VARCHAR(40),
          IN  p_cyfr  VARCHAR(64),
          OUT p_kee  VARCHAR(40)
      )
      BEGIN
          DECLARE p_tmp VARCHAR(64);
          DECLARE p_kountr INT;
          SET p_tmp := CONCAT('kee.', p_puzz, '.kee');
          SET p_kountr := 1;
          WHILE p_kountr <= 10000 DO
            SET p_tmp := SHA1(p_tmp);
            SET p_kountr := p_kountr + 1;
          END WHILE;
          SET p_tmp := AES_DECRYPT(UNHEX(p_cyfr), p_tmp);
          SELECT p_tmp INTO p_kee;
      END
    • mysql> SHOW CREATE PROCEDURE GetPuzzMishMash \G;
    • PROCEDURE `GetPuzzMishMash`(
          IN  p_puzz      VARCHAR(40),
          IN  p_sawlt     VARCHAR(4),
          OUT p_mishmash  VARCHAR(40)
      )
      BEGIN
          DECLARE p_tmp VARCHAR(50);
          SET p_tmp := CONCAT(p_sawlt, '.', p_puzz, '.', p_sawlt);
          SELECT SHA1(p_tmp) INTO p_mishmash;
      END
    • mysql> SHOW CREATE PROCEDURE KryptKee \G;
    • PROCEDURE `KryptKee`(
          IN  p_puzz  VARCHAR(40),
          IN  p_kee  VARCHAR(40),
          OUT p_cyfr   VARCHAR(64)
      )
      BEGIN
          DECLARE p_tmp VARCHAR(64);
          DECLARE p_kountr INT;
          SET p_tmp := CONCAT('kee.', p_puzz, '.kee');
          SET p_kountr := 1;
          WHILE p_kountr <= 10000 DO
            SET p_tmp := SHA1(p_tmp);
            SET p_kountr := p_kountr + 1;
          END WHILE;
          SET p_tmp := HEX(AES_ENCRYPT(p_kee, p_tmp));
          SELECT p_tmp INTO p_cyfr;
      END
    • cudaHashcat64.bin -m4900 -a3 hashfile.txt -1 ?l mask.txt
    • hashfile.txt
    • 943f9ecbbd91306a561d0e3c15e18ee700007083:abcd
      915d253cb5ba6f0a220bca83e2d6d3258af15e68:nmlk
      1742ae4507fc480958e2437104e677e70aa5e857:jklm
      0cf32f8f418659f23f8968d4f63ea5c98b39f833:zyxw (✓)
      de2278f5bcafcbb097ecc1fb54e5ab8a9e912c55:efgh
    • mask.txt
    • .?1?1?1?1?1?1?1?1.
    • mysql> SELECT * FROM uzr WHERE id=3443;
    • +------+--------+------------------------------------------+-------+
      | id   | neighm | puzz                                     | sawlt |
      +------+--------+------------------------------------------+-------+
      | 3443 | chuck  | 0cf32f8f418659f23f8968d4f63ea5c98b39f833 | zyxw  |
      +------+--------+------------------------------------------+-------+
    • SHA1(zyxw.snakeoil.zyxw) = 0cf32f8f418659f23f8968d4f63ea5c98b39f833
    • ...so p_puzz = snakeoil
    • mysql> SELECT * FROM kee WHERE uzrid=3443;
    • +------+-------+------------------------------------------------------------------+
      | id   | uzrid | kee                                                              |
      +------+-------+------------------------------------------------------------------+
      | 2332 |  3443 | 1ABF4B7CD25C61FDF0E74EC2BFB43BD1C2D8ECD803AFA3AA376F4C0000052813 |
      +------+-------+------------------------------------------------------------------+
    • mysql> SELECT id, keeid FROM fyle WHERE keeid=2332;
    • +------+-------+
      | id   | keeid |
      +------+-------+
      | 3492 |  2332 |
      +------+-------+
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      import sys
      import pymysql
      import pymysql.cursors
      
      conn = pymysql.connect(
      		host="localhost", port=3306,
      		# unix_socket="/opt/local/var/run/mysql57/mysqld.sock",
      		user="root",
      		passwd="P@ssw0rd", password="P@ssw0rd",
      		db="humpty",
      		cursorclass=pymysql.cursors.DictCursor)
      
      try:
      	with conn.cursor() as cur:
      		_id, uzrid = 2332, 3443
      		sql = "SELECT `kee` FROM `kee` WHERE `id`=%s AND `uzrid`=%s"
      		cur.execute(sql, (_id, uzrid,))
      		kee = cur.fetchone()["kee"]
       		# kee = 1ABF4B7CD25C61FDF0E74EC2BFB43BD1C2D8ECD803AFA3AA376F4C0000052813
      
       		# CALL DeekryptKee('snakeoil', '1ABF4B7CD25C61FDF0E74EC2BFB43BD1C2D8ECD803AFA3AA376F4C0000052813', @p_kee); SELECT @p_kee;
       		sql = "CALL DeekryptKee(%s, %s, @p_kee)"
       		cur.execute(sql, ("snakeoil", kee,))
       		sql = "SELECT @p_kee"
       		cur.execute(sql)
       		p_kee = cur.fetchone()["@p_kee"]
      		# p_kee = jpP8HeoEC5OCCBqdf9N3
      
      		_id, keeid = 3492, 2332
      		sql = "SELECT AES_DECRYPT(`blahb`, %s) AS data FROM `fyle` WHERE `id`=%s and `keeid`=%s"
      		cur.execute(sql, (p_kee, _id, keeid,))
      		fp = "egg20.png"
      		with open(fp, "wb") as f:
      			f.write(cur.fetchone()["data"])
      		print>>sys.stderr, "=>", fp
      finally: conn.close()
    Clever crypto brains had a little get-together. Find out who they are and break the riddles they created! Each plain text contains a password - once you've got them all, enter them in the Egg-O-Matic below. Lowercase only.
    
    
    DV D UXOH PHQ ZRUUB PRUH DERXW ZKDW WKHB FDQW VHH WKDQ DERXW ZKDW WKHB FDQ SDVVZRUG LV FDUWKDJR
    
    
    4423154215 2443 3334 52244433154343 4334 1442151114214531 3334 11131345431542 4334 4415424224123115 1143 442315 13343343132415331315 44231144 145215313143 2433 442315 2315114244 3421 1551154254 321133 3515313435343333154315 2443 442315 3511434352344214
    
    
    EHIIKT YFC FTEU QK PLTPWBY MQYTNVZW LAJ JGGN ZVLD A EWTAE WIEXLP QF IHV DAALROW DF JIACT GWMGCRQF WIJ NSIHVZ BTAE IJGAEOWS FFZ ZXM KW ZPVV I UAAJAARAC MVJCRBADN ZV HPRZA TAAZAW SE MQYTNVZW HTLLATD XZWTK RVV WESZWL UELWG AUZAPNLA LJREMTJS RVV YERV VDRRB SI TYM SVE FN SVE JMNTNKMWC HV MFIEIMV IHV LAELFUSIIT AWGVZKW PNU ZWBAZVWS TYMJT FFZ LWIIBQ NERZK UIMM QTAIA ACTF PAH CRZWTR YM SRCFUHPNZMV IHV NJTNTP WCVFG DDUZA SSHVUSG DV OJXGEIF IO KPW SIVB GU WFZEH AJ I BJNZWJ HETZWIAIG ZT EEBWGEU BZT SVZNXCV WX IHV LMZE FN FTVVZK PS YQK HETZWIAIG S EOJQLXOE PW WECL MCTZT LWE UMSIHJ WX IHV LMZE RVV WIJ AGC HV IDHO JMJKEU IK P SVKJTTRZQ IO YMFGY ZQA
    
    
    WEN XQWVIBQZ KGQEAL TWB WEH GKQCW QLTBAKBTU LKIQTME DWCOAKWZAKNB BKMETP WEW NOTHPA HWB GBXHCEWG IA OTTQPWD SEATWCWNBA NZW HTO BHQWG HIWAL MCMG LQWVIBQL TOF QLFVCHWG WEW XNW FM WET NGQEAL QWBDSCMF KO CPWCKWMAX
    
    • Caesar Cipher, key=23
      • as a rule men worry more about what they cant see than about what they can password is carthago
    • Polybius Square
      • there is no witness so dreadful no accuser so terrible as the conscience that dwells in the heart of every man peloponnese is the password
    • Vigenère Cipher, key=paris
      • phrase you need is alchemy vigenere was born into a noble family in the village of saint pourcain his father jean arranged for him to have a classical education in paris blaise de vigenere studied greek and hebrew under adrianus turnebus and jean dorat at the age of age seventeen he entered the diplomatic service and remained there for thirty years five years into his career he accompanied the french envoy louis adhemar de grignan to the diet of worms as a junior secretary he entered the service of the duke of nevers as his secretary a position he held until the deaths of the duke and his son he also served as a secretary to henry iii
    • Playfair cipher, key=ZUVXYTWHEACSONBKDFGIRLMPQ
      • the playfair cipher was the first practical digraph substitution cipher the scheme was invented by charles wheatstone but was named after lord playfair who promoted the use of the cipher password is bletchley
    You've sniffed some password hashes of a web site:
    	hash 1: fad202a6e094dd8f1d63da8bdf85b3ba099971d3
    	hash 2: f71e1b0b9b3a57d864c2e9f7bd6dd90f66b5a7d6
    	hash 3: 84c6bcb681b79b690b53f9f3a8ba24e1e970d348
    	hash 4: 0d6bb0df8918168798ce6b770014aeb81ac6ce76
    
    However, none of your tools succeeded in cracking the hashes. As a last resort, you inspected the dumpster of the software development company which created the web site. And indeed you found something: a paper with a part of the hash calculation code.
    
    Can you crack the hashes now?
    
    
    
    • standard SHA1 implementation, init with different const, i.e.
      • h0 = 0x67452301 0x10325476
      • h1 = 0xEFCDAB89 0x98BADCFE
      • h2 = 0x98BADCFE 0xEFCDAB89
      • h3 = 0x10325476 0x67452301
      • h4 = 0xC3D2E1F0 0x0F1E2D3C
    • @ //codereview.stackexchange.com/questions/37648/python-implementation-of-sha1
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      def sha1(data):
      	bytes = ""
      
      	h0 = 0x10325476
      	h1 = 0x98BADCFE
      	h2 = 0xEFCDAB89
      	h3 = 0x67452301
      	h4 = 0x0F1E2D3C
      
      	for n in xrange(len(data)):
      		bytes+="{0:08b}".format(ord(data[n]))
      	bits = bytes+"1"
      	pBits = bits
      	while len(pBits)%512 != 448: pBits+="0"
      	pBits+="{0:064b}".format(len(bits)-1)
      	def chunks(l, n):
      		return [l[i:i+n] for i in xrange(0, len(l), n)]
      	def rot_l(n, b):
      		return ((n << b) | (n >> (32 - b))) & 0xffffffff
      	for c in chunks(pBits, 512):
      		words = chunks(c, 32)
      		w = [0]*80
      		for n in xrange(16):
      			w[n] = int(words[n], 2)
      		for i in xrange(16, 80):
      			w[i] = rot_l((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1)
      		a = h0
      		b = h1
      		c = h2
      		d = h3
      		e = h4
      		for i in xrange(80):
      			if 0 <= i <= 19:
      				f = (b & c) | ((~b) & d)
      				k = 0x5A827999
      			elif 20 <= i <= 39:
      				f = b ^ c ^ d
      				k = 0x6ED9EBA1
      			elif 40 <= i <= 59:
      				f = (b & c) | (b & d) | (c & d)
      				k = 0x8F1BBCDC
      			elif 60 <= i <= 79:
      				f = b ^ c ^ d
      				k = 0xCA62C1D6
      			tmp = rot_l(a, 5) + f + e + k + w[i] & 0xffffffff
      			e = d
      			d = c
      			c = rot_l(b, 30)
      			b = a
      			a = tmp
      		h0 = (h0+a) & 0xffffffff
      		h1 = (h1+b) & 0xffffffff
      		h2 = (h2+c) & 0xffffffff
      		h3 = (h3+d) & 0xffffffff
      		h4 = (h4+e) & 0xffffffff
      	return "%08x%08x%08x%08x%08x" %(h0,h1,h2,h3,h4)
    • bruteforce using this:
      • fad202a6e094dd8f1d63da8bdf85b3ba099971d3: zombie
      • f71e1b0b9b3a57d864c2e9f7bd6dd90f66b5a7d6: Denver1
      • 84c6bcb681b79b690b53f9f3a8ba24e1e970d348: Placebo
      • 0d6bb0df8918168798ce6b770014aeb81ac6ce76: SHADOWLAND
    Can you crack the Heizohack?
    
    The password for the Egg-O-Matic is hidden in the image.
    
    
    
    • LSB steganography
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      import sys
      from PIL import Image
      
      bin_n = lambda x, n: format(x, "b").zfill(n)
      
      img = Image.open("heizohack.bmp")
      pix = img.convert("RGBA").load()
      w, h = img.size
      
      pw, lsb = [], 7
      for y in xrange(h):
      	for x in xrange(w):
      		r = bin_n(pix[x,y][0], 8)
      		g = bin_n(pix[x,y][1], 8)
      		b = bin_n(pix[x,y][2], 8)
      		b = bin_n(pix[x,y][2], 8)
      		pw.append(r[lsb])
      		pw.append(g[lsb])
      		pw.append(b[lsb])
      mac = "".join(pw)
      print "".join(chr(int(mac[i:i+8],2)) for i in xrange(0,len(mac),8))
    • produces:
    • follow as instructed:
    • #!/usr/bin/env python
      #-*- coding: utf-8 -*-
      
      import sys
      from PIL import Image
      
      bin_n = lambda x, n: format(x, "b").zfill(n)
      
      img = Image.open("heizohack.png")
      pix = img.convert("RGBA").load()
      w, h = img.size
      
      pw, lsb = [], 7
      for y in xrange(h):
      	for x in xrange(w):
      		r = bin_n(pix[x,y][0], 8)
      		g = bin_n(pix[x,y][1], 8)
      		b = bin_n(pix[x,y][2], 8)
      		a = bin_n(pix[x,y][3], 8)
      		if int(r[lsb]) ^ int(g[lsb]) ^ int(b[lsb]) ^ int(a[lsb]) == 1:
      			pw.append(r[lsb])
      mac = "".join(pw)
      print "".join(chr(int(mac[i:i+8],2)) for i in xrange(0,len(mac),8))
    • lostinthewoooods
    Do you know crunch.ly, the fancy new URL shortener? It was used to create a short URL for Hacky Easter. In order to lure people onto the web site of your alternative hacking competition "Evil Easter", you decide to attack this service.
    
    What you know
    • Short URL for Hacky Easter: http://crunch.ly/IU66SMI
    • Web site of crunch.ly (not a real domain!): OPEN WEB SITE
    • Algorithms used on the web site: DOWNLOAD
    
    Your mission
    1. find a URL starting with http://evileaster.com, which produces the same short URL
    2. make the web site store your URL, instead of the original URL
    3. open the short URL on the web site
    4. do not bomb or DoS the server - you'll have no luck with it; cracking must happen offline
    
    1. possible URLs (pick any one):
    2. import java.io.*;
      import java.lang.*;
      import java.net.*;
      import java.security.*;
      
      import javax.crypto.*;
      import javax.crypto.spec.*;
      
      // @ //commons.apache.org/proper/commons-codec/download_codec.cgi
      import org.apache.commons.codec.binary.*;
      
      public class Crunchly {
      	public void run() {
      		bruteForceShortUrl("", 6, "IU66SMI");
      	}
      
      	public static void main(String[] args) throws Exception {
      		new Crunchly().run();
      	}
      
      	public void bruteForceShortUrl(String str, int maxlen, String match) {
      		String charset = "abcdefghijklmnopqrstuvwxyz"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"0123456789";//+"/";
      		if (str.length() >= maxlen) {
      			// base case
      			String strUrl = "http://evileaster.com/"+str;
      			String shortUrl = calculateShortUrl(strUrl);
      			String matchUrl = "http://crunch.ly/"+match;
      			if (shortUrl.equals(matchUrl)) {
      				System.out.println("[done]: "+strUrl);
      				System.exit(0);
      			}
      			return;
      		}
      
      		// recursive case
      		for (int i=0; i<charset.length(); i++) {
      			bruteForceShortUrl(str+charset.charAt(i), maxlen, match);
      		}
      	}
      
      	// given code //
      	private String calculateShortUrl(String url) {
      		try {
      			MessageDigest md = MessageDigest.getInstance("SHA-256");
      			md.update(url.getBytes("UTF-8"));
      			byte[] hash = md.digest();
      			byte[] part = new byte[4];
      			System.arraycopy(hash, 0, part, 0, 4);
      			String b32 = new String(new Base32().encode(part), "UTF-8");
      			b32 = b32.replaceAll("=", "");
      			return "http://crunch.ly/" + b32;
      		} catch (Exception e) {
      			e.printStackTrace();
      		}
      		return null;
      	}
      }
    • key: tKguF
    • import java.io.*;
      import java.lang.*;
      import java.net.*;
      import java.security.*;
      
      import javax.crypto.*;
      import javax.crypto.spec.*;
      
      // @ //commons.apache.org/proper/commons-codec/download_codec.cgi
      import org.apache.commons.codec.binary.*;
      
      public class Crunchly {
      	public void run() {
      		// String keyFull = "x"+key+key+key; //128-bit
      		// 128 bits = 16 bytes
      		// "x" + key*3 = 16 chars
      		// => key = 5 chars
      		bruteForceKey("", 5);
      	}
      
      	public static void main(String[] args) throws Exception {
      		new Crunchly().run();
      	}
      
      	public void bruteForceKey(String str, int maxlen) {
      		String charset = "abcdefghijklmnopqrstuvwxyz"+"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      		if (str.length() >= maxlen) {
      			// base case: known testcase //
      			String url = "http://.";
      			String shortUrl = "http://crunch.ly/FN2ERFA";
      			String tixActual = cryptTicket(url, shortUrl, str);
      			String tixExpected = "CNgdmr+C40sYmW2e07VycSsEbwDEteBwV5Da6/ERCySirkDHktUMZ7Ky+utNUkAk";
      			if (tixActual.equals(tixExpected)) {
      				System.out.println("[done]: "+str);
      				System.exit(0);
      			}
      			return;
      		}
      
      		// recursive case
      		for (int i=0; i<charset.length(); i++) {
      			bruteForceKey(str+charset.charAt(i), maxlen);
      		}
      	}
      
      	// given code //
      	private static final String IV = "hackyeasterisfun";
      	private String cryptTicket(String url, String shortUrl, String key) {
      		String keyFull = "x"+key+key+key; //128-bit
      		try {
      			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      			SecretKeySpec keySpec = new SecretKeySpec(keyFull.getBytes("UTF-8"), "AES");
      			cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(IV.getBytes("UTF-8")));
      			String plain = new String(Base64.encodeBase64(url.getBytes("UTF-8")), "UTF-8");
      			plain += "@" + new String(Base64.encodeBase64(shortUrl.getBytes("UTF-8")), "UTF-8");
      			byte[] crypted = cipher.doFinal(plain.getBytes("UTF-8"));
      			return Base64.encodeBase64String(crypted);
      		} catch (Exception e) {
      			e.printStackTrace();
      		}
      		return null;
      	}
      }
    • curl -c cookies.txt -sL "http://hackyeaster.hacking-lab.com/hackyeaster/crunch?service=save&ticket=Hgo3UsPWbH%2B4kkfQwZ0dOAbQzQy7HXmhCcwLzE4m%2F06I3E5d4Zl2LJ7hLXVuOe6USoykVYjijBkc8Rv%2FtMXnJHkU66WiET3AEwka8zz%2BV%2Fs%3D" && curl -b cookies.txt -sL "http://hackyeaster.hacking-lab.com/hackyeaster/crunch?service=go&shorturl=http%3A%2F%2Fcrunch.ly%2FIU66SMI"
    • import java.io.*;
      import java.lang.*;
      import java.net.*;
      import java.security.*;
      
      import javax.crypto.*;
      import javax.crypto.spec.*;
      
      // @ //commons.apache.org/proper/commons-codec/download_codec.cgi
      import org.apache.commons.codec.binary.*;
      
      public class Crunchly {
      	public void run() {
      		String url = "http://evileaster.com/elL12H";
      		String shortUrl = "http://crunch.ly/IU66SMI";
      
      		String key = "tKguF";
      
      		String tix = cryptTicket(url, shortUrl, key);
      		// Hgo3UsPWbH+4kkfQwZ0dOAbQzQy7HXmhCcwLzE4m/06I3E5d4Zl2LJ7hLXVuOe6USoykVYjijBkc8Rv/tMXnJHkU66WiET3AEwka8zz+V/s=
      
      		String svcUrl = "http://hackyeaster.hacking-lab.com/hackyeaster/crunch";
      		// service=check: url=<shortUrl>
      		// service=go: shorturl=<shortUrl>
      		// service=save: ticket=<tix>
      
      		try {
      			String charset = java.nio.charset.StandardCharsets.UTF_8.name();
      
      			String q = String.format("service=%s&ticket=%s",
      				URLEncoder.encode("save", charset),
      				URLEncoder.encode(tix, charset));
      			URLConnection conn = new URL(svcUrl+"?"+q).openConnection();
      			conn.setRequestProperty("Accept-Charset", charset);
      
      			String hdr = null;
      			String cookie = null;
      			for (int i=1; (hdr=conn.getHeaderFieldKey(i))!=null; i++) {
      				if (hdr.equals("Set-Cookie")) {
      					if (cookie == null) {
      						cookie = conn.getHeaderField(i);
      						cookie = cookie.substring(0, cookie.indexOf(";"));
      					}
      				}
      			}
      
      			q = String.format("service=%s&shorturl=%s",
      				URLEncoder.encode("go", charset),
      				URLEncoder.encode(shortUrl, charset));
      			conn = new URL(svcUrl+"?"+q).openConnection();
      			conn.setRequestProperty("Accept-Charset", charset);
      			conn.setRequestProperty("Cookie", cookie);
      
      			InputStream resp = conn.getInputStream();
      			try (BufferedReader rdr = new BufferedReader(
      				new InputStreamReader(resp, charset)
      			)) {
      				for (String line; (line=rdr.readLine())!=null;) {
      					System.err.println(URLDecoder.decode(line, charset));
      				}
      			}
      		} catch (IOException ex) {}
      	}
      
      	public static void main(String[] args) throws Exception {
      		new Crunchly().run();
      	}
      
      	// given code //
      	private static final String IV = "hackyeasterisfun";
      	private String cryptTicket(String url, String shortUrl, String key) {
      		String keyFull = "x"+key+key+key; //128-bit
      		try {
      			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      			SecretKeySpec keySpec = new SecretKeySpec(keyFull.getBytes("UTF-8"), "AES");
      			cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(IV.getBytes("UTF-8")));
      			String plain = new String(Base64.encodeBase64(url.getBytes("UTF-8")), "UTF-8");
      			plain += "@" + new String(Base64.encodeBase64(shortUrl.getBytes("UTF-8")), "UTF-8");
      			byte[] crypted = cipher.doFinal(plain.getBytes("UTF-8"));
      			return Base64.encodeBase64String(crypted);
      		} catch (Exception e) {
      			e.printStackTrace();
      		}
      		return null;
      	}
      }
    • @ //hackyeaster.hacking-lab.com/hackyeaster/images/egg24_bHIrQh1VR141TPmapETM.png