Description:
We have hidden a message in png file using jar file. Flag is hidden message. Flag is in this format:
SharifCTF{flag}
Download
Смысл задачи в том, чтобы декомпилировать Hide.jar.
Тащиим любой java decompiler, декомпилируем и получаем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
/* * Decompiled with CFR 0_110. */ import java.awt.Point; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import java.io.PrintStream; import javax.imageio.ImageIO; public class Hide { protected void steg(String string, String string2) { BufferedImage bufferedImage = this.loadImage(string2 + ".png"); BufferedImage bufferedImage2 = this.steg(string, bufferedImage); try { ImageIO.write((RenderedImage)bufferedImage2, "png", new File(string2 + "_out.png")); } catch (IOException var5_5) { throw new RuntimeException("Unable to write image!"); } } protected BufferedImage steg(String string, BufferedImage bufferedImage) { if ((string = "" + string.length() + ":" + string).length() * 8 > bufferedImage.getWidth() * bufferedImage.getHeight()) { System.out.println("There won't be enough space to store this message!"); System.out.println("Message length: " + string.length() + " bytes. " + "Image can hold a maximum of " + bufferedImage.getWidth() * bufferedImage.getHeight() / 8); throw new RuntimeException("There won't be enough space to store this message!"); } byte[] arrby = string.getBytes(); Point point = new Point(0, 0); for (int n : arrby) { for (int i = 0; i < 8; ++i) { if ((n & 128) == 128) { bufferedImage.setRGB(point.x, point.y, this.setLeastSignificantBit(bufferedImage.getRGB(point.x, point.y), true)); } else { bufferedImage.setRGB(point.x, point.y, this.setLeastSignificantBit(bufferedImage.getRGB(point.x, point.y), false)); } n <<= 1; this.movePointer(point, bufferedImage); } } return bufferedImage; } protected int setLeastSignificantBit(int n, boolean bl) { n >>= 1; n <<= 1; if (bl) { ++n; } return n; } protected void movePointer(Point point, BufferedImage bufferedImage) { if (point.x == bufferedImage.getWidth() - 1) { point.x = -1; ++point.y; } ++point.x; if (point.y == bufferedImage.getHeight()) { throw new RuntimeException("Pointer moved beyond the end of the image"); } } private BufferedImage loadImage(String string) { try { BufferedImage bufferedImage = ImageIO.read(new File(string)); return bufferedImage; } catch (IOException var2_3) { System.out.println("Unable to load \"" + string + "\""); System.exit(0); return null; } } public static void main(String[] arrstring) { if (arrstring.length < 2) { System.out.println("Input Arguments Is Not Valid."); System.out.println("Run By 'java -jar Hide.jar `file-path` `message`'"); return; } System.out.println("Welcome!\nDecrypt The Image And Capture The Flag!"); Hide hide = new Hide(); hide.steg(arrstring[1], arrstring[0]); } } |
После небольшого анализа получаем вот такой скрипт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from PIL import Image im=Image.open("AsianCheetah1.png") l=list(im.getdata()) b=[] for x in l: b.append(x[2]&1) s=[] for i in range(100): c=0 for j in range(8): c*=2 c+=b[i*8+j] s.append(chr(c)) print repr("".join(s)) |