top of page
Want to get notified when I create a new blog post?

Thanks for subscribing!

  • Kyser Clark

100 Days of Code: 51-100



Summary

IT'S DONE!! What a long learning journey that had a lot of ups but also a few downs. The goal was to learn python to be a better hacker and cybersecurity professional. NOT an application developer. And I firmly believe my goal has been accomplished across these 100 days.


The stats:


Lessons learned:

  • I understand how to automate easy but tedious tasks

  • I can solve simple problems in a programmatic way

  • I know how to take existing hacking exploits and modify them to work for me (NOT A SCRIPT KIDDIE ANYMORE!)

  • I understand how to read code, and I can learn how a given program works (for the most part)

  • I can't build a new robust cybersecurity/hacking tool from the ground up

  • I am NOT a full fledge application developer, and I have no desire to become one

  • I must keep coding to make sure I don't get rusty; I plan to do a challenge weekly

  • I want to learn more programming languages, but not sure if I can dedicate the time to them (learning other skills is going to take priority)

You can view my completed projects at: https://github.com/KyserClark/Completed-Projects

You can view each day's log at: https://github.com/KyserClark/100-Days-of-Code

You can view the Days 1-50 post at: https://www.kyserclark.com/post/100-days-of-code-1-50


Click here to jump to Day 51


Day 100

For the last day of this challenge, I decided to complete a challenge on pythonprinciples.com/challenges/. The challenge I completed was the "Capital Indexes" challenge:


Write a function named capital_indexes. The function takes a single parameter, which is a string. Your function should return a list of all the indexes in the string that have capital letters.

For example, calling capital_indexes("HeLlO") should return the list [0, 2, 4].


My code that solved the challenge:

def capital_indexes(word):
    found = []
    last_index = -1
    for character in word:
        if character.isupper() == True:
            try:
                last_index = word.index(character, last_index+1)
            except ValueError:
                break
            else:
                found.append(last_index)
    return found
    
capital_indexes("HeLlO")

The example solutions:

# naive solution
def capital_indexes(s):
    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    result = []
    for i, l in enumerate(s):
        if l in upper:
            result.append(i)
    return result

# shorter version
from string import uppercase
def capital_indexes(s):return [i for i in range(len(s)) if s[i] in uppercase]

# you can also use the .isupper() string method.

I'm glad I was able to solve it without the hints, and I'm glad that my code is very different than the intended solutions. Unfortunately, this took me about an hour to complete, so I'll have to continue to do a challenge at least once a week to keep my skills sharp.


Total Time Dedicated to Python Learning = 240 hours


Day 99

Today in one hour, I consolidated all my individual blog posts about this 100 Days of Code journey into two separate blog posts. Transferring 96 blog posts takes a lot of time, but well worth it. I wanted to make a single post, but my website wouldn't let me post for more than 75 days, so I was forced to split the journey into two posts. It was nice re-reading all my old posts and seeing how I progressed throughout this journey.


Total Time Dedicated to Python Learning = 239 hours


Day 98

Today in one hour, I transferred all my python code saved on my computer to my GitHub page. https://github.com/KyserClark/Completed-Projects


Total Time Dedicated to Python Learning = 238 hours


Day 97

Today in one hour, I started and finished the Python for Pentesters room on TryHackMe. Tomorrow I plan on taking all the code I've written across the 100 days and putting it on my GitHub page. After that is complete, I plan on finding daily python practice challenges on the internet to keep my skills sharp.


Total Time Dedicated to Python Learning = 237 hours


Day 96

Today in one hour, I started and finished the Python Basics room on TryHackMe. Tomorrow I will start Python for Pentesters room on TryHackMe.


Total Time Dedicated to Python Learning = 236 hours


Day 95

Today, in one hour, I finished Python 201 for Hackers; I went over Project #5 - Encrypted Bind Shell, Extending Burp, and Debugging. Tomorrow I will start the Python Basics room on TryHackMe.


Total Time Dedicated to Python Learning = 235 hours


Day 94

Today, in one hour, continuing with Python 201 for Hackers, I went over Project #2 - Process Creation and Shellcode Execution (pt1&2), Project #3- Keylogging a System, and Project #4 - Buffer Overflow. Tomorrow I will continue Python 201 for hackers.


