From 26db64326f4cfee23a03481e2fe56f7d12d78705 Mon Sep 17 00:00:00 2001 From: pranav2007 Date: Sat, 14 Mar 2026 17:06:39 +0530 Subject: [PATCH 1/7] Add bandit wargames writeup --- banditWargames.md | 295 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 banditWargames.md diff --git a/banditWargames.md b/banditWargames.md new file mode 100644 index 0000000..d6730ef --- /dev/null +++ b/banditWargames.md @@ -0,0 +1,295 @@ +# Bandit Wargames + +## 1. Level 0 + +Opening SSH server in PowerShell : +```bash +ssh username@hostname -p port +``` + +eg: +```bash +ssh myuser@example.com -p 22 +``` + +## 2. Level 0 → 1 + +Commands: + +- `cd` – enters into sub folder +- `ls` – lists items in the folder +- `cat` – shows the expected content of the file that the operation is used on +- `file` – gives the type of file it is +- `du` – gives the disk usage of the file +- `find` – finds the file by name + +password level 1 → `ZjLjTmM6FvvyRnrb2rfNWOZOTa6ip5If` + +## 3. Level 1 → 2 + +for file name `-` the normal cat function wont work as the terminal understands it as dev/stdin or dev/stdout so if we want to run the cat command on a file named `-` we must do so in the following way: +```bash +cat ./- +``` + +As a precaution we should set a standard to always write the file name in the following syntax: +```bash +cat ./'filename' +``` +```bash +cat ./"Filename" +``` + +password level 2 → `263JGJPfgU6LtdEvgfWU1XP5yac29mFx` + +## 4. Level 2 → 3 + +If a file name consists of spaces then writing cat ./filename with spaces wont give the desired output so instead we have to use ("") or ('') and enter the filename in those braces for the command to execute in a desired manner. + +Password level 3 → `MNk8KNH3Usiio41PRUEoDFPqfxLPlSmx` + +## 5. Level 3 → 4 + +The hidden file wont be shown in the ls command list. We have to use the `find` command to discover the file which was hiding from us. + +Password level 4 → `2WmrDFRmJIq3IPxneAaMGhap0pFhF3NJ` + +## 6. Level 4 → 5 + +7 files are given out of which in 6 of them human unreadable code is given and only one of the files has the readable code. Somehow if we run the find command it automatically pushes the human readable list to the top and thus we can just cat the readable file and obtain our password. + +Password 5 → `4oQYVPkxZOOEOO5pTW81FB8j8lxXGUQw` + +## 7. Level 5 → 6 + +We are required to find a file with a particular find size of 1033 bytes. To do so we use the extension of the find function in our powershell (`c` stands for bytes): +```bash +find . -size 1033c +``` + +Password 6 → `HWasnPhtq9AVKe0dmk45nxy20cvUa6EG` + +## 8. Level 6 → 7 + +This was the first of proper multistep level. We are given specification for the file that contains the password for the next level: + +- Owned by user - bandit7 +- Owned by group - bandit6 +- File size – 33c + +To do this we have to run a find command with various filters. To do so we have to use the following syntax: +```bash +find / -filter1 filter1condition -filter2 filter2condition -filter3 filter3condition …… +``` + +For example the code we have to use in this particular level is: +```bash +find / -type f -user bandit7 -group bandit6 -size 33c +``` + +But this will show all the files with error messages who denied permission at this stage so to remove the files with such error message we use the following extended command: +```bash +find / -type f -user bandit7 -group bandit6 -size 33c 2>/dev/null +``` + +This will only give the desired files. Then just cat the location of the file given and obtain the password. + +Password 7 → `morbNTDkSW6jIlUc0ymOdMaLnOlFVAaj` + +## 9. Level 7 → 8 + +The txt file is very long and has 2 words in each line. It is almost impossible to manually find "millionth" word so we use a search function called grep. We can also find the line number of the given file using `-n` extension to the existing command grep. The syntax is as follows: +```bash +grep "wordthatyouwanttofind" filename +``` + +For example: +```bash +grep "millionth" data.txt +``` + +Password 8 → `dfwvzFQi4mU0wfNbFOe9RoWskMLg7eEc` + +## 10. Level 8 → 9 + +The `uniq` command only removes adjacent duplicate lines. To remove all duplicate lines from a file, regardless of their position, you must first sort the file to bring identical lines together. This is achieved by piping the output of the `sort` command into the `uniq` command. + +Now the required line can be obtained in two ways: + +1. Sort data.txt | uniq -c — This will give the count of each line repeated, just look manually for the line which has count 1: +```bash +sort data.txt | uniq -c +``` + +2. Sort data.txt | uniq -u — This will give the only line which has only been repeated once directly, avoiding the hassle to read the count of each string manually (preferable method): +```bash +sort data.txt | uniq -u +``` + +Password 9 → `4CKMh1JI91bUIZZPXDqGanal4xvAg0JM` + +## 11. Level 9 → 10 + +Just use the strings command, it pretty much shows the password as is. + +Password 10 → `FGUlW5ilLVJrxX9kMYMmlN4MgbpfMiqey` + +## 12. Level 10 → 11 + +The data.txt file contains a base64 file so now we have to decode it. Just run the `base64 --help` command which will show the command for decoding a base64 file (it is –decode ;)) +```bash +base64 --decode data.txt +``` + +It will give the password. + +Password 11 → `dtR173fZKb0RRsDFSGsg2RWnpNVj3qRr` + +## 13. Level 11 → 12 + +This is a bit peculiar. +```bash +cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m' +``` + +First enter the things that you want to change in the given manner then break the transformation because writing directly "N-An-A" will raise an error saying it is in reverse order so break it into parts where it looks like it is in normal so as to give rise to the following string `N-ZA-Mn-za-m`. + +Password 12 → `7x16WNeHIi5YkIhWsfFIqoognUTyj9Q4` + +## 14. Level 12 → 13 + +https://david-varghese.medium.com/overthewire-bandit-level-12-level-13-2ec761a88907 + +Need to know commands: +```bash +mktemp -d # makes temp folder +mv # rename or relocate +cp # copies file/folder +xxd -r hexdump # converts hexdump to binary +tar -xf filename # unarchives files +rm # deletes files +gunzip # decompress (file should have .gz extension) +bunzip2 # decompress +``` + +This article gives the most perfect way to solve this particular level. The given file is in hexdump form so we convert this to binary using xxd. Then we have to decompress the file multiple times and finally we get a file with the required ascii text which contains the password. + +Password 13 → `FO5dwFsc0cbaIiH0h8J2eUks2vdTDwAn` + +## 15. Level 13 → 14 + +We have been given a private ssh key and asked to log into next level. To connect using a private ssh key the following syntax is used: +```bash +ssh -i '/path/to/keyfile' username@server +``` + +In this the username is bandit14, server is localhost, and port is 2220. Therefore the required syntax would be: +```bash +ssh -i /home/bandit13/sshkey.private bandit14@localhost -p 2220 +``` + +Password 14 → (no password) + +## 16. Level 14 → 15 + +Get the password from the given location. The name of the file containing the file is bandit14 so use cat. We have to login to localhost port 30000. To do so we use telnet command with the following syntax: +```bash +telnet --login localhost 30000 +``` + +Then enter the password. + +Password 15.1 → `MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS` + +## 17. Level 15 → 16 + +To connect to a port with ssl/tls encryption use the following syntax: +```bash +openssl s_client -connect : +``` + +Password 15.2 → `8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo` + +Password 16 → `kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx` + +## 18. Level 16 → 17 + +We have been given a range of 1000 ports (31000-32000). We have to find the port which has a server listening to it and also has ssl encryption. To do such search we use nmap command: +```bash +nmap -sV -p 31000-32000 localhost +``` + +We login to bandit16 using ssh and then procure the file password with the following command: +```bash +cat /etc/bandit_pass/bandit16 +``` + +Copy the password and follow the next steps. This gives the list of all the ports which are having a server listening to them then further it shows the ports which have ssl encryption. The port 31518 has echo which cant be trusted so we use the port 31790 port and connect to it with ssl encryption using the following command: +```bash +openssl s_client --connect localhost:31790 -ign_eof +``` + +This gives us the private ssh key. Now create a new directory in which you can store the ssh key: +```bash +mkdir /tmp/random_sshkey +cd /tmp/random_sshkey +touch private.key +vim private.key +``` + +Press `i`, paste the sshkey, then press `Esc` and type `:wq`. By doing so you have now created your private.key file. Now connect to the port using private key: +```bash +chmod 400 private.key +ssh -i /tmp/random_sshkey/private.key bandit17@localhost -p 2220 +``` + +You will then enter level 17 + +## 19. Level 17 → 18 + +Only one line has been changed between two files so to find this line we use the diff command: +```bash +diff filename1 filename2 +``` + +The output is something like: + aksdjfhkjadshfadsjk + +The first part is corresponding to the different line in file 1 and 2nd part corresponds to the different part in the second file. + +Password (diff bw the two files) → `x2gLTTjFwMOhQ8oWNbMN362QKxfRqGlO` + +But when we try to login level 18 using this password we get byebye, to resolve this we have to go to next level. + +## 20. Level 18 → 19 + +We are told that we can't use ssh normally because someone has messed with bashrc. So now we have to login using another shell. We can find the list of shells by: +```bash +cat /etc/shells +``` + +We use the first shell available by the following command: +```bash +ssh bandit18@bandit.labs.overthewire.org -p 2220 -t "/bin/sh" +``` + +Then do: +```bash +ls +cat readme +``` + +Get the password for level 19. + +Level 19 → `cGWpMaKXVwDUNgPAVJbWYuGHVn9zl3j8` + +## 21. Level 19 → 20 + +We have a setuid binary file. `ls -l` tells us about the properties of the file. We can see that the bandit20 file is owned by bandit20. When we do `./bandit20-do` it tells us that we can now run files as another user called bandit20. Then do the normal: +```bash +./bandit20-do cat /etc/bandit_pass/bandit20 +``` + +To get the password. + +Password 20 → `0qXahG8ZjOVMN9Ghs7iOWsCfZyXOUbYO` \ No newline at end of file From 21c338a2c0610f7bf645b0c11ced4b8c601fdf49 Mon Sep 17 00:00:00 2001 From: Pranav Date: Sun, 15 Mar 2026 00:21:15 +0530 Subject: [PATCH 2/7] adding monkey type --- typetesting.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 typetesting.sh diff --git a/typetesting.sh b/typetesting.sh new file mode 100644 index 0000000..fb16896 --- /dev/null +++ b/typetesting.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +goal_text="innovation distinguishes between a leader and a follower, and the code we write today becomes the foundation for the intelligence of tomorrow." + +while true; do + clear + echo "typing test" + echo "" + echo "$goal_text" + echo "" + echo "press [enter] to begin" + read + + begin=$(date +%s) + + echo -n "typing> " + read user_attempt + + finish=$(date +%s) + + elapsed_seconds=$(( finish - begin )) + + # safety check for division operations + if [ $elapsed_seconds -lt 1 ]; then elapsed_seconds=1; fi + + # calculate words per minute + total_chars=${#user_attempt} + words_per_minute=$(( (total_chars * 60) / (elapsed_seconds * 5) )) + + # accuracy + correct_hits=0 + goal_length=${#goal_text} + attempt_length=${#user_attempt} + + for (( i=0; i<$goal_length && i<$attempt_length; i++ )); do + if [[ "${goal_text:$i:1}" == "${user_attempt:$i:1}" ]]; then + ((correct_hits++)) + fi + done + + precision_score=$(( (correct_hits * 100) / goal_length )) + + echo -e "\n--- results ---" + echo "duration: $elapsed_seconds s" + echo "wpm: $words_per_minute wpm" + echo "precision: $precision_score%" + echo "" + + echo "try again? (r= retry, q = quit): " + read action_choice + if [[ "$action_choice" == "q" ]]; then + echo "goodbye!" + break + fi +done \ No newline at end of file From 640b96498ed2c68697b533db644dbde88a5688b8 Mon Sep 17 00:00:00 2001 From: pranav2007 Date: Sun, 15 Mar 2026 19:51:45 +0530 Subject: [PATCH 3/7] Add improvements to the typing test --- typetesting.sh | 174 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 47 deletions(-) diff --git a/typetesting.sh b/typetesting.sh index fb16896..892da99 100644 --- a/typetesting.sh +++ b/typetesting.sh @@ -1,55 +1,135 @@ #!/bin/bash -goal_text="innovation distinguishes between a leader and a follower, and the code we write today becomes the foundation for the intelligence of tomorrow." +WORD_FILE="/usr/share/dict/words" +COUNT=20 +DIFF="medium" + +# colors +GRN="\033[32m" +RED="\033[31m" +DIM="\033[2m" +RST="\033[0m" +UND="\033[4m" +UND_OFF="\033[24m" + +# generate words +generate_words() { + count=$1 + min=$2 + max=$3 + grep -E "^[a-z]{$min,$max}$" "$WORD_FILE" | sort -R | head -n "$count" +} + +# pick words +case "$DIFF" in + easy) raw=$(generate_words "$COUNT" 2 5);; + medium) raw=$(generate_words "$COUNT" 4 8);; + hard) raw=$(generate_words "$COUNT" 6 12);; + *) raw=$(generate_words "$COUNT" 3 8);; +esac + +words=$(echo "$raw" | tr '\n' ' ') +words="${words% }" + +# draw screen +render() { -while true; do clear echo "typing test" - echo "" - echo "$goal_text" - echo "" - echo "press [enter] to begin" - read - - begin=$(date +%s) - - echo -n "typing> " - read user_attempt - - finish=$(date +%s) - - elapsed_seconds=$(( finish - begin )) - - # safety check for division operations - if [ $elapsed_seconds -lt 1 ]; then elapsed_seconds=1; fi - - # calculate words per minute - total_chars=${#user_attempt} - words_per_minute=$(( (total_chars * 60) / (elapsed_seconds * 5) )) - - # accuracy - correct_hits=0 - goal_length=${#goal_text} - attempt_length=${#user_attempt} - - for (( i=0; i<$goal_length && i<$attempt_length; i++ )); do - if [[ "${goal_text:$i:1}" == "${user_attempt:$i:1}" ]]; then - ((correct_hits++)) + echo "----------------" + echo + + for ((i=0;i<${#words};i++)); do + c="${words:$i:1}" + + if ((i < pos)); then + if [[ "${typed:$i:1}" == "$c" ]]; then + printf "${GRN}%s${RST}" "$c" + else + printf "${RED}%s${RST}" "$c" + fi + + elif ((i == pos)); then + printf "${UND}%s${UND_OFF}" "$c" + + else + printf "${DIM}%s${RST}" "$c" fi done - - precision_score=$(( (correct_hits * 100) / goal_length )) - - echo -e "\n--- results ---" - echo "duration: $elapsed_seconds s" - echo "wpm: $words_per_minute wpm" - echo "precision: $precision_score%" - echo "" - - echo "try again? (r= retry, q = quit): " - read action_choice - if [[ "$action_choice" == "q" ]]; then - echo "goodbye!" - break + + echo + echo +} + +# results +results() { + + secs=$1 + correct=0 + + for ((i=0;i<${#words} && i<${#typed};i++)); do + [[ "${typed:$i:1}" == "${words:$i:1}" ]] && ((correct++)) + done + + wc=$(echo "$words" | wc -w | tr -d ' ') + + wpm=0 + if ((secs>0)); then + wpm=$(( (wc * 60) / secs )) + fi + + acc=0 + if ((${#words}>0)); then + acc=$(( (correct * 100) / ${#words} )) fi -done \ No newline at end of file + + clear + echo + echo "results" + echo "-------" + echo "time: $secs seconds" + echo "wpm: $wpm" + echo "accuracy: $acc%" + echo +} + +# main +pos=0 +typed="" +started=0 +t0=0 + +echo "press enter to start" +read + +render + +while ((pos < ${#words})); do + + IFS= read -rsn1 key + + if ((started==0)); then + t0=$SECONDS + started=1 + fi + + # backspace + if [[ "$key" == $'\x7f' ]]; then + if ((pos>0)); then + ((pos--)) + typed="${typed:0:$pos}" + fi + render + continue + fi + + [[ -z "$key" ]] && key=" " + + typed+="$key" + ((pos++)) + + render + +done + +results $((SECONDS - t0)) \ No newline at end of file From 7443c9afe9008d033fdc11b0c3a081a8c7a2930e Mon Sep 17 00:00:00 2001 From: pranav2007 Date: Mon, 16 Mar 2026 00:10:42 +0530 Subject: [PATCH 4/7] Add cli options to choose difficuty and num of words, also result store in csv --- typetesting.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/typetesting.sh b/typetesting.sh index 892da99..dad9a4e 100644 --- a/typetesting.sh +++ b/typetesting.sh @@ -1,9 +1,17 @@ -#!/bin/bash +640b964#!/bin/bash WORD_FILE="/usr/share/dict/words" COUNT=20 DIFF="medium" +# CLI options +while getopts "n:d:" opt; do + case $opt in + n) COUNT=$OPTARG ;; + d) DIFF=$OPTARG ;; + esac +done + # colors GRN="\033[32m" RED="\033[31m" @@ -91,6 +99,14 @@ results() { echo "wpm: $wpm" echo "accuracy: $acc%" echo + + LOG="$HOME/.typetest_log.csv" + + if [[ ! -f "$LOG" ]]; then + echo "date,time,wpm,accuracy" > "$LOG" + fi + + echo "$(date +%F),$secs,$wpm,$acc" >> "$LOG" } # main From 4dc8af911815c459e00756e42d29582dcb94d81a Mon Sep 17 00:00:00 2001 From: pranav2007 Date: Mon, 16 Mar 2026 00:25:57 +0530 Subject: [PATCH 5/7] Remove accidental string in code --- typetesting.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typetesting.sh b/typetesting.sh index dad9a4e..4643f66 100644 --- a/typetesting.sh +++ b/typetesting.sh @@ -1,4 +1,4 @@ -640b964#!/bin/bash +#!/bin/bash WORD_FILE="/usr/share/dict/words" COUNT=20 From a5a161a51f7ab313d4fb8b4b67d036b8a48d41f0 Mon Sep 17 00:00:00 2001 From: pranav2007 Date: Mon, 16 Mar 2026 00:58:45 +0530 Subject: [PATCH 6/7] Add git exercise and improve directory structure --- .../banditWargames.md | 0 writeups/gitwriteup.md | 177 ++++++++++++++++++ 2 files changed, 177 insertions(+) rename banditWargames.md => writeups/banditWargames.md (100%) create mode 100644 writeups/gitwriteup.md diff --git a/banditWargames.md b/writeups/banditWargames.md similarity index 100% rename from banditWargames.md rename to writeups/banditWargames.md diff --git a/writeups/gitwriteup.md b/writeups/gitwriteup.md new file mode 100644 index 0000000..6bdfad0 --- /dev/null +++ b/writeups/gitwriteup.md @@ -0,0 +1,177 @@ +# Git Exercises + +## 1. master + +```bash +git start master +git start next +``` + +--- + +## 2. commit-one-file + +Here we simply add A.txt to the staging area and then commit it. + +```bash +git add A.txt +git commit -m "commit A" +``` + +--- + +## 3. commit-one-file-staged + +In this case we commit only A.txt directly by putting the file in the commit. + +```bash +git commit A.txt -m "commit A" +``` + +--- + +## 4. ignore-them + +We create a .gitignore file first. Inside it we add these entries so git ignores those files: + +/libraries +*.exe +*.o +*.jar + +```bash +touch .gitignore +nano .gitignore +git add .gitignore +git commit -m "add gitignore rules" +``` + +--- + +## 5. chase-branch + +We can solve this using a hard reset. + +```bash +git reset --hard escaped +``` + +--- + +## 6. merge-conflict + +Two branches had conflicting changes in the file equation.txt. + +One branch contained: + +2 + ? = 5 + +The other branch contained: + +? + 3 = 5 + +To resolve the conflict we edit the file so that the correct equation becomes: + +2+3=5 + +```bash +nano equation.txt +git add equation.txt +git commit -m "resolve merge conflict" +``` + +--- + +## 7. saving-your-work + +This step uses git stash. + +First we stash the changes. Then we fix a bug in bug.txt. commit it and then go back to the stashed work using git stash pop. + +```bash +git stash +nano bug.txt +git add bug.txt +git commit -m "fix bug" +git stash pop +nano bug.txt +git add bug.txt +git commit -m "restore changes" +``` + +--- + +## 8. change-branch-history + +We need to move the commit from the branch change-branch-history into the branch hot-bugfix. This is done using git rebase. + +```bash +git rebase hot-bugfix +``` + +--- + +## 9. remove-ignored + +Here we remove ignored.txt and stage and commit the change. + +```bash +rm ignored.txt +git add . +git commit -m "remove ignored file" +``` + +--- + +## 10. case-sensitive-filename + +Rename File.txt to file.txt. + +```bash +mv File.txt file.txt +git add . +git commit -m "rename file" +``` + +--- + +## 11. fix-typo + +First we edit the file and fix the typo. Then we check the previous commit message using git log. rather than creating a new commit we change the previous commit using amend. + +```bash +nano file.txt +git add file.txt +git log +git commit --amend -m "Add Hello world" +``` + +--- + +## 12. forge-date + +Here we over ride the previous commit and manually set the commit date.This is done using the date flag with git commit amend. + +```bash +git commit --amend --date "1987-01-01 00:00:00" +``` + +--- + +## 13. fix-old-typo + +This step involves an interactive rebase. We start the rebase and edit the second newest commit. We change pick to edit. + +After that we fix the typo in the file, stage the change, and continue the rebase. During the process git expects to correct the commit message, we fix that also. + +Once everything is resolved we continue the rebase. + +```bash +git rebase -i HEAD~2 +nano file.txt +git add file.txt +git rebase --continue +nano file.txt +git add file.txt +git rebase --continue +``` From e74c5e294527c6e2e2d1ddec8bd9c13bdb1a2e0e Mon Sep 17 00:00:00 2001 From: pranav2007 Date: Mon, 16 Mar 2026 01:21:19 +0530 Subject: [PATCH 7/7] Add --help flag and improve rendering with tput cup 0 0 --- typetesting.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) mode change 100644 => 100755 typetesting.sh diff --git a/typetesting.sh b/typetesting.sh old mode 100644 new mode 100755 index 4643f66..804c12d --- a/typetesting.sh +++ b/typetesting.sh @@ -4,6 +4,18 @@ WORD_FILE="/usr/share/dict/words" COUNT=20 DIFF="medium" +show_help() { + echo "flags:" + echo "-n number of words" + echo "-d difficulty | easy | medium | hard" + echo "--help get help" +} + +if [[ "$1" == "--help" ]]; then + show_help + exit 0 +fi + # CLI options while getopts "n:d:" opt; do case $opt in @@ -22,7 +34,7 @@ UND_OFF="\033[24m" # generate words generate_words() { - count=$1 + local count=$1 min=$2 max=$3 grep -E "^[a-z]{$min,$max}$" "$WORD_FILE" | sort -R | head -n "$count" @@ -42,7 +54,7 @@ words="${words% }" # draw screen render() { - clear + tput cup 0 0 echo "typing test" echo "----------------" echo