Disassembly of main:
push rbp
mov rbp, rsp
sub rsp, 10h
lea rax, unk_6E8
mov [rbp+var_8], rax
lea rdi, s ; "Nothing to see here.."
call _puts
mov eax, 0
leave
retn
Before puts
is called, we see an address 0x6e8
being stored in rax
.
If we go to the address we find the flag characters separated by several
bytes (due to which we won't be able to find it using strings
).
0x6E8 unk_6E8 db 32h ; 2 ; DATA XREF: main+8↑o
0x6E9 db 0
0x6EA db 0
0x6EB db 0
0x6EC db 34h ; 4
0x6ED db 0
0x6EE db 0
0x6EF db 0
0x6F0 db 37h ; 7
0x6F1 db 0
0x6F2 db 0
0x6F3 db 0
0x6F4 db 43h ; C
0x6F5 db 0
0x6F6 db 0
0x6F7 db 0
0x6F8 db 54h ; T
Flag: 247CTF{6df215eb3cc73407267031a15b0ab36c}
On decompiling the main function in IDA, we see that a strings of ASCII encoded hex characters are being XORed with some data stored on the stack.
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+8h] [rbp-A8h]
int j; // [rsp+Ch] [rbp-A4h]
char s[48]; // [rsp+10h] [rbp-A0h]
char s2[8]; // [rsp+40h] [rbp-70h]
__int64 v8; // [rsp+48h] [rbp-68h]
__int64 v9; // [rsp+50h] [rbp-60h]
__int64 v10; // [rsp+58h] [rbp-58h]
char v11; // [rsp+60h] [rbp-50h]
char s1[40]; // [rsp+70h] [rbp-40h]
unsigned __int64 v13; // [rsp+98h] [rbp-18h]
v13 = __readfsqword(0x28u);
strcpy(s, "875e9409f9811ba8560beee6fb0c77d2");
*(_QWORD *)s2 = 0x5A53010106040309LL;
v8 = 0x5C585354500A5B00LL;
v9 = 0x555157570108520DLL;
v10 = 0x5707530453040752LL;
v11 = 0;
for ( i = 0; i < strlen(s); ++i )
s2[i] ^= s[i];
puts("Enter the secret password:");
fgets(s1, 33, stdin);
if ( !strcmp(s1, s2) )
printf("You found the flag!\n247CTF{%s}\n", s2);
for ( j = 0; j < strlen(s); ++j )
s2[j] = 0;
return 0LL;
}
Here is a script that emulates the above code to get the flag.
from pwn import *
p = make_packer('all')
h = p(0x5A53010106040309)
h += p(0x5C585354500A5B00)
h += p(0x555157570108520D)
h += p(0x5707530453040752)
s = '875e9409f9811ba8560beee6fb0c77d2'
ans = ''
for x,y in zip(s,h):
ans += chr(ord(x) ^ y)
print('247CTF{%s}' % ans)
Flag: 247CTF{141c85ccfb2ae19d8d8c224c4e403dce}
Here we have an MS-DOS executable. We can go into any dissassembler of our
choice and see how the program works. At the offset 0x23
we get the
flag verification code and reading through the assembly, I came up with
the following script to get the flag.
si = [0x77, 0x21, 0x67, 0x30, 0x60, 0x35, 0x0c, 0x0c, 0x78, 0x79, 0x2e, \
0x2e, 0x20, 0x72, 0x70, 0x75, 0x29, 0x2b, 0x00, 0x5c, 0x21, 0x70, \
0x62, 0x63, 0x65, 0x60, 0x07, 0x0d, 0x06, 0x02, 0x3b, 0x3b]
def xs(al,si,c):
si[c] ^= al
si[c+1] ^= al
return c+2
c = 0
c = xs(0x4b^0x0c,si,c)
c = xs(0x53^0x06,si,c)
c = xs(0x58-0x01,si,c)
c = xs(0x62-0x29,si,c)
c = xs(0x68^0x23,si,c)
c = xs(0x4b^0x00,si,c)
c = xs(0x62-0x1e,si,c)
c = xs(0x4d-0x0b,si,c)
c = xs(0x45^0x0d,si,c)
c = xs(0x10^0x28,si,c)
c = xs(0x58^0x1d,si,c)
c = xs(0x7a^0x28,si,c)
c = xs(0x65-0x13,si,c)
c = xs(0x33^0x07,si,c)
c = xs(0x25^0x15,si,c)
c = xs(0x4c+0x0c,si,c)
flag = ''
for i in si:
flag += chr(i)
print('247CTF{%s}' % flag)
Flag: 247CTF{0f2e7b5532eed627ac8dd501723962cc}
In this challenge we are given a webpage where we have to submit the
flag that is then verified by javascript in the checkFlag
function
which has a long list of equations to be satisfied.
checkFlag(flag){
let result = "LOCKED"
this.dom.lock.classList.remove('verified');
if (Object.keys(flag).length == 40 &&
((flag[37] - flag[37]) * flag[15] == 0) &&
((flag[3] + flag[31]) ^ ...) {
result = "";
for (var idx in flag) {
result += (String.fromCharCode(flag[idx]));
}
this.dom.lock.classList.add('verified');
}
return result;
}
So I decided to use the z3-solver
package in python to solve the
equations.
from z3 import *
flag = [
BitVec("flag[0]", 8), BitVec("flag[1]", 8), BitVec("flag[2]", 8),
BitVec("flag[3]", 8), BitVec("flag[4]", 8), BitVec("flag[5]", 8),
BitVec("flag[6]", 8), BitVec("flag[7]", 8), BitVec("flag[8]", 8),
BitVec("flag[9]", 8), BitVec("flag[10]", 8), BitVec("flag[11]", 8),
BitVec("flag[12]", 8), BitVec("flag[13]", 8), BitVec("flag[14]", 8),
BitVec("flag[15]", 8), BitVec("flag[16]", 8), BitVec("flag[17]", 8),
BitVec("flag[18]", 8), BitVec("flag[19]", 8), BitVec("flag[20]", 8),
BitVec("flag[21]", 8), BitVec("flag[22]", 8), BitVec("flag[23]", 8),
BitVec("flag[24]", 8), BitVec("flag[25]", 8), BitVec("flag[26]", 8),
BitVec("flag[27]", 8), BitVec("flag[28]", 8), BitVec("flag[29]", 8),
BitVec("flag[30]", 8), BitVec("flag[31]", 8), BitVec("flag[32]", 8),
BitVec("flag[33]", 8), BitVec("flag[34]", 8), BitVec("flag[35]", 8),
BitVec("flag[36]", 8), BitVec("flag[37]", 8), BitVec("flag[38]", 8),
BitVec("flag[39]", 8),
]
s = Solver()
s.add((flag[37] - flag[37]) * flag[15] == 0)
s.add((flag[3] + flag[31]) ^ (flag[29] + flag[8]) == 234)
s.add((flag[32] - flag[12]) * flag[9] == -2332)
s.add((flag[24] - flag[27] + flag[13]) ^ flag[6] == 114)
s.add((flag[38] - flag[15]) * flag[33] == 800)
s.add((flag[34] - flag[21]) * flag[26] == 98)
s.add((flag[29] + flag[0]) ^ (flag[8] + flag[38]) == 248)
s.add((flag[21] * flag[18]) ^ (flag[7] - flag[15]) == 2694)
s.add((flag[28] * flag[23]) ^ (flag[19] - flag[5]) == -9813)
s.add((flag[34] + flag[30]) ^ (flag[37] + flag[6]) == 72)
s.add((flag[23] - flag[22]) * flag[12] == 4950)
s.add((flag[9] * flag[28]) ^ (flag[20] - flag[11]) == 5143)
s.add((flag[2] * flag[22]) ^ (flag[37] - flag[0]) == 2759)
s.add((flag[26] - flag[12]) * flag[3] == -3350)
s.add((flag[35] * flag[0]) ^ (flag[23] - flag[21]) == 2698)
s.add((flag[20] + flag[31]) ^ (flag[5] + flag[10]) == 22)
s.add((flag[31] * flag[19]) ^ (flag[1] - flag[2]) == -2655)
s.add((flag[38] - flag[14]) * flag[18] == 55)
s.add((flag[29] - flag[19] + flag[10]) ^ flag[2] == 93)
s.add((flag[13] - flag[25] + flag[30]) ^ flag[29] == 13)
s.add((flag[35] + flag[33]) ^ (flag[26] + flag[21]) == 249)
s.add((flag[17] + flag[24]) ^ (flag[34] + flag[1]) == 253)
s.add((flag[32] - flag[35] + flag[19]) ^ flag[1] == 0)
s.add((flag[22] - flag[11] + flag[3]) ^ flag[31] == 113)
s.add((flag[19] - flag[0]) * flag[13] == 108)
s.add((flag[19] - flag[17]) * flag[14] == -2475)
s.add((flag[31] - flag[35] + flag[16]) ^ flag[19] == 84)
s.add((flag[24] * flag[27]) ^ (flag[35] - flag[17]) == -5792)
s.add((flag[11] * flag[35]) ^ (flag[15] - flag[28]) == -2845)
s.add((flag[18] - flag[19] + flag[31]) ^ flag[5] == 112)
s.add((flag[20] - flag[6]) * flag[10] == -3933)
s.add((flag[39] - flag[33]) * flag[6] == 3075)
s.add((flag[22] + flag[1]) ^ (flag[39] + flag[14]) == 211)
s.add((flag[37] * flag[24]) ^ (flag[12] - flag[39]) == -5726)
s.add((flag[29] + flag[3]) ^ (flag[8] + flag[11]) == 195)
s.add((flag[26] * flag[7]) ^ (flag[10] - flag[17]) == -2375)
s.add((flag[11] - flag[12]) * flag[12] == -4653)
s.add((flag[13] * flag[5]) ^ (flag[12] - flag[25]) == 3829)
s.add((flag[24] * flag[0]) ^ (flag[13] - flag[23]) == -2829)
s.add((flag[17] + flag[12]) ^ (flag[8] + flag[14]) == 170)
s.add((flag[38] + flag[23]) ^ (flag[11] + flag[1]) == 245)
s.add((flag[22] + flag[5]) ^ (flag[21] + flag[24]) == 19)
s.add((flag[35] - flag[8] + flag[21]) ^ flag[30] == 85)
s.add((flag[18] - flag[31] + flag[28]) ^ flag[29] == 0)
s.add((flag[30] * flag[35]) ^ (flag[27] - flag[29]) == 5501)
s.add((flag[8] - flag[30] + flag[16]) ^ flag[36] == 81)
s.add((flag[13] * flag[18]) ^ (flag[35] - flag[38]) == -2971)
s.add((flag[27] - flag[14]) * flag[39] == 5875)
s.add((flag[34] - flag[33]) * flag[6] == -6027)
s.add((flag[38] * flag[1]) ^ (flag[20] - flag[10]) == -2915)
s.add((flag[1] - flag[1]) * flag[3] == 0)
s.add((flag[36] - flag[20]) * flag[8] == 2640)
s.add((flag[23] - flag[11] + flag[17]) ^ flag[33] == 246)
s.add((flag[13] - flag[38]) * flag[0] == -100)
s.add((flag[28] - flag[14]) * flag[31] == 2142)
s.add((flag[26] + flag[15]) ^ (flag[13] + flag[31]) == 8)
s.add((flag[36] - flag[15]) * flag[17] == 5238)
s.add((flag[16] - flag[30]) * flag[33] == 0)
s.add((flag[2] - flag[20] + flag[13]) ^ flag[6] == 76)
s.add((flag[10] - flag[14] + flag[31]) ^ flag[13] == 3)
s.add((flag[0] * flag[10]) ^ (flag[14] - flag[31]) == 2854)
s.add((flag[28] - flag[34] + flag[14]) ^ flag[14] == 82)
s.add((flag[28] - flag[25]) * flag[1] == 2444)
s.add((flag[34] - flag[12]) * flag[25] == -2400)
s.add((flag[28] * flag[38]) ^ (flag[17] - flag[4]) == 5429)
s.add((flag[21] - flag[21] + flag[26]) ^ flag[23] == 84)
s.add((flag[9] - flag[4] + flag[18]) ^ flag[35] == 47)
s.add((flag[28] - flag[21] + flag[1]) ^ flag[33] == 0)
s.add((flag[24] - flag[25] + flag[22]) ^ flag[0] == 8)
s.add((flag[28] - flag[25]) * flag[12] == 4653)
s.add((flag[1] * flag[15]) ^ (flag[10] - flag[8]) == 2498)
s.add((flag[5] * flag[7]) ^ (flag[15] - flag[34]) == -3429)
s.add((flag[8] * flag[3]) ^ (flag[23] - flag[22]) == 3671)
s.add((flag[25] - flag[33]) * flag[11] == -2600)
s.add((flag[21] + flag[12]) ^ (flag[37] + flag[28]) == 81)
s.add((flag[30] + flag[33]) ^ (flag[34] + flag[14]) == 162)
s.add((flag[6] - flag[25]) * flag[8] == 4015)
s.add((flag[24] - flag[7] + flag[12]) ^ flag[7] == 90)
s.add((flag[18] * flag[12]) ^ (flag[8] - flag[4]) == -5466)
s.add((flag[32] * flag[7]) ^ (flag[32] - flag[27]) == -2730)
s.add((flag[32] * flag[34]) ^ (flag[29] - flag[16]) == 2804)
s.add((flag[25] * flag[22]) ^ (flag[28] - flag[39]) == -2542)
s.add((flag[8] - flag[15]) * flag[6] == 861)
s.add((flag[20] + flag[18]) ^ (flag[25] + flag[36]) == 245)
s.add((flag[5] - flag[28] + flag[14]) ^ flag[39] == 97)
s.add((flag[30] * flag[11]) ^ (flag[16] - flag[11]) == 5216)
s.add((flag[11] + flag[18]) ^ (flag[7] + flag[9]) == 13)
s.add((flag[9] - flag[2]) * flag[30] == -200)
s.add((flag[12] + flag[37]) ^ (flag[9] + flag[4]) == 78)
s.add((flag[10] - flag[37]) * flag[38] == -2408)
s.add((flag[5] * flag[19]) ^ (flag[20] - flag[21]) == 3645)
s.add((flag[27] * flag[29]) ^ (flag[39] - flag[21]) == 10354)
s.add((flag[15] * flag[32]) ^ (flag[7] - flag[22]) == -2642)
s.add((flag[1] - flag[3] + flag[24]) ^ flag[31] == 25)
s.add((flag[13] - flag[0]) * flag[30] == 400)
s.add((flag[18] - flag[15] + flag[36]) ^ flag[28] == 12)
s.add((flag[34] + flag[21]) ^ (flag[12] + flag[37]) == 163)
s.add((flag[36] - flag[33]) * flag[14] == 110)
s.add((flag[2] - flag[3]) * flag[3] == -804)
s.add((flag[35] - flag[27] + flag[22]) ^ flag[4] == 80)
s.add((flag[10] + flag[9]) ^ (flag[17] + flag[2]) == 246)
s.add((flag[25] * flag[4]) ^ (flag[27] - flag[23]) == 4201)
s.add((flag[32] * flag[19]) ^ (flag[3] - flag[25]) == 2877)
s.add((flag[37] - flag[14]) * flag[23] == 4545)
s.add((flag[32] + flag[13]) ^ (flag[31] + flag[32]) == 7)
s.add((flag[11] - flag[25]) * flag[39] == 250)
s.add((flag[17] + flag[31]) ^ (flag[6] + flag[9]) == 36)
s.add((flag[4] + flag[27]) ^ (flag[2] + flag[31]) == 208)
s.add((flag[6] + flag[7]) ^ (flag[26] + flag[21]) == 206)
s.add((flag[19] + flag[25]) ^ (flag[22] + flag[10]) == 10)
s.add((flag[34] + flag[2]) ^ (flag[8] + flag[26]) == 2)
s.add((flag[7] + flag[5]) ^ (flag[12] + flag[14]) == 237)
s.add((flag[1] - flag[13]) * flag[38] == -112)
s.add((flag[0] - flag[19] + flag[16]) ^ flag[0] == 80)
s.add((flag[31] + flag[36]) ^ (flag[3] + flag[2]) == 227)
s.add((flag[32] - flag[3] + flag[26]) ^ flag[4] == 113)
s.add((flag[3] * flag[6]) ^ (flag[16] - flag[27]) == -8241)
s.add((flag[24] + flag[15]) ^ (flag[2] + flag[30]) == 242)
s.add((flag[11] + flag[21]) ^ (flag[31] + flag[20]) == 12)
s.add((flag[9] - flag[26] + flag[23]) ^ flag[30] == 13)
sol = ''
s.check()
val = s.model()
for i in range(40): sol += chr(val[flag[i]].as_long())
print(sol)
Flag: 247CTF{17594c670da74613e921faed37d37fd8}
In this challenge we get a simple ELF64 binary which can be decompiled using IDA. The goal of this challenge is to find of of many product codes, which when entered into the online service will reap us the flag.
The decompiled code in itself is easy to understand. The main function asks us for a 32-bit string of characters in the uppercase ASCII range. It then calls a verification function that depending upon whether the letter comes before or after 'M', keeps a running sum with some other constants. In the end if the sum modulo 248 equals 247, we get the flag.
Below I have scripted the logic for the verification check. After I did that, I got the desired value of 247 through trial and error.
def sub_120A(a1):
if ord(a1) <= 77: return ord(a1) + 181
else: return ord(a1) + 177
a1 = 'BBBBBZBBBBBBBBAAAAAAAAAAAAOOOOOO'
# print(sub_120A(a1[0])) # Gives us the first letter ??
v3 = 247
for j in range(1,32):
v3 += sub_120A(a1[j]) - j + 247
print(v3)
print(v3%248) # Should be 247
Submitting the product code on the socket:
$ nc d19274d14f21d488.247ctf.com 50112
Enter a valid product key to gain access to the flag:
BBBBBZBBBBBBBBAAAAAAAAAAAAOOOOOO
Valid product key!
247CTF{fb88b9fe80e969e73a27541f62d6f89c}