Total Time Dedicated to Python Learning = 234 hours


Day 93

Today, in one hour, continuing with Python 201 for Hackers, I went over Pycryptodome, Argparse, and Project #1 - Remote DLL Injection. Tomorrow I will continue Python 201 for hackers.


Total Time Dedicated to Python Learning = 233 hours


Day 92

Today, in one hour, continuing with Python 201 for Hackers I went over Direct Syscalls, Execution From a DLL, BeautifulSoup, Py2exe, Sockets, Scapy, Subprocess, and Threading. Tomorrow I will continue Python 201 for hackers.


Total Time Dedicated to Python Learning = 232 hours


Day 91

Today, in one hour, continuing with Python 201 for Hackers I went over operator overloading, class decorators, introduction to the Windows API, C Data Types and Structures, Interfacing with the Windows API, and Undocumented API Calls. Tomorrow I will continue Python 201 for hackers.


Total Time Dedicated to Python Learning = 231 hours


Day 90

Today, in one hour, I finished Python 101 for Hackers and graduated to Python 201 for Hackers. Today I went over Project #4 - Exploiting a SQL injection, Project #5 - Exploiting a restricted SQL Injection, Decorators, Generators, Serialization, Closures, Inheritance Encapsulation, and Polymorphism. Tomorrow I will continue Python 201 for hackers.


Total Time Dedicated to Python Learning = 230 hours


Day 89

Today is actually a combination of two days. However, I didn't count yesterday because I only put in 30 hours of coding. The 100 Days of Code must be for at least an hour a day. Plus, I counted a 30-minute day earlier in my 100 days of code journey, so it's fair to count both of those half-hour days as one full day.


With that being said, yesterday, I started Python 101 for Hackers. I watched Comprehensions, Lambdas, and Introduction to sys.


Today within an hour, I watched the introduction to requests, introduction to pwntools, Project #1 - SSH login brute forcing, Project #2 - SHA256 password cracking, and Project #3 - Web login form brute forcing. Tomorrow I will Continue with Projects 4 & 5 to close the course.


It's worth noting that I skipped all the basic introductory stuff of the course because I already know the basics of Python and how it works. I wanted to really focus on the content specifically made for hackers.


Total Time Dedicated to Python Learning = 229 hours


Day 88

With 1 hour dedicated to Python coding today, I got through the 3rd section of Chapter 2 in Black Hat Python by Justin Seitz and Tim Arnold. Today was all about building an SSH Server. Once again, unfortunately, the tool did not work as advertised. I carefully read the book, installing every package that it tells me to in the order it tells me to. I coded along and tried my best to understand the code. I even copied and pasted the code from the author's source code library into my machine. Ensuring I change the IP address to my machine's IP address. But no matter what I do, I can't get this SSH server to run. This is the 2nd application in the book that has failed to work. Furthermore, the source code for the book on the NoStarchPress website is a little different than the code in the book. Neither works. It's just frustrating to see this from such a highly-rated book. It's not like I don't know what I'm doing. I know my way around a Linux machine, Python, as well as Hacking concepts VERY well. I honestly think the book is just flawed. Because of this, I am forced to stop reading the book and finish out my last 12 days of Python code using a different learning source.


I will switch to Python 101 for Hackers on the TCM Security Academy website. Once I finish Python 101 for hackers, I will level up to Python 201 for Hackers to close out my 100 days of code.


Total Time Dedicated to Python Learning = 227.5 hours


Day 87

With 1.5 hours dedicated to Python coding today, I got through the 2nd section of Chapter 2 in Black Hat Python by Justin Seitz and Tim Arnold. Today was all about building a TCP Proxy. Unfortunately, the program doesn't work as expected. I double-checked the code and even tested the author's source code, but it does not keep the connection between the local and remote hosts very long. Regardless, it's nice to understand some of the logic that goes into these types of tools.


Total Time Dedicated to Python Learning = 226.5 hours


# I do not take credit for this code. This comes from the book "Black Hat Python 2nd Edition" by Justin Seitz and Tim Arnold

import sys
import socket
import threading

HEX_FILTER = ''.join([(len(repr(chr(i))) == 3) and chr(i) or '.' for i in range(256)])


