initial commit
287
.gitignore
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node,macos,python
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node,macos,python
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
.env*.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
pytestdebug.log
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
doc/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
pythonenv*
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# profiling data
|
||||
.prof
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node,macos,python
|
||||
|
||||
/blinky/code/blinky/build
|
0
Fighting_scientists/.gitkeep
Normal file
18
Fighting_scientists/Bliep.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Title
|
||||
Fighting scientists
|
||||
|
||||
# Description
|
||||
|
||||
A war has occured in the science faculty, the physicists and NLP-scientists had an argument about frequencies and the order of magnitude of them in x-rays.
|
||||
Because they like to taunt each other someone has deleted all code and wrote 2 txt's after each other so it's very clear what type their shared document had.
|
||||
Besides this I do like watching people argue and lose there minds, I also like the first order Taylor expansion of the sine function, just the abilty to say sin(x) = x.
|
||||
It's remarkable no?
|
||||
|
||||
# files
|
||||
swt.txt.txt
|
||||
|
||||
# deployment
|
||||
n/a just open a scripting language that's able to open txt files
|
||||
|
||||
# type
|
||||
Steganography
|
17
Fighting_scientists/Write-up.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Fighting Scientists
|
||||
|
||||
# Description
|
||||
A war has occured in the science faculty, the physicists and NLP-scientists had an argument about frequencies and the order of magnitude of them in x-rays.
|
||||
Because they like to taunt each other someone has deleted all code and wrote 2 txt's after each other so it's very clear what type their shared document had.
|
||||
Besides this I do like watching people argue and lose there minds, I also like the first order Taylor expansion of the sine function, just the abilty to say sin(x) = x.
|
||||
It's remarkable no?
|
||||
|
||||
# Files
|
||||
swt.txt.txt
|
||||
|
||||
# How to solve
|
||||
|
||||
Easy, just use a tool that counts every character, if you then print every letter in descending order the flag will appear.
|
||||
|
||||
# flag
|
||||
IGCTF{EOAN}
|
7882
Fighting_scientists/swt.txt.txt
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# IGCTF writeups 2020-2021
|
||||
You can find all the challenges here in these folders. Each challenge folder should contain a SOLUTION.md that contains a (possible) solution for the challenge.
|
||||
|
||||
Have fun!
|
38
Risky-Business/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
== Title ==
|
||||
|
||||
Risky Business
|
||||
|
||||
== Description ==
|
||||
Warning: Difficult challenge.
|
||||
|
||||
I found a RISC-V emulator lying around. I heard that there's a flag in there somewhere...
|
||||
To help you get started, I'll give you an ELF binary that runs on the emulator. It won't help you find the flag, but it will help you figure out what the binaries look like.
|
||||
|
||||
== Flag ==
|
||||
|
||||
IGCTF{RISC-V_is_amazing_and_so_are_you}
|
||||
|
||||
== Files ==
|
||||
Participants should receive the riscv_sim_RV64 and the example file.
|
||||
|
||||
== Deployment ==
|
||||
/
|
||||
|
||||
== Solution ==
|
||||
First of all, a command that lets you compile riscv assembly code for the emulator:
|
||||
Of course, clang needs to be compiled with support for riscv.
|
||||
|
||||
clang -nostdlib -Ttext 0x80000000 --target=riscv64-unknown-freebsd -march=rv64g -mno-relax -o binary source.S
|
||||
|
||||
Before we move on to writing some code, we can have a look at the emulator in Ghidra.
|
||||
Searching for strings will allow us to find a number of strings called FLAG_PART1, FLAG_PART2, etc.
|
||||
Upon further inspection, these variables will contain (contiguous) addresses of parts of the flag starting at 0xd000.
|
||||
|
||||
These raw addresses are not addressable. There is still an offset missing. Searching through the address space in assembly, or closely inspecting the decompiled emulator should yield the correct offset, namely 0x2000000 (start of CLINT).
|
||||
|
||||
Writing some assembly code that reads these addresses into registers should print the flag in hexadecimal format in the log of the emulator.
|
||||
|
||||
An example is given in the solution/ directory. This directory also contains some macros that take care of the initialisation of the emulator. They can be found online, for example here: https://github.com/riscv/riscv-test-env/blob/master/p/riscv_test.h
|
||||
The other macro file can be found in the same repository.
|
||||
|
||||
Compiling and running the provided code will load the flag in register x12. Grepping on "x12" through the logs of the emulator will yield the flag in hex.
|
BIN
Risky-Business/example
Executable file
BIN
Risky-Business/riscv_sim_RV64
Executable file
2829
Risky-Business/solution/encoding.h
Normal file
22
Risky-Business/solution/solution.S
Normal file
@ -0,0 +1,22 @@
|
||||
#include "test_macros.h"
|
||||
|
||||
RVTEST_RV64U
|
||||
RVTEST_CODE_BEGIN
|
||||
|
||||
li x10, 0x2000000
|
||||
li x11, 0xd000
|
||||
add x10, x10, x11
|
||||
ld x12, (x10)
|
||||
addi x10, x10, 8
|
||||
ld x12, (x10)
|
||||
addi x10, x10, 8
|
||||
ld x12, (x10)
|
||||
addi x10, x10, 8
|
||||
ld x12, (x10)
|
||||
addi x10, x10, 8
|
||||
ld x12, (x10)
|
||||
|
||||
RVTEST_PASS
|
||||
RVTEST_CODE_END
|
||||
|
||||
.align 6; .global tohost; tohost: .dword 0;
|
267
Risky-Business/solution/test_macros.h
Normal file
@ -0,0 +1,267 @@
|
||||
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
|
||||
#define _ENV_PHYSICAL_SINGLE_CORE_H
|
||||
|
||||
#include "encoding.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Begin Macro
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#define RVTEST_RV64U \
|
||||
.macro init; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV64UF \
|
||||
.macro init; \
|
||||
RVTEST_FP_ENABLE; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV64UV \
|
||||
.macro init; \
|
||||
RVTEST_VECTOR_ENABLE; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV32U \
|
||||
.macro init; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV32UF \
|
||||
.macro init; \
|
||||
RVTEST_FP_ENABLE; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV32UV \
|
||||
.macro init; \
|
||||
RVTEST_VECTOR_ENABLE; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV64M \
|
||||
.macro init; \
|
||||
RVTEST_ENABLE_MACHINE; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV64S \
|
||||
.macro init; \
|
||||
RVTEST_ENABLE_SUPERVISOR; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV32M \
|
||||
.macro init; \
|
||||
RVTEST_ENABLE_MACHINE; \
|
||||
.endm
|
||||
|
||||
#define RVTEST_RV32S \
|
||||
.macro init; \
|
||||
RVTEST_ENABLE_SUPERVISOR; \
|
||||
.endm
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
|
||||
#else
|
||||
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
|
||||
#endif
|
||||
|
||||
#define INIT_XREG \
|
||||
li x1, 0; \
|
||||
li x2, 0; \
|
||||
li x3, 0; \
|
||||
li x4, 0; \
|
||||
li x5, 0; \
|
||||
li x6, 0; \
|
||||
li x7, 0; \
|
||||
li x8, 0; \
|
||||
li x9, 0; \
|
||||
li x10, 0; \
|
||||
li x11, 0; \
|
||||
li x12, 0; \
|
||||
li x13, 0; \
|
||||
li x14, 0; \
|
||||
li x15, 0; \
|
||||
li x16, 0; \
|
||||
li x17, 0; \
|
||||
li x18, 0; \
|
||||
li x19, 0; \
|
||||
li x20, 0; \
|
||||
li x21, 0; \
|
||||
li x22, 0; \
|
||||
li x23, 0; \
|
||||
li x24, 0; \
|
||||
li x25, 0; \
|
||||
li x26, 0; \
|
||||
li x27, 0; \
|
||||
li x28, 0; \
|
||||
li x29, 0; \
|
||||
li x30, 0; \
|
||||
li x31, 0;
|
||||
|
||||
#define INIT_PMP \
|
||||
la t0, 1f; \
|
||||
csrw mtvec, t0; \
|
||||
/* Set up a PMP to permit all accesses */ \
|
||||
li t0, (1 << (31 + (__riscv_xlen / 64) * (53 - 31))) - 1; \
|
||||
csrw pmpaddr0, t0; \
|
||||
li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \
|
||||
csrw pmpcfg0, t0; \
|
||||
.align 2; \
|
||||
1:
|
||||
|
||||
#define INIT_SATP \
|
||||
la t0, 1f; \
|
||||
csrw mtvec, t0; \
|
||||
csrwi satp, 0; \
|
||||
.align 2; \
|
||||
1:
|
||||
|
||||
#define DELEGATE_NO_TRAPS \
|
||||
csrwi mie, 0; \
|
||||
la t0, 1f; \
|
||||
csrw mtvec, t0; \
|
||||
csrwi medeleg, 0; \
|
||||
csrwi mideleg, 0; \
|
||||
.align 2; \
|
||||
1:
|
||||
|
||||
#define RVTEST_ENABLE_SUPERVISOR \
|
||||
li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \
|
||||
csrs mstatus, a0; \
|
||||
li a0, SIP_SSIP | SIP_STIP; \
|
||||
csrs mideleg, a0; \
|
||||
|
||||
#define RVTEST_ENABLE_MACHINE \
|
||||
li a0, MSTATUS_MPP; \
|
||||
csrs mstatus, a0; \
|
||||
|
||||
#define RVTEST_FP_ENABLE \
|
||||
li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
|
||||
csrs mstatus, a0; \
|
||||
csrwi fcsr, 0
|
||||
|
||||
#define RVTEST_VECTOR_ENABLE \
|
||||
li a0, (MSTATUS_VS & (MSTATUS_VS >> 1)) | \
|
||||
(MSTATUS_FS & (MSTATUS_FS >> 1)); \
|
||||
csrs mstatus, a0; \
|
||||
csrwi fcsr, 0; \
|
||||
csrwi vcsr, 0;
|
||||
|
||||
#define RISCV_MULTICORE_DISABLE \
|
||||
csrr a0, mhartid; \
|
||||
1: bnez a0, 1b
|
||||
|
||||
#define EXTRA_TVEC_USER
|
||||
#define EXTRA_TVEC_MACHINE
|
||||
#define EXTRA_INIT
|
||||
#define EXTRA_INIT_TIMER
|
||||
|
||||
#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
|
||||
|
||||
#define RVTEST_CODE_BEGIN \
|
||||
.section .text.init; \
|
||||
.align 6; \
|
||||
.weak stvec_handler; \
|
||||
.weak mtvec_handler; \
|
||||
.globl _start; \
|
||||
_start: \
|
||||
/* reset vector */ \
|
||||
j reset_vector; \
|
||||
.align 2; \
|
||||
trap_vector: \
|
||||
/* test whether the test came from pass/fail */ \
|
||||
csrr t5, mcause; \
|
||||
li t6, CAUSE_USER_ECALL; \
|
||||
beq t5, t6, write_tohost; \
|
||||
li t6, CAUSE_SUPERVISOR_ECALL; \
|
||||
beq t5, t6, write_tohost; \
|
||||
li t6, CAUSE_MACHINE_ECALL; \
|
||||
beq t5, t6, write_tohost; \
|
||||
/* if an mtvec_handler is defined, jump to it */ \
|
||||
la t5, mtvec_handler; \
|
||||
beqz t5, 1f; \
|
||||
jr t5; \
|
||||
/* was it an interrupt or an exception? */ \
|
||||
1: csrr t5, mcause; \
|
||||
bgez t5, handle_exception; \
|
||||
INTERRUPT_HANDLER; \
|
||||
handle_exception: \
|
||||
/* we don't know how to handle whatever the exception was */ \
|
||||
other_exception: \
|
||||
/* some unhandlable exception occurred */ \
|
||||
1: ori TESTNUM, TESTNUM, 1337; \
|
||||
write_tohost: \
|
||||
sw TESTNUM, tohost, t5; \
|
||||
j write_tohost; \
|
||||
reset_vector: \
|
||||
INIT_XREG; \
|
||||
RISCV_MULTICORE_DISABLE; \
|
||||
INIT_SATP; \
|
||||
INIT_PMP; \
|
||||
DELEGATE_NO_TRAPS; \
|
||||
li TESTNUM, 0; \
|
||||
la t0, trap_vector; \
|
||||
csrw mtvec, t0; \
|
||||
CHECK_XLEN; \
|
||||
/* if an stvec_handler is defined, delegate exceptions to it */ \
|
||||
la t0, stvec_handler; \
|
||||
beqz t0, 1f; \
|
||||
csrw stvec, t0; \
|
||||
li t0, (1 << CAUSE_LOAD_PAGE_FAULT) | \
|
||||
(1 << CAUSE_STORE_PAGE_FAULT) | \
|
||||
(1 << CAUSE_FETCH_PAGE_FAULT) | \
|
||||
(1 << CAUSE_MISALIGNED_FETCH) | \
|
||||
(1 << CAUSE_USER_ECALL) | \
|
||||
(1 << CAUSE_BREAKPOINT); \
|
||||
csrw medeleg, t0; \
|
||||
1: csrwi mstatus, 0; \
|
||||
init; \
|
||||
EXTRA_INIT; \
|
||||
EXTRA_INIT_TIMER; \
|
||||
la t0, 1f; \
|
||||
csrw mepc, t0; \
|
||||
csrr a0, mhartid; \
|
||||
mret; \
|
||||
1:
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// End Macro
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#define RVTEST_CODE_END \
|
||||
unimp
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Pass/Fail Macro
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#define RVTEST_PASS \
|
||||
fence; \
|
||||
li TESTNUM, 1; \
|
||||
li a7, 93; \
|
||||
li a0, 0; \
|
||||
ecall
|
||||
|
||||
#define TESTNUM gp
|
||||
#define RVTEST_FAIL \
|
||||
fence; \
|
||||
1: beqz TESTNUM, 1b; \
|
||||
sll TESTNUM, TESTNUM, 1; \
|
||||
or TESTNUM, TESTNUM, 1; \
|
||||
li a7, 93; \
|
||||
addi a0, TESTNUM, 0; \
|
||||
ecall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Data Section Macro
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#define EXTRA_DATA
|
||||
|
||||
#define RVTEST_DATA_BEGIN \
|
||||
EXTRA_DATA \
|
||||
.pushsection .tohost,"aw",@progbits; \
|
||||
.align 6; .global tohost; tohost: .dword 0; \
|
||||
.align 6; .global fromhost; fromhost: .dword 0; \
|
||||
.popsection; \
|
||||
.align 4; .global begin_signature; begin_signature:
|
||||
|
||||
#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
|
||||
|
||||
#endif
|
8
WIP_Challenges
Normal file
@ -0,0 +1,8 @@
|
||||
Vermeld hier challenges waar je momenteel aan bezig bent, tot welke categorie
|
||||
ze behoren, hoe ze moeten opgelost worden en moeilijk je zelf schat dat die
|
||||
challenge zal zijn.
|
||||
|
||||
- Een serie van Scheme challenges, nog niet (helemaal) uitgewerkt (Robin)
|
||||
|
||||
- Een reeks (eenvoudige) webchallenges (Benj)
|
||||
- Een encription challenge zoals die van vorig jaar (Decrypt Me) maar met een nieuwe sleutel (Benj)
|
23
ancient_stone/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
== Title ==
|
||||
|
||||
Ancient Stone
|
||||
|
||||
== Description ==
|
||||
On my way to Munster, during my trip to Ireland, I found some weird markings on a stone laying on the side of the road. Grooves in the stone seemed to try to tell me a message. Half an hour of decoding later, and I did not manage to figure out any meaning. As I was very intrigued by this stone, I made note of the markings on a piece of paper I had brought along. Might you help me decipher the ancient knowledge given by the markings?
|
||||
|
||||
Note: This challenge does not follow the standard flag format, however the flag still starts with "IG".
|
||||
|
||||
== Flag ==
|
||||
IGTOBEORNOTTOBE
|
||||
|
||||
== Files ==
|
||||
Participants should receive the scribbles.png file.
|
||||
|
||||
== Deployment ==
|
||||
/
|
||||
|
||||
== Solution/Writeup ==
|
||||
This markings are an ancient writing system called Ogham.
|
||||
The word "Ogham" was spelled out by the first letter of each sentence of the description. Munster and Ireland were also hints, since the system originated from there.
|
||||
The following image can be used to decode the message.
|
||||
https://en.wikipedia.org/wiki/Ogham#/media/File:All_Ogham_letters_including_Forfeda_-_%C3%9Cbersicht_aller_Ogham-Zeichen_einschlie%C3%9Flich_Forfeda.jpg
|
17
ancient_stone/bliep.md
Normal file
@ -0,0 +1,17 @@
|
||||
== Title ==
|
||||
|
||||
Ancient Stone
|
||||
|
||||
== Description ==
|
||||
On my way to Munster, during my trip to Ireland, I found some weird markings on a stone laying on the side of the road. Grooves in the stone seemed to try to tell me a message. Half an hour of decoding later, and I did not manage to figure out any meaning. As I was very intrigued by this stone, I made note of the markings on a piece of paper I had brought along. Might you help me decipher the ancient knowledge given by the markings?
|
||||
|
||||
Note: This challenge does not follow the standard flag format, however the flag still starts with "IG".
|
||||
|
||||
== Files ==
|
||||
Participants should receive the scribbles.png file.
|
||||
|
||||
== Deployment ==
|
||||
/
|
||||
|
||||
40 punten
|
||||
Gewoon de foto in het bestand decoderen. Zou niet zo moeilijk moeten zijn, description goed lezen.
|
BIN
ancient_stone/scribbles.png
Normal file
After Width: | Height: | Size: 19 KiB |
70
break_the_gate/1.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
require('flags.php');
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
header('Location: 2.php');
|
||||
break;
|
||||
case $flag_2:
|
||||
header('Location: 3.php');
|
||||
break;
|
||||
case $flag_3:
|
||||
header('Location: 4.php');
|
||||
break;
|
||||
case $flag_4:
|
||||
header('Location: 5.php');
|
||||
break;
|
||||
case $flag_5:
|
||||
header('Location: final.php');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Level 1</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="author" content="Benjamin Ver">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||
|
||||
<script type="text/javascript" src="script/jquery.js"></script>
|
||||
<script type="text/javascript" src="script/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="script/main.js"></script>
|
||||
<script type="text/javascript" src="script/1.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="front">
|
||||
<div class="lock intel">
|
||||
<img src="img/lock_locked.jpg">
|
||||
</div>
|
||||
<!-- username: admin, password: admin -->
|
||||
<table class="unlockpad intel">
|
||||
<tr>
|
||||
<td class='formInfo'>Username:</td>
|
||||
<td><input type="text" name="user" id="inp_user"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='formInfo'>Password:</td>
|
||||
<td><input type="password" name="passw" id="inp_passw"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<button id='submit'>Give it a shot...</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="half left"></div>
|
||||
<div class="half right"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
73
break_the_gate/2.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
require('flags.php');
|
||||
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
break;
|
||||
case $flag_2:
|
||||
header('Location: 3.php');
|
||||
break;
|
||||
case $flag_3:
|
||||
header('Location: 4.php');
|
||||
break;
|
||||
case $flag_4:
|
||||
header('Location: 5.php');
|
||||
break;
|
||||
case $flag_5:
|
||||
header('Location: final.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: 1.php');
|
||||
break;
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Level 2</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="author" content="Benjamin Ver">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||
|
||||
<script type="text/javascript" src="script/jquery.js"></script>
|
||||
<script type="text/javascript" src="script/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="script/main.js"></script>
|
||||
<script type="text/javascript"> var userDb = {}; </script>
|
||||
<script type="text/javascript" src="script/2.js"></script>
|
||||
<script type="text/javascript" src="script/ssdb.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="front">
|
||||
<div class="lock intel">
|
||||
<img src="img/lock_locked.jpg">
|
||||
</div>
|
||||
<table class="unlockpad intel">
|
||||
<tr>
|
||||
<td class='formInfo'>Username:</td>
|
||||
<td><input type="text" name="user" id="inp_user"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='formInfo'>Password:</td>
|
||||
<td><input type="password" name="passw" id="inp_passw"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<button id='submit'>Give it a shot...</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="half left"></div>
|
||||
<div class="half right"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
70
break_the_gate/3.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
require('flags.php');
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
header('Location: 2.php');
|
||||
break;
|
||||
case $flag_2:
|
||||
break;
|
||||
case $flag_3:
|
||||
header('Location: 4.php');
|
||||
break;
|
||||
case $flag_4:
|
||||
header('Location: 5.php');
|
||||
break;
|
||||
case $flag_5:
|
||||
header('Location: final.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: 1.php');
|
||||
break;
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Level 3</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="author" content="Benjamin Ver">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||
|
||||
<script type="text/javascript" src="script/jquery.js"></script>
|
||||
<script type="text/javascript" src="script/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="script/main.js"></script>
|
||||
<script type="text/javascript" src="script/1.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="front">
|
||||
<div class="lock intel">
|
||||
<img src="img/lock_locked.jpg">
|
||||
</div>
|
||||
<table class="unlockpad intel">
|
||||
<tr>
|
||||
<td class='formInfo'>Username:</td>
|
||||
<td><input type="text" name="user" id="inp_user"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='formInfo'>Password:</td>
|
||||
<td><input type="password" name="passw" id="inp_passw"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<button id='submit'>Give it a shot...</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="half left"></div>
|
||||
<div class="half right"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
109
break_the_gate/4.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
require('flags.php');
|
||||
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
header('Location: 2.php');
|
||||
break;
|
||||
case $flag_2:
|
||||
header('Location: 3.php');
|
||||
break;
|
||||
case $flag_3:
|
||||
break;
|
||||
case $flag_4:
|
||||
header('Location: 5.php');
|
||||
break;
|
||||
case $flag_5:
|
||||
header('Location: final.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: 1.php');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$fa = 0;
|
||||
if (isset($_GET['try'])) {
|
||||
$fa = intval($_GET['try']);
|
||||
|
||||
}
|
||||
$fa100 = floor($fa / 100);
|
||||
$fa -= 100 * $fa100;
|
||||
$fa10 = floor($fa / 10);
|
||||
$fa -= 10 * $fa10;
|
||||
$fa1 = $fa;
|
||||
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Level 4</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="author" content="Benjamin Ver">
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/pl.css">
|
||||
<?php if (isset($_GET['try']) && $_GET['try'] != 732) { echo "<style> .w {color: red;} </style>"; } ?>
|
||||
|
||||
|
||||
<script type="text/javascript" src="script/jquery.js"></script>
|
||||
<script type="text/javascript" src="script/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="script/main.js"></script>
|
||||
<script type="text/javascript" src="script/pl.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
<?php
|
||||
require('flags.php');
|
||||
if ($_GET['try'] == 732) {
|
||||
echo 'document.cookie = "currentLevel=' . $flag_4 . '"' . ";\n";
|
||||
echo 'goNext();';
|
||||
} elseif (isset($_GET['try'])) {
|
||||
echo 'errorAnimation();';
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
?>
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="front">
|
||||
<div class="lock intel">
|
||||
<img src="img/lock_locked.jpg">
|
||||
</div>
|
||||
<table class="unlockpad intel">
|
||||
<tr>
|
||||
<td><div class='triangle up' id='100up'></div></td>
|
||||
<td><div class='triangle up' id='10up'></div></td>
|
||||
<td><div class='triangle up' id='1up'></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='digit w' id='num100'><?php echo $fa100; ?></td>
|
||||
<td class='digit w' id='num10'><?php echo $fa10; ?></td>
|
||||
<td class='digit w' id='num1'><?php echo $fa1; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class='triangle down' id='100down'></div></td>
|
||||
<td><div class='triangle down' id='10down'></div></td>
|
||||
<td><div class='triangle down' id='1down'></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="half left"></div>
|
||||
<div class="half right"></div>
|
||||
|
||||
<form action='4.php' method='GET'>
|
||||
<input type='hidden' name='try' id='try'>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
70
break_the_gate/5.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
require('flags.php');
|
||||
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
header('Location: 2.php');
|
||||
break;
|
||||
case $flag_2:
|
||||
header('Location: 3.php');
|
||||
break;
|
||||
case $flag_3:
|
||||
header('Location: 4.php');
|
||||
break;
|
||||
case $flag_4:
|
||||
break;
|
||||
case $flag_5:
|
||||
header('Location: final.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: 1.php');
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Level 5</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="author" content="Benjamin Ver">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/normalize.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||
|
||||
<script type="text/javascript" src="script/jquery.js"></script>
|
||||
<script type="text/javascript" src="script/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="script/main.js"></script>
|
||||
<script type="text/javascript" src="script/1.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="front">
|
||||
<div class="lock intel">
|
||||
<img src="img/lock_locked.jpg">
|
||||
</div>
|
||||
<table class="unlockpad intel">
|
||||
<tr>
|
||||
<td class='formInfo'>Username:</td>
|
||||
<td><input type="text" name="user" id="inp_user"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='formInfo'>Password:</td>
|
||||
<td><input type="password" name="passw" id="inp_passw"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<button id='submit'>Give it a shot...</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="half left"></div>
|
||||
<div class="half right"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
25
break_the_gate/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Break The Gate (1-5)
|
||||
|
||||
## Description
|
||||
Different for each challenge
|
||||
|
||||
## Deployment
|
||||
Place on server, write-protect `secret-database.db`
|
||||
|
||||
## Difficulty
|
||||
*Easy*
|
||||
|
||||
## Solution
|
||||
Per challenge, after a succesful login a cookie with the flag will apear.
|
||||
1. Login details are as comment in the html
|
||||
2. Login details are in a JavaScript dictionary calles `userDb`. In console you can print this variable, or you can open `script/ssdb.js`.
|
||||
3. An sql-injection will get you in. Example: `" OR 1=1;` as password
|
||||
4. As there are only 1000 possible combination, brute-force should go pretty fast. You can write a simple Pythin-program that sends request to [challenge-url]/4.php?try=[0->999] and compare results. (Correct code was 732)
|
||||
5. The login details were send over http, meaning they were in plain text in the pcap file (open the pcap file and check the last packet)
|
||||
|
||||
## Flag
|
||||
* IGCTF{ThatWasNotSoHard}
|
||||
* IGCTF{StopHackingMySitePrettyPlease}
|
||||
* IGCTF{AllHailOurLordAndSaviourPHP}
|
||||
* IGCTF{I_may_have_made_this_challenge_last_night}
|
||||
* IGCTF{KgonnaGoToSleepnow_Bye}
|
97
break_the_gate/authenticateLevel.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
require('flags.php');
|
||||
|
||||
function authCred($u, $p) {
|
||||
if (isset($_POST['user']) && isset($_POST['passw'])) {
|
||||
if ($_POST['user'] === $u && $_POST['passw'] === $p) {
|
||||
return True;
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkInj() {
|
||||
if (isset($_POST['user']) && isset($_POST['passw'])) {
|
||||
if ($_POST['passw'][0] == '"' || $_POST['passw'][0] == "'") {
|
||||
return True;
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkInDatabase($query) {
|
||||
$handle = new SQLite3('secretDataBase.db');
|
||||
$array['dbhandle'] = $handle;
|
||||
$array['query'] = $query;
|
||||
$result = $handle->query($query);
|
||||
$i = 0;
|
||||
while ($result->columnName($i)) {
|
||||
$columns[ ] = $result->columnName($i);
|
||||
$i++;
|
||||
}
|
||||
$resx = $result->fetchArray(SQLITE3_ASSOC);
|
||||
return $resx;
|
||||
}
|
||||
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
if (isset($_POST['thisUser'])) {
|
||||
echo $flag_2;
|
||||
} else {
|
||||
echo '0';
|
||||
}
|
||||
break;
|
||||
case $flag_2:
|
||||
$badQuery = 'SELECT * FROM users WHERE username = "' . $_POST['user'] . '" and password = "' . $_POST['passw'] . '";';
|
||||
if (strpos(strtoupper($_POST['passw']), 'UPDATE')) {
|
||||
$_POST['passw'] = '';
|
||||
}
|
||||
if (strpos(strtoupper($_POST['passw']), 'DELETE')) {
|
||||
$_POST['passw'] = '';
|
||||
}
|
||||
if (strpos(strtoupper($_POST['passw']), 'DROP')) {
|
||||
$_POST['passw'] = '';
|
||||
}
|
||||
if (strpos(strtoupper($_POST['user']), 'UPDATE')) {
|
||||
$_POST['user'] = '';
|
||||
}
|
||||
if (strpos(strtoupper($_POST['user']), 'DELETE')) {
|
||||
$_POST['user'] = '';
|
||||
}
|
||||
if (strpos(strtoupper($_POST['user']), 'DROP')) {
|
||||
$_POST['user'] = '';
|
||||
}
|
||||
if (checkInDatabase($badQuery)) {
|
||||
echo $flag_3;
|
||||
} else {
|
||||
echo '0';
|
||||
}
|
||||
break;
|
||||
case $flag_3:
|
||||
break;
|
||||
case $flag_4:
|
||||
if (authCred('LarsIX', 'FXrm264!&Rdjka')) {
|
||||
echo $flag_5;
|
||||
} else {
|
||||
echo '0';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (authCred('admin', 'admin')) {
|
||||
echo $flag_1;
|
||||
} else {
|
||||
echo '0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
1312
break_the_gate/css/jquery-ui.css
vendored
Normal file
74
break_the_gate/css/main.css
Normal file
@ -0,0 +1,74 @@
|
||||
/* I really, really hate CSS... */
|
||||
/* So don't bother finding flags here */
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
font-family: sans-serif;
|
||||
font-size: 2vw;
|
||||
}
|
||||
|
||||
.half {
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
background-image: url("../img/barrier.jpg");
|
||||
background-size: 25vw;
|
||||
background-repeat: repeat;
|
||||
background-color: grey;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.front {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.intel {
|
||||
border: 2px solid black;
|
||||
background-color: #4D4A4E;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.lock {
|
||||
top: 30%;
|
||||
left: 50%;
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
width: 10vw;
|
||||
height: 10vw;
|
||||
-moz-border-radius: 5vw;
|
||||
-webkit-border-radius: 5vw;
|
||||
border-radius: 5vw;
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.lock img {
|
||||
height: 62%;
|
||||
}
|
||||
|
||||
.unlockpad {
|
||||
background-color: white;
|
||||
top: 65%;
|
||||
left: 50%;
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
/* width: 25vw;
|
||||
height: 15vh;*/
|
||||
padding: 5vh 3vw;
|
||||
z-index: 4;
|
||||
text-align: center;
|
||||
}
|
||||
.formInfo { padding-right: 2vw; }
|
||||
#submit {
|
||||
font-size: 1.5vw;
|
||||
}
|
349
break_the_gate/css/normalize.css
vendored
Normal file
@ -0,0 +1,349 @@
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the `main` element consistently in IE.
|
||||
*/
|
||||
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background on active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57-
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers.
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the padding in Firefox.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE 10+.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10.
|
||||
* 2. Remove the padding in IE 10.
|
||||
*/
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||
*/
|
||||
|
||||
details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Misc
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10+.
|
||||
*/
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
64
break_the_gate/css/pl.css
Normal file
@ -0,0 +1,64 @@
|
||||
html {
|
||||
font-family: roboto;
|
||||
}
|
||||
|
||||
.unlockpad {
|
||||
padding: 2.5vh 3vw;
|
||||
}
|
||||
table {
|
||||
margin: 1vh, 1vw;
|
||||
}
|
||||
|
||||
.full {
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 5px 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
tr td img {
|
||||
margin-top: 20px;
|
||||
width: 5%;
|
||||
}
|
||||
|
||||
.lock:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.triangle {
|
||||
margin: auto;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 25px solid transparent;
|
||||
border-right: 25px solid transparent;
|
||||
|
||||
}
|
||||
.triangle:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.up { border-bottom: 50px solid #555; }
|
||||
.down { border-top: 50px solid #555; }
|
||||
|
||||
.digit {
|
||||
text-align: center;
|
||||
font-size: 5vw;
|
||||
/*border: 1px solid black;*/
|
||||
}
|
||||
|
||||
#solution, #nosolution {
|
||||
margin: auto;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-size: 5vw;
|
||||
font-weight: bold;
|
||||
}
|
||||
#nosolution img {
|
||||
margin-top: 5vw;
|
||||
width: 20%;
|
||||
}
|
72
break_the_gate/final.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
require('flags.php');
|
||||
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
header('Location: 2.php');
|
||||
break;
|
||||
case $flag_2:
|
||||
header('Location: 3.php');
|
||||
break;
|
||||
case $flag_3:
|
||||
header('Location: 4.php');
|
||||
break;
|
||||
case $flag_4:
|
||||
header('Location: 5.php');
|
||||
break;
|
||||
case $flag_5:
|
||||
break;
|
||||
default:
|
||||
header('Location: 1.php');
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>All done</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="author" content="Benjamin Ver">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/normalize.css">
|
||||
|
||||
<script type="text/javascript" src="script/jquery.js"></script>
|
||||
<script type="text/javascript" src="script/jquery-ui.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('div').hide("fade", 2000)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: black;
|
||||
background-image: url("img/thatsall.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
}
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
body div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<!-- No challenges here anymore -->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
9
break_the_gate/flags.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$flag_1 = "IGCTF{ThatWasNotSoHard}";
|
||||
$flag_2 = "IGCTF{StopHackingMySitePrettyPlease}";
|
||||
$flag_3 = "IGCTF{AllHailOurLordAndSaviourPHP}";
|
||||
$flag_4 = "IGCTF{I_may_have_made_this_challenge_last_night}";
|
||||
$flag_5 = "IGCTF{KgonnaGoToSleepnow_Bye}";
|
||||
|
||||
?>
|
BIN
break_the_gate/img/barrier.jpg
Normal file
After Width: | Height: | Size: 542 KiB |
BIN
break_the_gate/img/lock_locked.jpg
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
break_the_gate/img/lock_unlock.gif
Normal file
After Width: | Height: | Size: 335 KiB |
BIN
break_the_gate/img/lock_unlocked.gif
Normal file
After Width: | Height: | Size: 160 KiB |
BIN
break_the_gate/img/thatsall.gif
Normal file
After Width: | Height: | Size: 2.5 MiB |
BIN
break_the_gate/img/unlock.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
33
break_the_gate/index.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
require('flags.php');
|
||||
|
||||
if(!isset($_COOKIE['currentLevel'])) {
|
||||
setcookie("currentLevel", "Flags_will_appear_here_when_you_complete_a_level...", time()+24*60*60);
|
||||
}
|
||||
switch ($_COOKIE['currentLevel']) {
|
||||
case $flag_1:
|
||||
header('Location: 2.php');
|
||||
break;
|
||||
case $flag_2:
|
||||
header('Location: 3.php');
|
||||
break;
|
||||
case $flag_3:
|
||||
header('Location: 4.php');
|
||||
break;
|
||||
case $flag_4:
|
||||
header('Location: 5.php');
|
||||
break;
|
||||
case $flag_5:
|
||||
header('Location: final.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: 1.php');
|
||||
break;
|
||||
}
|
||||
|
||||
exit()
|
||||
|
||||
|
||||
|
||||
?>
|
15
break_the_gate/script/1.js
Normal file
@ -0,0 +1,15 @@
|
||||
function auth1() {
|
||||
var inp = { user: $('#inp_user').val(), passw: $('#inp_passw').val() }
|
||||
sendAuth(inp, goNext, errorAnimation)
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#submit').click(function(){
|
||||
auth1();
|
||||
})
|
||||
$(document).on('keypress',function(e) {
|
||||
if(e.which == 13) {
|
||||
auth1();
|
||||
}
|
||||
});
|
||||
})
|
19
break_the_gate/script/2.js
Normal file
@ -0,0 +1,19 @@
|
||||
function authenticate() {
|
||||
if (userDb[$('#inp_user').val()] == $('#inp_passw').val()) {
|
||||
sendAuth({thisUser: userDb[$('#inp_user').val()]}, goNext, errorAnimation);
|
||||
} else {
|
||||
errorAnimation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#submit').click(function(){
|
||||
authenticate();
|
||||
})
|
||||
$(document).on('keypress',function(e) {
|
||||
if(e.which == 13) {
|
||||
authenticate();
|
||||
}
|
||||
});
|
||||
})
|
18706
break_the_gate/script/jquery-ui.js
vendored
Normal file
2
break_the_gate/script/jquery.js
vendored
Normal file
35
break_the_gate/script/main.js
Normal file
@ -0,0 +1,35 @@
|
||||
function openAnimation() {
|
||||
$('.lock img').attr('src', 'img/lock_unlocked.gif')
|
||||
$('.front').delay(1000).fadeOut('slow')
|
||||
$('.left').delay(1300).hide("slide", {direction: "left" }, 1000)
|
||||
$('.right').delay(1300).hide("slide", {direction: "right" }, 1000)
|
||||
}
|
||||
|
||||
function errorAnimation() {
|
||||
$('body').css('background-color', 'red');
|
||||
for (var i = 0; i <= 3; i++) {
|
||||
$('.half').delay(500).hide(1)
|
||||
$('.half').delay(500).show(1)
|
||||
}
|
||||
}
|
||||
|
||||
function goNext() {
|
||||
$('body').css('background-color', 'black');
|
||||
openAnimation();
|
||||
setTimeout(function(){ window.location = "index.php"; }, 2900);
|
||||
}
|
||||
|
||||
function sendAuth(thisData, ok, nok) {
|
||||
$.ajax('authenticateLevel.php', {
|
||||
type: 'POST',
|
||||
data: thisData,
|
||||
success: function (data) {
|
||||
if (data.substr(0, 6) == 'IGCTF{') {
|
||||
document.cookie = "currentLevel=" + data;
|
||||
ok()
|
||||
} else {
|
||||
nok()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
44
break_the_gate/script/pl.js
Normal file
@ -0,0 +1,44 @@
|
||||
var cn = true;
|
||||
|
||||
function resetColor() {
|
||||
cn = false;
|
||||
$('.digit').removeClass('w');
|
||||
}
|
||||
|
||||
function setUp(numId) {
|
||||
if (cn) { resetColor(); }
|
||||
numId.html((parseInt(numId.html()) + 1) % 10);
|
||||
}
|
||||
|
||||
function setDown(numId) {
|
||||
if (cn) { resetColor(); }
|
||||
if (numId.html() == "0") {
|
||||
numId.html(9)
|
||||
} else {
|
||||
numId.html(parseInt(numId.html()) - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function send() {
|
||||
var tryVal = parseInt($('#num1').html())
|
||||
tryVal += 10 * parseInt($('#num10').html())
|
||||
tryVal += 100 * parseInt($('#num100').html())
|
||||
$('#try').val(tryVal);
|
||||
$('form').submit()
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$("#1000up").click(function(){ setUp($('#num1000')); })
|
||||
$("#100up").click(function(){ setUp($('#num100')); })
|
||||
$("#10up").click(function(){ setUp($('#num10')); })
|
||||
$("#1up").click(function(){ setUp($('#num1')); })
|
||||
$("#1000down").click(function(){ setDown($('#num1000')); })
|
||||
$("#100down").click(function(){ setDown($('#num100')); })
|
||||
$("#10down").click(function(){ setDown($('#num10')); })
|
||||
$("#1down").click(function(){ setDown($('#num1')); })
|
||||
|
||||
$('img').click(function(){
|
||||
send();
|
||||
});
|
||||
})
|
6
break_the_gate/script/ssdb.js
Normal file
@ -0,0 +1,6 @@
|
||||
userDb['peter'] = 'roadHouse';
|
||||
userDb['lois'] = 'lois123';
|
||||
userDb['brian'] = 'd0gbackwards';
|
||||
userDb['chirs'] = 'password';
|
||||
userDb['meg'] = 'megatron';
|
||||
userDb['stewie'] = '<3RUPERT';
|
BIN
break_the_gate/secretDataBase.db
Normal file
38
deployment/configuration.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{ ... }: {
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
|
||||
];
|
||||
|
||||
boot.cleanTmpDir = true;
|
||||
networking.hostName = "igctf-test3";
|
||||
networking.firewall.allowPing = true;
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"#"
|
||||
"# WARNING: Automatically generated file"
|
||||
"# This file will be erased at every boot"
|
||||
"# This file was generated with '/usr/sbin/scw-fetch-ssh-keys'"
|
||||
"#"
|
||||
"# To add a new key, you can:"
|
||||
"# -- Add keys on your Scaleway account https://cloud.scaleway.com/#/credentials"
|
||||
"# -- Add keys using server tags - https://cloud.scaleway.com/#/servers/ce59daa2-b92d-4c9b-a595-f904099d4d6b"
|
||||
"ssh-rsa_XXXXXXXXXXX AUTHORIZED_KEY=ssh-rsa_YYYYYYYYYYYYYYY""
|
||||
"# - Be sure to replace all spaces with underscores"
|
||||
"# - $> sed 's/ /_/g' ~/.ssh/id_rsa.pub"
|
||||
"# -- Add the keys to '/root/.ssh/instance_keys' which will be imported"
|
||||
"#"
|
||||
"# And recreate your 'authorized_keys' file with the new keys:"
|
||||
"ssh-keys --upgrade'"
|
||||
"#"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+55wyXDs3Bmb1SZajBs9Uhazw/XWSu91iYSQo4dyDd5CLqfAaLrRKIc5SbdAucCWO0/atorjxAocdxey+O/mY8kLM1DnooPL75ckEWgu3s+v2pAtZYXIN8mDzOOB+pWW2caWWg0BZXL5KITWyKbXK9EnoDYisT/uevoKSMBPYodyrIaKZ7fT099VOZHzYiowcS8h0/ereLtr6PjjTZdkaqDKcVw+MJceSc9+g2kW1CGCHkf08zeYUteoYuf8vH/o1YNTnCNu/RROxfvVTGHrgM1ERg6bm0Eeu28yrj2HF7K1rg4CKLapsDMqCd1+dnCvaX9TVpRWNi3J8UInBOTPr bram@localhost.localdomain"
|
||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBH7DEXBvwCshz+Ga3oxZhjwqJl3wjJgq7dJCDkUrbIQhw7qH7uHPmGuCRezcvr4OWUavXXklsVypmDB4L7715MaW1BasGXp3soP+ip9Jp6Rca6S3oYfDNYqp9E4wSXE46g== JuiceSSH"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfAjwk4jY0BXRSrGIeyuOzmKPQjjHPnwGLKdcJK/c473oKHNwBbie2Wr0HuIjlGIUvob/QZq8L8vGQwkb4TUJfVWWP2rvwYOg5OsVkjoOmDThBykfJ/9la/rVFNlBKBCXAGmB106oDK2+7RTsB+DDC4Eb01GkTPfLh7fvv1d1MGLYO86z1gC1bDSqw1nWrZRMVf8fzOzM5807SThTa7LoHP/CmvGkUfL6dv661VnldQgqNj+2ULKt1GgMP7c0Csi8F48yBcQAiCZpz3J+oILDNoEp/ZN6EtwB7PxcBKWRgO4pCfc9hjtKWCIz+aC8dxyHDXWmycYGLnI9Eo2kX8jsB JuiceSSH"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDqzW3TxIL28oUZ3EZXIPsGdB5SOlBrIVvS2NSJUaSNhInR2dUw3/W8nRsm92j5pqJaA1q0N1GOo1wTHd9n8OcDlU/hK7Iih7OPEWkfHYDGYkHs0DxUcgWdC4xJJg2S89rb1Wtr9ygpeAU+pgu0NWJTUFOqZeiagpECanEt1XJ+psChYbeHF61J6S5+LVGiUhoctLHjR1Hi1u8caAlNgtDYmYifCcpebJfCkzLsvFPMZCC1uzg6djGsaP9vkAEQ7VCnrNR6VYJFZTffIHcGfa4GHTzZzbigeyK5fa5f+YwX0/8XmpJsf6z4xHanekORAElYAfrn5N95o3czrETwvPnf bram@bramvaoi"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEDuKmIktfHOlI9poqfStDPL02Ilu8QXCLe1nrEfyXa7lG8VkrCx8B86IBbYC+CD3MHdQ5IH2GaG5sRY63VnxlIjM0tE8PVxxguBoh3tHrkssJ68SZerU2Aqxk9DAyu8e9h4jYk131LwbDiAIb+1U4DIc9aF4mPmNjvAFa7pkrYu6NAVB6Pme5AL1/qYj2D9h0HjwcVr4Tjvshk9dlBkt4yXMO8jUp6uou6WoCCKqVZstBJMc7e2NKAp1vbh7KENGeFZNooi65P7UdGGRYdbgeQPTKp/8aS5txvIV7X33FBHxs2o9xqFPqyoGDiCO9ZaoAqlEi3DqMUy5OJCItC3Q/ bramvandenbogaerde@bramweb-retina.local"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDH6rScSr37gXv/dVxDRn54sNiq2dV0c9m6u1Ks2ZJFtz6/Kwn7rRq+3OSiccT46sllSZ01Jf7MjigQ/Er3QgJxxyQ6dDEJs8IUTz9Js3NHKdSh6/w3ROIjy71oYmN5/7WJRjOfGtXcVAnTd5qOGh5zlMtyKCkVQqtGtVcwptPi4a+lwPXy8M8ov8K2oics3EDjqei7yJZ8dzho4vHj5mg7Yd5z4d9EUU1Hi+MPLmf1loJD2l+dNhC3EpKZ1wsb5gsxFKqLPBaySMWhyK55Eeo4WEYHZIlKETRkW2sLx9SLIZ2L/e2qYJHU3Qm8hBvx9ccekggdVTos9uuxqoddZI9j bram@debianserv"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC9Lgo2qydGu5zThFX7xv3dav2kN7TuiNoAqPUa5anvy29dSBPOlj94aE2Snw7tnNh9l7SGD/0iyDLXaRqYxzsbUOqPh3nG/w+NI5kH7RvR2nCDvKjdna6FALgctqWNsuDZ4nbdWEsLdiVKTMartiVUoTwmejko7H0yPf7VjX723pIEXtXMqjJT/e1lbJDvlRgP/QBoZtbmb3UvF7H4JtQFOXRais751HGbVUu1vhmqYF3TaUNOwMrwzKeTFBDOHw6FCb8R5SE+S2OPrfDVLywMEIhQhVfpSXMZt5Nm1nDDpJPm1z34+x6MaORIB4/9wi/YqWnru+XDefSfb8h2dC4QZzXyAxGqJ/cPtkseNH0vg7MytvajEMwf8v2tCguYy3xDKl7Rfyp9lXVXYxmPoEn+Fjj9tJ2t6Tm0qgarCAF726oXghHlY+2qh7S0/93LNymbSUTiegpX5Lp0h5emgDb/xe20htfI9RWh9zFqV2zD3K5icoaaOscAKf7Ctgm/Ff8= nibor@Rylia"
|
||||
"# Below your custom ssh keys from '/root/.ssh/instance_keys'"
|
||||
];
|
||||
}
|
61
deployment/containers.nix
Normal file
@ -0,0 +1,61 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
run = ({name, image, ports, environment ? {}, ... }@attrs:
|
||||
let rest = builtins.removeAttrs attrs [ "name" "image" "ports" "environment" ]; in
|
||||
{
|
||||
image = name;
|
||||
inherit ports;
|
||||
imageFile = image;
|
||||
inherit environment;
|
||||
autoStart = true;
|
||||
} // rest) ; in
|
||||
{
|
||||
options = {};
|
||||
config = {
|
||||
networking.firewall.allowedTCPPorts = [ 5000 8080 8081 9001 9002 9003 ];
|
||||
virtualisation.oci-containers.containers = {
|
||||
"schemingschemer1" = run {
|
||||
name = "ss/1";
|
||||
image = import ../scheming-schemer/first/nix/image.nix {};
|
||||
ports = [ "9001:20000" ];
|
||||
};
|
||||
"schemingschemer2" = run {
|
||||
name = "ss/2";
|
||||
image = import ../scheming-schemer/second/nix/image.nix {};
|
||||
ports = [ "9002:20000" ];
|
||||
};
|
||||
"schemingschemer3" = run {
|
||||
name = "ss/3";
|
||||
image = import ../scheming-schemer/third/nix/image.nix {};
|
||||
ports = [ "9003:20000" ];
|
||||
};
|
||||
"fancy-text" = run {
|
||||
name = "fancy-text";
|
||||
image = import ../fancy_text/image.nix {};
|
||||
ports = [ "9004:20000" ];
|
||||
};
|
||||
"gottacatchthemallfront" = run {
|
||||
name = "frontend-gotta-catch-them-all";
|
||||
image = import ../gotta_catch_em_all/nix/frontend.nix {};
|
||||
ports = [ "8080:80" ];
|
||||
};
|
||||
"gottacatchthemallback" = run {
|
||||
name = "gotta-catch-them-all-backend";
|
||||
image = import ../gotta_catch_em_all/nix/backend.nix {};
|
||||
ports = [ "5000:5000" ];
|
||||
};
|
||||
"lost-keys" = run {
|
||||
name = "lost-keys";
|
||||
image = import ../lost-keys/image.nix {};
|
||||
ports = [ "2222:2222" ];
|
||||
};
|
||||
"ruby-challenge" = run {
|
||||
name = "ruby-challenge";
|
||||
image = import ../ruby_challenge/image.nix {};
|
||||
ports = [ "8081:3000" ];
|
||||
user = "joske:joske";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
6
deployment/hardware-configuration.nix
Normal file
@ -0,0 +1,6 @@
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||
boot.loader.grub.device = "/dev/vda";
|
||||
fileSystems."/" = { device = "/dev/vda1"; fsType = "ext4"; };
|
||||
}
|
12
deployment/hosts.nix
Normal file
@ -0,0 +1,12 @@
|
||||
let pkgs = import <nixpkgs> {}; in
|
||||
{
|
||||
"igctf-test3" = { config, pkgs, ... }: {
|
||||
deployment.targetHost = "51.15.125.82";
|
||||
deployment.targetUser = "root";
|
||||
|
||||
imports = [
|
||||
./configuration.nix
|
||||
./containers.nix
|
||||
];
|
||||
};
|
||||
}
|
3
deployment/nix-infect-init.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
#cloud-config
|
||||
runcmd:
|
||||
- curl https://raw.githubusercontent.com/elitak/nixos-infect/master/nixos-infect | NIX_CHANNEL=nixos-20.09 bash 2>&1 | tee /tmp/infect.log
|
10
deployment/setup.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Provisioning instance"
|
||||
|
||||
SERVER_ID=$(scw create --commercial-type=STARDUST1-S --name=igctf-test3 449bdf2d)
|
||||
|
||||
scw _userdata $SERVER_ID cloud-init=@$PWD/nix-infect-init.yaml
|
||||
scw start $SERVER_ID
|
||||
|
||||
IP=$(scw inspect $SERVER_ID -f '.server.public_ip.address')
|
5
deployment/shell.nix
Normal file
@ -0,0 +1,5 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs ; [ scaleway-cli morph ];
|
||||
}
|
7
deployment/utils.nix
Normal file
@ -0,0 +1,7 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
{
|
||||
copy = (source: destination:
|
||||
pkgs.writeTextDir destination (builtins.readFile source)
|
||||
);
|
||||
}
|
0
fancy_text/.gitkeep
Normal file
18
fancy_text/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Fancy Text
|
||||
|
||||
## Description
|
||||
Found some fancy text, but my dumb computer can't read it... Can yours?
|
||||
|
||||
|
||||
## Deployment
|
||||
Netcat challenge
|
||||
|
||||
## Difficulty
|
||||
*Easy*
|
||||
|
||||
## Solution
|
||||
As you can try a string yourself, you can pass all printable characters and build a dictionary for them. Then you can decode any string with this dictionary.
|
||||
A solution for the programming part of the challenge is provided in `solution.py`. You can use the python libraries `requests` and `nclib` or `pwntools` to communicate with the server.
|
||||
|
||||
## Flag
|
||||
IGCTF{You_should_really_consider_buying_AMC_stocks.<3}
|
3
fancy_text/docker-entrypoint.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
python3 /home/ig/serverside.py
|
60
fancy_text/generic.nix
Normal file
@ -0,0 +1,60 @@
|
||||
{ pkgs ? import <nixpkgs> {}, ... }:
|
||||
|
||||
with (import ../deployment/utils.nix {});
|
||||
calculator-app: docker-entrypoint: name:
|
||||
let
|
||||
protocols = pkgs.writeTextDir "etc/protocols" ''
|
||||
tcp 6 TCP # Transmission Control
|
||||
'';
|
||||
config = pkgs.writeTextDir "etc/xinetd.conf"
|
||||
''
|
||||
service ctf
|
||||
{
|
||||
disable = no
|
||||
socket_type = stream
|
||||
protocol = tcp
|
||||
wait = no
|
||||
user = ig
|
||||
type = UNLISTED
|
||||
port = 20000
|
||||
bind = 0.0.0.0
|
||||
server = /home/ig/docker-entrypoint.sh
|
||||
# banner_fail = /etc/banner_fail
|
||||
# safety options
|
||||
# the maximum instances of this service per source IP address
|
||||
per_source = 10
|
||||
# the maximum number of CPU seconds that the service may use
|
||||
rlimit_cpu = 20
|
||||
# the Address Space resource limit for the service
|
||||
rlimit_as = 512M
|
||||
# kafel_rule = /etc/pwn.kafel
|
||||
}
|
||||
'';
|
||||
add_files = [
|
||||
(copy docker-entrypoint "home/ig/docker-entrypoint.sh")
|
||||
(copy calculator-app "home/ig/serverside.py")
|
||||
];
|
||||
image = pkgs.dockerTools.buildImage {
|
||||
name = name ;
|
||||
tag = "latest";
|
||||
|
||||
runAsRoot = ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
${pkgs.dockerTools.shadowSetup}
|
||||
useradd -U -m ig && mkdir -p /home/ig
|
||||
chown -R ig:ig /home/ig
|
||||
mkdir -p /usr/local/bin
|
||||
chmod -R -w /home/ig
|
||||
chmod +x /home/ig/docker-entrypoint.sh
|
||||
'';
|
||||
|
||||
contents = [ pkgs.xinetd pkgs.bash pkgs.python38Packages.pip pkgs.python3 config protocols ] ++ add_files;
|
||||
config = {
|
||||
ExposedPorts = {
|
||||
"20000/tcp" = {};
|
||||
};
|
||||
|
||||
Cmd = [ ./run.sh ];
|
||||
};
|
||||
}; in image
|
||||
|
4
fancy_text/image.nix
Normal file
@ -0,0 +1,4 @@
|
||||
{ pkgs ? import <nixpkgs> {}, ... }:
|
||||
|
||||
let build = import ./generic.nix ;
|
||||
in build {} ./serverside.py ./docker-entrypoint.sh "fancy-text"
|
4
fancy_text/run.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
pip install art
|
||||
xinetd -dontfork -stayalive
|
55
fancy_text/serverside.py
Normal file
@ -0,0 +1,55 @@
|
||||
from art import text2art
|
||||
from time import sleep
|
||||
from random import randint
|
||||
from datetime import datetime
|
||||
|
||||
FLAG = 'IGCTF{You_should_really_consider_buying_AMC_stocks.<3}'
|
||||
|
||||
|
||||
print(text2art('Welcome!'))
|
||||
|
||||
|
||||
def example():
|
||||
exString = input('Provide a string: ')
|
||||
exString = " ".join(exString[i:i+1] for i in range(0, len(exString), 1))
|
||||
print(text2art(exString))
|
||||
|
||||
|
||||
def forReal():
|
||||
solution = ''
|
||||
for i in range(0, randint(7,9)):
|
||||
solution += chr(randint(33,125))
|
||||
startTime = datetime.now()
|
||||
print(text2art(" ".join(solution[i:i+1] for i in range(0, len(solution), 1))))
|
||||
tried = input('What does it say? ')
|
||||
totaltime = (datetime.now() - startTime).seconds
|
||||
if (totaltime > 2):
|
||||
print("Too late!")
|
||||
elif (tried == solution):
|
||||
print("Congratulations!")
|
||||
print(FLAG)
|
||||
return True
|
||||
else:
|
||||
print("Wrong! (correct: " + solution + ")")
|
||||
|
||||
|
||||
while(True):
|
||||
print()
|
||||
print(" -- MENU --")
|
||||
print("1. Give an example")
|
||||
print("2. Try yourself")
|
||||
print("3. Close connection")
|
||||
choice = input('Choose a number: ')
|
||||
|
||||
if (choice == '1'):
|
||||
example()
|
||||
elif(choice == '2'):
|
||||
if forReal():
|
||||
break
|
||||
elif(choice == '3'):
|
||||
break
|
||||
else:
|
||||
print(choice, "not recognized...")
|
||||
|
||||
print()
|
||||
print("Bye!")
|
31
fancy_text/skeleton.rkt
Normal file
@ -0,0 +1,31 @@
|
||||
#lang racket
|
||||
|
||||
; You can use this skeleton to connect to the server
|
||||
; but feel free to use any programming language to your
|
||||
; liking
|
||||
|
||||
|
||||
; connect to the server
|
||||
(define-values (in out) (tcp-connect "51.15.125.82" 9004))
|
||||
(file-stream-buffer-mode in 'none)
|
||||
(file-stream-buffer-mode out 'none)
|
||||
|
||||
; Some commands you can use
|
||||
|
||||
; Read a line
|
||||
(read-line in)
|
||||
|
||||
; Read a single character
|
||||
(read-char in)
|
||||
|
||||
; Read 5 characters
|
||||
(read-string 5 in)
|
||||
|
||||
; Write a string to the server
|
||||
(write-char #\a out)
|
||||
|
||||
; Write a string to the server
|
||||
(write-string "AMC to the moon" out)
|
||||
|
||||
; Write a newline to the server
|
||||
(newline out)
|
64
fancy_text/solution.py
Normal file
@ -0,0 +1,64 @@
|
||||
#
|
||||
# SOLUTION: Fancy Letters
|
||||
# by Benjamin Vermunicht
|
||||
#
|
||||
# Approach:
|
||||
# We'll first try to build a dictionary mapping each letter
|
||||
# in ascii-art to the real letter. Than we'll request a string
|
||||
# and translate it with our dictionary.
|
||||
#
|
||||
|
||||
|
||||
|
||||
# A dictionary with how each character looks
|
||||
translation = {}
|
||||
|
||||
|
||||
# Function to split a ascii-art string in ascii-art letters
|
||||
# returns a list of srings, each string representing a letter
|
||||
def readCharacters(asciiString):
|
||||
characters = []
|
||||
# splits each line of the ascii-art, lines will be
|
||||
# iterated synchronously
|
||||
asciiLines = asciiString.split('\n')[:-1]
|
||||
thisChar = [''] * len(asciiLines)
|
||||
for i in range(0, len(asciiLines[0])):
|
||||
space = True
|
||||
for j in range(0, len(asciiLines)):
|
||||
# if all lines contain a space on the same index,
|
||||
# we detect a new letter
|
||||
if (asciiLines[j][i] != ' '):
|
||||
space = False
|
||||
thisChar[j] += asciiLines[j][i]
|
||||
if space:
|
||||
# if we detect a new letter, save the previou letter
|
||||
# to our output
|
||||
for j in range(0, len(asciiLines)):
|
||||
thisChar[j] = thisChar[j][:-1]
|
||||
# merge the characters of this character of each line
|
||||
# to one string with newlines
|
||||
characters.append('\n'.join(thisChar))
|
||||
thisChar = [''] * len(asciiLines)
|
||||
# save the last letter to the output
|
||||
characters.append('\n'.join(thisChar))
|
||||
return characters
|
||||
|
||||
|
||||
|
||||
# Iterates all characters of a known string to build
|
||||
# a dictionary
|
||||
def buildDictionary(asciiString, knownString):
|
||||
i = 0
|
||||
for c in readCharacters(asciiString):
|
||||
translation[c] = knownString[i]
|
||||
i += 1
|
||||
|
||||
|
||||
|
||||
# Translates an ascii-art string to regular text
|
||||
# using the dictionary created with buildDictionary()
|
||||
def translateString(asciiString):
|
||||
resultString = ''
|
||||
for c in readCharacters(asciiString):
|
||||
resultString += translation[c]
|
||||
return resultString
|
5
gotta_catch_em_all/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
1
gotta_catch_em_all/.idea/.name
Normal file
@ -0,0 +1 @@
|
||||
gotta_catch_em_all
|
12
gotta_catch_em_all/.idea/gotta_catch_em_all.iml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$/../gotta_catch_em_all">
|
||||
<excludeFolder url="file://$MODULE_DIR$/../gotta_catch_em_all/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../gotta_catch_em_all/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/../gotta_catch_em_all/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
gotta_catch_em_all/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/../gotta_catch_em_all/.idea/gotta_catch_em_all.iml" filepath="$PROJECT_DIR$/../gotta_catch_em_all/.idea/gotta_catch_em_all.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
gotta_catch_em_all/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
20
gotta_catch_em_all/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Gotta Catch 'em All! (Really Fast)
|
||||
|
||||
## Text
|
||||
I am an aspiring new Pokémon trainer that is ready to explore the world and catch many Pokémon. Unfortunately, due to the COVID pandemic, everything will be going digital now. Professor Oak made us a game to play instead, and developed this Pokédex website to register all the Pokémon we caught in the game.
|
||||
|
||||
Gary, my rival, bragged to me that he managed to complete the entire Pokédex in under a minute. He probably didn't play the game at all and just selected all the Pokémon on the Pokédex. Whatever the case may be, I intend to beat him, legitimately or not.
|
||||
|
||||
The website is connected to a NodeJS backend with a web socket that keeps track of the Pokédex and its completion. Somehow, I must fool the backend that I captured all Pokémon in an insanely fast time, without looking too suspicious. And knowing Professor Oak's programming skills and the fact that its written in JavaScript, there's probably some kind of vulnerability I can abuse.
|
||||
|
||||
## How To Solve
|
||||
Difficulty: Advanced
|
||||
|
||||
There is a hint given when adding Poison-type Pokémon that there's a bug caused by the poison of the Pokémon that affects the shared prototype. You have to use prototype poisoning to inject the value `captured: true` into the shared prototype of all Pokémon (which is 2 levels up), or, alternatively, inject the property on all different Pokémon types (grass, water, fire, etc...):
|
||||
|
||||
```javascript
|
||||
webSocket.send('{"msg": "updatePokedex", "data": {"pokemon": "Bulbasaur", "values": {"__proto__": {"__proto__": {"captured": true}}}}}')
|
||||
```
|
||||
|
||||
## Flag
|
||||
IGCTF{MissingNo}
|
11
gotta_catch_em_all/backend/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM node
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY . /usr/src/app
|
||||
|
||||
RUN npm install
|
||||
|
||||
#EXPOSE 5000
|
||||
|
||||
CMD ["node", "index.js"]
|
17
gotta_catch_em_all/backend/default.nix
Normal file
@ -0,0 +1,17 @@
|
||||
# This file has been generated by node2nix 1.8.0. Do not edit!
|
||||
|
||||
{pkgs ? import <nixpkgs> {
|
||||
inherit system;
|
||||
}, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-12_x"}:
|
||||
|
||||
let
|
||||
nodeEnv = import ./node-env.nix {
|
||||
inherit (pkgs) stdenv python2 utillinux runCommand writeTextFile;
|
||||
inherit nodejs;
|
||||
libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
|
||||
};
|
||||
in
|
||||
import ./node-packages.nix {
|
||||
inherit (pkgs) fetchurl fetchgit;
|
||||
inherit nodeEnv;
|
||||
}
|
129
gotta_catch_em_all/backend/index.js
Normal file
@ -0,0 +1,129 @@
|
||||
const WebSocket = require('ws');
|
||||
const pokemon = require('pokemon')
|
||||
const pokeTypes = require('./poketypes.json')
|
||||
|
||||
const wss = new WebSocket.Server({
|
||||
port: 5000
|
||||
})
|
||||
|
||||
function flatten(obj) {
|
||||
if(obj !== null && obj !== undefined) {
|
||||
let ret = {};
|
||||
for (let i in obj) {
|
||||
ret[i] = obj[i];
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return obj
|
||||
}
|
||||
}
|
||||
|
||||
function badObjectCopy(values, object) {
|
||||
if(values !== undefined && object !== undefined && values !== null && object !== null) {
|
||||
for(let i in values) {
|
||||
if(typeof values[i] === "object") {
|
||||
badObjectCopy(values[i], object[i])
|
||||
} else {
|
||||
object[i] = values[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function flattenObject(obj) {
|
||||
return Object.fromEntries(Object.entries(obj).map(([key, val]) => [key, flatten(val)]))
|
||||
}
|
||||
|
||||
wss.on('connection', ws => {
|
||||
try {
|
||||
const timeStarted = new Date();
|
||||
|
||||
const Pokemon = {}
|
||||
|
||||
const types = {
|
||||
grass: {type: 'grass' , __proto__: Pokemon},
|
||||
fire: {type: 'fire' , __proto__: Pokemon},
|
||||
water: {type: 'water' , __proto__: Pokemon},
|
||||
poison: {type: 'poison' , __proto__: Pokemon},
|
||||
flying: {type: 'flying' , __proto__: Pokemon},
|
||||
bug: {type: 'bug' , __proto__: Pokemon},
|
||||
normal: {type: 'normal' , __proto__: Pokemon},
|
||||
electric: {type: 'electric', __proto__: Pokemon},
|
||||
ground: {type: 'ground' , __proto__: Pokemon},
|
||||
fairy: {type: 'fairy' , __proto__: Pokemon},
|
||||
fighting: {type: 'fighting', __proto__: Pokemon},
|
||||
psychic: {type: 'psychic' , __proto__: Pokemon},
|
||||
rock: {type: 'rock' , __proto__: Pokemon},
|
||||
steel: {type: 'steel' , __proto__: Pokemon},
|
||||
ice: {type: 'ice' , __proto__: Pokemon},
|
||||
ghost: {type: 'ghost' , __proto__: Pokemon},
|
||||
dragon: {type: 'dragon' , __proto__: Pokemon}
|
||||
}
|
||||
|
||||
const pokedex = Object.fromEntries(pokemon.all().slice(0, 151).map(poke => {
|
||||
const type = types[pokeTypes[poke]]
|
||||
return [poke, {__proto__: type}]
|
||||
}))
|
||||
|
||||
const send = async(msg, data) => await ws.send(JSON.stringify({msg, data}))
|
||||
|
||||
const checkIfAllCaptured = async () => {
|
||||
if(Object.values(pokedex).every(poke => poke["captured"])) {
|
||||
const diff = new Date() - timeStarted;
|
||||
if(diff < 60000) {
|
||||
send("pokedexCompleted", {
|
||||
msg: "I can't believe you beat my near impossible 60 second speedrun! It's impossible! I am the best trainer to have ever lived! Urgh... I guess I don't have a choice but to give you this item...\n\n*You obtained the key IGCTF{MissingNo}!*\n\nHave fun with it... I guess.\n\n-Gary"
|
||||
})
|
||||
} else {
|
||||
send("pokedexCompleted", {
|
||||
msg: "Hah, you did good, but not nearly as good as I did. You still got a long way to beat my 1 minute run, loser.\n\n-Gary"
|
||||
})
|
||||
}
|
||||
ws.close()
|
||||
}
|
||||
}
|
||||
|
||||
let messagesReceived = 0;
|
||||
let timeOfLastMessage = 0;
|
||||
let poisonMessageSent = false;
|
||||
ws.on('message', evt => {
|
||||
messagesReceived++;
|
||||
const currentTime = new Date()
|
||||
console.log(currentTime - timeOfLastMessage)
|
||||
if(currentTime - timeOfLastMessage < 500) {
|
||||
send("error", {msg: "You are sending messages too fast to the backend. Please slow down."})
|
||||
timeOfLastMessage = currentTime
|
||||
return
|
||||
} else {
|
||||
timeOfLastMessage = currentTime
|
||||
}
|
||||
const {msg, data} = JSON.parse(evt)
|
||||
switch (msg) {
|
||||
case "initializePokedex": send('pokedexInitialized', flattenObject(pokedex)); break;
|
||||
case "updatePokedex": {
|
||||
const {pokemon, values} = data;
|
||||
|
||||
if(pokemon !== '__proto__') {
|
||||
if(pokeTypes[pokemon] === 'poison') {
|
||||
badObjectCopy(values, pokedex[pokemon].__proto__);
|
||||
if(!poisonMessageSent) {
|
||||
send("error", {msg: "Dear Pokémon trainer,\n\n There seems to be a bug when adding a Poison type Pokémon: it automatically registers all Poison type Pokémon in the Pokédex as captured! Somehow the poison seems to affect the shared prototype...\n\nYours truly,\nProfessor Oak"})
|
||||
poisonMessageSent = true
|
||||
}
|
||||
} else {
|
||||
badObjectCopy(values, pokedex[pokemon]);
|
||||
}
|
||||
} else {
|
||||
send("error", {msg: "I read somewhere that letting the client change the __proto__ property isn't such a good idea, so I'll just add this check here. I sure hope that I didn't forget to check this anywhere else... \n\n -Professor Oak"})
|
||||
}
|
||||
|
||||
send('pokedexUpdated', flattenObject(pokedex))
|
||||
checkIfAllCaptured()
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
542
gotta_catch_em_all/backend/node-env.nix
Normal file
@ -0,0 +1,542 @@
|
||||
# This file originates from node2nix
|
||||
|
||||
{stdenv, nodejs, python2, utillinux, libtool, runCommand, writeTextFile}:
|
||||
|
||||
let
|
||||
python = if nodejs ? python then nodejs.python else python2;
|
||||
|
||||
# Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
|
||||
tarWrapper = runCommand "tarWrapper" {} ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
cat > $out/bin/tar <<EOF
|
||||
#! ${stdenv.shell} -e
|
||||
$(type -p tar) "\$@" --warning=no-unknown-keyword --delay-directory-restore
|
||||
EOF
|
||||
|
||||
chmod +x $out/bin/tar
|
||||
'';
|
||||
|
||||
# Function that generates a TGZ file from a NPM project
|
||||
buildNodeSourceDist =
|
||||
{ name, version, src, ... }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "node-tarball-${name}-${version}";
|
||||
inherit src;
|
||||
buildInputs = [ nodejs ];
|
||||
buildPhase = ''
|
||||
export HOME=$TMPDIR
|
||||
tgzFile=$(npm pack | tail -n 1) # Hooks to the pack command will add output (https://docs.npmjs.com/misc/scripts)
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out/tarballs
|
||||
mv $tgzFile $out/tarballs
|
||||
mkdir -p $out/nix-support
|
||||
echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
};
|
||||
|
||||
includeDependencies = {dependencies}:
|
||||
stdenv.lib.optionalString (dependencies != [])
|
||||
(stdenv.lib.concatMapStrings (dependency:
|
||||
''
|
||||
# Bundle the dependencies of the package
|
||||
mkdir -p node_modules
|
||||
cd node_modules
|
||||
|
||||
# Only include dependencies if they don't exist. They may also be bundled in the package.
|
||||
if [ ! -e "${dependency.name}" ]
|
||||
then
|
||||
${composePackage dependency}
|
||||
fi
|
||||
|
||||
cd ..
|
||||
''
|
||||
) dependencies);
|
||||
|
||||
# Recursively composes the dependencies of a package
|
||||
composePackage = { name, packageName, src, dependencies ? [], ... }@args:
|
||||
builtins.addErrorContext "while evaluating node package '${packageName}'" ''
|
||||
DIR=$(pwd)
|
||||
cd $TMPDIR
|
||||
|
||||
unpackFile ${src}
|
||||
|
||||
# Make the base dir in which the target dependency resides first
|
||||
mkdir -p "$(dirname "$DIR/${packageName}")"
|
||||
|
||||
if [ -f "${src}" ]
|
||||
then
|
||||
# Figure out what directory has been unpacked
|
||||
packageDir="$(find . -maxdepth 1 -type d | tail -1)"
|
||||
|
||||
# Restore write permissions to make building work
|
||||
find "$packageDir" -type d -exec chmod u+x {} \;
|
||||
chmod -R u+w "$packageDir"
|
||||
|
||||
# Move the extracted tarball into the output folder
|
||||
mv "$packageDir" "$DIR/${packageName}"
|
||||
elif [ -d "${src}" ]
|
||||
then
|
||||
# Get a stripped name (without hash) of the source directory.
|
||||
# On old nixpkgs it's already set internally.
|
||||
if [ -z "$strippedName" ]
|
||||
then
|
||||
strippedName="$(stripHash ${src})"
|
||||
fi
|
||||
|
||||
# Restore write permissions to make building work
|
||||
chmod -R u+w "$strippedName"
|
||||
|
||||
# Move the extracted directory into the output folder
|
||||
mv "$strippedName" "$DIR/${packageName}"
|
||||
fi
|
||||
|
||||
# Unset the stripped name to not confuse the next unpack step
|
||||
unset strippedName
|
||||
|
||||
# Include the dependencies of the package
|
||||
cd "$DIR/${packageName}"
|
||||
${includeDependencies { inherit dependencies; }}
|
||||
cd ..
|
||||
${stdenv.lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
|
||||
'';
|
||||
|
||||
pinpointDependencies = {dependencies, production}:
|
||||
let
|
||||
pinpointDependenciesFromPackageJSON = writeTextFile {
|
||||
name = "pinpointDependencies.js";
|
||||
text = ''
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
function resolveDependencyVersion(location, name) {
|
||||
if(location == process.env['NIX_STORE']) {
|
||||
return null;
|
||||
} else {
|
||||
var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json");
|
||||
|
||||
if(fs.existsSync(dependencyPackageJSON)) {
|
||||
var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON));
|
||||
|
||||
if(dependencyPackageObj.name == name) {
|
||||
return dependencyPackageObj.version;
|
||||
}
|
||||
} else {
|
||||
return resolveDependencyVersion(path.resolve(location, ".."), name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replaceDependencies(dependencies) {
|
||||
if(typeof dependencies == "object" && dependencies !== null) {
|
||||
for(var dependency in dependencies) {
|
||||
var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency);
|
||||
|
||||
if(resolvedVersion === null) {
|
||||
process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n");
|
||||
} else {
|
||||
dependencies[dependency] = resolvedVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the package.json configuration */
|
||||
var packageObj = JSON.parse(fs.readFileSync('./package.json'));
|
||||
|
||||
/* Pinpoint all dependencies */
|
||||
replaceDependencies(packageObj.dependencies);
|
||||
if(process.argv[2] == "development") {
|
||||
replaceDependencies(packageObj.devDependencies);
|
||||
}
|
||||
replaceDependencies(packageObj.optionalDependencies);
|
||||
|
||||
/* Write the fixed package.json file */
|
||||
fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2));
|
||||
'';
|
||||
};
|
||||
in
|
||||
''
|
||||
node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"}
|
||||
|
||||
${stdenv.lib.optionalString (dependencies != [])
|
||||
''
|
||||
if [ -d node_modules ]
|
||||
then
|
||||
cd node_modules
|
||||
${stdenv.lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies}
|
||||
cd ..
|
||||
fi
|
||||
''}
|
||||
'';
|
||||
|
||||
# Recursively traverses all dependencies of a package and pinpoints all
|
||||
# dependencies in the package.json file to the versions that are actually
|
||||
# being used.
|
||||
|
||||
pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args:
|
||||
''
|
||||
if [ -d "${packageName}" ]
|
||||
then
|
||||
cd "${packageName}"
|
||||
${pinpointDependencies { inherit dependencies production; }}
|
||||
cd ..
|
||||
${stdenv.lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
|
||||
fi
|
||||
'';
|
||||
|
||||
# Extract the Node.js source code which is used to compile packages with
|
||||
# native bindings
|
||||
nodeSources = runCommand "node-sources" {} ''
|
||||
tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
|
||||
mv node-* $out
|
||||
'';
|
||||
|
||||
# Script that adds _integrity fields to all package.json files to prevent NPM from consulting the cache (that is empty)
|
||||
addIntegrityFieldsScript = writeTextFile {
|
||||
name = "addintegrityfields.js";
|
||||
text = ''
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
function augmentDependencies(baseDir, dependencies) {
|
||||
for(var dependencyName in dependencies) {
|
||||
var dependency = dependencies[dependencyName];
|
||||
|
||||
// Open package.json and augment metadata fields
|
||||
var packageJSONDir = path.join(baseDir, "node_modules", dependencyName);
|
||||
var packageJSONPath = path.join(packageJSONDir, "package.json");
|
||||
|
||||
if(fs.existsSync(packageJSONPath)) { // Only augment packages that exist. Sometimes we may have production installs in which development dependencies can be ignored
|
||||
console.log("Adding metadata fields to: "+packageJSONPath);
|
||||
var packageObj = JSON.parse(fs.readFileSync(packageJSONPath));
|
||||
|
||||
if(dependency.integrity) {
|
||||
packageObj["_integrity"] = dependency.integrity;
|
||||
} else {
|
||||
packageObj["_integrity"] = "sha1-000000000000000000000000000="; // When no _integrity string has been provided (e.g. by Git dependencies), add a dummy one. It does not seem to harm and it bypasses downloads.
|
||||
}
|
||||
|
||||
if(dependency.resolved) {
|
||||
packageObj["_resolved"] = dependency.resolved; // Adopt the resolved property if one has been provided
|
||||
} else {
|
||||
packageObj["_resolved"] = dependency.version; // Set the resolved version to the version identifier. This prevents NPM from cloning Git repositories.
|
||||
}
|
||||
|
||||
if(dependency.from !== undefined) { // Adopt from property if one has been provided
|
||||
packageObj["_from"] = dependency.from;
|
||||
}
|
||||
|
||||
fs.writeFileSync(packageJSONPath, JSON.stringify(packageObj, null, 2));
|
||||
}
|
||||
|
||||
// Augment transitive dependencies
|
||||
if(dependency.dependencies !== undefined) {
|
||||
augmentDependencies(packageJSONDir, dependency.dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(fs.existsSync("./package-lock.json")) {
|
||||
var packageLock = JSON.parse(fs.readFileSync("./package-lock.json"));
|
||||
|
||||
if(packageLock.lockfileVersion !== 1) {
|
||||
process.stderr.write("Sorry, I only understand lock file version 1!\n");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if(packageLock.dependencies !== undefined) {
|
||||
augmentDependencies(".", packageLock.dependencies);
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Reconstructs a package-lock file from the node_modules/ folder structure and package.json files with dummy sha1 hashes
|
||||
reconstructPackageLock = writeTextFile {
|
||||
name = "addintegrityfields.js";
|
||||
text = ''
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var packageObj = JSON.parse(fs.readFileSync("package.json"));
|
||||
|
||||
var lockObj = {
|
||||
name: packageObj.name,
|
||||
version: packageObj.version,
|
||||
lockfileVersion: 1,
|
||||
requires: true,
|
||||
dependencies: {}
|
||||
};
|
||||
|
||||
function augmentPackageJSON(filePath, dependencies) {
|
||||
var packageJSON = path.join(filePath, "package.json");
|
||||
if(fs.existsSync(packageJSON)) {
|
||||
var packageObj = JSON.parse(fs.readFileSync(packageJSON));
|
||||
dependencies[packageObj.name] = {
|
||||
version: packageObj.version,
|
||||
integrity: "sha1-000000000000000000000000000=",
|
||||
dependencies: {}
|
||||
};
|
||||
processDependencies(path.join(filePath, "node_modules"), dependencies[packageObj.name].dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
function processDependencies(dir, dependencies) {
|
||||
if(fs.existsSync(dir)) {
|
||||
var files = fs.readdirSync(dir);
|
||||
|
||||
files.forEach(function(entry) {
|
||||
var filePath = path.join(dir, entry);
|
||||
var stats = fs.statSync(filePath);
|
||||
|
||||
if(stats.isDirectory()) {
|
||||
if(entry.substr(0, 1) == "@") {
|
||||
// When we encounter a namespace folder, augment all packages belonging to the scope
|
||||
var pkgFiles = fs.readdirSync(filePath);
|
||||
|
||||
pkgFiles.forEach(function(entry) {
|
||||
if(stats.isDirectory()) {
|
||||
var pkgFilePath = path.join(filePath, entry);
|
||||
augmentPackageJSON(pkgFilePath, dependencies);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
augmentPackageJSON(filePath, dependencies);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
processDependencies("node_modules", lockObj.dependencies);
|
||||
|
||||
fs.writeFileSync("package-lock.json", JSON.stringify(lockObj, null, 2));
|
||||
'';
|
||||
};
|
||||
|
||||
prepareAndInvokeNPM = {packageName, bypassCache, reconstructLock, npmFlags, production}:
|
||||
let
|
||||
forceOfflineFlag = if bypassCache then "--offline" else "--registry http://www.example.com";
|
||||
in
|
||||
''
|
||||
# Pinpoint the versions of all dependencies to the ones that are actually being used
|
||||
echo "pinpointing versions of dependencies..."
|
||||
source $pinpointDependenciesScriptPath
|
||||
|
||||
# Patch the shebangs of the bundled modules to prevent them from
|
||||
# calling executables outside the Nix store as much as possible
|
||||
patchShebangs .
|
||||
|
||||
# Deploy the Node.js package by running npm install. Since the
|
||||
# dependencies have been provided already by ourselves, it should not
|
||||
# attempt to install them again, which is good, because we want to make
|
||||
# it Nix's responsibility. If it needs to install any dependencies
|
||||
# anyway (e.g. because the dependency parameters are
|
||||
# incomplete/incorrect), it fails.
|
||||
#
|
||||
# The other responsibilities of NPM are kept -- version checks, build
|
||||
# steps, postprocessing etc.
|
||||
|
||||
export HOME=$TMPDIR
|
||||
cd "${packageName}"
|
||||
runHook preRebuild
|
||||
|
||||
${stdenv.lib.optionalString bypassCache ''
|
||||
${stdenv.lib.optionalString reconstructLock ''
|
||||
if [ -f package-lock.json ]
|
||||
then
|
||||
echo "WARNING: Reconstruct lock option enabled, but a lock file already exists!"
|
||||
echo "This will most likely result in version mismatches! We will remove the lock file and regenerate it!"
|
||||
rm package-lock.json
|
||||
else
|
||||
echo "No package-lock.json file found, reconstructing..."
|
||||
fi
|
||||
|
||||
node ${reconstructPackageLock}
|
||||
''}
|
||||
|
||||
node ${addIntegrityFieldsScript}
|
||||
''}
|
||||
|
||||
npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${stdenv.lib.optionalString production "--production"} rebuild
|
||||
|
||||
if [ "''${dontNpmInstall-}" != "1" ]
|
||||
then
|
||||
# NPM tries to download packages even when they already exist if npm-shrinkwrap is used.
|
||||
rm -f npm-shrinkwrap.json
|
||||
|
||||
npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${stdenv.lib.optionalString production "--production"} install
|
||||
fi
|
||||
'';
|
||||
|
||||
# Builds and composes an NPM package including all its dependencies
|
||||
buildNodePackage =
|
||||
{ name
|
||||
, packageName
|
||||
, version
|
||||
, dependencies ? []
|
||||
, buildInputs ? []
|
||||
, production ? true
|
||||
, npmFlags ? ""
|
||||
, dontNpmInstall ? false
|
||||
, bypassCache ? false
|
||||
, reconstructLock ? false
|
||||
, preRebuild ? ""
|
||||
, dontStrip ? true
|
||||
, unpackPhase ? "true"
|
||||
, buildPhase ? "true"
|
||||
, ... }@args:
|
||||
|
||||
let
|
||||
extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "preRebuild" "unpackPhase" "buildPhase" ];
|
||||
in
|
||||
stdenv.mkDerivation ({
|
||||
name = "node_${name}-${version}";
|
||||
buildInputs = [ tarWrapper python nodejs ]
|
||||
++ stdenv.lib.optional (stdenv.isLinux) utillinux
|
||||
++ stdenv.lib.optional (stdenv.isDarwin) libtool
|
||||
++ buildInputs;
|
||||
|
||||
inherit nodejs;
|
||||
|
||||
inherit dontStrip; # Stripping may fail a build for some package deployments
|
||||
inherit dontNpmInstall preRebuild unpackPhase buildPhase;
|
||||
|
||||
compositionScript = composePackage args;
|
||||
pinpointDependenciesScript = pinpointDependenciesOfPackage args;
|
||||
|
||||
passAsFile = [ "compositionScript" "pinpointDependenciesScript" ];
|
||||
|
||||
installPhase = ''
|
||||
# Create and enter a root node_modules/ folder
|
||||
mkdir -p $out/lib/node_modules
|
||||
cd $out/lib/node_modules
|
||||
|
||||
# Compose the package and all its dependencies
|
||||
source $compositionScriptPath
|
||||
|
||||
${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
|
||||
|
||||
# Create symlink to the deployed executable folder, if applicable
|
||||
if [ -d "$out/lib/node_modules/.bin" ]
|
||||
then
|
||||
ln -s $out/lib/node_modules/.bin $out/bin
|
||||
fi
|
||||
|
||||
# Create symlinks to the deployed manual page folders, if applicable
|
||||
if [ -d "$out/lib/node_modules/${packageName}/man" ]
|
||||
then
|
||||
mkdir -p $out/share
|
||||
for dir in "$out/lib/node_modules/${packageName}/man/"*
|
||||
do
|
||||
mkdir -p $out/share/man/$(basename "$dir")
|
||||
for page in "$dir"/*
|
||||
do
|
||||
ln -s $page $out/share/man/$(basename "$dir")
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Run post install hook, if provided
|
||||
runHook postInstall
|
||||
'';
|
||||
} // extraArgs);
|
||||
|
||||
# Builds a development shell
|
||||
buildNodeShell =
|
||||
{ name
|
||||
, packageName
|
||||
, version
|
||||
, src
|
||||
, dependencies ? []
|
||||
, buildInputs ? []
|
||||
, production ? true
|
||||
, npmFlags ? ""
|
||||
, dontNpmInstall ? false
|
||||
, bypassCache ? false
|
||||
, reconstructLock ? false
|
||||
, dontStrip ? true
|
||||
, unpackPhase ? "true"
|
||||
, buildPhase ? "true"
|
||||
, ... }@args:
|
||||
|
||||
let
|
||||
extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" ];
|
||||
|
||||
nodeDependencies = stdenv.mkDerivation ({
|
||||
name = "node-dependencies-${name}-${version}";
|
||||
|
||||
buildInputs = [ tarWrapper python nodejs ]
|
||||
++ stdenv.lib.optional (stdenv.isLinux) utillinux
|
||||
++ stdenv.lib.optional (stdenv.isDarwin) libtool
|
||||
++ buildInputs;
|
||||
|
||||
inherit dontStrip; # Stripping may fail a build for some package deployments
|
||||
inherit dontNpmInstall unpackPhase buildPhase;
|
||||
|
||||
includeScript = includeDependencies { inherit dependencies; };
|
||||
pinpointDependenciesScript = pinpointDependenciesOfPackage args;
|
||||
|
||||
passAsFile = [ "includeScript" "pinpointDependenciesScript" ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/${packageName}
|
||||
cd $out/${packageName}
|
||||
|
||||
source $includeScriptPath
|
||||
|
||||
# Create fake package.json to make the npm commands work properly
|
||||
cp ${src}/package.json .
|
||||
chmod 644 package.json
|
||||
${stdenv.lib.optionalString bypassCache ''
|
||||
if [ -f ${src}/package-lock.json ]
|
||||
then
|
||||
cp ${src}/package-lock.json .
|
||||
fi
|
||||
''}
|
||||
|
||||
# Go to the parent folder to make sure that all packages are pinpointed
|
||||
cd ..
|
||||
${stdenv.lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
|
||||
|
||||
${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
|
||||
|
||||
# Expose the executables that were installed
|
||||
cd ..
|
||||
${stdenv.lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
|
||||
|
||||
mv ${packageName} lib
|
||||
ln -s $out/lib/node_modules/.bin $out/bin
|
||||
'';
|
||||
} // extraArgs);
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "node-shell-${name}-${version}";
|
||||
|
||||
buildInputs = [ python nodejs ] ++ stdenv.lib.optional (stdenv.isLinux) utillinux ++ buildInputs;
|
||||
buildCommand = ''
|
||||
mkdir -p $out/bin
|
||||
cat > $out/bin/shell <<EOF
|
||||
#! ${stdenv.shell} -e
|
||||
$shellHook
|
||||
exec ${stdenv.shell}
|
||||
EOF
|
||||
chmod +x $out/bin/shell
|
||||
'';
|
||||
|
||||
# Provide the dependencies in a development shell through the NODE_PATH environment variable
|
||||
inherit nodeDependencies;
|
||||
shellHook = stdenv.lib.optionalString (dependencies != []) ''
|
||||
export NODE_PATH=${nodeDependencies}/lib/node_modules
|
||||
export PATH="${nodeDependencies}/bin:$PATH"
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
buildNodeSourceDist = stdenv.lib.makeOverridable buildNodeSourceDist;
|
||||
buildNodePackage = stdenv.lib.makeOverridable buildNodePackage;
|
||||
buildNodeShell = stdenv.lib.makeOverridable buildNodeShell;
|
||||
}
|
1410
gotta_catch_em_all/backend/node-packages.nix
Normal file
980
gotta_catch_em_all/backend/package-lock.json
generated
Normal file
@ -0,0 +1,980 @@
|
||||
{
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "5.7.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
|
||||
"integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg=="
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
|
||||
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
|
||||
"requires": {
|
||||
"acorn": "^3.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
|
||||
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
||||
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
|
||||
"requires": {
|
||||
"co": "^4.6.0",
|
||||
"fast-deep-equal": "^1.0.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"ajv-keywords": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
|
||||
"integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I="
|
||||
},
|
||||
"ansi-escapes": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
|
||||
"integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ=="
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||
"requires": {
|
||||
"chalk": "^1.1.3",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
},
|
||||
"caller-path": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
|
||||
"integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
|
||||
"requires": {
|
||||
"callsites": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
|
||||
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chardet": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
|
||||
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
|
||||
},
|
||||
"circular-json": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
|
||||
"integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A=="
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
|
||||
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
|
||||
"requires": {
|
||||
"restore-cursor": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"cli-width": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
|
||||
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
"integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
|
||||
"requires": {
|
||||
"lru-cache": "^4.0.1",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"deep-is": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
|
||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
|
||||
},
|
||||
"doctrine": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
||||
"requires": {
|
||||
"esutils": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"eslint": {
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
|
||||
"integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
|
||||
"requires": {
|
||||
"ajv": "^5.3.0",
|
||||
"babel-code-frame": "^6.22.0",
|
||||
"chalk": "^2.1.0",
|
||||
"concat-stream": "^1.6.0",
|
||||
"cross-spawn": "^5.1.0",
|
||||
"debug": "^3.1.0",
|
||||
"doctrine": "^2.1.0",
|
||||
"eslint-scope": "^3.7.1",
|
||||
"eslint-visitor-keys": "^1.0.0",
|
||||
"espree": "^3.5.4",
|
||||
"esquery": "^1.0.0",
|
||||
"esutils": "^2.0.2",
|
||||
"file-entry-cache": "^2.0.0",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"glob": "^7.1.2",
|
||||
"globals": "^11.0.1",
|
||||
"ignore": "^3.3.3",
|
||||
"imurmurhash": "^0.1.4",
|
||||
"inquirer": "^3.0.6",
|
||||
"is-resolvable": "^1.0.0",
|
||||
"js-yaml": "^3.9.1",
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"levn": "^0.3.0",
|
||||
"lodash": "^4.17.4",
|
||||
"minimatch": "^3.0.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.8.2",
|
||||
"path-is-inside": "^1.0.2",
|
||||
"pluralize": "^7.0.0",
|
||||
"progress": "^2.0.0",
|
||||
"regexpp": "^1.0.1",
|
||||
"require-uncached": "^1.0.3",
|
||||
"semver": "^5.3.0",
|
||||
"strip-ansi": "^4.0.0",
|
||||
"strip-json-comments": "~2.0.1",
|
||||
"table": "4.0.2",
|
||||
"text-table": "~0.2.0"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "3.7.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz",
|
||||
"integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==",
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
"estraverse": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"eslint-visitor-keys": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
|
||||
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
|
||||
},
|
||||
"espree": {
|
||||
"version": "3.5.4",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
|
||||
"integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
|
||||
"requires": {
|
||||
"acorn": "^5.5.0",
|
||||
"acorn-jsx": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"esquery": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
||||
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
||||
"requires": {
|
||||
"estraverse": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estraverse": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"esrecurse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"requires": {
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estraverse": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
|
||||
},
|
||||
"external-editor": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
|
||||
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
|
||||
"requires": {
|
||||
"chardet": "^0.4.0",
|
||||
"iconv-lite": "^0.4.17",
|
||||
"tmp": "^0.0.33"
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
|
||||
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||
},
|
||||
"figures": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
||||
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
|
||||
"requires": {
|
||||
"escape-string-regexp": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"file-entry-cache": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
|
||||
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
|
||||
"requires": {
|
||||
"flat-cache": "^1.2.1",
|
||||
"object-assign": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"flat-cache": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
|
||||
"integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
|
||||
"requires": {
|
||||
"circular-json": "^0.3.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"rimraf": "~2.6.2",
|
||||
"write": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"functional-red-black-tree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
|
||||
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
"version": "3.3.10",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
|
||||
"integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug=="
|
||||
},
|
||||
"imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
|
||||
"integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
|
||||
"requires": {
|
||||
"ansi-escapes": "^3.0.0",
|
||||
"chalk": "^2.0.0",
|
||||
"cli-cursor": "^2.1.0",
|
||||
"cli-width": "^2.0.0",
|
||||
"external-editor": "^2.0.4",
|
||||
"figures": "^2.0.0",
|
||||
"lodash": "^4.3.0",
|
||||
"mute-stream": "0.0.7",
|
||||
"run-async": "^2.2.0",
|
||||
"rx-lite": "^4.0.8",
|
||||
"rx-lite-aggregates": "^4.0.8",
|
||||
"string-width": "^2.1.0",
|
||||
"strip-ansi": "^4.0.0",
|
||||
"through": "^2.3.6"
|
||||
}
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||
},
|
||||
"is-resolvable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
|
||||
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
|
||||
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
|
||||
},
|
||||
"json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
|
||||
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
|
||||
"requires": {
|
||||
"prelude-ls": "~1.1.2",
|
||||
"type-check": "~0.3.2"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||
"requires": {
|
||||
"pseudomap": "^1.0.2",
|
||||
"yallist": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
|
||||
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
|
||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"onetime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
|
||||
"requires": {
|
||||
"mimic-fn": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"optionator": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
|
||||
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
|
||||
"requires": {
|
||||
"deep-is": "~0.1.3",
|
||||
"fast-levenshtein": "~2.0.6",
|
||||
"levn": "~0.3.0",
|
||||
"prelude-ls": "~1.1.2",
|
||||
"type-check": "~0.3.2",
|
||||
"word-wrap": "~1.2.3"
|
||||
}
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"path-is-inside": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
|
||||
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
|
||||
},
|
||||
"pluralize": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
|
||||
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow=="
|
||||
},
|
||||
"pokemon": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pokemon/-/pokemon-2.0.2.tgz",
|
||||
"integrity": "sha512-lKfv+uUYOut9gO2w21/Nau+aIFF8JIUiuLXAymr09j+ie8oiUOoV2rqX8LhLFWppcz4lEnPNPV5wGPWla0x0wQ==",
|
||||
"requires": {
|
||||
"unique-random-array": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"pokemon-node": {
|
||||
"version": "1.0.0-fix2",
|
||||
"resolved": "https://registry.npmjs.org/pokemon-node/-/pokemon-node-1.0.0-fix2.tgz",
|
||||
"integrity": "sha512-0BcJBhbLppCj8JQgmGNSwW458Xh61fXASmY0oCxXm96KbK/ZBKwjBlYwSfB6CsTE1dUpObgYVtAbp8RGY62WFQ==",
|
||||
"requires": {
|
||||
"eslint": "^4.19.1",
|
||||
"snekfetch": "^3.6.4"
|
||||
}
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
|
||||
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
||||
},
|
||||
"pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
|
||||
"integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw=="
|
||||
},
|
||||
"require-uncached": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
|
||||
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
|
||||
"requires": {
|
||||
"caller-path": "^0.1.0",
|
||||
"resolve-from": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
|
||||
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY="
|
||||
},
|
||||
"restore-cursor": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
|
||||
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
|
||||
"requires": {
|
||||
"onetime": "^2.0.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
|
||||
},
|
||||
"rx-lite": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
|
||||
"integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ="
|
||||
},
|
||||
"rx-lite-aggregates": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
|
||||
"integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
|
||||
"requires": {
|
||||
"rx-lite": "*"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
|
||||
"requires": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||
},
|
||||
"slice-ansi": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
|
||||
"integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
|
||||
"requires": {
|
||||
"is-fullwidth-code-point": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"snekfetch": {
|
||||
"version": "3.6.4",
|
||||
"resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.4.tgz",
|
||||
"integrity": "sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw=="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
||||
"requires": {
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||
},
|
||||
"table": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
|
||||
"integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
|
||||
"requires": {
|
||||
"ajv": "^5.2.3",
|
||||
"ajv-keywords": "^2.1.0",
|
||||
"chalk": "^2.1.0",
|
||||
"lodash": "^4.17.4",
|
||||
"slice-ansi": "1.0.0",
|
||||
"string-width": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||
"requires": {
|
||||
"os-tmpdir": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
|
||||
"requires": {
|
||||
"prelude-ls": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"unique-random": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unique-random/-/unique-random-2.1.0.tgz",
|
||||
"integrity": "sha512-iQ1ZgWac3b8YxGThecQFRQiqgk6xFERRwHZIWeVVsqlbmgCRl0PY13R4mUkodNgctmg5b5odG1nyW/IbOxQTqg=="
|
||||
},
|
||||
"unique-random-array": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unique-random-array/-/unique-random-array-2.0.0.tgz",
|
||||
"integrity": "sha512-xR87O95fZ7hljw84J8r1YDXrvffPLWN513BNOP4Bv0KcgG5dyEUrHwsvP7mVAOKg4Y80uqRbpUk0GKr8il70qg==",
|
||||
"requires": {
|
||||
"unique-random": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"write": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
|
||||
"integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
|
||||
"requires": {
|
||||
"mkdirp": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
|
||||
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
||||
}
|
||||
}
|
||||
}
|
16
gotta_catch_em_all/backend/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"gotta-catch-them-all": "./index.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"pokemon": "^2.0.2",
|
||||
"pokemon-node": "^1.0.0-fix2",
|
||||
"ws": "^7.4.2"
|
||||
}
|
||||
}
|
153
gotta_catch_em_all/backend/poketypes.json
Normal file
@ -0,0 +1,153 @@
|
||||
{
|
||||
"Bulbasaur": "grass",
|
||||
"Ivysaur": "grass",
|
||||
"Venusaur": "grass",
|
||||
"Charmander": "fire",
|
||||
"Charmeleon": "fire",
|
||||
"Charizard": "fire",
|
||||
"Squirtle": "water",
|
||||
"Wartortle": "water",
|
||||
"Blastoise": "water",
|
||||
"Caterpie": "bug",
|
||||
"Metapod": "bug",
|
||||
"Butterfree": "bug",
|
||||
"Weedle": "bug",
|
||||
"Kakuna": "bug",
|
||||
"Beedrill": "bug",
|
||||
"Pidgey": "normal",
|
||||
"Pidgeotto": "normal",
|
||||
"Pidgeot": "normal",
|
||||
"Rattata": "normal",
|
||||
"Raticate": "normal",
|
||||
"Spearow": "normal",
|
||||
"Fearow": "normal",
|
||||
"Ekans": "poison",
|
||||
"Arbok": "poison",
|
||||
"Pikachu": "electric",
|
||||
"Raichu": "electric",
|
||||
"Sandshrew": "ground",
|
||||
"Sandslash": "ground",
|
||||
"Nidoran♀": "poison",
|
||||
"Nidorina": "poison",
|
||||
"Nidoqueen": "poison",
|
||||
"Nidoran♂": "poison",
|
||||
"Nidorino": "poison",
|
||||
"Nidoking": "poison",
|
||||
"Clefairy": "fairy",
|
||||
"Clefable": "fairy",
|
||||
"Vulpix": "fire",
|
||||
"Ninetales": "fire",
|
||||
"Jigglypuff": "fairy",
|
||||
"Wigglytuff": "fairy",
|
||||
"Zubat": "poison",
|
||||
"Golbat": "poison",
|
||||
"Oddish": "grass",
|
||||
"Gloom": "grass",
|
||||
"Vileplume": "grass",
|
||||
"Paras": "bug",
|
||||
"Parasect": "bug",
|
||||
"Venonat": "bug",
|
||||
"Venomoth": "bug",
|
||||
"Diglett": "ground",
|
||||
"Dugtrio": "ground",
|
||||
"Meowth": "normal",
|
||||
"Persian": "normal",
|
||||
"Psyduck": "water",
|
||||
"Golduck": "water",
|
||||
"Mankey": "fighting",
|
||||
"Primeape": "fighting",
|
||||
"Growlithe": "fire",
|
||||
"Arcanine": "fire",
|
||||
"Poliwag": "water",
|
||||
"Poliwhirl": "water",
|
||||
"Poliwrath": "water",
|
||||
"Abra": "psychic",
|
||||
"Kadabra": "psychic",
|
||||
"Alakazam": "psychic",
|
||||
"Machop": "fighting",
|
||||
"Machoke": "fighting",
|
||||
"Machamp": "fighting",
|
||||
"Bellsprout": "grass",
|
||||
"Weepinbell": "grass",
|
||||
"Victreebel": "grass",
|
||||
"Tentacool": "water",
|
||||
"Tentacruel": "water",
|
||||
"Geodude": "rock",
|
||||
"Graveler": "rock",
|
||||
"Golem": "rock",
|
||||
"Ponyta": "fire",
|
||||
"Rapidash": "fire",
|
||||
"Slowpoke": "water",
|
||||
"Slowbro": "water",
|
||||
"Magnemite": "electric",
|
||||
"Magneton": "electric",
|
||||
"Farfetch’d": "normal",
|
||||
"Doduo": "normal",
|
||||
"Dodrio": "normal",
|
||||
"Seel": "water",
|
||||
"Dewgong": "water",
|
||||
"Grimer": "poison",
|
||||
"Muk": "poison",
|
||||
"Shellder": "water",
|
||||
"Cloyster": "water",
|
||||
"Gastly": "ghost",
|
||||
"Haunter": "ghost",
|
||||
"Gengar": "ghost",
|
||||
"Onix": "rock",
|
||||
"Drowzee": "psychic",
|
||||
"Hypno": "psychic",
|
||||
"Krabby": "water",
|
||||
"Kingler": "water",
|
||||
"Voltorb": "electric",
|
||||
"Electrode": "electric",
|
||||
"Exeggcute": "grass",
|
||||
"Exeggutor": "grass",
|
||||
"Cubone": "ground",
|
||||
"Marowak": "ground",
|
||||
"Hitmonlee": "fighting",
|
||||
"Hitmonchan": "fighting",
|
||||
"Lickitung": "normal",
|
||||
"Koffing": "poison",
|
||||
"Weezing": "poison",
|
||||
"Rhyhorn": "ground",
|
||||
"Rhydon": "ground",
|
||||
"Chansey": "normal",
|
||||
"Tangela": "grass",
|
||||
"Kangaskhan": "normal",
|
||||
"Horsea": "water",
|
||||
"Seadra": "water",
|
||||
"Goldeen": "water",
|
||||
"Seaking": "water",
|
||||
"Staryu": "water",
|
||||
"Starmie": "water",
|
||||
"Mr. Mime": "psychic",
|
||||
"Scyther": "bug",
|
||||
"Jynx": "ice",
|
||||
"Electabuzz": "electric",
|
||||
"Magmar": "fire",
|
||||
"Pinsir": "bug",
|
||||
"Tauros": "normal",
|
||||
"Magikarp": "water",
|
||||
"Gyarados": "water",
|
||||
"Lapras": "water",
|
||||
"Ditto": "normal",
|
||||
"Eevee": "normal",
|
||||
"Vaporeon": "water",
|
||||
"Jolteon": "electric",
|
||||
"Flareon": "fire",
|
||||
"Porygon": "normal",
|
||||
"Omanyte": "rock",
|
||||
"Omastar": "rock",
|
||||
"Kabuto": "rock",
|
||||
"Kabutops": "rock",
|
||||
"Aerodactyl": "rock",
|
||||
"Snorlax": "normal",
|
||||
"Articuno": "ice",
|
||||
"Zapdos": "electric",
|
||||
"Moltres": "fire",
|
||||
"Dratini": "dragon",
|
||||
"Dragonair": "dragon",
|
||||
"Dragonite": "dragon",
|
||||
"Mewtwo": "psychic",
|
||||
"Mew": "psychic"
|
||||
}
|
12
gotta_catch_em_all/bliep.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Gotta Catch 'em All! (Really Fast)
|
||||
|
||||
## Text
|
||||
I am an aspiring new Pokémon trainer that is ready to explore the world and catch many Pokémon. Unfortunately, due to the COVID pandemic, everything will be going digital now. Professor Oak made us a game to play instead, and developed this Pokédex website to register all the Pokémon we caught in the game.
|
||||
|
||||
Gary, my rival, bragged to me that he managed to complete the entire Pokédex in under a minute. He probably didn't play the game at all and just selected all the Pokémon on the Pokédex. Whatever the case may be, I intend to beat him, legitimately or not.
|
||||
|
||||
The website is connected to a NodeJS backend with a web socket that keeps track of the Pokédex and its completion. Somehow, I must fool the backend that I captured all Pokémon in an insanely fast time, without looking too suspicious. And knowing Professor Oak's programming skills and the fact that its written in JavaScript, there's probably some kind of vulnerability I can abuse.
|
||||
|
||||
## Deployment
|
||||
For the backend: node index.js
|
||||
For the frontend: Just run it in a http server, for example using http-server (https://www.npmjs.com/package/http-server) which deploys all files in the directory it is called
|
13
gotta_catch_em_all/docker-compose.yml
Normal file
@ -0,0 +1,13 @@
|
||||
version: '3.1'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build: backend
|
||||
restart: always
|
||||
ports:
|
||||
- "5000:5000"
|
||||
frontend:
|
||||
build: frontend
|
||||
restart: always
|
||||
ports:
|
||||
- "4000:80"
|
3
gotta_catch_em_all/frontend/Dockerfile
Normal file
@ -0,0 +1,3 @@
|
||||
FROM nginx
|
||||
|
||||
COPY . /usr/share/nginx/html
|
23
gotta_catch_em_all/frontend/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script src="index.js"></script>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<meta charset="UTF-8">
|
||||
<title>Pokédex</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<form>
|
||||
<label for="pokeselect">Add captured Pokémon</label>
|
||||
<select id="pokeselect" onchange="catchPokemon()">
|
||||
<option>Select your Pokémon</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<h1 id="pokedexTitle">Kanto Pokédex</h1>
|
||||
<table id="capturedPokemon">
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
111
gotta_catch_em_all/frontend/index.js
Normal file
@ -0,0 +1,111 @@
|
||||
const webSocket = new WebSocket('ws://51.15.125.82:5000')
|
||||
|
||||
|
||||
const waitForOpenConnection = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const maxNumberOfAttempts = 10
|
||||
const intervalTime = 200 //ms
|
||||
|
||||
let currentAttempt = 0
|
||||
const interval = setInterval(() => {
|
||||
if (currentAttempt > maxNumberOfAttempts - 1) {
|
||||
clearInterval(interval)
|
||||
reject(new Error('Maximum number of attempts exceeded'))
|
||||
} else if (webSocket.readyState === webSocket.OPEN) {
|
||||
clearInterval(interval)
|
||||
resolve()
|
||||
}
|
||||
currentAttempt++
|
||||
}, intervalTime)
|
||||
})
|
||||
}
|
||||
|
||||
async function send(msg, data) {
|
||||
await waitForOpenConnection();
|
||||
webSocket.send(JSON.stringify({msg, data}))
|
||||
}
|
||||
|
||||
let pokedex = {}
|
||||
webSocket.onmessage = evt => {
|
||||
const {msg, data} = JSON.parse(evt.data);
|
||||
switch (msg) {
|
||||
case 'pokedexUpdated': pokedex = data; showPokedex(); break;
|
||||
case 'pokedexInitialized': pokedex = data; initGUI(); break;
|
||||
case 'pokedexCompleted': window.alert(data.msg); break;
|
||||
case 'error': window.alert(data.msg); break;
|
||||
}
|
||||
}
|
||||
|
||||
function fillInPokémons(pkdx) {
|
||||
window.setTimeout(() => {
|
||||
send('updatePokedex', {pokemon: pkdx[0], values: {captured: true}})
|
||||
fillInPokémons(pkdx.slice(1))
|
||||
}, 200)
|
||||
}
|
||||
|
||||
function initializePokedex() {
|
||||
send('initializePokedex')
|
||||
}
|
||||
|
||||
initializePokedex()
|
||||
|
||||
function initGUI() {
|
||||
const selection = document.getElementById("pokeselect");
|
||||
const options = Object.entries(pokedex).map(([pokemon, properties]) => {
|
||||
const option = document.createElement("option")
|
||||
option.setAttribute("value", pokemon)
|
||||
option.append(pokemon)
|
||||
return option
|
||||
})
|
||||
selection.append(...options);
|
||||
showPokedex();
|
||||
}
|
||||
|
||||
function catchPokemon() {
|
||||
const selection = document.getElementById("pokeselect").value;
|
||||
send('updatePokedex', {pokemon: selection, values: {captured: true}})
|
||||
}
|
||||
|
||||
|
||||
function showPokedex() {
|
||||
const container = document.getElementById("capturedPokemon");
|
||||
container.textContent = '';
|
||||
const pokedexTable = Object.entries(pokedex)
|
||||
.reduce((acc, val) =>
|
||||
(acc[acc.length - 1].length === 5)
|
||||
? [...acc, [val]]
|
||||
: [...acc.slice(0, acc.length - 1), [...acc[acc.length - 1], val]],
|
||||
[[]]
|
||||
)
|
||||
|
||||
const pokedexGUI = pokedexTable.map((pokeRow, colNum) => {
|
||||
const ths = pokeRow.map(([pokemon, properties], rowNum) => {
|
||||
const th = document.createElement("th");
|
||||
th.setAttribute("class", "pokecell")
|
||||
if(properties.captured) {
|
||||
const img = document.createElement("img");
|
||||
const htmlFriendlyPokeName = pokemon
|
||||
.toLowerCase()
|
||||
.replace("♀", "-f")
|
||||
.replace("♂", "-m")
|
||||
.replace("’", "")
|
||||
.replace(". ", "-")
|
||||
img.setAttribute("src", `https://img.pokemondb.net/artwork/${htmlFriendlyPokeName}.jpg`);
|
||||
img.setAttribute("height", "100");
|
||||
img.setAttribute("width", "100");
|
||||
const name = document.createElement("h2")
|
||||
name.innerText = pokemon
|
||||
th.append(img, name)
|
||||
} else {
|
||||
const name = document.createElement("h1")
|
||||
name.innerText = `${colNum * 5 + rowNum + 1}`
|
||||
th.append(name)
|
||||
}
|
||||
return th
|
||||
})
|
||||
const tr = document.createElement("tr");
|
||||
tr.append(...ths)
|
||||
return tr
|
||||
})
|
||||
container.append(...pokedexGUI)
|
||||
}
|
3
gotta_catch_em_all/frontend/package-lock.json
generated
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
BIN
gotta_catch_em_all/frontend/pokefont.ttf
Normal file
44
gotta_catch_em_all/frontend/styles.css
Normal file
@ -0,0 +1,44 @@
|
||||
@font-face {
|
||||
font-family: pokefont;
|
||||
src: url(./pokefont.ttf);
|
||||
}
|
||||
|
||||
.pokecell {
|
||||
text-align: center;
|
||||
min-width: 200px;
|
||||
width: 200px;
|
||||
max-width: 200px;
|
||||
min-height: 200px;
|
||||
height: 200px;
|
||||
max-height: 200px;
|
||||
border: 3px solid black;
|
||||
}
|
||||
|
||||
#capturedPokemon {
|
||||
/*display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;*/
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
form {
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
padding: 1rem;
|
||||
margin-left: 40%;
|
||||
margin-right: 40%;
|
||||
}
|
||||
|
||||
#pokedexTitle {
|
||||
font-family: pokefont;
|
||||
letter-spacing: 7px;
|
||||
color: yellow;
|
||||
font-size: 5rem;
|
||||
-webkit-text-stroke-width: 3px;
|
||||
-webkit-text-stroke-color: blue;
|
||||
}
|
15
gotta_catch_em_all/nix/backend.nix
Normal file
@ -0,0 +1,15 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
let app = (pkgs.callPackage ../backend/default.nix {}).package ;
|
||||
in
|
||||
pkgs.dockerTools.buildImage {
|
||||
name = "gotta-catch-them-all-backend";
|
||||
tag = "latest";
|
||||
contents = [ pkgs.nodejs app ];
|
||||
config = {
|
||||
ExposedPorts = {
|
||||
"5000/tcp" = {};
|
||||
};
|
||||
Cmd = [ "${pkgs.nodejs}/bin/node" "${app}/bin/gotta-catch-them-all" ];
|
||||
};
|
||||
}
|
38
gotta_catch_em_all/nix/frontend.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
let utils = import ../../../deployment/utils.nix ;
|
||||
nginx_conf = pkgs.writeTextFile {
|
||||
name = "nginx.conf";
|
||||
text= ''
|
||||
user root;
|
||||
daemon off;
|
||||
error_log /dev/stdout info;
|
||||
pid /dev/null;
|
||||
events {}
|
||||
http {
|
||||
access_log /dev/stdout;
|
||||
server {
|
||||
listen 80;
|
||||
index index.html;
|
||||
root ${../frontend};
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
in
|
||||
pkgs.dockerTools.buildImage {
|
||||
name = "frontend-gotta-catch-them-all";
|
||||
tag = "latest";
|
||||
contents = [ pkgs.nginx ] ;
|
||||
runAsRoot = ''
|
||||
${pkgs.dockerTools.shadowSetup}
|
||||
mkdir -p var/log/nginx
|
||||
mkdir -p var/cache/nginx
|
||||
'';
|
||||
config = {
|
||||
ExposedPorts = {
|
||||
"80/tcp" = {};
|
||||
};
|
||||
Cmd = [ "${pkgs.nginx}/bin/nginx" "-c" "${nginx_conf}" ];
|
||||
} ;
|
||||
}
|
16
i_am_from_ancient_greece/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# I am from ancient Greece
|
||||
## Text
|
||||
|
||||
A group of archeologists managed to find some notes of an ancient Greek philosopher. Unfortunately, because his philosophy is so complex, it cannot simply be put into plain mortal words. Thus, he encrypted it using a Polybius square (see attached file)! Can you unravel his wise words? This is what was written on the scroll:
|
||||
24-13-43-44-51-{-44-15-44-42-11-22-15-14-42-35-33-}
|
||||
|
||||
## Files
|
||||
- polybius.png
|
||||
|
||||
## How To Solve
|
||||
|
||||
Difficulty: Easy
|
||||
Every pair of numbers corresponds to a greek letter in the polybius square. Translate the letters (https://en.wikipedia.org/wiki/Greek_alphabet) and you get the key in Latin alphabet
|
||||
|
||||
## Flag
|
||||
IGCTF{TETRAHEDRON}
|
8
i_am_from_ancient_greece/bliep.md
Normal file
@ -0,0 +1,8 @@
|
||||
# I am from ancient Greece
|
||||
## Text
|
||||
|
||||
A group of archeologists managed to find some notes of an ancient Greek philosopher. Unfortunately, because his philosophy is so complex, it cannot simply be put into plain mortal words. Thus, he encrypted it using a Polybius square (see attached file)! Can you unravel his wise words? This is what was written on the scroll:
|
||||
24-13-43-44-51-{-44-15-44-42-11-22-15-14-42-35-33-}
|
||||
|
||||
## Files
|
||||
- polybius.png
|
BIN
i_am_from_ancient_greece/polybius.png
Normal file
After Width: | Height: | Size: 31 KiB |
3
lost-keys/Dockerfile
Normal file
@ -0,0 +1,3 @@
|
||||
FROM linuxserver/openssh-server:latest
|
||||
|
||||
COPY ./flag.txt /home/joske/
|
78
lost-keys/README.md
Normal file
@ -0,0 +1,78 @@
|
||||
== Title ==
|
||||
|
||||
Lost My Keys
|
||||
|
||||
== Description ==
|
||||
|
||||
There's this old server which I haven't accessed in years. It seems that I have forgotten the password...
|
||||
I left some important files on that server. Can you help me get access again and recover my files?
|
||||
There should still be an ssh server running on port 2222.
|
||||
I made a disk image of the computer that I used to have access with a long time ago, maybe you can figure something out?
|
||||
IP address of the server:
|
||||
|
||||
Hint: Don't bother trying to brute-force the password.
|
||||
|
||||
== Flag ==
|
||||
IGCTF{TheyWereInMyJacket!}
|
||||
|
||||
== Files ==
|
||||
Participants should receive the disk.zip file.
|
||||
|
||||
== Deployment ==
|
||||
The docker container providing an ssh server with a flag in it needs to be deployed.
|
||||
|
||||
== Solution/Writeup ==
|
||||
<---- Filler ---->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Unzip the disk.zip file to find the ISO of an ext4 file system.
|
||||
Mount the iso using mount:
|
||||
|
||||
mount disk.iso /mnt
|
||||
|
||||
Navigate to the only home directory. Its name is joske.
|
||||
This will also be the username used to login to the ssh server.
|
||||
You should now notice that there is an empty .ssh directory.
|
||||
The title "lost my keys" hints at a possibility for using ssh keys.
|
||||
|
||||
The ssh private key is deleted but not lost. You should be able to recover it using standard recovery tools. An easier way is to simply grep for the string "OPENSSH" on the entire iso and add enough context to read the full key.
|
||||
|
||||
strings disk.iso | grep -A 50 "OPENSSH" | less
|
||||
|
||||
The private key should be present in the output, copy it into a file (e.g., called key).
|
||||
|
||||
Next, simply login to the ssh server using the private key.
|
||||
|
||||
ssh -p 2222 -i key joske@<IP> (TODO fill in IP)
|
||||
|
||||
Finally, go to the home directory of joske and read the flag file:
|
||||
|
||||
cd /home/joske
|
||||
cat flag.txt
|
25
lost-keys/bliep.md
Normal file
@ -0,0 +1,25 @@
|
||||
== Title ==
|
||||
|
||||
Lost My Keys
|
||||
|
||||
== Description ==
|
||||
|
||||
There's this old server which I haven't accessed in years. It seems that I have forgotten the password...
|
||||
I left some important files on that server. Can you help me get access again and recover my files?
|
||||
There should still be an ssh server running on port 2222.
|
||||
I made a disk image of the computer that I used to have access with a long time ago, maybe you can figure something out?
|
||||
IP address of the server:
|
||||
|
||||
Hint: Don't bother trying to brute-force the password.
|
||||
|
||||
== Files ==
|
||||
Participants should receive the disk.zip file.
|
||||
|
||||
== Deployment ==
|
||||
The docker container providing an ssh server with a flag in it needs to be deployed.
|
||||
|
||||
Run ./docker_run.sh voor de ssh server, dan bolt em op localhost:2222 (docker moet geinstalleerd zijn).
|
||||
@Benjamin Niet lui zijn en dit skippen, gewoon docker installeren gij patattenzak.
|
||||
|
||||
Forensics challenge
|
||||
70 punten
|
BIN
lost-keys/disk.zip
Normal file
27
lost-keys/docker_run.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
docker kill lost-keys
|
||||
docker rm lost-keys
|
||||
|
||||
docker build -t lost-keys .
|
||||
|
||||
docker run -d \
|
||||
--name=lost-keys \
|
||||
-e PUID=1000 \
|
||||
-e PGID=1000 \
|
||||
-e TZ=Europe/Brussels \
|
||||
-e USER_NAME=joske \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD="hvfu7s7xBNGe6Rxa" \
|
||||
-e PUBLIC_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDO2F8WY5XTTcCapt0QhOOAetHTkdBJo+mc/bJ6oRg/0FJ9Ro74yZxcqOTbyEPf/khg9qY9TKf121CaXvJJSLmv3U20X15UlHnDPrh+EsRiCMaiMGd/N+l1ZQ+grj1klcblYxSt7nKtLhh36JaC9A6olFF8ahzcm1Rl69tE4bLdKqALpAbhbTmTlofIH1dzGDF31EfJeLZnuV5XRLq9XCF2YJkbyUJjeBs+4iHQFWxZFfYZJBMAYFLkNrmYvsKjwgwHBEC/g2nCRvW/0KhkXl/N8NU5jXw67Snf/unqD8JmC7Or3GgKT6+sdthbi2dWO4beSEnVoijmvFt+2uwSwU97tij7a7j6Z+J7ekkDDbt8Due1CxNL7sBcIbB22ELC0WwpEijzYC+RaCtiRegzEuGJui9wdjX7kOKxEobSVfSHgzzrT6FJWdThnQ4SZ2vsF6Yt5OjyXNI5TRiNv9DZAYdK6KNyxsxjEmkVZc1JGAsWzdq/GcBH1MilrK5w97JYat8= nibor@Rylia" \
|
||||
-p 2222:2222 \
|
||||
--restart unless-stopped \
|
||||
lost-keys
|
||||
|
||||
# Permissions set in Dockerfile are overwritten
|
||||
# For some reason, it doesn't work immediately
|
||||
sleep 3s
|
||||
|
||||
docker exec lost-keys chmod -R -w /config
|
||||
docker exec lost-keys chmod -R +w /config/logs
|
1
lost-keys/flag.txt
Normal file
@ -0,0 +1 @@
|
||||
IGCTF{TheyWereInMyJacket!}
|
33
lost-keys/image.nix
Normal file
@ -0,0 +1,33 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
let utils = import ../deployment/utils.nix {} ;
|
||||
files = [
|
||||
(utils.copy ./flag.txt "home/joske/flag.txt")
|
||||
(pkgs.writeTextDir "home/joske/.ssh/authorized_keys" ''
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDO2F8WY5XTTcCapt0QhOOAetHTkdBJo+mc/bJ6oRg/0FJ9Ro74yZxcqOTbyEPf/khg9qY9TKf121CaXvJJSLmv3U20X15UlHnDPrh+EsRiCMaiMGd/N+l1ZQ+grj1klcblYxSt7nKtLhh36JaC9A6olFF8ahzcm1Rl69tE4bLdKqALpAbhbTmTlofIH1dzGDF31EfJeLZnuV5XRLq9XCF2YJkbyUJjeBs+4iHQFWxZFfYZJBMAYFLkNrmYvsKjwgwHBEC/g2nCRvW/0KhkXl/N8NU5jXw67Snf/unqD8JmC7Or3GgKT6+sdthbi2dWO4beSEnVoijmvFt+2uwSwU97tij7a7j6Z+J7ekkDDbt8Due1CxNL7sBcIbB22ELC0WwpEijzYC+RaCtiRegzEuGJui9wdjX7kOKxEobSVfSHgzzrT6FJWdThnQ4SZ2vsF6Yt5OjyXNI5TRiNv9DZAYdK6KNyxsxjEmkVZc1JGAsWzdq/GcBH1MilrK5w97JYat8= nibor@Rylia
|
||||
'')
|
||||
] ;
|
||||
in
|
||||
pkgs.dockerTools.buildImage {
|
||||
name = "lost-keys";
|
||||
tag = "latest";
|
||||
contents = files ++ [ pkgs.busybox ];
|
||||
runAsRoot = ''
|
||||
${pkgs.dockerTools.shadowSetup}
|
||||
useradd -U -m joske
|
||||
mkdir -p /home/joske/
|
||||
chown -R joske:joske /home/joske/
|
||||
echo "joske:hvfu7s7xBNGe6Rxa" | chpasswd
|
||||
mkdir -p /root
|
||||
${pkgs.dropbear}/bin/dropbearkey -t rsa -f /root/hostkey
|
||||
chmod o-r /root/hostkey
|
||||
chmod -R -w /home/joske/
|
||||
'';
|
||||
|
||||
config = {
|
||||
ExposedPorts = {
|
||||
"2222/tcp" = {};
|
||||
};
|
||||
Cmd = [ "${pkgs.dropbear}/bin/dropbear" "-r" "/root/hostkey" "-F" "-g" "-j" "-k" "-p" "2222" ];
|
||||
};
|
||||
}
|
39
lost-keys/test_script/id_rsa
Normal file
@ -0,0 +1,39 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAYEAzthfFmOV003AmqbdEITjgHrR05HQSaPpnP2yeqEYP9BSfUaO+Mmc
|
||||
XKjk28hD3/5IYPamPUyn9dtQml7ySUi5r91NtF9eVJR5wz64fhLEYgjGojBnfzfpdWUPoK
|
||||
49ZJXG5WMUre5yrS4Yd+iWgvQOqJRRfGoc3JtUZevbROGy3SqgC6QG4W05k5aHyB9Xcxgx
|
||||
d9RHyXi2Z7leV0S6vVwhdmCZG8lCY3gbPuIh0BVsWRX2GSQTAGBS5Da5mL7Co8IMBwRAv4
|
||||
Npwkb1v9CoZF5fzfDVOY18Ou0p3/7p6g/CZguzq9xoCk+vrHbYW4tnVjuG3khJ1aIo5rxb
|
||||
ftrsEsFPe7Yo+2u4+mfie3pJAw27fA7ntQsTS+7AXCGwdthCwtFsKRIo82AvkWgrYkXoMx
|
||||
LhibovcHY1+5DisRKG0lX0h4M860+hSVnU4Z0OEmdr7BemLeTo8lzSOU0Yjb/Q2QGHSuij
|
||||
csbMYxJpFWXNSRgLFs3avxnAR9TIpayucPeyWGrfAAAFgCbLOeAmyzngAAAAB3NzaC1yc2
|
||||
EAAAGBAM7YXxZjldNNwJqm3RCE44B60dOR0Emj6Zz9snqhGD/QUn1GjvjJnFyo5NvIQ9/+
|
||||
SGD2pj1Mp/XbUJpe8klIua/dTbRfXlSUecM+uH4SxGIIxqIwZ3836XVlD6CuPWSVxuVjFK
|
||||
3ucq0uGHfoloL0DqiUUXxqHNybVGXr20Thst0qoAukBuFtOZOWh8gfV3MYMXfUR8l4tme5
|
||||
XldEur1cIXZgmRvJQmN4Gz7iIdAVbFkV9hkkEwBgUuQ2uZi+wqPCDAcEQL+DacJG9b/QqG
|
||||
ReX83w1TmNfDrtKd/+6eoPwmYLs6vcaApPr6x22FuLZ1Y7ht5ISdWiKOa8W37a7BLBT3u2
|
||||
KPtruPpn4nt6SQMNu3wO57ULE0vuwFwhsHbYQsLRbCkSKPNgL5FoK2JF6DMS4Ym6L3B2Nf
|
||||
uQ4rEShtJV9IeDPOtPoUlZ1OGdDhJna+wXpi3k6PJc0jlNGI2/0NkBh0roo3LGzGMSaRVl
|
||||
zUkYCxbN2r8ZwEfUyKWsrnD3slhq3wAAAAMBAAEAAAGAUh6/KaFh42FUHVIwJBXOSLz6Px
|
||||
f97K6h2g0y5dK9UOCBT3FK4+UPKg53xfYtVGmdDLn/6AheCpMG3jLh2EyCRBsFdZ4DUmsc
|
||||
KHLnRk5nH1DCo7O5810cV9pGqRFkGGIKdBmxJRis+Kp7VmfGEbmZdD5mV5G9YaxdhpVsGV
|
||||
3N6Fa68cQuYyM9H6Y8xCwFSRGK2jsyQP+m02lZ1iXYScOhGWFiiBCQRfNyRbX7nKRUvs2k
|
||||
Rfj3fke/wRElAEqD9gXcj9cjy3DHCZMuTw7RFaUbL69Wsffw3A3bakeiQd0vW3AChx23+j
|
||||
FY50NODnpAfQp4seEPZMeyGpIaXDB2bvd3uG6T4jsGK5eY9A4WDOgybTQU+kg2hxQWXp8t
|
||||
5O/ayDlu0IFGiOWt8CQu8LabVJDmDWsGvZS8gLpOljEKo7eUCPYXVGTghg1MfZZXbRFDaG
|
||||
2AV13PX5aecnL2av5mmpl4/+yGN/iut+mdsh3w7HNcuNGAbgZ85Na8WYCY1fYCjRBhAAAA
|
||||
wF7vcDZOHz+upLdM+4R4J85SS5K0MavYU+waCem0G+p1YpU/jWdyOG73dfpu2FVJEN1gtQ
|
||||
WZkpmPVdaUmkj7mpmq1eIHO31mT2Yoww4duLpR1Za1lOcZmVsBOu0mp1kOr8UPS9M2vrVz
|
||||
ENJscsY6IRBvbeqUg3te3GdneRoC1SiZCzG48FRcA5VJ+TM427A8RpOL/jTDA13Pnooxo0
|
||||
jBgcflcmID+Id5qhfg5XsAogrmq3iv+ETVGc8UxD6FeMTQNQAAAMEA5+lN+eDVQNA/tPWO
|
||||
RC3ZHDkR9diL1c5/aQl+XPmZiiaIQW6HsajACn+1pPoJlEe1QMEfRr9CBOsHbf9nLa9GV+
|
||||
Q6H1tgUjOPClInm4Sg1RLDs05DvKnXYzYgpIvGj0sJf/A6sBXSaf+THBDTrM5mgGTWbygW
|
||||
uB26MUggcKG4DlL70+LeZyEDBkCq6ViiGU8Jd8Ei3UkIuDKtyToRI1GxN68vTVPtAYde5B
|
||||
h+n6Vjjiitk12HFE/1+/WQ02t3U3dxAAAAwQDkVIoUaPfgM3F46czRA3chitWU5EQibJsE
|
||||
IzIOocCtikwZe0u4Q5JIz/44+vLQpvghpeQBJ7oBA9ehLVp+lrofywDY3foKHT0FvpE0Y+
|
||||
POU3Cjjp5kN7ivgZnWHmb3z2Zj55rduINAjkb51PkF21/tT63Kk37u2LF2ZegKubgOKLR1
|
||||
WvuqP/Ue78FVvVOwoixwu/SgZagjxEm/n9sIUtUbYreHSdFQtxe7zwORLB4AwdCy9niNFi
|
||||
mHYLnr6qjt/08AAAALbmlib3JAUnlsaWE=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
|
13
lost-keys/test_script/test_script.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# $1: IP, $2: Port
|
||||
|
||||
RES=$(ssh -p $2 -i id_rsa joske@$1 "cat flag.txt")
|
||||
|
||||
echo $RES
|
||||
|
||||
if [[ "$RES" == *"IGCTF"* ]]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
0
mad_cows/.gitkeep
Normal file
15
mad_cows/bliep.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Title
|
||||
Mad cows
|
||||
|
||||
# Description
|
||||
Because of corona there are no standup comedy acts no more, to flower up your day I have provided you with an audio element of Geert Hoste a belgian comedian.
|
||||
Corona is said to be started by eating bats, we'll the mad cow disease has presumable started after Belgian prime minister Jean-Luc Dehaene sat on a pneumatic bull shouting the phrase "let the beast go" in 1995.
|
||||
|
||||
# files
|
||||
mad_cows_geert_hoste.mp3
|
||||
|
||||
# deployment
|
||||
n/a
|
||||
|
||||
# type
|
||||
Steganography
|