← Back to Writeups
HTBVery EasyCryptography

Gonna-Lift-Em-All

D3v0o0Nu119/2/20262 min read
#cryptography#htb#very easy

Gonna-Lift-Em-All

Platform: HackTheBox | Category: Cryptography | Difficulty: Very Easy | Author: D3v0o0Nu11 | Date: 2026-02-10

Description

Quick, there's a new custom Pokemon in the bush called "The Custom Pokemon". Can you find out what its weakness is and capture it?

Solution Approach

Core idea: Identify the weakness from source review or fingerprinting first. Iterate with incremental payloads instead of guessing.

Steps

  1. First, unzip the .zip file given, then jump to the extracted directory.
py
from Crypto.Util.number import bytes_to_long, getPrime
import random

FLAG = b'REDACTED'

def gen_params():
    p = getPrime(1024)
    g = random.randint(2, p - 2)
    x = random.randint(2, p - 2)
    h = pow(g, x, p)
    return (p, g, h), x

def encrypt(pubkey):
    p, g, h = pubkey
    m = bytes_to_long(FLAG)
    y = random.randint(2, p - 2)
    s = pow(h, y, p)
    return (g * y % p, m * s % p)

def main():
    pubkey, _ = gen_params()
    c1, c2 = encrypt(pubkey)

    with open('out.txt', 'w') as f:
        f.write(
            f'p = {pubkey[0]}\ng = {pubkey[1]}\nh = {pubkey[2]}\n(c1, c2) = ({c1}, {c2})\n'
        )

if __name__ == "__main__":
    main()
  1. Since i'm new to cryptography then i tried to use rsactftools and got nothing.
  2. Then i tried to read the forum and found out that we need to use z3 to solve this challenge.
  3. After did a small outsource about z3 theorem, i used this custom script.
py
from z3 import *
import os
from Crypto.Util.number import long_to_bytes
#from pwn import *
os.system('clear')

#context.log_level = 'debug'

p = 163924920994230253637901818188432016168244271739612329857589126113342762280179217681751572174802922903476854156324228497960403054780444742311082033470378692771947296079573091561798164949003989592245623978327019668789826246878280613414312438425787726549209707561194579292492350868953301012702750092281807657719
g = 97407673851268146184804267386115296213106535602908738837573109808033224187746927894605766365039669844761355888387043653015559933298433068597707383843814893442087063136640943475006105673619942401850890433169719970841218851182254280222787630139143746993351533776324254770080289574521452767936507196421481076841
h = 7771801879117000288817915415260102060832587957130098985489551063161695391373720317596178655146834967333192201720460001561670355858493084613455139466487717364432242890680666229302181326080340061384604634749443972114930849979067572441792867514664636574923631540074373758015873624100768698622048136552173788916
c1 = 83194887666722435308945316429939841668109985194860518882743309895332330525232854733374220834562004665371728589040849388337869965962272329974327341953512030547150987478914221697662859702721549751949905379177524490596978865458493461926865553151329446008396048857775620413257603550197735539508582063967332954541
c2 = 46980139827823872709797876525359718565495105542826335055296195898993549717497706297570900140303523646691120660896057591142474133027314700072754720423416473219145616105901315902667461002549138134613137623172629251106773324834864521095329972962212429468236356687505826351839310216384806147074454773818037349470

y = Int(b'y')

solver = Solver()

### c1 = g * y % p

solver.add(y < p)
solver.add(y > 2)
solver.add(c1 == g * y %p)
solver.check()
yval = solver.model()[y].as_long()

### y = 151545036818752418931716093171030939827729309717327611184964755063685533596024474465903219353892430936128129116061427826165388249908655823309049171719865481058072839169911183783187254412879190149192386989186799988830028288993778261809217410313001568877314905167838867719115514855795015291428405597461040625720

s = pow(h, yval, p)
#print(s)
#s = 95244363070080550713266246371562456046084564061558782268652023764134097105187808511715502141546487304193610470058615149101415153739741876517557429124778198260651131217203882949297747623083040021035931473107457836071017171919815595724870051962097474916689177221114864946468626174013799063814269859213421712272

### c2 = FLAG * s % p

solver = Solver()

flag = Int(b'flag')
solver.add(c2 == flag * s % p)
solver.check()
flagVal = solver.model()[flag].as_long()
#print(flagVal)
#flagVal = 205357888392943589580902786974561391650590968371698047999459858913772423263744616351029459666275327727761663649918391299343583138034557
result = long_to_bytes(flagVal) 
print(result.decode()) # convert bytes to string

OUTPUT

  1. Got the flag!

Flag

REDACTED

Lessons Learned

  1. Identify the weakness from source review or fingerprinting first.
  2. Iterate with incremental payloads instead of guessing.
  3. Reuse the same pattern in future engagements.