Tổng hợp Write-up cuộc thi WhiteHat Grand Prix 06 - Vietnam Today - Vòng sơ loại

misc01 | Team: perfect blue

Hoi An is colorful ancient town, right?

http://52.78.210.118/Trip_to_Hoi_An.png

Hints

The embedded data is encrypted using AES.

Writeup
First, we download the image. It is a beautiful image in Vietnam:

upload_2020-1-16_23-32-32.png

We immediately notice that there is data appended to the end of the image, by searching for IEND:

upload_2020-1-16_23-33-32.png
This means there is another png file appended to our image. We also see the comment in the first image, stating:


Find the password to get the colors using stego tool

Extracting the second png, we get this image:

upload_2020-1-16_23-34-25.png

This is a weird QR code. After filtering it to black and white, we get:

upload_2020-1-16_23-35-57.png
With the power of QR scanners like Snapchat, we are able to decode this, and it says:

VGhlIHBhc3N3b3JkIGZvciB0aGlzIHBpY3R1cmUgaXM6IFJHQg==
or 'The password for this picture is: RGB'.

From here, we spent a day trying to find which stego tool was used to hide data, and we eventually found that the correct tool was "Stegosuite." Using the latest version of stegosuite, we are able to extract data from the image:


Mã:
root@4aa2f718fd26:/# stegosuite -x -d  -k RGB Trip_to_Hoi_An.png  
Loading png image from /Trip_to_Hoi_An.png
07:55:30.405 @ main (PNGImage.java:27) Width, height, type: 1440*810*5
Extracting data...
07:55:30.435 @ main (PNGLsbMultiColorChannel.java:128) Performing PNG LSB extraction
07:55:30.766 @ main (PayloadExtractor.java:145) Payload of 117 bytes to be extracted
07:55:30.769 @ main (PayloadExtractor.java:83) Unpacking payload from 117 extracted bytes
07:55:31.168 @ main (PayloadExtractor.java:104) Unpacked 106 bytes of payload
Extracting completed
Extracted message: Here is your colors:
1196,152
818,504
167,465
1424,680
786,309
448,383
1198,302
187,43
341,280
27,477

It seems that the colors at these coordinates in the image will give us the flag.

Writing a quick solve script:

Mã:
from PIL import Image

ps = []
with open("colors") as f:
    for line in f:
        ps.append(tuple(map(int, line.strip().split(','))))

t = Image.open("Trip_to_Hoi_An.png")
pix = t.load()
vs = []
for x, y in ps:
    print(pix[x,y])
    vs += list(pix[x,y])

print(bytes(vs))

Gives:

Mã:
(119, 51, 76)
(67, 48, 109)
(51, 95, 116)
(48, 95, 72)
(79, 73, 95)
(65, 78, 95)
(52, 110, 99)
(49, 51, 110)
(116, 95, 116)
(48, 119, 110)
[119, 51, 76, 67, 48, 109, 51, 95, 116, 48, 95, 72, 79, 73, 95, 65, 78, 95, 52, 110, 99, 49, 51, 110, 116, 95, 116, 48, 119, 110]```

Which gives us the flag.

```python
>>> ''.join([chr(i) for i in [119, 51, 76, 67, 48, 109, 51, 95, 116, 48, 95, 72, 79, 73, 95, 65, 78, 95, 52, 110, 99, 49, 51, 110, 116, 95, 116, 48, 119, 110]])
'w3LC0m3_t0_HOI_AN_4nc13nt_t0wn'

Flag:

w3LC0m3_t0_HOI_AN_4nc13nt_t0wn
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
misc02 | Team: perfect blue

What are we going to do now, Elliot???

http://52.78.210.118/Elliot.zip

Hints
After finding "password" string, find correct password to extract file by trying permutation of that string. Have you watch the video yet ? Just do what he did. Some things are hidden in the picture.

Writeup
We were the only team to solve this one! I had to use the full extent of my brain power to solve this one, but once we figured out the trick, it was relatively straightforward.

We are given a zip file. Inside there is:

Mã:
Ecorp's Encrypted data
    EED2.iso
    junk.DAT