def hexdump(src, length=16, show=True):if isinstance(src, bytes):
        src = src.decode()
    results = list()for i in range(0, len(src), length):
        word = str(src[i:i+length])
        printable = word.translate(HEX_FILTER)
        hexa = ' '.join([f'{ord(c):02X}' for c in word])
        hexwidth = length*3
        results.append(f'{i:04x}  {hexa:<{hexwidth}}  {printable}')if show:for line in results:print(line)else:return results


def receive_from(connection):
    buffer = b""
    connection.settimeout(10)try:while True:
            data = connection.recv(4096)if not data:break

            buffer += data
    except Exception as e:print('error ', e)
        pass

    return buffer


def request_handler(buffer):
    # perform packet modifications
    return buffer


def response_handler(buffer):
    # perform packet modifications
    return buffer


def proxy_handler(client_socket, remote_host, remote_port, receive_first):
    remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    remote_socket.connect((remote_host, remote_port))if receive_first:
        remote_buffer = receive_from(remote_socket)if len(remote_buffer):print("[<==] Received %d bytes from remote." % len(remote_buffer))hexdump(remote_buffer)

            # remote_buffer = response_handler(remote_buffer)
            # client_socket.send(remote_buffer)
            # print("[==>] Sent to local.")while True:
        local_buffer = receive_from(client_socket)if len(local_buffer):print("[<==] Received %d bytes from local." % len(local_buffer))hexdump(local_buffer)

            local_buffer = request_handler(local_buffer)
            remote_socket.send(local_buffer)print("[==>] Sent to remote.")

        remote_buffer = receive_from(remote_socket)if len(remote_buffer):print("[<==] Received %d bytes from remote." % len(remote_buffer))hexdump(remote_buffer)

            remote_buffer = response_handler(remote_buffer)
            client_socket.send(remote_buffer)print("[==>] Sent to local.")if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()print("[*] No more data. Closing connections.")break


def server_loop(local_host, local_port, remote_host, remote_port, receive_first):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:server.bind((local_host, local_port))
    except Exception as e:print("[!!] Failed to listen on %s:%d" % (local_host, local_port))print("[!!] Check for other listening sockets or correct permissions.")print(e)
        sys.exit(0)print("[*] Listening on %s:%d" % (local_host, local_port))
    server.listen(5)while True:
        client_socket, addr = server.accept()print("> Received incoming connection from %s:%d" % (addr[0], addr[1]))
        
        proxy_thread = threading.Thread(
            target=proxy_handler,
            args=(client_socket, remote_host,
                  remote_port, receive_first))
        proxy_thread.start()


def main():if len(sys.argv[1:]) != 5:print("Usage: ./proxy.py [localhost] [localport]", end='')print("[remotehost] [remoteport] [receive_first]")print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
        sys.exit(0)
    
    local_host = sys.argv[1]
    local_port = int(sys.argv[2])

    remote_host = sys.argv[3]
    remote_port = int(sys.argv[4])

    receive_first = sys.argv[5]if "True" in receive_first:
        receive_first = True
    else:
        receive_first = False

    server_loop(local_host, local_port,
                remote_host, remote_port, receive_first)if __name__ == '__main__':main()

Day 86

With two hours dedicated to Python coding today, I got through the first section of chapter 2 in Black Hat Python by Justin Seitz and Tim Arnold. I learned how to create a NetCat-style tool in Python. It works VERY well, and I will undoubtedly use this code when I can't use/install NetCat during a Penetration Test/Red Team engagement but have access to python. I take no credit for this code. Perhaps I can find a way to improve it and make it my own in the future.


Total Time Dedicated to Python Learning = 225 hours

# I do not take credit for this code. This comes from the book "Black Hat Python 2nd Edition" by Justin Seitz and Tim Arnold

import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading


