├── README.md ├── algorithm ├── README.md ├── dictionary │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ ├── chall-06.md │ ├── chall-07.md │ ├── chall-08.md │ ├── chall-09.md │ └── chall-10.md ├── list │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ ├── chall-06.md │ ├── chall-07.md │ ├── chall-08.md │ ├── chall-09.md │ ├── chall-10.md │ ├── chall-11.md │ ├── chall-12.md │ ├── chall-13.md │ ├── chall-14.md │ ├── chall-15.md │ └── chall-16.md ├── number │ ├── chall-00.md │ ├── chall-01.md │ └── chall-02.md ├── regex │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ ├── chall-06.md │ └── chall-07.md └── string │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ ├── chall-06.md │ ├── chall-07.md │ ├── chall-08.md │ ├── chall-09.md │ └── chall-10.md ├── binary ├── README.md ├── disassembly │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ └── resources │ │ ├── sample-00.bin │ │ ├── sample-00.nasm │ │ ├── sample-01.bin │ │ ├── sample-01.nasm │ │ ├── sample-02.bin │ │ ├── sample-02.nasm │ │ ├── sample-03 │ │ └── sample-03.nasm ├── interoperable │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ └── resources │ │ ├── clib-32.dll │ │ ├── clib-32.so │ │ ├── clib-64.dll │ │ ├── clib-64.so │ │ ├── clib-dll.c │ │ └── clib-so.c └── parsing │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ ├── chall-06.md │ ├── chall-07.md │ ├── chall-08.md │ ├── chall-09.md │ └── chall-10.md ├── bruteforce ├── README.md ├── fuzzing │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ └── chall-03.md └── wordlist-gen │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ └── chall-05.md ├── crypto ├── README.md ├── cipher │ ├── asymmetric │ │ ├── chall-00.md │ │ ├── chall-01.md │ │ ├── chall-02.md │ │ ├── chall-03.md │ │ ├── chall-04.md │ │ ├── chall-05.md │ │ └── chall-06.md │ ├── attack │ │ ├── chall-00.md │ │ ├── chall-01.md │ │ ├── chall-02.md │ │ └── chall-03.md │ ├── block │ │ ├── chall-00.md │ │ ├── chall-01.md │ │ ├── chall-02.md │ │ ├── chall-03.md │ │ ├── chall-04.md │ │ ├── chall-05.md │ │ ├── chall-06.md │ │ └── chall-07.md │ ├── classic │ │ ├── chall-00.md │ │ ├── chall-01.md │ │ ├── chall-02.md │ │ ├── chall-03.md │ │ ├── chall-04.md │ │ ├── chall-05.md │ │ ├── chall-06.md │ │ └── chall-07.md │ └── stream │ │ └── chall-00.md ├── encode │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ └── chall-04.md └── hash │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ └── chall-05.md ├── files ├── README.md ├── access │ ├── chall-00.md │ └── chall-01.md ├── compression │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ └── resources │ │ ├── sample-00.bin │ │ ├── sample-01.bin │ │ ├── sample-02.bin │ │ ├── sample-03.bin │ │ ├── sample-04.tar │ │ └── sample-05.zip ├── parsing │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ └── resources │ │ ├── sample-00.txt │ │ ├── sample-01.bin │ │ ├── sample-02a.csv │ │ ├── sample-02b.csv │ │ ├── sample-03.bin │ │ └── sample-04.bin └── raw │ └── chall-00.md ├── network ├── README.md ├── protocol │ ├── client │ │ ├── chall-00.md │ │ ├── chall-01.md │ │ ├── chall-02.md │ │ ├── chall-03.md │ │ ├── chall-04.md │ │ ├── chall-05.md │ │ ├── chall-06.md │ │ ├── chall-07.md │ │ ├── chall-08.md │ │ ├── chall-09.md │ │ ├── chall-10.md │ │ ├── chall-11.md │ │ ├── chall-12.md │ │ └── chall-13.md │ └── server │ │ ├── chall-00.md │ │ ├── chall-01.md │ │ ├── chall-02.md │ │ ├── chall-03.md │ │ ├── chall-04.md │ │ ├── chall-05.md │ │ └── chall-06.md └── socket │ ├── client │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ └── chall-04.md │ ├── raw │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ └── chall-03.md │ └── server │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ ├── chall-04.md │ ├── chall-05.md │ ├── chall-06.md │ └── chall-07.md ├── process ├── README.md ├── multiprocess │ ├── chall-00.md │ ├── chall-01.md │ └── chall-02.md ├── multithread │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ └── chall-03.md └── subprocess │ ├── chall-00.md │ ├── chall-01.md │ ├── chall-02.md │ ├── chall-03.md │ └── resources │ ├── echoer │ ├── echoer.c │ ├── echoer.exe │ ├── runme │ ├── runme.c │ └── runme.exe └── web ├── README.md ├── requests ├── chall-00.md ├── chall-01.md ├── chall-02.md ├── chall-03.md ├── chall-04.md ├── chall-05.md ├── chall-06.md ├── chall-07.md └── chall-08.md └── scraping ├── chall-00.md ├── chall-01.md ├── chall-02.md ├── chall-03.md ├── chall-04.md ├── chall-05.md ├── chall-06.md └── chall-07.md /README.md: -------------------------------------------------------------------------------- 1 | # Pythonidae Challenge 2 | 3 | Learn Python for Cyber Security by completing challenges. 4 | 5 | ### Overview 6 | 7 | Programming is the heart of problem solving. And you heard that people in cyber security love Python very much. Whether you are offensive or defensive, writing efficient scripts are helpful for your daily routines. 8 | 9 | Python is simple and flexible. Extensive libraries make Python wonderful for working on common tasks. In short, Python provide entire spectrum of features to create powerful and novel programs. 10 | 11 | So you know Python, but you wonder how can you apply it to Cyber Security field? Where to start? 12 | 13 | We've built a collection of exercise that guide you to apply your Python programming knowledge into Cyber Security. We believe that a script is a collection of smaller tasks. Thus, completing task can help in creating complex code for your needs. 14 | 15 | ### What are the rules? 16 | 17 | First of all, we only provide tasks and you can complete it on your own pace. We don't provide any solution and don't ask us for them. 18 | 19 | You can use any approach to tackle the problems. Use existing library or create your own, do whatever you want. We don't restrict your creativity. You can also publish your ellegant and efficient solution. We don't mind. 20 | 21 | Stuck on something? You are allowed to ask help from others. Discuss the problem and experiment. But we don't encourage you to ask for the code. Solving them by yourself is very satisfying, don't you think so? 22 | 23 | And last, enjoy the game. 24 | 25 | ### How much Python do I need to know? 26 | 27 | Basically, no deep and complex knowledge on Python is used. You can even learn Python while work on `Pythonidae Challenge` in parallel. 28 | 29 | However, we suggest you to at least know basic of Python before you start. Let's say: decision making, loop, and functions. 30 | 31 | ### What should I expect? 32 | 33 | Our challenges are divided into some sets. Each set contain various challenge which get progressively harder. You can solve the set individually. To make it more exciting, these challenges are based on real-world tasks found in making script for Cyber Security field. 34 | 35 | Some tasks can be solved by writing one simple function. Some might need couple of them. 36 | 37 | ### Who did this? 38 | 39 | - Dicky Hermansyah | [github:dickyher-lab](https://github.com/dickyher-lab) 40 | - Digit Oktavianto | [github:digitoktavianto](https://github.com/digitoktavianto) 41 | - M. Dzikri Ramdhani | [github:HadrianCorbett](https://github.com/HadrianCorbett) 42 | - Satria Ady Pradana | [github:xathrya](https://github.com/xathrya) 43 | 44 | Pythonidae is maintained and expanded by `xathrya`, in conjunction with MII Cybersec Team at [Mitra Integrasi Informatika](https://mii.co.id). 45 | 46 | Want to add some challenges? Pull Requests are always welcomed. -------------------------------------------------------------------------------- /algorithm/README.md: -------------------------------------------------------------------------------- 1 | # Pythonidae Challenge 2 | 3 | Learn Python for Cyber Security by completing challenges. 4 | 5 | ## Algorithm 6 | 7 | This is `Algorithm Set`. We challenge you to use algorithm (and data structure) for simple data processing. 8 | 9 | This challenge may not be directly related to Cyber Security. But efficiently processing data is the key for succesful operation. 10 | 11 | ## Contents 12 | 13 | You will see 14 | 15 | - `String` manipulation 16 | - `Number` operation 17 | - `List` manipulation 18 | - `Dictionary` manipulation 19 | - `Regular Expression` 20 | 21 | #### String Manipulation 22 | 23 | Modify partial or whole string and transform it to our needs. 24 | 25 | 0. Convert an `str` string to bytes string and get the length. 26 | 1. Given string `U` and list of string `E`. Create a new list by concatenating `U` with each element of `E`. 27 | 2. Given string `D`. Rewrite substring from index `S` to `E` by filling with `x`. 28 | 3. Given integer `N`, `S`, `E`. Create a `bytearray` with length `N`. Fill index `S` to `E` with random number. 29 | 4. Extract a valid URL (starts with `http://` or `https://`) from a very long string. 30 | 5. Decode a hexpair string to bytes. 31 | 6. Do `XOR` with a single byte for each caracter of a given string. 32 | 7. Do `XOR` of two hexpair string with same length. 33 | 8. Do `XOR` of two hexpair string with different length. 34 | 9. Print all permutation of string. 35 | 10. Given string `S` and array of integer `P`. Do reposition using `P` as index of new string. 36 | 37 | #### Number Operation 38 | 39 | 0. compute the `GCD` of two numbers. 40 | 1. list all factors of N. 41 | 2. check the range which include the given integer. 42 | 43 | #### List Manipulation 44 | 45 | 0. find maximum element from non-sorted list. 46 | 1. multiply each element of list with `3` 47 | 2. sum all item of odd index. 48 | 3. given list of string, sort by length. 49 | 4. take all unique element from list. 50 | 5. pick all unique element from list. 51 | 6. pick random item from list. 52 | 7. shuffle the position of each item. 53 | 8. flatten 2-dimension list to 1-dimension list. 54 | 9. given integer S and E with S < E. Create a list of unique integer with value in the range S to E. The position of value is random. 55 | 10. given a string S, create a list of integer with each element is ASCII representation of S. 56 | 11. pick all items common in two list. 57 | 12. zipping element of two list. 58 | 13. partition, split a list every N items. 59 | 14. partition, split a list into N partitions. 60 | 15. build a list of integers starting from 1 to `N`, excluding multiples of `K`. 61 | 16. range expansion. 62 | 63 | #### Dictionary Manipulation 64 | 65 | 0. add value to dictionary only if key not exists. 66 | 1. create a list of all keys (without values). 67 | 2. create a list of all values (without keys). 68 | 3. create a dictionary with key is a number from 1 to N. 69 | 4. given a string, create a dictionary where `key` is a character appear on string and the `value` is the number of occurrence. 70 | 5. delete key if exists. 71 | 6. delete key which has certain value. 72 | 7. create a dictionary by list of Keys and Values. 73 | 8. given list of dictionary, sort the list by the value of certain key. 74 | 9. given list of dictionary, remove certain key from each dictionary. 75 | 10. create a list of dictionary by two lists as values. 76 | 77 | #### Regular Expression 78 | 79 | Regular Expression, or regex, is a special text string for describing a search pattern. 80 | 81 | 0. find and extract IP address (IPv4) 82 | 1. find and extract IP address (IPv6) 83 | 2. find and extract domain name. 84 | 3. find and extract valid email address. 85 | 4. find and extract SSN (Social Security Number). 86 | 5. find and extract 3-digit numbers. 87 | 6. find and extract HTML tag. 88 | 7. find and extract fields from /etc/shadow password. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a dictionary `D`, pair of string `K` and `V`. 4 | 5 | Add value `V` only if the specified key `K` is not exists. No value replaced. 6 | 7 | ## Remarks 8 | 9 | Conditional insertion. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a dictionary `D`. 4 | 5 | Create a list of all the keys without the values. 6 | 7 | ## Test 8 | 9 | Given a dictionary `D` 10 | 11 | ``` 12 | { 13 | "name": "xathrya", 14 | "hp": "100", 15 | "mp": "32" 16 | } 17 | ``` 18 | 19 | should produce 20 | 21 | ``` 22 | [ "name", "hp", "mp" ] 23 | ``` -------------------------------------------------------------------------------- /algorithm/dictionary/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a dictionary `D`. 4 | 5 | Create a list of all the values without the keys. 6 | 7 | ## Test 8 | 9 | Given a dictionary `D` 10 | 11 | ``` 12 | { 13 | "name": "xathrya", 14 | "hp": "100", 15 | "mp": "32" 16 | } 17 | ``` 18 | 19 | should produce 20 | 21 | ``` 22 | [ "xathrya", "100", "32" ] 23 | ``` -------------------------------------------------------------------------------- /algorithm/dictionary/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a number `N`. 4 | 5 | Generate a dictionary where the key is a number from `1` to `N` and the value will be square of the key. 6 | 7 | ## Test 8 | 9 | given `N = 5`, the following dictionary will be produced. 10 | 11 | ``` 12 | { 1: 1, 2: 4, 3: 9, 4: 16, 5: 25 } 13 | ``` 14 | 15 | ## Remarks 16 | 17 | Dictionary comprehension to generate dictionary with criteria. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Given a string `S`. 4 | 5 | Create a dictionary where the key is a character and the value is the number of its appearance in the string. 6 | 7 | Only existing character appear in the dictionary. 8 | 9 | ## Test 10 | 11 | Given a string 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | will give result 18 | 19 | ``` 20 | { 21 | 'M': 1, 22 | 'I': 2, 23 | ' ': 1, 24 | 'C': 1, 25 | 'y': 1, 26 | 'b': 1, 27 | 'e': 2, 28 | 'r': 1, 29 | 's': 1, 30 | 'c': 1 31 | } 32 | ``` 33 | 34 | ## Remarks 35 | 36 | Frequency counting with dictionary. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a dictionary `D` and a string `K`. 4 | 5 | Delete key `K` if exist. 6 | 7 | ## Test 8 | 9 | Given a dictionary 10 | 11 | ``` 12 | { 13 | "key1": 0, 14 | "key2": 2, 15 | "key3": 5, 16 | } 17 | ``` 18 | 19 | deleting `key2` will give result 20 | 21 | ``` 22 | { 23 | "key1": 0, 24 | "key3": 5, 25 | } 26 | ``` -------------------------------------------------------------------------------- /algorithm/dictionary/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a dictionary `D` and value `V`. 4 | 5 | Delete every key which have value `V`. 6 | 7 | Note: as alternative, create new dictionary which had eliminated the keys. 8 | 9 | ## Test 10 | 11 | Given a dictionary 12 | 13 | ``` 14 | { 15 | "key1": 0, 16 | "key2": 2, 17 | "key3": 5, 18 | "key4": 5, 19 | } 20 | ``` 21 | 22 | Removing all keys which have value 5 will give result 23 | 24 | ``` 25 | { 26 | "key1": 0, 27 | "key2": 2, 28 | } 29 | ``` 30 | 31 | ## Remarks 32 | 33 | Filtering by value. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given two lists `K` and `V`. 4 | 5 | Create a dictionary where the key-value pair is combination of `K` and `V` at same index. 6 | 7 | Note: handle the case when the length of two lists are not equal. 8 | 9 | ## Test 10 | 11 | Given two list, `K` and `V` 12 | 13 | ``` 14 | K = [ "name", "hp", "mp" ] 15 | V = [ "xathrya", "100", "32" ] 16 | ``` 17 | 18 | will produce new dictionary 19 | 20 | ``` 21 | { 22 | "name": "xathrya", 23 | "hp": "100", 24 | "mp": "32" 25 | } 26 | ``` 27 | 28 | ## Remarks 29 | 30 | Create dictionary by list of keys and values. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-08.md: -------------------------------------------------------------------------------- 1 | ## Challenge 08 2 | 3 | Given a list of dictionary `L` and key `K`. 4 | 5 | Sort the list by the value of key `K`. 6 | 7 | ## Test 8 | 9 | Given a list 10 | 11 | ``` 12 | [ {'key': 1}, {'key': 10}, {'key': 5} ] 13 | ``` 14 | 15 | using `key` as pivot, the list would be sorted as 16 | 17 | ``` 18 | [ {'key': 1}, {'key': 5}, {'key': 10} ] 19 | ``` 20 | 21 | ## Remarks 22 | 23 | Sort list of dictionary. Dictionary can be a representation of JSON. -------------------------------------------------------------------------------- /algorithm/dictionary/chall-09.md: -------------------------------------------------------------------------------- 1 | ## Challenge 09 2 | 3 | Given a list of dictionary `L`. 4 | 5 | Remove a common key from each items. 6 | 7 | There is no guarantee that the key exists on each item (dictionary). 8 | 9 | Note: handle exclusion, where certain key is important and must not be removed. 10 | 11 | ## Test 12 | 13 | Given a list 14 | 15 | ``` 16 | [ {'id':'1', 'room': '404', 'duration': '4'}, {'id':'2', 'room':'405'} ] 17 | ``` 18 | 19 | Removing key `room` from every list item. 20 | 21 | ``` 22 | [ {'id':'1', 'duration': '4'}, {'id':'2'} ] 23 | ``` 24 | 25 | As seen, `id` is important key in this case to identified each item -------------------------------------------------------------------------------- /algorithm/dictionary/chall-10.md: -------------------------------------------------------------------------------- 1 | ## Challenge 10 2 | 3 | Given two lists `N` and `C`. 4 | 5 | Create a new list of dictionaries. The dictionary has two entries, `name` and `code`. The `name` is assigned by element of `N` and `code` is assigned by element of `C`. 6 | 7 | Note: `N` and `C` is guaranteed to be equal length. 8 | 9 | ## Test 10 | 11 | Given two list, `N` and `C` 12 | 13 | ``` 14 | N = [ "black", "red", "maroon", "yellow" ] 15 | C = [ "#000000", "#FF0000", "#800000", "#FFFF00" ] 16 | ``` 17 | 18 | will produce new list 19 | 20 | ``` 21 | [ {'name': 'Black', 'code': '#000000'}, {'name': 'Red', 'code': '#FF0000'}, {'name': 'Maroon', 'code': '#800000'}, {'name': 'Yellow', 'code': '#FFFF00'} ] 22 | ``` 23 | 24 | ## Remarks 25 | 26 | Create a new type of collection by list existing of data. -------------------------------------------------------------------------------- /algorithm/list/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a list of integer `L`. 4 | 5 | Get the largest number from the list. 6 | 7 | There is no guarantee that the list is in ordered (sorted) condition. 8 | 9 | If the largest number appear multiple time, return them all. 10 | 11 | ## Test 12 | 13 | Given a list of integer `L` 14 | 15 | ``` 16 | [ 4, 5, 1, 6, 7, 2, 8, 9, 1, 6, 9 ] 17 | ``` 18 | 19 | the largest number from the list is `9`, so the result is `[9, 9]`. 20 | 21 | ## Remarks 22 | 23 | Filtering item of the list based on some criteria. 24 | 25 | The result might be a single item or sublist. The filtering can be thought as simple iteration and processing of each item in the list. 26 | 27 | Filtering is useful to obtain right item for the operation such as selecting correct payload based on target. -------------------------------------------------------------------------------- /algorithm/list/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a list of integer `L`. 4 | 5 | Multiplies all items with 3. 6 | 7 | ## Test 8 | 9 | Given a list of integer `L` 10 | 11 | ``` 12 | [ 1, 6, 7, 2, 8 ] 13 | ``` 14 | 15 | the result is: 16 | 17 | ``` 18 | [ 3, 18, 21, 6, 24 ] 19 | ``` 20 | 21 | ## Remarks 22 | 23 | Map or transform. 24 | 25 | Processing every items on collection in uniform. Giving same treatment on all elements. It is also possible to process in concurrent (parallel execution). 26 | 27 | Map is useful for applying some action on multiple objects, such as sending command to connected agents/implants simultaneously. -------------------------------------------------------------------------------- /algorithm/list/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a list of integer. Sum all items in odd index (i.e: 1, 3, 5, ...). 4 | 5 | Note: first item is index 0. 6 | 7 | ## Test 8 | 9 | Given list of integer 10 | 11 | ``` 12 | [ 3, 0, 4, 9, 7, 9, 7, 2, 9, 4, 1, 4, 2, 5, 5, 7, 4, 0, 6, 9 ] 13 | ``` 14 | 15 | the sum of odd-index value is: `40` 16 | 17 | ## Remarks 18 | 19 | Fold or accumulate. 20 | Get single result (conclusion) by combining multiple objects. -------------------------------------------------------------------------------- /algorithm/list/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a list of string with various length. 4 | 5 | Sort (ascending) the list based on their length. 6 | 7 | ## Test 8 | 9 | Given list of string 10 | 11 | ``` 12 | MII-CyberSec 13 | Xathrya 14 | Reversing.ID 15 | ``` 16 | 17 | sorting by the length will give result: 18 | 19 | ``` 20 | Xathrya 21 | MII-CyberSec 22 | Reversing.ID 23 | ``` 24 | 25 | ## Remarks 26 | 27 | Sort the list based on criteria. -------------------------------------------------------------------------------- /algorithm/list/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Given a list `L`. 4 | 5 | Remove the duplicate items on `L`. 6 | 7 | ## Test 8 | 9 | Given a list `L` 10 | 11 | ``` 12 | [ 1, 1, 2, 3, 4, 4, 6, 9 ] 13 | ``` 14 | 15 | removing duplicate items, we produce 16 | 17 | ``` 18 | [ 1, 2, 3, 4, 6, 9 ] 19 | ``` -------------------------------------------------------------------------------- /algorithm/list/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a list `L`. 4 | 5 | Create a list `U` where the items is unique (not repeating) values from `L`. 6 | 7 | ## Test 8 | 9 | Given a list `L` 10 | 11 | ``` 12 | [ 1, 1, 2, 3, 4, 4, 6, 9 ] 13 | ``` 14 | 15 | extracting all unique values will produce: 16 | 17 | ``` 18 | [ 2, 3, 6, 9 ] 19 | ``` -------------------------------------------------------------------------------- /algorithm/list/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a list `L`. 4 | 5 | Choose item randomly from `L`. 6 | 7 | Create two version, where: 8 | - chosen item is kept in `L`. 9 | - chosen item is discard from `L`. -------------------------------------------------------------------------------- /algorithm/list/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given a list `L`. 4 | 5 | Shuffle the position of all items. Shuffling is repositioning each item to random place. Modification is in-place and no new list created. 6 | 7 | ## Test 8 | 9 | Given a list of integer `L`. 10 | 11 | ``` 12 | [ 3, 2, 6, 7, 2 ] 13 | ``` 14 | 15 | One of possible result from shuffling is: 16 | 17 | ``` 18 | [ 6, 2, 7, 2, 3 ] 19 | ``` -------------------------------------------------------------------------------- /algorithm/list/chall-08.md: -------------------------------------------------------------------------------- 1 | ## Challenge 08 2 | 3 | Given `L`, a 2-dimension list (list of list) with various length. 4 | 5 | Concatenate all items and make 1-dimension list. 6 | 7 | ## Testing 8 | 9 | Given a list of list of integer. 10 | 11 | ``` 12 | [ [2, 4, 3], [1, 5, 6], [9], [7, 9] ] 13 | ``` 14 | 15 | which will produce: 16 | 17 | ``` 18 | [ 2, 4, 3, 1, 5, 6, 9, 7, 9 ] 19 | ``` 20 | 21 | ## Remarks 22 | 23 | Flatten the shallow list. 24 | 25 | Flattening is creating a new list by combining (concatenating) all member of list. This is useful if you have large results from different sources and only interest in the item itself. Processing 1-dimension list is simpler than 2-dimension list. -------------------------------------------------------------------------------- /algorithm/list/chall-09.md: -------------------------------------------------------------------------------- 1 | ## Challenge 09 2 | 3 | Given two integers `S` and `E`, with `S` less than `E`. 4 | 5 | Create a list of unique (non-repeating) integers with value from `S` to `E`. The position of the value is random. 6 | 7 | ## Test 8 | 9 | Given integer `S = 3`, `E = 10`. One of possible result will be: 10 | 11 | ``` 12 | [ 3, 8, 7, 4, 10, 9, 6, 5 ] 13 | ``` 14 | 15 | From `S = 3` to `E = 10`, there are 8 integers. -------------------------------------------------------------------------------- /algorithm/list/chall-10.md: -------------------------------------------------------------------------------- 1 | ## Challenge 10 2 | 3 | Given a string `S`. 4 | 5 | Create list of integer. Each element is ASCII representation of `S`. 6 | 7 | ## Test 8 | 9 | Given a string `S` 10 | 11 | ``` 12 | "MII" 13 | ``` 14 | 15 | representing the string as list of character would give 16 | 17 | ``` 18 | [ 'M', 'I', 'I' ] 19 | ``` 20 | 21 | converting each element to integer will produce: 22 | 23 | ``` 24 | [ 77, 73, 73 ] 25 | ``` -------------------------------------------------------------------------------- /algorithm/list/chall-11.md: -------------------------------------------------------------------------------- 1 | ## Challenge 11 2 | 3 | Given two lists `L` & `M`. 4 | 5 | Find the common items from two lists. 6 | 7 | ## Test 8 | 9 | Given two list, `L` and `M` 10 | 11 | ``` 12 | L = [ 1, 2, 3, 4, 5, 6, 7 ] 13 | M = [ 2, 6, 10, 12 ] 14 | ``` 15 | 16 | will produce new list 17 | 18 | ``` 19 | [ 2, 6 ] 20 | ``` 21 | 22 | ## Remarks 23 | 24 | Finding intersected items. -------------------------------------------------------------------------------- /algorithm/list/chall-12.md: -------------------------------------------------------------------------------- 1 | ## Challenge 12 2 | 3 | Given two lists `L` & `M`. 4 | 5 | Create a new list which each item is tuple of item from both list at the same index. 6 | 7 | Only perform the action on existing element. 8 | 9 | ## Test 10 | 11 | Given two list, L and M 12 | 13 | ``` 14 | L = [ 1, 3, 5, 7, 9 ] 15 | M = [ 2, 4, 6 ] 16 | ``` 17 | 18 | will produce new list 19 | 20 | ``` 21 | [ (1, 2), (3, 4), (5, 6) ] 22 | ``` 23 | 24 | ## Remarks 25 | 26 | Zipping element of two lists. 27 | 28 | Zipping usually used to pair two items, which work together. -------------------------------------------------------------------------------- /algorithm/list/chall-13.md: -------------------------------------------------------------------------------- 1 | ## Challenge 13 2 | 3 | Given a list `L` and integer `N`. 4 | 5 | Split list every N-th element. 6 | 7 | If the size of `L` is not multiple of `N`, then the last partition might have less member than the rest. 8 | 9 | ## Test 10 | 11 | Given a list `L` (length = 14) 12 | 13 | ``` 14 | [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' ] 15 | ``` 16 | 17 | using `N = 3`, it will produce 18 | 19 | ``` 20 | [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['j', 'k', 'l'], ['m', 'n'] ] 21 | ``` 22 | 23 | ## Remarks 24 | 25 | Partitioning or splitting the list into several blocks of equal length. 26 | 27 | Partitioning is useful to divide the load so we can distribute it into several workers and executed concurrently. -------------------------------------------------------------------------------- /algorithm/list/chall-14.md: -------------------------------------------------------------------------------- 1 | ## Challenge 14 2 | 3 | Given a list `L` and integer `N`. 4 | 5 | Split list into `N` partitions. 6 | 7 | If the size of `L` is not multiple of `N`, some blocks might have less member than the rest. 8 | 9 | ## Test 10 | 11 | Given a list `L` (length = 14) 12 | 13 | ``` 14 | [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' ] 15 | ``` 16 | 17 | using `N = 3`, it will produce 18 | 19 | ``` 20 | [ ['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h', 'i', 'j'], ['k', 'l', 'm', 'n'] ] 21 | ``` 22 | 23 | the first and second partition (block) has 5 members while the last block has 4. 24 | 25 | ## Remarks 26 | 27 | Partitioning or splitting the list into several blocks of equal length. 28 | 29 | Partitioning is useful to divide the load so we can distribute it into several workers and executed concurrently. -------------------------------------------------------------------------------- /algorithm/list/chall-15.md: -------------------------------------------------------------------------------- 1 | ## Challenge 15 2 | 3 | Given an integer `N` and `K`. 4 | 5 | Build list of number starting at 1 and up to but not including `N`. The list also exclude any number which is multiple of `K`. 6 | 7 | ## Test 8 | 9 | Given an integer `N = 15` and `K = 4`. 10 | 11 | The list should be `[1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14]` 12 | 13 | ## Remarks 14 | 15 | Generating a list with a criteria. -------------------------------------------------------------------------------- /algorithm/list/chall-16.md: -------------------------------------------------------------------------------- 1 | ## Challenge 16 2 | 3 | Given a string of comma-separated integers `L`. Instead of an integer, some elements might be written as range `a-b` (two numbers separated by dash), with a <> b. 4 | 5 | For each ranges, replace with individual numbers in that range. 6 | 7 | ## Test 8 | 9 | Given list `L`. 10 | 11 | ``` 12 | L = [1,3,5-9,13] 13 | ``` 14 | 15 | should produce 16 | 17 | ``` 18 | [1,3,5,6,7,8,9,13] 19 | ``` 20 | 21 | ## Remarks 22 | 23 | Range expansion. -------------------------------------------------------------------------------- /algorithm/number/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given two integers `A` and `B`. 4 | 5 | Find the `Greatest Common Divisor` between these two. 6 | 7 | ## Test 8 | 9 | Given two integers `A = 15` and `B = 27`. The `GCD` of both integer is 3. 10 | 11 | ## Remarks 12 | 13 | GCD is one of important concept in Discrete Math, especially some topics on Cryptography. -------------------------------------------------------------------------------- /algorithm/number/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given an integer `N`. 4 | 5 | List all of its factors. 6 | 7 | ## Test 8 | 9 | Given an integer `N = 120`, which value can be written as `2^3 x 3 x 5` (^ means power). Then the factors are `2, 3, 5` 10 | 11 | ## Remarks 12 | 13 | Some number can be decomposed as product (multiplication) of prime numbers. This process is also known as factorization. Factorization is important process in Discrete Math especially some topics on Cryptography. -------------------------------------------------------------------------------- /algorithm/number/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a list of tuple representing a range (Start - End) and an integer `I`. 4 | 5 | Find out if there is any range which include the integer `I`. 6 | 7 | ## Test 8 | 9 | Given a list of tuple 10 | 11 | ``` 12 | (0x00400000, 0x006fa000) 13 | (0x008f9000, 0x008fa000) 14 | (0x008fa000, 0x00986000) 15 | (0x00986000, 0x009a2000) 16 | (0x021ba000, 0x022a4000) 17 | (0x7f343d797000, 0x7f343de79000) 18 | (0x7f343de79000, 0x7f343df7e000) 19 | (0x7f343df7e000, 0x7f343e17d000) 20 | (0x7f343e17d000, 0x7f343e17e000) 21 | (0x7f343f000000, 0x7f343f1b6000) 22 | (0x7f343f1c5000, 0x7f343f1cc000) 23 | (0x7f343f1cc000, 0x7f343f1ce000) 24 | (0x7f343f1ce000, 0x7f343f1cf000) 25 | (0x7f343f1cf000, 0x7f343f1d0000) 26 | (0x7f343f1d0000, 0x7f343f1d1000) 27 | (0x7ffccf1fd000, 0x7ffccf21e000) 28 | (0x7ffccf23c000, 0x7ffccf23e000) 29 | (0x7ffccf23e000, 0x7ffccf240000) 30 | ``` 31 | 32 | an integer `0x7f343f010210` is in the range of `(0x7f343f000000, 0x7f343f1b6000)`. 33 | 34 | ## Remarks 35 | 36 | Section of executable binary will be mapped to a memory region at load time. Sometimes, we need to locate the memory region which an address belong to. -------------------------------------------------------------------------------- /algorithm/regex/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a possible long text, find and extract valid IPv4 addresses. 4 | 5 | An IPv4 address consists of 4 segments, separated by a dots. Each segment is a value ranged from 0 to 255. -------------------------------------------------------------------------------- /algorithm/regex/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a possible long text, find and extract valid IPv6 addresses. 4 | 5 | An IPv6 address consists of 8 segments, separated by colons. Each segment is four hexadecimal digits which value ranged from 0 to ffff. 6 | 7 | If there are consecutive zeros, the IP representation can be shortened. For example, `2001:0db8:0000:0000:0000:8a2e:0370:7334` become `2001:0db8::8a2e:370:7334`. -------------------------------------------------------------------------------- /algorithm/regex/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a possible long text, find and extract domain names. 4 | 5 | Domain name consists of several string, separated by dots. The right most string is top-level domain, which value is defined (i.e. com, net, id, org). The rest are defining hostnames, which can be any arbitrary string. 6 | 7 | ## Remarks 8 | 9 | Some malware use communication with Command and Control server over DNS. The message is transported as DNS request/reply. To ensure communication, a random subdomain is generated using Domain Generation Algorithm. -------------------------------------------------------------------------------- /algorithm/regex/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a possible long text, find and extract valid email addresses. 4 | 5 | An email address consists of two parts username and domain, which separated by @. -------------------------------------------------------------------------------- /algorithm/regex/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Find and capture SSN (Social Security Number) from long text. 4 | 5 | A SSN is any series of 9 consecutive digits. SSN consists of 3 digits followed by delimit (space/dash), then 2 digits followed by delimit (space/dash), then 4 digits. Common format for writing SSN could be: 6 | 7 | * XXX YY ZZZZ 8 | * XXX-YY-ZZZZ 9 | * XXXYYZZZZ 10 | 11 | ## Remarks 12 | 13 | SSN or Social Security Number is number to identified citizens, permanent residents, and temporary (working) residents of USA. 14 | 15 | The purpose of SSN is to track the earning histories of US worksers, for use in determining Social Security benefit entitlement and computing benefit levels. -------------------------------------------------------------------------------- /algorithm/regex/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a long text `S`. 4 | 5 | Find and extract only 3-digit numbers. If 3 digits are part of larger number (4 or more digits) then this number is excluded. 6 | 7 | The 3-digit numbers must be preceeded by and followed by a non-word character. 8 | 9 | ## Test 10 | 11 | Given `S` 12 | 13 | ``` 14 | 123 56789 013 15 | ``` 16 | 17 | will result only 123 and 013. -------------------------------------------------------------------------------- /algorithm/regex/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a possible long text, find and extract HTML tags and list its attibutes. 4 | 5 | HTML elements is defined by tags and content. A tag, like XML tag, is a string enclosed by angle braces `<>`. Some popular tags are ``, ``, `
`, etc. The opening tag is the tag which start an element, while the end tag is the matching pair which marks the end of element. In general, HTML element follow this format ` content `. 6 | 7 | Tag might have attributes. The attributes are special words inside the opening tag to control the element behavior. -------------------------------------------------------------------------------- /algorithm/regex/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Shadow file is a colon delimited file with 2nd field contain the password information. The password is encoded using the following format: 4 | 5 | - consists of 3 parts delimited by dollar sign. 6 | - first part indicate cipher algorithm. 7 | - second part indicate salt 8 | - third part indicate password hash. 9 | 10 | Given an such entry, retrieve each field. -------------------------------------------------------------------------------- /algorithm/string/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a string `S`. 4 | 5 | Convert `S` to sequence of bytes object then get its length. 6 | 7 | ## Remarks 8 | 9 | Python3 has two types of object representing a string. First is `str` which represent sequence of characters, other is `bytes` which represent sequence of bytes. Both are immutable string. The `str` object represent string as multibyte string, which supports unicode. In other hand, `bytes` represent single byte character. 10 | 11 | In most case, string in Python refer to the string of `str` type. 12 | 13 | In some cases, we need to operate on low level data which are sequence of bytes. Thus, converting string to sequence of byte is desirable. 14 | 15 | When you will see and use bytes? 16 | 17 | - crafting shellcode (payload). 18 | - send/receive data on socket. 19 | - analyze value of memory addresses. 20 | - dump data from disk. -------------------------------------------------------------------------------- /algorithm/string/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a string `U` and list of string `E`. 4 | 5 | Create a new list by concatenating each element of `E` with `U`. 6 | 7 | ## Test 8 | 9 | Given a string `U` 10 | 11 | ``` 12 | https://pythonidae.herokuapp.com/ 13 | ``` 14 | 15 | and a list of string `E` 16 | 17 | ``` 18 | web/generate 19 | web/identify 20 | web/cookies 21 | ``` 22 | 23 | the result should be 24 | 25 | ``` 26 | https://pythonidae.herokuapp.com/web/generate 27 | https://pythonidae.herokuapp.com/web/identify 28 | https://pythonidae.herokuapp.com/web/cookies 29 | ``` 30 | 31 | ## Remarks 32 | 33 | Concatenation is used a lot, especially for generating target. 34 | 35 | Enumerating directory is common tasks in recon where you have a base URL and some directories or files. For each request, you need to get a full URL which combining base URL and the endpoints. -------------------------------------------------------------------------------- /algorithm/string/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a string `D` and two integers `S` and `E`. 4 | 5 | Rewrite the content of string, starts from index `S` to index `E`, fill with `x`. The resulting string and `D` should have same length. 6 | 7 | Also, try the same thing with `bytes` type. 8 | 9 | ## Test 10 | 11 | Given a string `D` 12 | 13 | ``` 14 | MII CyberSec Consulting Service 15 | ``` 16 | 17 | and two integers `S = 4` and `E = 11`. 18 | 19 | the result should be 20 | 21 | ``` 22 | MII xxxxxxxx Consulting Service 23 | ``` 24 | 25 | ## Remarks 26 | 27 | Index is a number to refer position of specific element. 28 | 29 | String `str` and `bytes` are both immutable and do not support item assignment on their element. 30 | 31 | Modify a string at certain range is not limited to masking. We can modify content of (structured) packets, and create a rule: where and what to replace. -------------------------------------------------------------------------------- /algorithm/string/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given three integers: `N`, `S`, `E`. 4 | 5 | Create a bytearray `B` with the length `N`. Fill `B` from index `S` to `E` with random byte . `N` is guaranteed to be no less than `E`. 6 | 7 | ## Test 8 | 9 | Given three integers: `N = 10`, `S = 5`, `E = 8`. 10 | 11 | one of possible output would be: 12 | 13 | ``` 14 | bytearray(b'\x00\x00\x00\x00\x00\x0B\xAD\xF0\x0D\x00') 15 | ``` 16 | 17 | ## Remarks 18 | 19 | The `bytearray` object is a mutable object consists of sequence of bytes. Bytearray is usually used as a buffer to support in-place modification of data. 20 | 21 | The `bytes` object and `bytearray` are usually complementing. 22 | 23 | Mutable buffer often needed to build a payload, which some parts will be modified later by other function. -------------------------------------------------------------------------------- /algorithm/string/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Given a long string (text) `S`. 4 | 5 | Find and extract all substring starts with `http://` or `https://`. The substring should have no whitespace. 6 | 7 | Optionally, you can validate the URL by checking if they are in `FQDN (Full Name Qualified Domain)` form. 8 | 9 | ## Remarks 10 | 11 | Finding valid URL in text is useful for scraping. When processing a paragraph, there should be many valuable information for recon. 12 | 13 | Valid URLs are not only found on a page. It can also be found on assets such as JavaScript file. -------------------------------------------------------------------------------- /algorithm/string/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a string of a hexpair `H`. 4 | 5 | Decode (or convert) `H` as a sequence of bytes. The content might or might not be printable characters. 6 | 7 | The length of `H` is guaranteed to be even. 8 | 9 | ## Test 10 | 11 | The hexpair string `H` (length = 24) 12 | 13 | ``` 14 | 526576657273696e672e4944 15 | ``` 16 | 17 | should be converted to (length = 12) 18 | 19 | ``` 20 | \x52\x65\x76\x65\x72\x73\x69\x6e\x67\x2e\x49\x44 21 | ``` 22 | 23 | ## Remarks 24 | 25 | Representing binary data in hexpair string is not unusual. Although some encoding such as Base64 is more popular. Hex pairs are often found on low level stuffs for representing stream of data. -------------------------------------------------------------------------------- /algorithm/string/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a string `S` and single-byte `C`. 4 | 5 | XOR each character of `S` with `C`. The result bytes might not be printable characters. 6 | 7 | Hint: Operate in `bytes` object is recommended. 8 | 9 | ## Test 10 | 11 | The hexpair string 12 | 13 | ``` 14 | 526576657273696e672e4944 15 | ``` 16 | 17 | if XOR-ed with 0x53 would give result 18 | 19 | ``` 20 | 0136253621203a3d347d1a17 21 | ``` 22 | 23 | ## Remarks 24 | 25 | XOR is primitive operation that often used to "encrypt" data. 26 | 27 | Simple string obfuscation can be implemented with XOR. -------------------------------------------------------------------------------- /algorithm/string/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given two equal-length hexpair string `S1` and `S2`. 4 | 5 | XOR `S1` and `S2`. 6 | 7 | Hint: Operate in `bytes` object is recommended. 8 | 9 | ## Test 10 | 11 | Given two string `S1` and `S2` 12 | 13 | ``` 14 | 44355050f07a7e2df0067d45 15 | ``` 16 | 17 | when XORed with 18 | 19 | ``` 20 | 165026358209174397283401 21 | ``` 22 | 23 | will produce 24 | 25 | ``` 26 | 526576657273696e672e4944 27 | ``` 28 | 29 | ## Remarks 30 | 31 | XOR is primitive operation that often used to `encrypt` data. 32 | 33 | Simple string obfuscation can be implemented with XOR. -------------------------------------------------------------------------------- /algorithm/string/chall-08.md: -------------------------------------------------------------------------------- 1 | ## Challenge 08 2 | 3 | Given two unequal-length hexpair string, `S1` and `S2`, with `S1` always longer than `S2`. 4 | 5 | XOR `S1` and `S2`. 6 | 7 | Also, try to handle when `S1` is shorter than `S2`. 8 | 9 | Hint: Operate in `bytes` object is recommended. 10 | 11 | ## Test 12 | 13 | Given a string `S1` 14 | 15 | ``` 16 | d5577f20f541602be01c4001 17 | ``` 18 | 19 | when XORed with another string `S2` 20 | 21 | ``` 22 | 87320945 23 | ``` 24 | 25 | will produce 26 | 27 | ``` 28 | 526576657273696e672e4944 29 | ``` 30 | 31 | As seen, `S2` is shorter. When iteration came to the end of `S2`, the operation is resumed from the beginning of `S2`. Thus 32 | 33 | ``` 34 | d5577f20 f541602b e01c4001 35 | 87320945 87320945 87320945 36 | -------------------------- xor 37 | 52657665 7273696e 672e4944 38 | ``` 39 | 40 | ## Remarks 41 | 42 | XOR is primitive operation that often used to `encrypt` data. 43 | 44 | Simple string obfuscation can be implemented with XOR. 45 | 46 | The "key" for XOR-ing usually a multi-byte integer. For simple calculation, it often represented in size of word or multiple of it. -------------------------------------------------------------------------------- /algorithm/string/chall-09.md: -------------------------------------------------------------------------------- 1 | ## Challenge 09 2 | 3 | Given a string with length `N`. 4 | 5 | Generate all possible permutation of the string. 6 | 7 | ## Test 8 | 9 | Given the string of length 3 10 | 11 | ``` 12 | ABC 13 | ``` 14 | 15 | all possible permutation would be 16 | 17 | ``` 18 | ABC 19 | ACB 20 | BAC 21 | BCA 22 | CAB 23 | CBA 24 | ``` 25 | 26 | ## Remarks 27 | 28 | Permutation is the arrangement of members or elements of a collection, in regards to the order of the arrangements. Permutation can be done on selected objects or subset. However, in most case we are interested in permutating the whole collection. 29 | 30 | Permutation of string is one of operation in classic cipher. Permutation is also used as operation in block cipher, such as `Substitution-Permutation Network (SPN)`, where plaintext is rearranged according a rule (Permutation Box). -------------------------------------------------------------------------------- /algorithm/string/chall-10.md: -------------------------------------------------------------------------------- 1 | ## Challenge 10 2 | 3 | Given a string `S` and list of integer `P`, both have the same length `N`. Each element of list `P` is a unique number which value is in range `0` to `N-1`. 4 | 5 | Create a new string `T`, which is permutation of `S` using `P` as index. 6 | 7 | ## Test 8 | 9 | Given the string `S` 10 | 11 | ``` 12 | MII-CyberSec 13 | ``` 14 | 15 | and the list of integer `P` 16 | 17 | ``` 18 | [4, 0, 9, 5, 6, 10, 2, 8, 1, 7, 3, 11] 19 | ``` 20 | 21 | will produce a new string 22 | 23 | ``` 24 | CMSybeIrIe-c 25 | ``` 26 | 27 | See that the list `P` at index 0 has value 4. If we look at the string `S`, we note that the character at index 4 is "C". Thus, "C" will be the character at index 0 of the string `T`. 28 | 29 | ## Remarks 30 | 31 | Permutation of string is one of operation in classic cipher. Even some operation in block cipher has permutation. 32 | 33 | Permutation of string is one of operation in classic cipher. Permutation is also used as operation in block cipher, such as `Substitution-Permutation Network (SPN)`, where bits of plaintext is rearranged according a rule (Permutation Box). -------------------------------------------------------------------------------- /binary/README.md: -------------------------------------------------------------------------------- 1 | # Pythonidae Challenge 2 | 3 | Learn Python for Cyber Security by completing challenges. 4 | 5 | ## Binary 6 | 7 | This is `Binary Set`. If you are confident in learning hex, then this challenge is right for you. 8 | 9 | This challenge consists of several activites relate to binary analysis, exploit development, and shellcodes creation utilities. 10 | 11 | ## Table of Content 12 | 13 | You will see 14 | 15 | - Executable `parsing` 16 | - `Disassembly` 17 | - `Interoperable` 18 | 19 | #### Executable Parsing 20 | 21 | 0. open executable (PE/ELF) and determine the target architecture. 22 | 1. get the entrypoint address from executable (PE/ELF). 23 | 2. list all sections with their size and permission. 24 | 3. list the name and address of all imported functions. 25 | 4. compute the entropy of each section. 26 | 5. list all printable string which length exceed certain number. 27 | 6. list all entries (name, offset) of relocation table. 28 | 7. modify section as writable and executable. 29 | 8. list all sections which have empty space before end of section. 30 | 9. find the last section of executable and add `N` pages after the end. 31 | 10. create minimalistic executable which will run shellcode. 32 | 33 | #### Disassembly 34 | 35 | 0. read shellcode file as blob and disassemble. 36 | 1. count the frequency of each instruction. 37 | 2. identify invoked syscall by syscall number. 38 | 3. create statistic of registers (source, destination). 39 | 4. list all memory addresses. 40 | 5. map all branching operations as (source, destination) tuple. 41 | 42 | #### Interoperable 43 | 44 | 0. call function from shared library (DLL / SO) based on function name. 45 | 1. get the return value of function call. 46 | 2. pass mutable string and print string after function call. 47 | 3. pass structure to function. -------------------------------------------------------------------------------- /binary/disassembly/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given sequence of byte representing shellcode. 4 | 5 | Disassemble the shellcode, use `0x1000` as base address. At least, these information should be present: 6 | 7 | - address 8 | - raw bytes 9 | - instruction 10 | 11 | Note: 12 | 13 | - feel free to use any external libraries you want. 14 | - read the file in binary mode. 15 | 16 | ## Test 17 | 18 | Use the shellcode [sample-00.bin](resources/sample-00.bin). 19 | 20 | This is `linux/x86` code. See also the [source code](resources/sample-00.nasm) 21 | 22 | ## Remarks 23 | 24 | Disassembling code is one of important aspects in reverse engineering, program analysis, and exploit development. The goal is to revert the sequence of bytes back to the assembly mnemonic, in hope to understand the code better. 25 | 26 | Disassemble can be done on whole program or portion of code. The code is mapped to memory address range, so (relative) jump can be resolved. 27 | 28 | Some libraries that can be used for disassembly: 29 | 30 | - amoco (arm, avr, x86) 31 | - capstone (arm, aarch64, mips, ppc, riscv, sparc, x86, ...) 32 | - distorm3 (x86/x64) 33 | - miasm (arm, mips, msp430, sh4, x86) 34 | 35 | -------------------------------------------------------------------------------- /binary/disassembly/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given sequence of byte representing shellcode. 4 | 5 | Count all mnemonic and create the statistic of occurrence. 6 | 7 | Note: 8 | 9 | - feel free to use any external libraries you want. 10 | - read the file in binary mode. 11 | 12 | ## Test 13 | 14 | Use shellcode [sample-01.bin](resources/sample-01.bin). 15 | 16 | This is `linux/x86` code. See also the [source code](resources/sample-01.nasm) 17 | 18 | ## Remarks 19 | 20 | Identifying instructions is essentially important for program analysis. For a script to analyze program, it's not enough to just disassemble. The analysis script should be aware to the instructions processed. -------------------------------------------------------------------------------- /binary/disassembly/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given sequence of byte representing shellcode. 4 | 5 | Identify which syscall number is called. 6 | 7 | Note: 8 | 9 | - feel free to use any external libraries you want. 10 | - read the file in binary mode. 11 | 12 | ## Test 13 | 14 | Use shellcode [sample-02.bin](resources/sample-02.bin). 15 | 16 | This is `linux/x86` code. See also the [source code](resources/sample-02.nasm). 17 | 18 | There are 5 (five) syscall invocation, which has 5 different syscall number. 19 | 20 | ## Remarks 21 | 22 | Syscalls, or System Calls, are requests of kernel's services, identified by numbers. Different operating system might provide different services. But some popular and common services: process control, file management, and communication. 23 | 24 | Identifying syscalls are useful when analyzing shellcode, especially in predicting what it will do. 25 | 26 | Different operating system provide different syscalls. Even for different architecture, the number might be different. In this case consult documentation for the correct platform. -------------------------------------------------------------------------------- /binary/disassembly/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given sequence of byte representing shellcode. 4 | 5 | Count all affected registers in instructions and create statistic based on types (source register, destination registers). 6 | 7 | Sample expected result: 8 | 9 | ``` 10 | RAX appears 3 times as source, 0 times as destination. 11 | ``` 12 | 13 | If a register never appear on disassembled code, exclude them from list. 14 | 15 | Some registers are related. Register such as RAX, EAX, AX, AH, AL have different size but actually aliases for different part of same register. Such registers should be treated as same register instead. 16 | 17 | Note: 18 | 19 | - feel free to use any external libraries you want. 20 | - read the file in binary mode. 21 | 22 | ## Remarks 23 | 24 | Identifying registers is useful to track the value of registers in `Data-Flow`, `Taint Analysis`, and other analyses. The goal might be varying, but the common purpose is to know the value of registers at a time. -------------------------------------------------------------------------------- /binary/disassembly/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Given sequence of byte representing shellcode. 4 | 5 | List all memory address involved in every instructions and specify the operation (read/write) to the address. 6 | 7 | Sample expected result: 8 | 9 | ``` 10 | Write to 0x11223344 11 | Read from 0x11223344 12 | ``` 13 | 14 | Only take the instruction which has memory access (direct or indirect by register). In case of indirect memory access (using register), try to get the value of register to determine the memory address. 15 | 16 | Note: 17 | 18 | - feel free to use any external libraries you want. 19 | - read the file in binary mode. 20 | 21 | ## Test 22 | 23 | Use executable [sample-03](resources/sample-03). 24 | 25 | This is `linux/x86` binary. See also the [source code](resources/sample-03.nasm). 26 | 27 | This executable is modified version of `execve` shellcode. Instead of setting buffer on stack, we use the `.bss` section. 28 | 29 | ## Remarks 30 | 31 | Identifying memory address is useful to track the value in `Data-Flow`, `Taint Analysis`, and other analyses. The goal might be varying, but the common purpose is to know the value of memory at a time. 32 | 33 | By identifying memory address and furthermore the value read/write, a deeper analysis on behavior can be done. -------------------------------------------------------------------------------- /binary/disassembly/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given sequence of byte representing shellcode. 4 | 5 | Identify all jump or branching instructions. Map the `address of jump instruction` to `address of destination`. Add a flag to each mapping to indicate whether the path is taken when the condition met. 6 | 7 | For example, the code below has one jump instruction: 8 | 9 | ``` 10 | 0x00: jnz 0x4 11 | 0x02: mov al, 1 12 | 0x04: mov bl, 1 13 | ``` 14 | 15 | which will produce two tuples: 16 | 17 | ``` 18 | (0x00, 0x04, 1) 19 | (0x00, 0x02, 0) 20 | ``` 21 | 22 | Because `0x00` will jump to `0x04` if condition for `JNZ` is met. Otherwise, `0x00` will jump to `0x02`. 23 | 24 | Note: 25 | 26 | - feel free to use any external libraries you want. 27 | - read the file in binary mode. 28 | 29 | ## Remarks 30 | 31 | List of mapping from address to address can be used to make a simple cross reference. -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-00.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/disassembly/resources/sample-00.bin -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-00.nasm: -------------------------------------------------------------------------------- 1 | ; nasm -f bin sample-00.nasm 2 | ; 3 | ; Exit shellcode 4 | ; Return a non zero value when exiting 5 | bits 32 6 | 7 | global _start 8 | 9 | section .text 10 | _start: 11 | xor eax, eax 12 | mov ebx, eax 13 | mov al, 1 14 | mov bl, 135 15 | int 0x80 -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-01.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/disassembly/resources/sample-01.bin -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-01.nasm: -------------------------------------------------------------------------------- 1 | ; nasm -f bin sample-01.nasm 2 | ; 3 | ; Write data to stack and print 4 | bits 32 5 | 6 | global _start 7 | 8 | section .text 9 | _start: 10 | sub esp, 32 11 | mov dword [esp ], 0x2049494d 12 | mov dword [esp+4], 0x65627943 13 | mov dword [esp+8], 0x63655372 14 | 15 | xor eax, eax 16 | xor ebx, ebx 17 | xor edx, edx 18 | mov byte [esp+12], al 19 | mov bl, 1 20 | mov ecx, esp 21 | mov dl, 12 22 | mov al, 4 23 | int 0x80 24 | 25 | xor eax, eax 26 | mov al, 0x1 27 | int 0x80 -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-02.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/disassembly/resources/sample-02.bin -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-02.nasm: -------------------------------------------------------------------------------- 1 | ; nasm -f bin sample-02.nasm 2 | ; 3 | ; setuid, setgid, stdin reopen shellcode (71 bytes) 4 | 5 | bits 32 6 | 7 | global _start 8 | 9 | section .text 10 | _start: 11 | add esp, 0x18 12 | 13 | ; close(0) 14 | xor eax, eax 15 | xor ebx, ebx 16 | mov al, 6 17 | int 0x80 18 | 19 | ; open("/dev/tty", O_RDWR | ) 20 | push ebx 21 | push 0x7974742f ; /tty 22 | push 0x7665642f ; /dev 23 | mov ebx, esp 24 | xor ecx, ecx 25 | mov cx, 0x2712 26 | mov al, 5 27 | int 0x80 28 | 29 | ; setuid(0) 30 | push 0x17 31 | pop eax 32 | xor ebx, ebx 33 | int 0x80 34 | 35 | ; setgid(0) 36 | push 0x2e 37 | pop eax 38 | push ebx 39 | int 0x80 40 | 41 | ; execve("/bin/sh", ["/bin/sh"], NULL) 42 | xor eax, eax 43 | push eax 44 | push 0x68732f2f ; //sh 45 | push 0x6e69622f ; /bin 46 | mov ebx, esp 47 | push eax 48 | push ebx 49 | mov ecx, esp 50 | cdq 51 | mov al, 0xb 52 | int 0x80 -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-03: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/disassembly/resources/sample-03 -------------------------------------------------------------------------------- /binary/disassembly/resources/sample-03.nasm: -------------------------------------------------------------------------------- 1 | ; Execve 2 | ; buffer is global address, not in stack. 3 | ; 4 | ; (linux) 5 | ; nasm -f elf32 sample-04.nasm -o sample-04.o && ld -m elf_i386 -o sample-04 sample-04.o 6 | 7 | bits 32 8 | 9 | global _start 10 | 11 | section .text 12 | _start: 13 | ; filling '/bin/sh' 14 | mov dword [buffer + 3], 0x68732f2f ; //sh 15 | mov dword [buffer ], 0x6e69622f ; /bin 16 | 17 | ; nullify 18 | xor ebx, ebx 19 | mov ecx, buffer 20 | mov byte [buffer + 7], bl ; Fill A 21 | mov dword [ecx + 8], ecx ; Fill BBBB 22 | mov dword [ecx + 12], ebx ; Fill CCCC 23 | 24 | ; execve 25 | lea ebx, [buffer ] 26 | lea ecx, [buffer + 8] 27 | lea edx, [buffer + 12] 28 | xor eax, eax 29 | mov al, 0xb 30 | int 0x80 31 | 32 | section .bss 33 | ; modify this buffer, fed to execve 34 | ; /bin/shABBBBCCCC 35 | ; A = 0 (null) 36 | ; BBBB = address to argument (null) 37 | ; CCCC = null address 38 | buffer: resb 16 -------------------------------------------------------------------------------- /binary/interoperable/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Load functions from shared libraries (DLL / SO) based on name. 4 | 5 | ## Test 6 | 7 | If you are in Windows, load the [clib-64.dll](clib-64.dll) (for Python x64) or [clib-32.dll](clib-32.dll) (for Python x86) and then execute function `hello`. 8 | 9 | If you are in Linux, load the [clib-64.so](clib-64.so) (for Python x64) or [clib-32.so](clib-32.so) (for Python x86) and then execute function `hello`. 10 | 11 | ## Remarks 12 | 13 | Some tools are implement as shared libraries and exported their functions to public. By loading the shared library, Python can call the functions directly. -------------------------------------------------------------------------------- /binary/interoperable/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Call function `retval_test` in given shared library, pass an integer and get the return value. 4 | 5 | ## Test 6 | 7 | Based on your architecture, load the `clib` shared library. Call `retval_test` which require an 32-bit integer and get the return value. -------------------------------------------------------------------------------- /binary/interoperable/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Call function `modify_str` in given shared library, pass a mutable string as argument. Print the string after call. 4 | 5 | Note: the string should be different. 6 | 7 | ## Test 8 | 9 | Based on your architecture, load the `clib` shared library. Call `modify_str` and pass a string. 10 | 11 | Each element of the string should shift to next alphabet. 12 | 13 | ## Remarks 14 | 15 | Python string is immutable, the string on low level might be not. When interacting with low level code, a mutable buffer should be used. -------------------------------------------------------------------------------- /binary/interoperable/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Call a function `init_monster` in shared library with a defined structure as argument. Print all the field's value. 4 | 5 | The structure defined as: 6 | 7 | ``` 8 | struct monster 9 | { 10 | char name [10]; 11 | int damage; 12 | }; 13 | ``` 14 | 15 | Note: argument is passed by reference. 16 | 17 | ## Test 18 | 19 | Based on your architecture, load the `clib` shared library. Call `init_monster` and pass a reference to structure. -------------------------------------------------------------------------------- /binary/interoperable/resources/clib-32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/interoperable/resources/clib-32.dll -------------------------------------------------------------------------------- /binary/interoperable/resources/clib-32.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/interoperable/resources/clib-32.so -------------------------------------------------------------------------------- /binary/interoperable/resources/clib-64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/interoperable/resources/clib-64.dll -------------------------------------------------------------------------------- /binary/interoperable/resources/clib-64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/binary/interoperable/resources/clib-64.so -------------------------------------------------------------------------------- /binary/interoperable/resources/clib-dll.c: -------------------------------------------------------------------------------- 1 | /* 2 | Compile: 3 | $ cl /LD clib-dll.c 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #ifdef _MSC_VER 11 | #pragma comment(lib,"advapi32") 12 | #pragma comment(lib,"kernel32") 13 | #pragma comment(lib,"user32") 14 | #pragma comment(lib,"vcruntime") 15 | #pragma comment(lib,"libucrt") 16 | #endif 17 | 18 | struct monster 19 | { 20 | char name [10]; 21 | int damage; 22 | }; 23 | 24 | __declspec(dllexport) 25 | void hello () 26 | { 27 | DWORD dwtemp = 62; 28 | TCHAR szname[64], szbuff[MAX_PATH+1]; 29 | 30 | if (GetUserName(szname, &dwtemp)) 31 | wsprintf(szbuff, "Hello %s", szname); 32 | else 33 | lstrcpyn(szbuff, "Hello stranger!", 15); 34 | MessageBox(NULL, szbuff, TEXT("Title"), MB_OK | MB_ICONINFORMATION); 35 | } 36 | 37 | __declspec(dllexport) 38 | int32_t retval_test (int32_t input) 39 | { 40 | return input + 135; 41 | } 42 | 43 | __declspec(dllexport) 44 | void modify_str (char * input) 45 | { 46 | int i, len; 47 | 48 | for (i = 0, len = strlen(input); i < len; i++) 49 | input[i] ++; 50 | } 51 | 52 | __declspec(dllexport) 53 | void init_monster (struct monster * m) 54 | { 55 | strcpy(m->name, "Monster"); 56 | m->damage = 10; 57 | } 58 | 59 | 60 | 61 | BOOL WINAPI _DllMainCRTStartup (HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) 62 | { 63 | return 1; 64 | } -------------------------------------------------------------------------------- /binary/interoperable/resources/clib-so.c: -------------------------------------------------------------------------------- 1 | /* 2 | Compile: 3 | (x64) 4 | $ gcc -shared -fPIC -o clib-x64.so clib-so.c 5 | 6 | (x86) 7 | $ gcc -shared -fPIC -m32 -o clib-x86.so clib-so.c 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct monster 15 | { 16 | char name [10]; 17 | int damage; 18 | }; 19 | 20 | void hello () 21 | { 22 | printf ("Hello World!\n"); 23 | } 24 | 25 | int32_t retval_test (int32_t input) 26 | { 27 | return input + 135; 28 | } 29 | 30 | void modify_str (char * input) 31 | { 32 | int i, len; 33 | 34 | for (i = 0, len = strlen(input); i < len; i++) 35 | input[i] ++; 36 | } 37 | 38 | void init_monster (struct monster * m) 39 | { 40 | strcpy(m->name, "Monster"); 41 | m->damage = 10; 42 | } -------------------------------------------------------------------------------- /binary/parsing/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Open any executable file (PE / ELF). Interpret the header and find out the target architecture or the machine type of the executable. 4 | 5 | ## Remarks 6 | 7 | Different architecture or cpu processor has different characteristics such as instruction set and register length. Executable for an architecture family are basically incompatible when ran on different architecture family. By knowing this, you can set a course of actions to properly analyze the executable. -------------------------------------------------------------------------------- /binary/parsing/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Open any executable file (PE / ELF). Get the (relative/virtual) address of `entrypoint`. 4 | 5 | You can use any library or parse the executable format manually. 6 | 7 | Optionally, calculate the entrypoint when program is loaded into memory. 8 | 9 | ## Remarks 10 | 11 | Entrypoint is the address of first instruction that will be executed. A compiler generated executable will do some setup to make sure the executable can run propertly. Once the setup is done, the user-defined main-function will be called. 12 | 13 | Getting the entrypoint is the first step in binary analysis. In the case when binary has no protection, we can simply trace all functions and basic-blocks from entrypoint. In the case of protection such as packer, we can search for code responsible for unpacking and try to emulate the code to obtain original program. 14 | 15 | Some functions declared at `TLS (Thread Local Storage)` might be executed before the main function. -------------------------------------------------------------------------------- /binary/parsing/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Open any executable file (PE / ELF). Print the name, size, and permission of each sections. 4 | 5 | You can use any library or parse the executable format manually. 6 | 7 | ## Remarks 8 | 9 | Section is an area on executable file which contain sequence of bytes. The bytes can be interpreted as code or data, depends on the flag. 10 | 11 | The size of section indicates the capacity, maximum amount of bytes it can hold. The actual usage might be less than this size. 12 | 13 | Permissions indicate the access rights (read, write, execute) for the section. Once the executable is loaded and mapped by OS, the permission is effectively enforced. Violating the permission (ex: executing the inexecutable section) will raise and exception. -------------------------------------------------------------------------------- /binary/parsing/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Open any executable file (PE / ELF). List all function with its address, registered at import section. 4 | 5 | You can use any library or parse the executable format manually. 6 | 7 | ## Remarks 8 | 9 | Import section is a section where executable will use functions from foreign object (executable or shared library). Shared libraries can be third party libraries or OS-provided libraries. Analyzing import libraries in some case can gain understanding of what executable will do. -------------------------------------------------------------------------------- /binary/parsing/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Open any executable file (PE / ELF). Calculate the entropy of each section. 4 | 5 | You can use any library or parse the executable format manually. 6 | 7 | ## Remarks 8 | 9 | In Information Theory, `Information Entropy` (or just `Entropy`) measures the randomness of sequence of data. The higher the Entropy (popular treshold: 7.5), the harder it is to draw any conclusion or pattern. Entropy often used to identify if the data has been transformed (encrypted or compressed). -------------------------------------------------------------------------------- /binary/parsing/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Open any executable file (PE / ELF). Given an integer `N`, list all printable string which has length no less than `N`. 4 | 5 | Optionally, you can: 6 | 7 | - accept a address range, in which searching will be conducted. 8 | - limit the searching to only data section. 9 | - accept a custom function to filter the string. 10 | 11 | ## Remarks 12 | 13 | Strings can be used as initial analysis. They can be messages which appears on specific events. They can be some hardcoded information used for undocumented processes. Some strings can also be used as reference to functions or code segment that is loaded manually. 14 | 15 | When dealing with interesting strings, one can try to do cross-reference and find any code which use the string. -------------------------------------------------------------------------------- /binary/parsing/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Open any executable file (PE / ELF). List all entries on relocation table. For each entry, print out the name and offset it will be relocated to. 4 | 5 | ## Remarks 6 | 7 | Relocation is the process of connecting symbols reference with symbol definition. Relocation is used as correction, identify and update storage location that need to be adjusted so accessing the variable will land in the correct address. -------------------------------------------------------------------------------- /binary/parsing/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given a path to executable `P` and section name `S`. 4 | 5 | Open `P` then add `readable`, `writable`, and `executable` permission to section `S`. Save as new executable. 6 | 7 | ## Remarks 8 | 9 | In executable, section is a container which hold actual data or code. When process is running, access to section is controlled by permission. In most executable format, there are three permission: readable, writable, and executable. 10 | 11 | Normally a code section is marked as `readable` and `writable`, thus making execution possible. While `writable` found on section designated as data section. 12 | 13 | Marking a section as `writable` grant permission for modifying section, while `executable` make the content can be interpreted as instruction. Usually, this is used for injection shellcode to an executable by finding a codecave inside a section. -------------------------------------------------------------------------------- /binary/parsing/chall-08.md: -------------------------------------------------------------------------------- 1 | ## Challenge 08 2 | 3 | Open any executable file (PE / ELF). 4 | 5 | List all sections which have empty space at the end of section. The empty space is defined as gap between `physical` and `virtual` address of section's end. 6 | 7 | For each gap found, give the virtual address and size. 8 | 9 | Optionally, you can filter code cave by the size. 10 | 11 | ## Remarks 12 | 13 | Finding code cave. 14 | 15 | A code cave is a series of unused byte in process memory. In offensive operation, this area is usually injected with custom instruction which then executed at runtime. 16 | 17 | A section is allocated as multiple of pages. Therefore, the start address and the size is physically set as multiple of pages. The actual size of content (code/data) however are not always have same size. Thus, the virtual size reflected the actual size which is mostly less than the physical size. -------------------------------------------------------------------------------- /binary/parsing/chall-09.md: -------------------------------------------------------------------------------- 1 | ## Challenge 09 2 | 3 | Given a path to executable `P` an integer `N`. 4 | 5 | Open `P`, find the section which is located at the end of file. Expand the size of section with `N` pages. Save as new executable. 6 | 7 | Note: 8 | 9 | - the resulting executable should have `N` pages larger than original. 10 | - the section information must be modified to reflect the change. 11 | 12 | ## Remarks 13 | 14 | Creating code cave. 15 | 16 | Instead of finding existing code cave, an executable can be expanded to have empty area. -------------------------------------------------------------------------------- /binary/parsing/chall-10.md: -------------------------------------------------------------------------------- 1 | ## Challenge 10 2 | 3 | Given a shellcode `S`. 4 | 5 | Create a minimalistic executable which run shellcode `S`. 6 | 7 | Assume shellcode is always Position-Independent Code. 8 | 9 | ## Remarks 10 | 11 | Creating executable as wrapper for shellcode. -------------------------------------------------------------------------------- /bruteforce/README.md: -------------------------------------------------------------------------------- 1 | # Pythonidae Challenge 2 | 3 | Learn Python for Cyber Security by completing challenges. 4 | 5 | #### Brute Force 6 | 7 | This is `Bruteforce Set`. This set is suitable for you to learn how to generate word list and create transformation of string. You will also use generated wordlist to bruteforce some formats. 8 | 9 | ## Table of Content 10 | 11 | You will see 12 | 13 | - `Wordlist` Generation 14 | - `Fuzzing` Payload Generation. 15 | 16 | #### Wordlist Generation 17 | 18 | 0. all string with certain length. 19 | 1. all string with length 1 to N. 20 | 2. all string with length S to E. 21 | 3. all string with certain length and defined alphabet. 22 | 4. permutation with all alternatives character. 23 | 5. regex-like rule for generating string. 24 | 25 | #### Fuzzing Payload Generation 26 | 27 | 0. mutate a byte at specific interval. 28 | 1. mutate N-bytes at specific interval. 29 | 2. mutate bytes by ratio. 30 | 3. grammar based mutation. -------------------------------------------------------------------------------- /bruteforce/fuzzing/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a large string `S`. 4 | 5 | Do the following until reaching end of string. 6 | 7 | - Choose a random number `O` which in the range `1 to 10` 8 | - Advance to next `O` characters from current position (initially start of string). If it past the last character, then stop. 9 | - Change whatever character on current position to random byte. 10 | 11 | Once done, compute the ratio of random characters and unchanged characters. 12 | 13 | ## Remarks 14 | 15 | `Fuzzing` is mutating (changing) a portion of string to random character and feed it as input to process. 16 | 17 | Mutation can be done in random position for certain amount of characters. -------------------------------------------------------------------------------- /bruteforce/fuzzing/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a large string `S`. 4 | 5 | Do the following until reaching end of string. 6 | 7 | - Choose a random number `O` and `N`, both are in the range `1 to 10`, with `N` < `O`. 8 | - Advance to next `O` characters from current position (initially start of string). Stop the process if it past the last character. 9 | - Take at most `N` characters from current position and change each to random byte. 10 | 11 | Once done, compute the ratio of random characters and unchanged characters. 12 | 13 | ## Remarks 14 | 15 | `Fuzzing` is mutating (changing) a portion of string to random character and feed it as input to process. 16 | 17 | Mutation can be done in random position for certain amount of characters. -------------------------------------------------------------------------------- /bruteforce/fuzzing/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a large string `S` and an integer `R` in the range `1 to 100`. 4 | 5 | The integer `R` represent the ratio of random characters and unchanged characters as percentage. 6 | 7 | Do the following until the ratio reach `R`. 8 | 9 | - Choose a random number `O` which in the range `1 to 10` 10 | - Advance to next `O` characters from current position (initially start of string). If it past the last character, then stop. 11 | - Change whatever character on current position to random byte. 12 | 13 | Once done, compute the ratio of random characters and unchanged characters. 14 | 15 | ## Remarks 16 | 17 | `Fuzzing` is mutating (changing) a portion of string to random character and feed it as input to process. 18 | 19 | Mutation can be done in random position for certain amount of characters. -------------------------------------------------------------------------------- /bruteforce/fuzzing/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a string `G` as grammar. 4 | 5 | 6 | The grammar consists of two parts: static and dynamic. Static part is immutable (cannot change) during operation, while dynamic part is mutable. Fuzzing only done on parts which marked as mutable. 7 | 8 | The grammar applied: 9 | 10 | - Alphabet can be letter (lowercase/uppercase), number, whitespaces, or special symbol. 11 | - static or immutable string is enclosed by `()`. 12 | - dynamic or mutable string is marked as `\f`. 13 | - if mutable string only valid for certain set alphabet, defined by enclosing with `[]`. 14 | - If symbol such as `{`,`}`,`\` will be used as alphabet, add `\` in front of them. 15 | 16 | Generate fuzzing payload which follow rules of `G`. 17 | 18 | ## Test 19 | 20 | Given a string `G` 21 | 22 | ``` 23 | (USER) \f 24 | ``` 25 | 26 | should give some payloads: 27 | 28 | ``` 29 | USER a 30 | ``` 31 | 32 | ## Remarks 33 | 34 | Protocol such as `HTTP`, `FTP`, etc defined strict standard of how it can communicate. Fuzzing for protocol should follow the standard. For this purpose, fuzzer should know which part is mutable and immutable. Some immutable parts can be command and flags. -------------------------------------------------------------------------------- /bruteforce/wordlist-gen/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given integer `N`. 4 | 5 | Generate list of string with length exactly `N`. Each element of string is lowercase alphabet (a-z). 6 | 7 | Save the list as file with each line contain only a string. 8 | 9 | ## Test 10 | 11 | Given `N = 2`, should produce `[ aa, ab, ac, ... , zy, zz ]` 12 | 13 | ## Remarks 14 | 15 | Brute force is an attempt to try all possibilities of states to crack verification system. The attack is based on trial and error. The heart of this attack is wordlist, a large amount of words that will be verified one by one. 16 | 17 | Larger wordlist will raise the chance of success but would require longer time. Therefore, creating a correct wordlist is essentially useful. 18 | 19 | One approach is to create all words from all possible characters on certain length. This require large space to store the result. -------------------------------------------------------------------------------- /bruteforce/wordlist-gen/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given integer `N`. 4 | 5 | Generate list of string which length is `1` to `N`. Each element of string is lowercase alphabet (a-z). 6 | 7 | Save the list as file with each line contain only a string. 8 | 9 | ## Test 10 | 11 | Given `N = 3`, should produce 12 | 13 | ``` 14 | a, b, c, ..., z, 15 | aa, ab, ac, ..., zy, zz 16 | aaa, aab, aac, ..., zzy, zzz 17 | ``` 18 | 19 | ## Remarks 20 | 21 | When the length is unknown, then one should generate all words in various length. -------------------------------------------------------------------------------- /bruteforce/wordlist-gen/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given two integers `S` and `E`. 4 | 5 | Generate list of string which length is `S` to `E`. Each element of string is lowercase alphabet (a-z). 6 | 7 | Save the list as file with each line contain only a string. 8 | 9 | ## Test 10 | 11 | Given `S = 2` and `E = 3`, should produce 12 | 13 | ``` 14 | aa, ab, ac, ..., zy, zz 15 | aaa, aab, aac, ..., zzy, zzz 16 | ``` 17 | 18 | ## Remarks 19 | 20 | Some systems dictate that the length of the word is in a fix range, no more or no less. -------------------------------------------------------------------------------- /bruteforce/wordlist-gen/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given integer `N` and a list of character `L`. 4 | 5 | Generate list of string which length is `N`. Each element of string is member of the list `L`. 6 | 7 | Save the list as file with each line contain only a string. 8 | 9 | ## Test 10 | 11 | Given `N = 2` and `L` is `a, b, c`. 12 | 13 | Should produce a list `aa, ab, ac, ba, bb, bc, ca, cb, cc` 14 | 15 | ## Remarks 16 | 17 | To speed up generation process, we can specify valid alphabets in system. -------------------------------------------------------------------------------- /bruteforce/wordlist-gen/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a word `W` and a dictionary of alternative characters `L`. 4 | 5 | Generate list of alternative words. Each word is produced by substitute one character with its alternative character. 6 | 7 | ## Test 8 | 9 | Given word `password` and list of substitute character as 10 | 11 | ``` 12 | { 13 | 'a': ['a','A','@','4'] 14 | } 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | password 21 | pAssword 22 | p@ssword 23 | p4ssword 24 | ``` 25 | 26 | ## Remarks 27 | 28 | Industry standard enforce password to contain letter (lowercase/uppercase), numbers, and special characters. User might use seasy to remember password related to company name, pet name, partner name, etc with slight modification. 29 | 30 | Our approach for this is to permutate word. Permutation is substituting a character with alternative characters. However, creating permutation will have more costs in storage or time. -------------------------------------------------------------------------------- /bruteforce/wordlist-gen/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a regex-like string `R`. 4 | 5 | Generate a word following the rules of `R`. 6 | 7 | `R` is a finite set of characters. Every alphabet of `R` indicate a single character of result word. The following rules are applied: 8 | 9 | - Alphabet can be letter (lowercase/uppercase), number, or special symbol. 10 | - The `[ ]` operator is used for alternative alphabet. 11 | * each alphabet inside is alternative of a single character on that position. For example `a[abc]` will produce 3 words: `aa, ab, ac`. 12 | * range of alphabet is specified by `-`. For example `3[a-d]` will produce 4 words: `3a, 3b, 3c, 3d`. 13 | * more complex range is possible. For example `c[a-b0-3]` will produce 8 words: `ca0, ca1, ca2, ca3, cb0, cb1, cb2, cb3`. 14 | - The `{ }` operator is used for repetition for alphabet or group. 15 | * `{N}` means the alphabet or group will repeat `N` times. The `a{2}` will produce `aa` but `[ab]{2}` will produce `aa, ab, ba, bb`. 16 | * `{L,M}` means the alphabet or group will repeat at least `L` times and at most `M` times. The `a{2,3}` will produce `aa, aaa`, while `[ab]{2,3}` will produce `aa, bb, aaa, bbb`. 17 | - If symbol such as `[`, `]`, `{`, `}`, `\` will be used as alphabet, add `\` in front of them. 18 | - escape characters exist to represent a group of alphabet. 19 | * `\u` for uppercase, has same effect as `[A-Z]` 20 | * `\l` for lowercase, has same effect as `[a-z]` 21 | * `\s` for lowercase + uppercase, has same effect as `[a-zA-Z]` 22 | * `\d` for numerical digit, has same effect as `[0-9]` 23 | 24 | ## Test 25 | 26 | Given a string `R` 27 | 28 | ``` 29 | p[aA@4]ssword\d{0,2} 30 | ``` 31 | 32 | should produce 33 | 34 | ``` 35 | password 36 | pAssword 37 | p@ssword 38 | p4ssword 39 | password1, password2, ... , password9 40 | pAssword1, pAssword2, ... , pAssword9 41 | p@ssword1, p@ssword2, ... , p@ssword9 42 | p4ssword1, p4ssword2, ... , p4ssword9 43 | password11, password12, ... , password99 44 | pAssword11, pAssword12, ... , pAssword99 45 | p@ssword11, p@ssword12, ... , p@ssword99 46 | p4ssword11, p4ssword12, ... , p4ssword99 47 | ``` 48 | 49 | with total of 4000 words. 50 | 51 | ## Remarks 52 | 53 | Instead of writing new script for each pattern, we can create a language to quickly generate a wordlist. With this approach, we only create a regex pattern to create a worldlist. -------------------------------------------------------------------------------- /crypto/README.md: -------------------------------------------------------------------------------- 1 | # Pythonidae Challenge 2 | 3 | Learn Python for Cyber Security by completing challenges. 4 | 5 | #### Crypto 6 | 7 | This is `Crypto Set`. This set is suitable for you to learn cryptography in Cyber Security context. 8 | 9 | The goal of cryptography is to securely sharing secrets with others so no adversaries can learn the secret. 10 | 11 | ## Table of Content 12 | 13 | You will see 14 | 15 | - `Encoding` 16 | - `Cipher` (Classic, Block, Stream, Asymmetric, Attack) 17 | - `Hash` & `MAC` 18 | 19 | #### Encode 20 | 21 | Encoding is conversion of data from one form to other form. Usually reduce loss in transmission or represent data in readable format. 22 | 23 | 0. base64. 24 | 1. base85. 25 | 2. url. 26 | 3. uu encoding. 27 | 4. xx encoding. 28 | 29 | #### Cipher 30 | 31 | classic 32 | 33 | 0. ROT13 34 | 1. Atbash 35 | 2. Affine 36 | 3. Rail-Fence 37 | 4. Vigenere 38 | 5. Beaufort 39 | 6. ADFGVX 40 | 7. Playfair 41 | 42 | block 43 | 44 | 0. generate random bytes for key 45 | 1. DES 46 | 2. 3DES 47 | 3. AES/ECB 48 | 4. AES/CBC 49 | 5. validate PKCS#7 and strip 50 | 6. AES/CTR 51 | 7. Camellia 52 | 53 | stream 54 | 55 | 0. Salsa20 56 | 57 | asymmetric 58 | 59 | 0. generate RSA key-pair and store in PEM. 60 | 1. generate RSA key-pair and store in PEM protected by passphrase. 61 | 2. read the public key from PEM file and do RSA encryption. 62 | 3. read the private key from PEM file and do RSA decryption. 63 | 4. generate ECC key-pair and store in PEM protected by passphrase. 64 | 5. read the private key from PEM file and do ECC encryption. 65 | 6. read the public key from PEM file and do ECC decryption. 66 | 67 | attack 68 | 69 | 0. N-gram frequency count 70 | 1. breaking single-byte XOR encryption 71 | 2. breaking repeating-key XOR encryption 72 | 3. detecting AES/ECB 73 | 74 | #### Hash 75 | 76 | 0. md5 77 | 1. md5 with salt (append, prepend) 78 | 2. sha-256 79 | 3. sha3-256 80 | 4. bcrypt 81 | 5. hmac -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Generate public and private key of 4096-bits for RSA with appropriate exponent. Encode and store each key into PEM-format file. 4 | 5 | You are free to use library or implement algorithm by yourself. 6 | 7 | ## Remarks 8 | 9 | `RSA (Rivest-Shamir-Adleman)` is a public-key cryptosystem and is widely used for secure data transmission. RSA use a pair of key: `public key` and `private key`. The public key is used to encrypt data which will be sent to system and private key is used by system to decrypt the data. 10 | 11 | The RSA strength comes from the difficult of the factorization of the product of two large prime numbers. 12 | 13 | `PEM` (Privacy Enhanced Mail) is a Base64-encoded text with start/end delimiters. 14 | 15 | Generating RSA public + private key involves following: 16 | 17 | - Find three very large integers `e`, `d`, and `n` such that: `(me)d ≡ m (mod n)` for all `m` in the range 0..n 18 | - `n` is modulus, defines the key length. 19 | - Pair `(n, e)` is public key. 20 | - `e` is public key exponent, usually `65537` (0x010001) 21 | - Pair `(n, d)` is private key. 22 | - `d` is private key exponent. 23 | -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Generate public and private key of 4096-bits for RSA with appropriate exponent. Encode and store each key into PEM-format file and protected by passphrase. 4 | 5 | Verify the key can be read by using correct passphrase, both using OpenSSL and by python code. 6 | 7 | You are free to use library or implement algorithm by yourself. -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a string `S` and path to PEM file for public key. 4 | 5 | Read the PEM-file and encrypt the string `S` using RSA with OAEP padding. Encode the result in `base64` encoding. 6 | 7 | You are free to use library or implement RSA algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | Compared to symmetric block cipher, RSA ran slower and might not be suitable to encrypt large data in real time. In practice, RSA is used in initial stage to establish a connection between the parties. RSA commonly used to encrypt symmetric key. This symmetric key as well as the agreed block cipher then used to communicate. 12 | 13 | Encrypting message using RSA public key `(n, e)` is done by following transformation: 14 | 15 | ``` 16 | c = p.e mod n 17 | ``` 18 | 19 | `p (plaintext)` is encoded as integer in the range [0..n). -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a base64-encoded string `S` and path to PEM file for private key. 4 | 5 | Read the PEM-file and decrypt the decoded string `S` using RSA with OAEP padding. 6 | 7 | You are free to use library or implement RSA algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | Decrypting message using RSA private key `(n, d)` is done by following transformation: 12 | 13 | ``` 14 | p = c.d mod n 15 | ``` 16 | 17 | `c (ciphertext)` is encoded as integer in the range [0..n). -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Generate public and private key or ECC with appropriate curve parameter. Encode and store each key into PEM-format file and protected by passphrase. 4 | 5 | You are free to use library or implement algorithm by yourself. 6 | 7 | ## Remarks 8 | 9 | `ECC` (Elliptic Curve Cryptography) is modern family of public-key cryptosystem, which is based on the algebraic structures of the elliptic curves over finite field and on the difficulty of th Elliptic Curve Discrete Logarithm Problem (ECDLP). 10 | 11 | ECC implements all major capabilities of the asymmetric cryptosystems: encryption/decryption, signatures, and key exchange. 12 | 13 | Compared to RSA, ECC use smaller keys for the same level of security and provides fast key generation, fast key agreement, and fast signatures. 14 | 15 | `PEM` (Privacy Enhanced Mail) is a Base64-encoded text with start/end delimiters. 16 | 17 | The private keys in the ECC are integers (in the range of the curve's field size). The public keys in the ECC are EC points, pairs of integers coordinate {x, y} laying on the curve. -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a string `S` and path to PEM file for private key. 4 | 5 | Read the PEM-file and encrypt the string `S` using ECC. Encode the result in `base64` encoding. 6 | 7 | You are free to use library or implement RSA algorithm by yourself. -------------------------------------------------------------------------------- /crypto/cipher/asymmetric/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a base64-encoded string `S` and path to PEM file for public key. 4 | 5 | Read the PEM-file and decrypt the decoded string `S` using ECC. 6 | 7 | You are free to use library or implement ECC algorithm by yourself. -------------------------------------------------------------------------------- /crypto/cipher/attack/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a string `S` and integer `N`. 4 | 5 | Divide the text into block of `N` character(s) and count the appearance of each block in the text. 6 | 7 | If `S` is not multiple of `N`, add padding at the end. 8 | 9 | ## Test 10 | 11 | Given a string 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | and `N = 2` 18 | 19 | will produce result: 20 | 21 | ``` 22 | { 23 | "MI": 1, 24 | "I ": 1, 25 | "Cy": 1, 26 | "be": 1, 27 | "rs": 1. 28 | "ec": 1 29 | } 30 | ``` 31 | 32 | ## Remarks 33 | 34 | Frequency counting create a statistic of individual character and how often it appears on text. Statistic then can be used to map most frequent character in language of reference. 35 | 36 | Often, it is desirable to look not at how often characters appear but at what characters they appear next to. N-gram (digram for 2, trigram for 3, etc) create statistic of how often characters appear. -------------------------------------------------------------------------------- /crypto/cipher/attack/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a string `S` which had been encrypted by a single-character XOR. 4 | 5 | Find the key. 6 | 7 | ## Test 8 | 9 | Given a string `S` (in hexpair representation) 10 | 11 | ``` 12 | d7fef3efe8e9eee3e6e2a7e4efe6ebebe2e9e0e2a7e5fea7caceceaac4fee5e2f5d4e2e4 13 | ``` 14 | 15 | should have key `0x87` 16 | 17 | ## Remarks 18 | 19 | XOR operation is still commonly used as fast encryption algorithm. 20 | 21 | One way to break this is to measure how much probability of it resemble a valid string. 22 | 23 | If the string is a valid message in certain language (i.e: English), then counting letter frequency might help. Find out the most common letter and map it to most common letter in that language. -------------------------------------------------------------------------------- /crypto/cipher/attack/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a string `S`, and two integer `M` and `N`. 4 | 5 | The string `S`, with size `M`, had been encrypted by a string `K` of size `N`. 6 | 7 | Find the `K`. 8 | 9 | ## Test 10 | 11 | Given a string `S` (length = 36) 12 | 13 | ``` 14 | 281800001d17081c001148111100140d1106151c411a1854253b304c3b18160d002a041b 15 | ``` 16 | 17 | and `N` = 7. 18 | 19 | the key should be: `78617468727961` (length = 7) 20 | 21 | ## Remarks 22 | 23 | XOR operation is still commonly used as fast encryption algorithm. 24 | 25 | One way to break this is to guessing the key length and find the edit distance between each block. 26 | 27 | General idea would be like this: 28 | 29 | 1. let `KEYSIZE` be the guess length of the key, which range from `2` to `N-1` 30 | 2. divide the string `S` into blocks of `KEYSIZE` data 31 | 3. compute the edit distance of a block with next block and then normalize this result by dividing by `KEYSIZE`. 32 | 4. the `KEYSIZE` with smallest normalized edit distance is probably the key. 33 | 5. after guessing the `KEYSIZE`, transpose the block, make a block that is the first byte of every block, and a block that is the second byte of every block, and so on. 34 | 6. solve each block as if it was single-character XOR. 35 | 7. single-byte XOR key that produce the best looking histogram is the repeating XOR key byte for that block. Putting them together and you get the key. -------------------------------------------------------------------------------- /crypto/cipher/attack/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a string `S`. 4 | 5 | Detect whether the string has been encrypted by `AES/ECB`. 6 | 7 | Note: 8 | - only predict whether the data is encrypted by `AES/ECB` or not. 9 | - use statistic analysis on the blocks. 10 | 11 | ## Remarks 12 | 13 | `ECB (Electronic Code Book)` is an encryption mode which divide message into blocks and each block is encrypted separately. The result of one block won't affecting other block. 14 | 15 | ECB is stateless and deterministic, which 16-byte plaintext block will always product the same 16-byte ciphertext. -------------------------------------------------------------------------------- /crypto/cipher/block/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Generate string of random bytes with length `N`. Use secure random source. 4 | 5 | Make sure the result is unique, not recurred when code executed at different time. 6 | 7 | ## Remarks 8 | 9 | One of crucial thing in encryption/decryption is the key. There are several way to obtain a key: 10 | 11 | - supplied by the user 12 | - generated or derived by system (random) 13 | 14 | In the case of key, randomness is desired which lead to unpredictable ciphertext. -------------------------------------------------------------------------------- /crypto/cipher/block/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a string `S` and key `K`. 4 | 5 | Encrypt the string with `DES` and `ECB` mode. Encode the result in `Base64` encoding. 6 | 7 | Note: you are free to use library or implement `DES` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `DES (Data Encryption Standard)` is old standard which has been superseded by `AES`. The algorithm for encryption/decryption is known as `DEA (Data Encryption Algorithm)`. 12 | 13 | DES used to be popular. Eventhough it's proven as broken, some (old) systems might still use it (or its sibling, `3DES`). -------------------------------------------------------------------------------- /crypto/cipher/block/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a string `S` and key `K`. 4 | 5 | Encrypt the string with `3DES` and `ECB` mode. Encode the result in `Base64` encoding. 6 | 7 | Note: you are free to use library or implement `3DES` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `Triple DES (3DES, TDES)` is an extension to `DES` which applying `DES` encryption three times to each data block. Therefore, instead of using one key `3DES` use three different keys. 12 | 13 | Usually the encryption algorithm is: 14 | 15 | ``` 16 | ciphertext = Ek3(Dk2(Ek1(plaintext))) 17 | ``` 18 | 19 | while the decryption is: 20 | 21 | ``` 22 | plaintext = Dk1(Ek2(Dk3(ciphertext))) 23 | ``` -------------------------------------------------------------------------------- /crypto/cipher/block/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a string `S` and key `K`. 4 | 5 | Encrypt the string with `AES-128` and `ECB` mode. Encode the result in `Base64` encoding. 6 | 7 | You are free to use library or implement `AES` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `AES (Advanced Encryption Standard)`, is a specification for the encryption of data. The algorithm itself is a subset of `Rijndael` block cipher. The standard specify same algorithm for three different block size: 128, 192, and 256 bits. 12 | 13 | `AES` is popular and widely used. Some system used `AES` in their communication and store the encryption hardcoded or in a configuration file. -------------------------------------------------------------------------------- /crypto/cipher/block/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Given a string `S` and key `K` 4 | 5 | Encrypt the string with `AES-128` and `CBC` mode. Encode the result in `base64` encoding. 6 | 7 | You are free to use library or implement `AES` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `CBC (Cipher Block Chaining)` is an encryption mode where the plaintext block is XORed with previous ciphertext block before being encrypted. This way each ciphertext block depends on the all plaintext blocks processed up to that point. 12 | 13 | When encrypting the first block, a special block dubbed as `IV (Initialization Vector)` is used to replace the previous ciphertext block. -------------------------------------------------------------------------------- /crypto/cipher/block/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a sequence of bytes supposed to be a plaintext append with PKCS#7 padding. 4 | 5 | Validate if the `PKCS#7` is valid and strips the padding off. 6 | 7 | ## Test 8 | 9 | Assuming the block is 16 byte. 10 | 11 | This sequence of bytes is valid `PKCS#7` 12 | 13 | ``` 14 | MII Cybersec\x04\x04\x04\x04 15 | ``` 16 | 17 | while this one is not 18 | 19 | ``` 20 | Pythonidae\x05\x05\x05\x05\x05\x05 21 | ``` -------------------------------------------------------------------------------- /crypto/cipher/block/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a string `S` and key `K`. 4 | 5 | Encrypt the string with `AES-128` and `CTR` mode. Encode the result in `Base64` encoding. 6 | 7 | You are free to use library or implement `AES` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `CTR (counter)` is an encryption mode where encryption is done against a running counter instead of plaintext. This will produce block of keystream which is XORed against the plaintext. 12 | 13 | Modern cryptography relies on `CTR` mode to adapt block ciphers into stream ciphers. -------------------------------------------------------------------------------- /crypto/cipher/block/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given a string `S` and key `K`. 4 | 5 | Encrypt the string with `Camellia` and `CBC` mode. Encode the result in `Base64` encoding. 6 | 7 | Note: you are free to use library or implement `Camellia` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `Camellia` is a symmetric key block cipher with block size of 128 bits and key size of 128, 192, and 256 bits. 12 | 13 | Alhtough less common, `Camellia` has been certified by several standards and supported in several products: 14 | 15 | - TLS/SSL 16 | - IPSec 17 | - Kerberos 18 | - OpenPGP -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a string `S`. 4 | 5 | Encrypt the string with `ROT13` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally, you can produce a string without space and uppercase. 8 | 9 | ## Test 10 | 11 | Given a string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | ZVV Plorefrp 21 | ``` 22 | 23 | If the whitespaces are trimmed and all letters become lowercase, then the result would be 24 | 25 | ``` 26 | zvvplorefrp 27 | ``` 28 | 29 | ## Remarks 30 | 31 | `ROT13` is a classic cipher, a simple letter substitution cipher that replace a letter with 13th letter after it in alphabet. ROT13 is a special case of Caesar Cipher. 32 | 33 | The mapping of each alphabet can be seen below: 34 | 35 | ``` 36 | ABCDEFGHIJKLM 37 | NOPQRSTUVWXYZ 38 | ``` 39 | 40 | The shift 13 is chosen because it is a number that divide alphabet to half, making it easier to do encrypting and decrypting. -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a string `S`. 4 | 5 | Encrypt the string with `Atbash Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally, you can produce a string without space and uppercase. 8 | 9 | ## Test 10 | 11 | Given a string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | NRR Xbyvihvx 21 | ``` 22 | 23 | ## Remarks 24 | 25 | `Atbash Cipher` is a classic cipher, a simple letter substitution cipher. 26 | 27 | The mapping of each alphabet can be seen below: 28 | 29 | ``` 30 | ABCDEFGHIJKLM 31 | ZYXWVUTSRQPON 32 | ``` -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a string `S` and two integers `A` and `B`. 4 | 5 | Encrypt the string with `Affine Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally, you can produce a string without space and uppercase. 8 | 9 | ## Test 10 | 11 | Given a string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | with `A = 5` and `B = 9`, should produce 18 | 19 | ``` 20 | RXX Tzodqvdt 21 | ``` 22 | 23 | ## Remarks 24 | 25 | `Affine Cipher` is a substitution cipher which requires two integers as key. It uses mathematic equation to generate the substituting character. 26 | 27 | The encryption algorithm has following equation 28 | 29 | ``` 30 | C = (A * P + B) mod M 31 | 32 | 1 <= A <= M 33 | 1 <= B <= M 34 | ``` 35 | 36 | And the decryption algorithm 37 | 38 | ``` 39 | P = A^(-1) * (C - B) mod M 40 | ``` 41 | 42 | Not all number can be used. The value of `M` is 26 or the space of possible alphabet. `A` and `B` should be relatively prime to `M` (`A` and `B` have no factors in common with `M`). Thus, the possible range of value: 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25 -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a string `P` as plaintext and string `K` as key. 4 | 5 | Encrypt the string with `Rail-Fence Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally, you can produce a string without space and uppercase. 8 | 9 | ## Test 10 | 11 | Given a string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | with `R = 3`, should produce 18 | 19 | ``` 20 | McrI yescIbe 21 | ``` 22 | 23 | ## Remarks 24 | 25 | `Rail-Fence cipher` is a very simple transposition cipher. It split the text into rows and columns and mix the position of character. 26 | 27 | The key `R` is the row. The plaintext then write in zig-zag order, alternately moving from top row to bottom row. The ciphertext is produced by read the aligned alphabet row by row. 28 | 29 | If we have string `MII Cybersec` and `R = 3`, we then write it as following: 30 | 31 | ``` 32 | M...C...r... 33 | .I. .y.e.s.c 34 | ..I...b...e 35 | ``` 36 | 37 | Reading row by row we get `McrI yescIbe`. -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Given a string `P` as plaintext and string `K` as key. 4 | 5 | Encrypt the string with `Vigenere Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally you can produce a string without uppercase. 8 | 9 | ## Test 10 | 11 | Given a string P and K 12 | 13 | ``` 14 | P = MII Cybersec 15 | L = Xathrya 16 | ``` 17 | 18 | should produce 19 | 20 | ``` 21 | JIBJpzeosxj 22 | ``` 23 | 24 | ## Remarks 25 | 26 | `Vigenere cipher` is a popular cipher polyalphabetic substitution cipher. The method was originally described by `Giovan Battista Bellaso` but misattributed to `Blaise de Vigenere`. Blaise de Vigenere actually create another cipher known as Autokey cipher. 27 | 28 | The encryption and decryption method use a table of characters. It use following tabula recta. 29 | 30 | ``` 31 | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 32 | --------------------------------------------------- 33 | A A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 34 | B B C D E F G H I J K L M N O P Q R S T U V W X Y Z A 35 | C C D E F G H I J K L M N O P Q R S T U V W X Y Z A B 36 | D D E F G H I J K L M N O P Q R S T U V W X Y Z A B C 37 | E E F G H I J K L M N O P Q R S T U V W X Y Z A B C D 38 | F F G H I J K L M N O P Q R S T U V W X Y Z A B C D E 39 | G G H I J K L M N O P Q R S T U V W X Y Z A B C D E F 40 | H H I J K L M N O P Q R S T U V W X Y Z A B C D E F G 41 | I I J K L M N O P Q R S T U V W X Y Z A B C D E F G H 42 | J J K L M N O P Q R S T U V W X Y Z A B C D E F G H I 43 | K K L M N O P Q R S T U V W X Y Z A B C D E F G H I J 44 | L L M N O P Q R S T U V W X Y Z A B C D E F G H I J K 45 | M M N O P Q R S T U V W X Y Z A B C D E F G H I J K L 46 | N N O P Q R S T U V W X Y Z A B C D E F G H I J K L M 47 | O O P Q R S T U V W X Y Z A B C D E F G H I J K L M N 48 | P P Q R S T U V W X Y Z A B C D E F G H I J K L M N O 49 | Q Q R S T U V W X Y Z A B C D E F G H I J K L M N O P 50 | R R S T U V W X Y Z A B C D E F G H I J K L M N O P Q 51 | S S T U V W X Y Z A B C D E F G H I J K L M N O P Q R 52 | T T U V W X Y Z A B C D E F G H I J K L M N O P Q R S 53 | U U V W X Y Z A B C D E F G H I J K L M N O P Q R S T 54 | V V W X Y Z A B C D E F G H I J K L M N O P Q R S T U 55 | W W X Y Z A B C D E F G H I J K L M N O P Q R S T U V 56 | X X Y Z A B C D E F G H I J K L M N O P Q R S T U V W 57 | Y Y Z A B C D E F G H I J K L M N O P Q R S T U V W X 58 | Z Z A B C D E F G H I J K L M N O P Q R S T U V W X Y 59 | ``` 60 | 61 | The top row is the alphabet for the key, and the first column is the alphabet for plaintext. To encipher a message, repeat the keyword above the plaintext 62 | 63 | ``` 64 | XathryaMIIC 65 | MIICybersec 66 | ``` 67 | 68 | First, find the row of plaintext `M`. Then find the column of key `X`. The row `M` and column `X` is intersected to `J` so `J` is the ciphertext. 69 | 70 | `Autokey` and `Vigenere` cipher differs in how they positioning the plaintext and key in the table. -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Given a string `P` as plaintext and string `K` as key. 4 | 5 | Encrypt the string with `Beaufort Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally you can produce a string without uppercase. 8 | 9 | ## Test 10 | 11 | Given a string `P` and `K` 12 | 13 | ``` 14 | P = MII Cybersec 15 | K = Xathrya 16 | ``` 17 | 18 | should produce 19 | 20 | ``` 21 | LSLFtxwgipf 22 | ``` 23 | 24 | ## Remarks 25 | 26 | `Beaufort` is less popular cipher polyalphaetic substitution cipher using tabula recta to substitute character. 27 | 28 | ``` 29 | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 30 | --------------------------------------------------- 31 | A A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 32 | B B C D E F G H I J K L M N O P Q R S T U V W X Y Z A 33 | C C D E F G H I J K L M N O P Q R S T U V W X Y Z A B 34 | D D E F G H I J K L M N O P Q R S T U V W X Y Z A B C 35 | E E F G H I J K L M N O P Q R S T U V W X Y Z A B C D 36 | F F G H I J K L M N O P Q R S T U V W X Y Z A B C D E 37 | G G H I J K L M N O P Q R S T U V W X Y Z A B C D E F 38 | H H I J K L M N O P Q R S T U V W X Y Z A B C D E F G 39 | I I J K L M N O P Q R S T U V W X Y Z A B C D E F G H 40 | J J K L M N O P Q R S T U V W X Y Z A B C D E F G H I 41 | K K L M N O P Q R S T U V W X Y Z A B C D E F G H I J 42 | L L M N O P Q R S T U V W X Y Z A B C D E F G H I J K 43 | M M N O P Q R S T U V W X Y Z A B C D E F G H I J K L 44 | N N O P Q R S T U V W X Y Z A B C D E F G H I J K L M 45 | O O P Q R S T U V W X Y Z A B C D E F G H I J K L M N 46 | P P Q R S T U V W X Y Z A B C D E F G H I J K L M N O 47 | Q Q R S T U V W X Y Z A B C D E F G H I J K L M N O P 48 | R R S T U V W X Y Z A B C D E F G H I J K L M N O P Q 49 | S S T U V W X Y Z A B C D E F G H I J K L M N O P Q R 50 | T T U V W X Y Z A B C D E F G H I J K L M N O P Q R S 51 | U U V W X Y Z A B C D E F G H I J K L M N O P Q R S T 52 | V V W X Y Z A B C D E F G H I J K L M N O P Q R S T U 53 | W W X Y Z A B C D E F G H I J K L M N O P Q R S T U V 54 | X X Y Z A B C D E F G H I J K L M N O P Q R S T U V W 55 | Y Y Z A B C D E F G H I J K L M N O P Q R S T U V W X 56 | Z Z A B C D E F G H I J K L M N O P Q R S T U V W X Y 57 | ``` 58 | 59 | The top row is the alphabet for the plaintext and the content of table is the key. To encipher a message, repeat the keyword above the plaintext 60 | 61 | ``` 62 | XathryaMIIC 63 | MIICybersec 64 | ``` 65 | 66 | First, find the column of plaintext `M`. Iterate over the column until the key `X` is found. Once found, the ciphertext is the row of that cell which is `L`. -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Given a string `P` as plaintext, a string `K` as key, and a string of 36 characters as `M`. 4 | 5 | Encrypt the string with `ADFGVX Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | Optionally you can produce a string without uppercase. 8 | 9 | ## Test 10 | 11 | Given a string P and K 12 | 13 | ``` 14 | P = MII Cybersec 15 | K = Xathrya 16 | ``` 17 | 18 | and string M `ph0qg64mea1yl2nofdxkr3cvs5zw7bj9uti8` which arranged as Polybius square: 19 | 20 | ``` 21 | p h 0 q g 6 22 | 4 m e a 1 y 23 | l 2 n o f d 24 | x k r 3 c v 25 | s 5 z w 7 b 26 | j 9 u t i 8 27 | ``` 28 | 29 | should produce 30 | 31 | ``` 32 | DDFGFGVVAXXDXXVDVGVVDF 33 | ``` 34 | 35 | ## Remarks 36 | 37 | `ADFGVX cipher` is an extension of earlier cipher `ADFGX cipher`. The cipher is a fractionating transposition cipher which combined a modified Polybius square with a single columnar transposition. The name of cipher comes from the six possible letters used in the ciphertext `A`, `D`, `F`, `G`, `V`, and `X`. 38 | 39 | The Polybius square is a 6x6 square containing all letters and numbers (a-z, 0-9). 40 | 41 | Build the square from `ph0qg64mea1yl2nofdxkr3cvs5zw7bj9uti8`: 42 | 43 | ``` 44 | A D F G V X 45 | A | p h 0 q g 6 46 | D | 4 m e a 1 y 47 | F | l 2 n o f d 48 | G | x k r 3 c v 49 | V | s 5 z w 7 b 50 | X | j 9 u t i 8 51 | ``` 52 | 53 | To encipher a message, find the character on the table. Once found, find the row and column. For example, 'C' can be found on row 'G' and column 'V' which result in 'GV'. This will produce `DDXVXVGVDXVXDFGFVADFGV`. 54 | 55 | Then Divide the string by length of key. If the key is `xathrya` which have length 7, then this will produce: 56 | 57 | ``` 58 | xathrya 59 | ------- 60 | DDXVXVG 61 | VDXVXDF 62 | GFVADFG 63 | V...... 64 | ``` 65 | 66 | Sort the column, which gives: 67 | 68 | ``` 69 | aahrtxy 70 | ------- 71 | DGVXXDV 72 | DFVXXVD 73 | FGADVGF 74 | .....V. 75 | ``` 76 | 77 | Then write the result column by column. 78 | 79 | ``` 80 | DDF GFG VVA XXD XXV DVGV VDF 81 | 82 | DDFGFGVVAXXDXXVDVGVVDF 83 | ``` -------------------------------------------------------------------------------- /crypto/cipher/classic/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given a pstring `P` as plaintext and string `K` as key. 4 | 5 | Encrypt the string with `Playfair Cipher` algorithm. Verify the result by decrypting it and compare to the plaintext. 6 | 7 | This algorithm require no whitespace. 8 | 9 | Optionally you can produce a string without uppercase. 10 | 11 | ## Test 12 | 13 | Given a string P and K 14 | 15 | ``` 16 | P = MII Cybersec 17 | K = xathrya 18 | ``` 19 | 20 | should produce 21 | 22 | ``` 23 | OFFVYDZAOCFY 24 | ``` 25 | 26 | ## Remarks 27 | 28 | `Playfair Cipher` is a digraph substitution cipher, encrypting pairs of letters (digraphs) instead of single letters. This algorithm use key-square which built based on the key. The size of square is `5x5`. 29 | 30 | Building the square take only unique alphabet from the key. Thus, key `xathrya` would be `xathry`. Then append other remaining alphabet which do not appear yet. The `I` and `J` are considered as same value. Which, the square for key `xathrya` would be: 31 | 32 | ``` 33 | x a t h r 34 | y b c d e 35 | f g i k l 36 | m n o p q 37 | s u v w z 38 | ``` 39 | 40 | Any sequence of 25 letters can be used as the key, as long as all letters are in and there are no repeats. 41 | 42 | For each digraph, locate the position of each character. Encryption process follow the rules below: 43 | 44 | - if both letters appear on the same row, replace with the letters to their immediate right. 45 | - if both letters appear on the same column, replace with the letters to their immediate below. 46 | - if the letters form a rectangle, replace with the letters on the same row but at the other pair of corners of the rectangle. 47 | 48 | For example the digraph 'MI' will create a rectangle 'MOIF', which makes the 'OF' as ciphertext. -------------------------------------------------------------------------------- /crypto/cipher/stream/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a string `S` and key `K`. 4 | 5 | Encrypt the string with `Salsa20`. Prepend the `nonce` before the ciphertext. 6 | 7 | Note: you are free to use library or implement `Salsa20` algorithm by yourself. 8 | 9 | ## Remarks 10 | 11 | `Salsa20` is a stream ciphers admitted as one of `eSTREAM` portofolio. The standard `Salsa20` require key size of 128 or 256 bits. 12 | 13 | As `eSTREAM` portofolio, `Salsa20` (and `Chacha20`) is popular and widely used. -------------------------------------------------------------------------------- /crypto/encode/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given a string `S`. 4 | 5 | Encode it with `Base64`. Verify te result by decoding it back and compare to original value. 6 | 7 | You are free to use library or implement `Base64` encoder/decoder by yourself. 8 | 9 | ## Test 10 | 11 | Given string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | TUlJIEN5YmVyc2Vj 21 | ``` 22 | 23 | ## Remarks 24 | 25 | `Base64` is one of common encoding used in many cases. It is used to represent binary data. Some common usages: 26 | 27 | - encode user credentials in basic HTTP authentication 28 | - encode email attachments for transmission over SMTP 29 | - transmit encrypted request/response body. 30 | 31 | `Base64` looks data in blocks of 3 bytes (24-bits). These 24 bits are then divided into 4 chunks of 6-bits each. Each chunks is then mapped to the corresponding `Base64` values (on a table). 32 | 33 | `Base64` use 64 different printable characters: a-z, A-Z, 0-9, +, / and padding =. 34 | 35 | Other encoding on same family: `Base32`, `Base16`, `Base85` (or `Ascii85`). -------------------------------------------------------------------------------- /crypto/encode/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Given a string `S`. 4 | 5 | Encode it with `Ascii85`. Verify te result by decoding it back and compare to original value. 6 | 7 | You are free to use library or implement `Ascii85` encoder/decoder by yourself. 8 | 9 | ## Test 10 | 11 | Given string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | O-V^0LwRCla&u*4 21 | ``` 22 | 23 | ## Remarks 24 | 25 | `Ascii85` or `Base85` is one of common encoding used in many cases. It is used to represent binary data. It is mainly used in Adobe's PostScript and Portable Document Format (PDF) file format. -------------------------------------------------------------------------------- /crypto/encode/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given a string `S`. 4 | 5 | Encode it with `URL encoding`. Verify te result by decoding it back and compare to original value. 6 | 7 | You are free to use library or implement URL encoder/decoder by yourself. 8 | 9 | ## Test 10 | 11 | Given string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | MII+Cybersec 21 | ``` 22 | 23 | ## Remarks 24 | 25 | `URL encoding` is commonly used in web technologies. It is used to represent some characters to avoid ambiguity. When dealing with URLs (and the body of POST request), they can only contain printable ASCII characters (codes between 32 and 126 or 0x20 - 0x7E). Some characters within this range has special meaning within the URL or within HTTP protocol. 26 | 27 | In general, `URL Encoding` might transform single character to their hex equivalent in the format `%XX` where XX is the hexpair. 28 | 29 | ``` 30 | % -> %25 31 | space -> %20 32 | tab -> %09 33 | = -> %3D 34 | ``` 35 | 36 | Note that, on URL you can also represent a space using +. -------------------------------------------------------------------------------- /crypto/encode/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given a string `S`. 4 | 5 | Encode it with `uu encoding`. Verify te result by decoding it back and compare to original value. 6 | 7 | You are free to use library or implement UU encoder/decoder by yourself. 8 | 9 | ## Test 10 | 11 | Given string `S` 12 | 13 | ``` 14 | MII Cybersec 15 | ``` 16 | 17 | should produce 18 | 19 | ``` 20 | begin 666 input.txt\n,34E)($-Y8F5R` or similar involved in the execution of script. 8 | 9 | ## Test 10 | 11 | Run [runme.exe](resources/runme.exe) (windows) or [runme](resources/runme) (linux) and give `MII Cybersec` as argument. 12 | 13 | All output should be stored into file. 14 | 15 | Both are 32 bit executable. The source code is available as [runme.c](resources/runme.c). -------------------------------------------------------------------------------- /process/subprocess/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Spawn an executable. Obtain the exit code (or return code) or executable upon program exit. 4 | 5 | ## Test 6 | 7 | Run [runme.exe](resources/runme.exe) (windows) or [runme](resources/runme) (linux) and give `MII Cybersec` as argument. 8 | 9 | Successfully running the process should print the exit code (code = 135). 10 | 11 | Both are 32 bit executable. The source code is available as [runme.c](resources/runme.c). -------------------------------------------------------------------------------- /process/subprocess/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Spawn an executable, get the stdin and stdout of the process using pipe. Send a string to stdin and get the result from stdout interactively. 4 | 5 | ## Test 6 | 7 | Run [echoer.exe](resources/echoer.exe) (windows) or [echoer](resources/echoer) (linux) and give `MII Cybersec` as argument. 8 | 9 | This program will have a infinite loop and will relay any message from stdin to stdout. To terminate, give a string `exit` as input. 10 | 11 | Both are 32 bit executable. The source code is available as [echoer.c](resources/echoer.c). 12 | 13 | -------------------------------------------------------------------------------- /process/subprocess/resources/echoer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/process/subprocess/resources/echoer -------------------------------------------------------------------------------- /process/subprocess/resources/echoer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | int length; 7 | char buffer[1024]; 8 | 9 | while(1) 10 | { 11 | fflush(stdin); 12 | // scanf("%127[^\n]", buffer); 13 | fgets (buffer, 1024, stdin); 14 | length = strlen(buffer); 15 | buffer[length-1] = 0; 16 | 17 | if (strcmp(buffer, "exit") == 0) 18 | break; 19 | else 20 | printf("%d %s\n", strlen(buffer), buffer); 21 | } 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /process/subprocess/resources/echoer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/process/subprocess/resources/echoer.exe -------------------------------------------------------------------------------- /process/subprocess/resources/runme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/process/subprocess/resources/runme -------------------------------------------------------------------------------- /process/subprocess/resources/runme.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char* argv[]) 4 | { 5 | if (argc > 1) 6 | printf("Receive: %s\n", argv[1]); 7 | 8 | return 135; 9 | } -------------------------------------------------------------------------------- /process/subprocess/resources/runme.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MII-Cybersec/pythonidae-challenge/80dbcca8c429ce951793f2a92565a2f90b93b5f2/process/subprocess/resources/runme.exe -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # Pythonidae Challenge 2 | 3 | Learn Python for Cyber Security by completing challenges. 4 | 5 | #### Web 6 | 7 | This is `Web Technology Set`. We pick some tasks related to accessing web (application, service) and processing request/response in communication exchange. 8 | 9 | Interaction to web can be sending request and process response from web application or web service API. Scripting for targetting web application usually dealing with HTML parsing. For web service API, we are parsing JSON (for RESTful) or XML (for SOAP) 10 | 11 | ## Contents 12 | 13 | You will see 14 | 15 | - HTTP `Request` 16 | - Web `scraping` 17 | 18 | #### HTTP Request 19 | 20 | 0. send request and get value of key from response. 21 | 1. send request with user-agent. 22 | 2. get cookie from response. 23 | 3. send request with modified cookie. 24 | 4. get JWT token from response. 25 | 5. send request with JWT token in body. 26 | 6. send request with JWT token in header. 27 | 7. use multiple random user-agent to send request. 28 | 8. send back a response within duration. 29 | 30 | #### Web Scraping 31 | 32 | 0. list all URL in page. 33 | 1. load response and search for flag on certain flag. 34 | 2. list all URL to JS file in page. 35 | 3. load image by URL. 36 | 4. list all valid email address. 37 | 5. get string inside a script 38 | 6. get value inside an embedded script. 39 | 7. find username and password field then brute force. -------------------------------------------------------------------------------- /web/requests/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Send a GET request to URL and get the value of specific key on the response JSON. 4 | 5 | Get the value of `token`. 6 | 7 | Note: this is web service API, so you won't see a visual display. 8 | 9 | ## Test 10 | 11 | Access URL 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/generate 15 | ``` -------------------------------------------------------------------------------- /web/requests/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Set custom user agent when sending GET request to URL. 4 | 5 | Use User-Agent `pythonidae`. 6 | 7 | Note: this is web service API, so you won't see a visual display. 8 | 9 | ## Test 10 | 11 | Access the following URL. 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/identity 15 | ``` 16 | 17 | ## Remarks 18 | 19 | User-Agent is a program that is acting on behalf of a user. In our case, a program that retrieves and facilitates end-user interaction with a web content. User agent characterize a class of software, platform, and operating system. In web technology, User-Agent is often used to determine the client and adjust the response accordingly. For example content for mobile user agent is different to desktop one. 20 | 21 | User-Agent can be used to reveal information about the environment of client software. As stated before User-Agent gives information about the software, platform, and operating system. In short: User-Agent is identity. 22 | 23 | Changing User-Agent is desirable for several scenario. One might want to impersonate other system or even avoid detection. 24 | -------------------------------------------------------------------------------- /web/requests/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Send a GET request to URL and get the values of cookies on response. 4 | 5 | Use User-Agent `pythonidae`. 6 | 7 | Get the value of `token`. 8 | 9 | ## Test 10 | 11 | Access the following URL. 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/cookies 15 | ``` 16 | 17 | ## Remarks 18 | 19 | Cookies are messages that pass to web agent when visiting internet sites. Cookies store some informations related to the site, and the content would vary depends on the site. -------------------------------------------------------------------------------- /web/requests/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Send a GET request with a modified cookie to URL. 4 | 5 | Use User-Agent `pythonidae`. 6 | 7 | Modify cookie and set `role` to 0. 8 | 9 | ## Test 10 | 11 | Access the following URL. 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/cookies 15 | ``` 16 | 17 | set `role` to 0, then sent the cookie as GET request to 18 | 19 | ``` 20 | https://pythonidae.herokuapp.com/web-api/modify 21 | ``` 22 | 23 | ## Remarks 24 | 25 | Cookies are still used to passed information on stateless HTTP. Often, cookies store parameter to the system. By modifying it, we might be able to change the behavior of the application. -------------------------------------------------------------------------------- /web/requests/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Send a POST request to URL with username and password. Get the JWT token on response. 4 | 5 | The request body should be in JSON with `user` and `pass` field. 6 | 7 | Get the `jwt_token` from response. 8 | 9 | ## Test 10 | 11 | Access the following URL. 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/login 15 | ``` 16 | 17 | example of valid request body: 18 | 19 | ``` 20 | {'user':'xathrya', 'pass':'Pythonidae'} 21 | ``` 22 | 23 | user and pass can be anything. 24 | 25 | ## Remarks 26 | 27 | Token based authentication is a mechanism where a security token is given for every succesful authentication. The token is a value generated by server, usually has limited time period. 28 | 29 | Each request to privileged area is restricted. Only when a request is accompanied by a signed token, it is able to proceed and allowed to fetch specific resource. 30 | 31 | `JSON Web Token` (JWT) is open standard (RFC-7519) that defines a compact and self-combined method for securely transmitting information between parties encoded as a JSON object. 32 | 33 | On system which use authentication and authorization mechanism, a request should be made to a single endpoint (ex: login) to grant a token. -------------------------------------------------------------------------------- /web/requests/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Send a POST request with an JWT token in body. 4 | 5 | Optionally, try to use random string as `jwt_token`. 6 | 7 | Note: the token is generated from `Challenge 04`. 8 | 9 | ## Test 10 | 11 | Send POST request with `user` and `pass` in JSON format, to this URL. 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/login 15 | ``` 16 | 17 | get `jwt_token`, send a POST request to this URL. 18 | 19 | ``` 20 | https://pythonidae.herokuapp.com/web/jwt_body 21 | ``` 22 | 23 | ## Remarks 24 | 25 | Some web service API need access token embedded in the body. 26 | 27 | JWT is not the only schme used to authenticate. In some machine to machine communication where environment is controlled, a simple API key can be used as token to authenticate. -------------------------------------------------------------------------------- /web/requests/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Send a POST request with an JWT token in headers as `authorization` header. 4 | 5 | Optionally, try to use random string as `Authorization`. 6 | 7 | Note: the token is generated from `Challenge 04`. 8 | 9 | ## Test 10 | 11 | Send POST request with `user` and `pass` in JSON format, to this URL. 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/login 15 | ``` 16 | 17 | get `jwt_token`, send a POST request to this URL. 18 | 19 | ``` 20 | https://pythonidae.herokuapp.com/web/jwt_header 21 | ``` 22 | 23 | ## Remarks 24 | 25 | Some web service API need access token embedded in the headers as `authorization` header. 26 | 27 | JWT is not the only schme used to authenticate. In some machine to machine communication where environment is controlled, a simple API key can be used as token to authenticate. -------------------------------------------------------------------------------- /web/requests/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Given an URL and list of user agent. 4 | 5 | Send GET requests with each user agent. The order of user agent is random. All user-agent should be used. 6 | 7 | ## Remarks 8 | 9 | There is a good list of user agents, thousands of entries, divided into several categories. 10 | 11 | ``` 12 | https://developers.whatismybrowser.com/useragents/explore/ 13 | ``` 14 | 15 | Randomizing user-agent is useful to avoid getting banned when scraping or sending mass requests for probing and exploiting. -------------------------------------------------------------------------------- /web/requests/chall-08.md: -------------------------------------------------------------------------------- 1 | ## Challenge 08 2 | 3 | Send a GET request to a given URL. Get a response which has challenge on it. Solve the challenge and send the answer back. You must answer it in under 5 seconds. 4 | 5 | Use User-Agent `pythonidae`. 6 | 7 | The request body should be in JSON with `user` field. 8 | 9 | ``` 10 | {'user':'any username'} 11 | ``` 12 | 13 | The response body would be in JSON with `token` and `challenge`. 14 | 15 | ``` 16 | { 17 | 'token':'your token', 18 | 'challenge':'100 characters long string' 19 | } 20 | ``` 21 | 22 | To solve the challenge, `reverse` the string. Send a POST request with request body in JSON. 23 | 24 | ``` 25 | { 26 | 'token':'your token', 27 | 'answer':'reverse of challenge' 28 | } 29 | ``` 30 | 31 | ## Test 32 | 33 | Given an URL 34 | 35 | ``` 36 | https://pythonidae.herokuapp.com/web/echo 37 | ``` 38 | 39 | solve the challenge by reverse the string. -------------------------------------------------------------------------------- /web/scraping/chall-00.md: -------------------------------------------------------------------------------- 1 | ## Challenge 00 2 | 3 | Given an URL of a web page. 4 | 5 | List all valid FQDN links. No duplicate entry should be in the list. 6 | 7 | ## Test 8 | 9 | Using this URL 10 | 11 | ``` 12 | https://pythonidae.herokuapp.com/web/scrape 13 | ``` 14 | 15 | ## Remarks 16 | 17 | Scraping is often used for several purposes, such as: 18 | 19 | - mapping the targets by URL 20 | - gather public information (recon phase). 21 | - extract script or media. 22 | - list hidden parameter 23 | 24 | some goal not directly related to cyber security are: 25 | 26 | - get the value or parameter of items (identified by id or classes) 27 | - create a bot that act acording to state visually presented. -------------------------------------------------------------------------------- /web/scraping/chall-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge 01 2 | 3 | Load content of a page and search the flag inside. 4 | 5 | The flag is a hidden field with id `flag`. 6 | 7 | ## Test 8 | 9 | Scrape this URL 10 | 11 | ``` 12 | https://pythonidae.herokuapp.com/web/flag 13 | ``` -------------------------------------------------------------------------------- /web/scraping/chall-02.md: -------------------------------------------------------------------------------- 1 | ## Challenge 02 2 | 3 | Given an URL. 4 | 5 | List all URL to JavaScript file. The JavaScript file can be in the same or different domain (i.e: CDN). 6 | 7 | Optionally, you can also scrape embedded javascript. 8 | 9 | ## Test 10 | 11 | Given an URL 12 | 13 | ``` 14 | https://pythonidae.herokuapp.com/web/js-file 15 | ``` 16 | 17 | This page have several scripts: 18 | 19 | - two (2) external javascript file in same domain. 20 | - one (1) external javascript file on CDN. 21 | - one (1) embedded javascript. -------------------------------------------------------------------------------- /web/scraping/chall-03.md: -------------------------------------------------------------------------------- 1 | ## Challenge 03 2 | 3 | Given an URL. 4 | 5 | Search for external image and load the content of image as binary data. 6 | 7 | ## Test 8 | 9 | Given an URL 10 | 11 | ``` 12 | https://pythonidae.herokuapp.com/web/scrape 13 | ``` 14 | 15 | store the content of image on variable. You can further instantiate it as image. -------------------------------------------------------------------------------- /web/scraping/chall-04.md: -------------------------------------------------------------------------------- 1 | ## Challenge 04 2 | 3 | Load content of a page. Get any valid email address from the page. 4 | 5 | Some email addresses will be written in format which is not easy to be inferred, such as `user [at] domain.com`, `user at domain dot com` etc. 6 | 7 | ## Test 8 | 9 | Given an URL 10 | 11 | ``` 12 | https://pythonidae.herokuapp.com/web/info 13 | ``` 14 | 15 | there exists several email address in different format. 16 | 17 | ## Remarks 18 | 19 | In recon phase, one might want to map all personel in the organization. These information can be used as another vector, such as social engineering. -------------------------------------------------------------------------------- /web/scraping/chall-05.md: -------------------------------------------------------------------------------- 1 | ## Challenge 05 2 | 3 | Load content of a page. Find and read the a JS script referenced by the page. Parse and get the string value. 4 | 5 | A configuration usually written in key-value form, with direct or indirect value assignment. 6 | 7 | Example of direct value assignment: 8 | 9 | - `key = value`, in case of variable assignment. 10 | - `"key":"value"`, in case of inside of structure (JSON). 11 | 12 | Example of indirect value assignment: 13 | 14 | - `temp = value; key=temp` 15 | 16 | ## Test 17 | 18 | Given an URL 19 | 20 | ``` 21 | https://pythonidae.herokuapp.com/web/js-file 22 | ``` 23 | 24 | ## Remarks 25 | 26 | Some sensitive information might be stored inside a JavaScript, such as: base API URL, API endpoint, API key, etc. 27 | 28 | One might also expect some functions which generate a string. However, executing the script is not the purpose of this challenge. -------------------------------------------------------------------------------- /web/scraping/chall-06.md: -------------------------------------------------------------------------------- 1 | ## Challenge 06 2 | 3 | Load content of a page which has embedded javascript code. Parse and get the value of variables declared. 4 | 5 | ## Test 6 | 7 | Given an URL 8 | 9 | ``` 10 | https://pythonidae.herokuapp.com/web/js-file 11 | ``` 12 | 13 | there should be a variable `author` which you should get its value. -------------------------------------------------------------------------------- /web/scraping/chall-07.md: -------------------------------------------------------------------------------- 1 | ## Challenge 07 2 | 3 | Load content of a page of login form. Find the field for `username` and `password` entry. Do a brute force and check if certain combination of username and password is correct. 4 | 5 | ## Test 6 | 7 | Given an URL 8 | 9 | ``` 10 | https://pythonidae.herokuapp.com/web/brute-login 11 | ``` 12 | 13 | The correct `username` is `pythonidae` and `password` is `pythonidae` 14 | 15 | Correct credential will print message `Welcome`, otherwise it will print `Incorrect username/password combination`. --------------------------------------------------------------------------------