Little help
    audio.wav
    Endding_mr_robot_e10_s3.mp4.mp4
    init.sh
track0.iso

Initially, we had no clue on what to do for this challenge. So we tried a huge variety of things! The track0.iso was a password-protected zip file, so we figured the first step was finding the password for it. This was corroborated by the first hint, that mentioned finding a password and permuting it. Here is a list of (a few) things we tried:
  1. Finding steganography in audio.wav

    Since the audio and video were separated when given to us, we figured that must be by design, and that there was some sort of steganography in the audio. We downloaded and tried many wav steg tools (DeepSound, steghide, stego_lsb, etc). and none worked. We also viewed spectrograms; that didn't work either. I combined the stereo audio to mono after inverting one track, and found that it canceled out the voice lines, but there was nothing there either. Eventually I gave up and concluded there was no steg in the audio here.

  2. Finding steganography in the mp4

    Same concept. Teammate thought that certain frames of the video would have steg in them, but I thought that would be too much work (for both us and the problem writers) and didn't even try.

  3. Brute forcing the password to the zip

    A teammate used a 3 gigabyte wordlist to try to crack the zip. It didn't work.

  4. Trying permutations of random strings.

    We tried cracking the zip with leetspeak and scrambled versions of "fsociety" "password" "superman" and song lyrics (we searched up the song that was playing in the audio and tried lyrics from it).

  5. Trying to operate directly on the EED2.iso and junk.DAT. This did not work.
By this time, we had sort of figured out how the challenge would go. We imagined we would have to retrace Elliot's steps to decrypt the "Encrypted E-corp data," which would first involve extracting the track0 from the zip, looking through that in deepsound for image files, extracting steg from the images using stepic, and generating an RSA private key to decrypt with. Then, the second hint came out, and we all got triggered because we had already figured that part out - but we were still stuck on the first part!

Later on, I was looking at the audio file in a hex editor:

upload_2020-1-16_23-49-53.png

And I noticed something quite interesting:
highlight.png

There's a lot of 1s, 2s, and 3s here! I asked my teammate braindead (who is extremely knowledgeable about everything):

upload_2020-1-16_23-50-46.png

And I knew I had found something! 0, 1, 2, and 3 indicated that the 2 lsb from each of these bytes were being used. I quickly extracted these bytes and got:

Mã:
00010110110001101100001000000111100101101111011101010010000001101110011001010110010101100100001000000111010001101111001000000110101101101110011011110111011100111010011101110111001001101111011011100110011100100000011100000110000101110011011100110111011101101111011100100110010000100000001111010010000001001001010011010011100101000111010111110011100100110101001101110011100100110001001011100111000001101110011001110010000001100001011011100110010000100000011001100010111001101110011000010110110101100101001000000011110100100000011100000110000101110011011100110111011101101111011100100110010000001010

Which, after fixing some offsets, gave:

All you need to know:wrong password = IM9G_95791.png and f.name = password

With this, everything clicked. We brute forced the password to the zip using the template IMG_######.png, using the numbers in the "wrong password," and discovered that the correct password was IMG_599197.png. This gave track0 - a rar archive - with 6 images in it. One of the images was named IMG_599197.png, and each of them had some lines of python steganography that we obtained using zsteg.

(For example, this was IMG_599192.png)

Mã:
~/ctf/whitehat/Elliot/1.forUser/track0/track0~/track0/My Memories$ zsteg -a IMG_599192.png
/usr/lib/ruby/2.3.0/open3.rb:199: warning: Insecure world writable dir /home/neptunia/.cargo/bin in PATH, mode 040777
imagedata           .. text: "\n\n\n\t\t\t\n\n\n"
b1,bgr,lsb,xy       .. <wbStego size=524292, ext="\x04\x02\x00", data="\x92\b \b\x00A\x00\x10 \x10"..., even=true>
b1,bgr,msb,xy       .. file: raw G3 data, byte-padded
b2,r,msb,xy         .. text: "bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU"
b2,g,msb,xy         .. text: "TUUUUUUUUUUUUUUUUUUUUUQUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU"
b2,rgb,msb,xy       .. text: "uYVeQVUQTuQUEY"
b2,bgr,msb,xy       .. text: "EUVU]TeUTeQ"
b4,r,msb,xy         .. text: "ywwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"
b4,g,msb,xy         .. text: "pwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"
b4,rgb,msb,xy       .. text: " wzgwpww"
b4,bgr,msb,xy       .. text: "w'wzgwpww"
b8,r,lsb,xy         .. text: "def notrand(n):notrand.i +=1return PBKDF2(master, str(notrand.i), dkLen=n, count =1)notrand.i=0key = RSA.generate(2048, randfunc=notrand)print key.exportKey()"