def execute(cmd):
    cmd = cmd.strip()if not cmd:return
    output = subprocess.check_output(shlex.split(cmd),
                                     stderr=subprocess.STDOUT)return output.decode()class NetCat:
    def __init__(self, args, buffer=None):
        self.args = args
        self.buffer = buffer
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def run(self):if self.args.listen:
            self.listen()else:
            self.send()

    def send(self):
        self.socket.connect((self.args.target, self.args.port))if self.buffer:
            self.socket.send(self.buffer)try:while True:
                recv_len = 1
                response = ''while recv_len:
                    data = self.socket.recv(4096)
                    recv_len = len(data)
                    response += data.decode()if recv_len < 4096:breakif response:print(response)
                    buffer = input('> ')
                    buffer += '\n'
                    self.socket.send(buffer.encode())
        except KeyboardInterrupt:print('User terminated.')
            self.socket.close()
            sys.exit()

    def listen(self):print('listening')
        self.socket.bind((self.args.target, self.args.port))
        self.socket.listen(5)while True:
            client_socket, _ = self.socket.accept()
            client_thread = threading.Thread(target=self.handle, args=(client_socket,))
            client_thread.start()

    def handle(self, client_socket):if self.args.execute:
            output = execute(self.args.execute)
            client_socket.send(output.encode())

        elif self.args.upload:
            file_buffer = b''while True:
                data = client_socket.recv(4096)if data:
                    file_buffer += data
                    print(len(file_buffer))else:breakwith open(self.args.upload, 'wb') as f:
                f.write(file_buffer)
            message = f'Saved file {self.args.upload}'
            client_socket.send(message.encode())

        elif self.args.command:
            cmd_buffer = b''while True:try:
                    client_socket.send(b' #> ')while '\n' not in cmd_buffer.decode():
                        cmd_buffer += client_socket.recv(64)
                    response = execute(cmd_buffer.decode())if response:
                        client_socket.send(response.encode())
                    cmd_buffer = b''
                except Exception as e:print(f'server killed {e}')
                    self.socket.close()
                    sys.exit()if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='BHP Net Tool',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=textwrap.dedent('''Example:
          netcat.py -t 192.168.1.108 -p 5555 -l -c # command shell
          netcat.py -t 192.168.1.108 -p 5555 -l -u=mytest.whatisup # upload to file
          netcat.py -t 192.168.1.108 -p 5555 -l -e=\"cat /etc/passwd\" # execute command
          echo 'ABCDEFGHI' | ./netcat.py -t 192.168.1.108 -p 135 # echo local text to server port 135
          netcat.py -t 192.168.1.108 -p 5555 # connect to server
          '''))
    parser.add_argument('-c', '--command', action='store_true', help='initialize command shell')
    parser.add_argument('-e', '--execute', help='execute specified command')
    parser.add_argument('-l', '--listen', action='store_true', help='listen')
    parser.add_argument('-p', '--port', type=int, default=5555, help='specified port')
    parser.add_argument('-t', '--target', default='192.168.1.203', help='specified IP')
    parser.add_argument('-u', '--upload', help='upload file')
    args = parser.parse_args()if args.listen:
        buffer = ''else:
        buffer = sys.stdin.read()

    nc = NetCat(args, buffer.encode('utf-8'))
    nc.run()

Day 85

I finally finished Automate the Boring Stuff with Python by Al Sweigart! I read the rest of chapter 20 and am VERY excited to be done with it. I have officially started the book Black Hat Python by Justin Seitz and Tim Arnold. I completed the introduction sections and chapter 1 which covers virtual machine (VM), Python3, and integrated development environment (IDE) installation. All stuff I'm very familiar with. Chapter 2, Basic Networking Tools, starts getting into the fun stuff. After doing courses and reading books about general python coding (for developers, not hackers), it's nice to finally code stuff specifically for hacking. The real reason why I wanted to begin learning python to begin with. I'm finally excited about the 100 Days of Code journey once again. Automate the Boring Stuff isn't a bad book, but for an aspiring hacker, It was boring. Most of the information didn't apply to the tools I want to write. This is why it took me so long to complete the book, and I stopped coding at the halfway point of the book (and strictly read the book rather than complete the exercises. I'm glad to get excited about my coding journey again and finish my last 15 days strong with a great book specifically tailored for hackers like myself.


Total Time Dedicated to Python Learning = 223 hours


Day 84

Today I read Automate the Boring Stuff with Python by Al Sweigart for an hour. I read the rest of chapter 19 and about half of chapter 20. Chapter 20 is particularly interesting because the book introduced the reader to mouse and keyboard automation. Good for graphical user interfaces (GUIs).


Total Time Dedicated to Python Learning = 222 hours


Day 83