This was the same script as Elliot used in the clip from Mr. Robot to generate a RSA key, with only the key size changed from 4096 to 2048. We combined the code to make this script:

Mã:
from Crypto.Protocol.KDF import PBKDF2
from Crypto.PublicKey import RSA
import getpass
infile = raw_input("File: ")
f = open(infile, 'r')
password = getpass.getpass()
f.seek(1024)
salt = f.read(32)
master = PBKDF2(password, salt, count=10000)
def notrand(n):
    notrand.i += 1
    return PBKDF2(master, str(notrand.i), dkLen=n, count=1)
notrand.i = 0
RSA_key = RSA.generate(2048, randfunc=notrand)
dice = RSA_key.exportKey()

a = open("key", "w")
a.write(dice)
a.close()

And ran it, using IMG_599197.png as both the key file and password. This resulted in the following RSA key:

Mã:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuyFXY7OF2msTPoz58mvwIjlO6bP+GnxgK1W94+1tTiQHg8t9
JMK/j4cDrU7LN5+FDOhchQMHPZ48sTmXZQnjFMwQOmMfDECypcTOklGDWeMHhF3A
RBwqq13XvU09rj/BIv/skI3oU6fiP6RYVtpXqwoL/2lhAy2s/ruZKJwLdyXHoDk+
4+6GG4N28Z0aIMW62cMuXa9sgbEiYyZ46ORLh3IyrxaD9V4jW56EIgZNg/qjmBkH
Wy3esgkybwe+yRq/rezbDnPyFPspI0oUU7n8Co+EUU1uzaJ0+r1eLAu6W1oEfn3J
ZqywvA/k/7M+JSoiH4pTQLwEBV4y/O/ikpVzLQIDAQABAoIBABVnUt+MgRridGkL
JuubfPPtKiGA/Od6omVSgU24sm/lnxZsB/xUaiS4hKsmAAh0rnszeKGeHw3lM3vx
4mckIl0WmiSTgdGc9NIRGK+TszpsxUdWkc84iYjgSvTUCOINWMHwE9bU5GXtJeux
mIkWoEBn/cdQ/k+mwcrBGluSvZz6+xJ8RZ/Kf4ntatOtdcakQ4VnTd1ZvVHsbH44
rNDaT91SEqw+rsNdekmwzlHAvGxglQyvYuDzBF/y5dZuRFdNdEB4b7XqzPQt7oWw
96pfSMnMpb8OFnAqjXcFm5+XJLN6spI/dJiTLLyuPgCNYAXB1C3FV52ucPxG7Vbt
L5UBDAECgYEAzGG3MplkVCoJ5U2mBs3WIwDCRN6SBd5RGw3cykS0Qf4D1n3WNHNn
qZNbrIWl5CjBgBIqbvqYxId0EaOq9rrSu4DSBPrPi9EJSmFUMQwjwbuoUJpoDh8L
ACrzi/Yn4m8OtfwHfLswFT7U+tb58oYWRyMGQ5Rmyrjr8AAhr5cQZyECgYEA6mQ7
1CTVFAMQfjR8FIzJivMircb7tGDsyX8vn4//7WiUVj057Ijr5oyYW3wreHtKk1xA
kubNM788Iu9JSeon7df5xXeNWgF0pYhUgnLKTatWJEnA2lI2Rgngrj397N7tY2DJ
qzNH+Bz1J2ZavoluOPww0hjdVED5clOZyxZF5o0CgYEAuV7zWvhXUCLk4M5hhJBS
5WJ90RsR1DLE20XieK6B080BTBzMGLyHS/20SzDYuqzgfDl9tTSjNLUqaAlLOgdO
tPPtCMk3TzfkNks6olXBZKjAy4KQWCZ9wsQyK0KzACP8csDJRa89uDdJ0s0C3J4T
PKgeuVKzPLEmhYKJCwp3vSECgYEA36FCc+WwZqeF1OO+ftzUbf4L2EFBZZgUUytG
BLcfNyPQY3eHDGaWrCD4PFD8KLd5L5+U/JO4tOaAOdST2DHQZtzpMb4e3wEEierI
tq1O10vhpD26ApLttWU3OQdsfdM0KtztjKogwFjgjfbaHXCB+VykN9ABW6GiXbHl
yh42EwECgYA/2xzmsf89XhZmFc9xQeBLr4WohKj5wObYF7Royc0MiOIi+vFe+9rq
DFiuAcSRof/TAPGRCKw9kr1MMf8N6/coAqRQAKLvYH7LCydd+/4+lAV65oKKeyYi
qhP61hcKEWCZsC6aajokghZvXjskrvWBo1bsfDSqVE9G1SRn2GNHig==
-----END RSA PRIVATE KEY-----

And we can use this to decrypt the encrypted E-corp data for the flag!
upload_2020-1-17_0-4-52.png
Which results in the flag:
WhiteHat{Th4nk_G0d_Y0u_Ar3_H3r3_Elliot}

Thoughts
Overall, although it seemed like a pretty toxic challenge at first, it was relatively straightforward after we figured out the first step. We were definitely overthinking it.
 
Chỉnh sửa lần cuối:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
misc03 | Team: perfect blue

We're given a image file pied_piper.png. Looking at the hexdump there a lot of additional data after the last chunk (IEND):

Mã:
$ hexdump -C pied_piper.png| grep -A10 -B10 IEND
00154ee0  38 08 25 95 fe 7c 00 d3  43 79 c8 14 04 4f 17 12  |8.%..|..Cy...O..|
00154ef0  0c 0f 0c 16 0a e0 84 0a  49 80 41 c3 b4 04 42 b5  |........I.A...B.|
00154f00  a0 9a f1 e1 06 32 8d 84  32 50 00 48 bb 22 84 2b  |.....2..2P.H.".+|
00154f10  d0 cb 0d 90 84 37 5c c3  a1 63 b0 50 98 24 f6 19  |.....7\..c.P.$..|
00154f20  1f 69 cc 4d 49 cc 4f 4f  6e aa 2c ef 6a 6c e8 69  |.i.MI.OOn.,.jl.i|
00154f30  69 82 16 e6 a6 24 5b 0c  7a 43 88 22 52 a7 85 19  |i....$[.zC."R...|
00154f40  6a a4 12 93 5a 25 e1 fb  42 11 63 23 4c c5 59 19  |j...Z%..B.c#L.Y.|
00154f50  28 bc 79 ed 1a 98 de bf  5f 7c fe eb cf 3e 21 6d  |(.y....._|...>!m|
00154f60  86 10 42 a6 d3 29 9c 90  80 1c b8 e2 f7 df 0e 1d  |..B..)..........|
00154f70  39 f4 dd 81 fd ff 0f 6f  a3 12 43 53 65 e6 6a 00  |9......o..CSe.j.|
00154f80  00 00 00 49 45 4e 44 ae  42 60 82 ce 17 09 00 4a  |...IEND.B`.....J|
00154f90  4d 5d 4d 47 47 47 4a 0e  0f 03 15 47 47 46 73 47  |M]MGGGJ....GGFsG|
00154fa0  47 47 93 4f 41 47 47 47  55 f5 98 ee 47 47 67 47  |GG.OAGGGU...GGgG|
00154fb0  0e 03 06 13 3f db aa 3a  28 c3 1a 1e fd b0 f6 5a  |....?..:(......Z|
00154fc0  00 03 d3 55 62 65 e9 ac  fd a9 c0 ac 39 cf 96 65  |...Ube......9..e|
00154fd0  81 5f 2a 1b 24 f3 cf 15  0d 6e 62 a1 04 cc 55 56  |._*.$....nb...UV|
00154fe0  2a 1b 2a 1b a4 12 e5 d3  3b ff 9d 5f e2 d3 15 0d  |*.*.....;.._....|
00154ff0  ce 5f ea d3 e4 5b 00 6e  6a 1d 03 03 f3 6f e2 03  |._...[.nj....o..|
00155000  f3 51 56 ea 82 2f a4 cd  6f 80 f6 2a ac 1a a8 39  |.QV../..o..*...9|
00155010  99 48 bc eb 32 d9 fa 89  1d 2c e8 f2 b1 9d a0 db  |.H..2....,......|
00155020  ed 1e 9d e8 34 ad db fa  b9 7a 88 f4 39 bc 1e 38  |....4....z..9..8|

Extracting the data and doing some analysis on it:

Mã:
>>> from pwn import *
>>> data = open('pied_piper.png', 'rb').read()
>>> data.index("IEND")
1396611
>>> extra = data[data.index("IEND")+8:]
>>> extra[:16]
'\xce\x17\t\x00JM]MGGGJ\x0e\x0f\x03\x15'
>>> xor(extra[:16], "G")
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR'
>>>

We see that it has some repeated bytes, we try to xor it with that and we get the PNG header. This means that the extra data is a PNG encrypted with a single-byte XOR. We can easily decrypt it and get the flag.png.

upload_2020-1-17_16-39-33.png
This flag image is a pigpen cipher, which we can decode online to get the flag.
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
misc04 | Team: perfect blue

We are given a windows memory dump and a comment "Let me show you, how to getting source code.", which we will ignore.

Using volatility
We detect a suitable volatility profile:
Mã:
$ volatility imageinfo -f kevin_mitnick.1.raw

The profile is Win10x64.

We list the processes:
Mã:
$ volatility pslist --profile=Win10x64 -f kevin_mitnick.1.raw | tee pslist

Nothing suspicious, mostly chrome.exe.

We look at open/cached files:

Mã:
volatility filescan --profile=Win10x64 -f kevin_mitnick.1.raw | tee filescan

Again, nothing much.

GREP to the rescue

Having found no interesting files, we will now look for URLs:

Mã:
egrep -a --only-matching 'https?://[[:print:]]*' kevin_mitnick.1.raw | sort | uniq > urls

Drawing from past CTF experience, we look specifically for dropbox.com, docs.google.com and drive.google.com urls. After going through a few we find https://drive.google.com/file/d/1trYCpFE5n1X5O0noENhCGjQF3mWuk_xW/view, it's a xlsx spreadsheet with one of tabs called "FLAG". We download it, unpack it as PKZip archive and grep all files for WhiteHat:

Mã:
$ unzip Hotel_Financial_Model_2013_Complete_V6-xls.xlsx
$ grep -rain WhiteHat
xl/sharedStrings.xml:10: ... WhiteHat{SHA1(G00D_J0B_Y0u4r3Dump5oExcellen7)} ...
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Blockchain | Team: perfect blue

We're given 2 private keys: 34a7370734caff5d129ad355f78f3ccf.pem, 8a95963d7bedd2b81ad09cd1838c7a4d.pem.

We can extract the modulus and private exponent using RsaCTFTool:

Mã:
$ python ~/hack/RsaCtfTool/RsaCtfTool.py --dumpkey --key 34a7370734caff5d129ad355f78f3ccf.pem
[*] n: 3933301738623482824438423527443174024034903340575254516502107781450241559896803239143883018509648345485361873725629555553640770848086782431505505692289
[*] e: 65537
$ python ~/hack/RsaCtfTool/RsaCtfTool.py --dumpkey --key 8a95963d7bedd2b81ad09cd1838c7a4d.pem
[*] n: 1057400219548831590862498475261646567798980178278784386310020560367089188125453414566736447119699796555751827787628247382978018443997557989020536943983
[*] e: 65537

If we take the GCD of both the modulus, we see that they have a common factor, which means we can factor them and generate the private key.

Mã:
>>> gcd(n1, n2)
1091951834898382993408357240646061116416467734213916798265279491274843400183L
>>> p = gcd(n1, n2)
>>> q1 = n1/p
>>> q2 = n2/p
>>> d1 = invert(65537, (p-1)*(q1-1))
>>> d2 = invert(65537, (p-1)*(q2-1))

Using, this we can decrypt the messages in the json blocks that we are given.

Mã:
>>> long_to_bytes(pow(864826346328927043007924641380681736981324987926997370887020532699182309378599192043216478265476219278213123962074508284028662403643532629433329761492, d1, n1))
'Do you understand the blockchain?'
>>> long_to_bytes(pow(259242051785557714557594066190019826465030870294179284671916925100489488841761299528416294893049464518482888070747927907550583942630013791833474340284, d2, n2))
'Password using open flag.zip'
>>> long_to_bytes(pow(3467074671076858427887425157777463145087476633275513864943463990703623032280801013924306443879332057123214793127862390154827554625137418534583896303616, d1, n1))
'flag in flag.txt'
>>> long_to_bytes(pow(260259490441096686614518844301454718739843509738983969165420676005404297357230613482141235832583253831691051931351295653801889428212969414301414329852, d2, n2))
'Password = Password1+Password2'
>>> long_to_bytes(pow(1535086324597057729311343510271769159442400498252787851926410538373297030193590329732950032623600137243772129943527400615893561445637150940979108765230, d1, n1))
"Password1:'irVOwoJR7d'"
>>> long_to_bytes(pow(182842058942028668693782090218012558408325328016978308589264490683273716484502724907545336344750909005728737352410277713521976130375761311818569486299, d2, n2))
"Password2:'D@V!4P##Ij'"
>>>

Using, the password, we can decrypt the flag.zip, which gives us a flag.txt which contains a base64 string. On decoding the base64 string, we get a PNG file containing a QR code.
upload_2020-1-17_16-47-40.png
On decoding the QR code, we get the flag

Whitehat{the_ flag_blockchain_ iot}
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
re02 | Team: OpenToA11

This challenge is not a typical reversing challenge, but more like a forensics/reversing one. It actually requires binary modifications to execute properly, and never prints the flag.

The binary itself is statically linked and stripped, and also packed with UPX. Unpacking it reveals that it consists of 3 stages:

  • Stage one, anti-debug through PTRACE_TRACEME. If a debugger is not present, the value input to the next stage is 0xe27fdee2. This is copied as "00000000e27fdee2" to a string.
  • Stage two, it prints a mysterious hex string: DF6C24C58419A0A15127F614BCE0CA05 with the message "Guess the key". The input value is which is sprintf'ed to a some invisible buffer as "e27fdee2...." with literal dots.
  • Stage three, it sets a constant to 0xB01ABA1A and then checks if that constant is 0xC0CAC01A. If it is, the constant is XORed with two other constants, and then invisble sprintf'ed to a buffer like "Incomplete flag: %s....%x%x", where the %s is the string from stage 2, and the %x are 0x2E95373B and 0x23939E84 XORed with 0xC0CAC01A.
The resulting (invisible) string is "e27fdee2........ee5ff721e3595e9e".

We can use one of the strings to decrypt the mysterious hex string with AES, which reveals the last bytes of the flag string.

Mã:
>>> AES.new("00000000e27fdee2", AES.MODE_ECB).decrypt("DF6C24C58419A0A15127F614BCE0CA05".decode('hex'))
'ccbf9759\x08\x08\x08\x08\x08\x08\x08\x08'

Then we use the hint about "something is base64-encoded" and encode it as base64

Mã:
>>> "e27fdee2ccbf9759ee5ff721e3595e9e".decode('hex').encode('base-64')
'4n/e4sy/l1nuX/ch41leng==\n'

Stripping away the newline and padding, then sha1-hashing the result, gives the flag
WhiteHat{09363c253799cddaf87cfcd0e4f92b9e2356fccc}
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Thẻ
whitehat grand prix
Bên trên