Today I read Automate the Boring Stuff with Python by Al Sweigart for an hour. I read the rest of chapter 18 and about half of chapter 19.


Total Time Dedicated to Python Learning = 221 hours


Day 82

Today I read Automate the Boring Stuff with Python by Al Sweigart for an hour. I read the rest of chapter 17 and about a quarter of chapter 18.


Total Time Dedicated to Python Learning = 220 hours


Day 81

Put in another hour of reading Automate the Boring Stuff with Python by Al Sweigart. I read all of chapters 16 and half of 17.


Total Time Dedicated to Python Learning = 219 hours


Day 80

Put in another hour of reading Automate the Boring Stuff with Python by Al Sweigart. I read all of chapters 14 and 15.


Total Time Dedicated to Python Learning = 218 hours


Day 79

Put in another hour of reading Automate the Boring Stuff with Python by Al Sweigart. Nothing new and exciting here, just another day closer to closing out my goal of 100 days of python.


Total Time Dedicated to Python Learning = 217 hours


Day 78

I took a bit of a break from coding. I'm now back in it and after 1 hour of reading Automate the Boring Stuff with Python by Al Sweigart. I can confidently say that I don't regret the long break, and I still don't really like coding. Development just isn't for me. I have come to the conclusion that I will only code stuff when I find myself repeating long tedious tasks for days on end. Other than that I don't think I will ever develop an entire useful application. I don't have the imagination, desire, or motivation for it. And that is ok because I want to be a hacker, not a developer. I only need to know basic python for my chosen career and I think I'm already past the point I need to know to have a successful ethical hacking career. Maybe things will change when I start to read python books specifically tailored to hacking. Time will tell. I will complete my 100 days of code, and I will finish this book. No matter how much I may not seem to enjoy it.


Total Time Dedicated to Python Learning = 216 hours


Day 77

After over two weeks of not coding, I got back into it. The two-week hiatus was due to a lack of interest in coding, TryHackMe focus shift, contracting covid and being sick, starting a new college course, and a few personal reasons I won't talk about. I'm glad to get back into the saddle.


Today I read all of Chapter 10: Organizing Files in Automate the Boring Stuff with Python by Al Sweigart. I also read about 3/4 of Chapter 11: Debugging. I read all of this in 1 hour's time. For the next day, I will finish Chapter 11, and read Chapter 12: Web Scraping.


Total Time Dedicated to Python Learning = 215 hours


Day 76

In two hours, I read Chapter 8: Input Validation and Chapter 9: Reading and Writing to files in Automate the Boring Stuff with Python by Al Sweigart. Everything in these chapters is something I already knew and already coded out in previous days. Because of that, I chose not to do the practice projects for these chapters. Tomorrow I will start with Chapter 10: Organizing Files.


Total Time Dedicated to Python Learning = 214 hours


Day 75

I took another day off from coding yesterday. This is because I had some personal things to handle. However, it wasn't an entire day off because I still did my daily TryHackMe goal. However, today I managed to squeeze in 2 hours of reading Automate the Boring Stuff with Python by Al Sweigart. I read all of Chapter 7: Pattern Matching with Regular Expressions.


I'll be honest, coding with Python has lost its charm. All the examples in the book and practice projects are programs that don't seem very useful to me. I have no idea how to create a useful program that fixes a problem. I don't want to waste my time coding something no one will use or something that already exists. I understand that it is good practice, but what am I practicing for? Reinventing the wheel? Nonsense. One day I will find a problem that I can solve with code, but I can't think of anything practical that hasn't already been made. So why should I reinvent the wheel with all these practice projects? How does one come up with a good program/application? Something to think about.


Total Time Dedicated to Python Learning = 212 hours


Day 74

Unfortunately, I had to take two days off from 100 Days of Code. I made it 73 days in a row, which I am VERY proud of. I was unable to put time into python the last two days due to a YouTube video that took me about 24 hours to produce and TryHackMe as well as setting my 2022 Goals. I definitely need to streamline my YouTube video creation process. I'm still fairly new to it so I will get better with time. The video looks great by the way. It turned out better than I could imagine. My editing skills are top tier if I say so myself. It can be seen here https://youtu.be/UFBT2Nq4BvI, and it was totally worth taking two days off of 100 Days of Code to make it.