commit c2b19dd5c3f0a781b4acdfef8726d96f5593a657
parent 37a7e3e567d4984a372e5a3135e28640e1000b51
Author: therealFIGBERT <figbertwelner@gmail.com>
Date: Sun, 5 Jan 2020 12:50:01 -0800
Add a walkthrough for the addition challenge
Diffstat:
1 file changed, 72 insertions(+), 0 deletions(-)
diff --git a/linux_and_misc/walkthroughs/addition.md b/linux_and_misc/walkthroughs/addition.md
@@ -0,0 +1,72 @@
+# addition Walkthrough
+
+[addition](https://twinpeaks.cs.ucdavis.edu/challenge?id=9) is the first challenge where we interact with a server from our own machine with code. For this challenge I used the [pwntools library](https://github.com/Gallopsled/pwntools) for Python 3.
+
+Connecting to the server with `nc` spits out this response:
+```
+John just noticed his homework is due in 10 seconds!
+Help him finish his homework, which contains 50 additions.
+Question 0 : 114314390 + 798790408
+Your answer:
+```
+The pwntools' library `remote` object gives us several options for filtering out the input we receive, including the `recvline_contains` function. The `recvline_contains` function ["[receives] lines until one line is found which contains at least one of items"](https://docs.pwntools.com/en/stable/tubes.html?highlight=recvline_contains#pwnlib.tubes.tube.tube.recvline_contains). Combined with the `recv` function, we can filter out all of the unnecessary text from the server output with some pretty simple code:
+```python
+from pwn import *
+
+# Connecting to the server
+connection = remote("twinpeaks.cs.ucdavis.edu", 30001)
+# Receive the line with the equation
+equation_line = connection.recvline_contains("Question")
+```
+At this stage, we have a program that capture the question and then terminates. We now need to filter the variable. Based on the output from the `nc` connection, we can see that each question is formatted like this: `[QUESTION NUMBER] : [NUMBER ONE] + [NUMBER TWO]`. Now knowing the formatting, we can isolate the numbers and add them:
+```python
+# Split the equation into a list of question parts
+# Value: ["QUESTION NUMBER", "NUMBER ONE + NUMBER TWO"]
+equation_line_list = equation_line.split(b":")
+# Select only the equation from the list, and eliminate whitespace
+# Value: "NUMBER ONE + NUMBER TWO"
+equation = equation_line_list[1].strip()
+# Split equation bytestring into list of bytestring numbers
+# Value: ["NUMBER ONE", "NUMBER TWO"]
+numbers_bytestring_list = equation.split(b"+")
+# Convert list of bytestring numbers to list of ints
+# Value: [NUMBER_ONE, NUMBER_TWO]
+numbers_list = [int(item.strip()) for item in numbers_bytestring_list]
+# Find the sum of the numbers
+number_sum = sum(numbers_list)
+```
+We could now attempt to send the line, but if we look at the formatting we can see that one thing is missing - the server prompts us for our answer before it accepts input! Thus, we have to receive output before sending it back:
+```python
+# Receive the input prompt
+connection.recv()
+# Send the sum back as a bytestring
+connection.sendline(bytes("%d"%num_sum, "utf-8")
+```
+Now, we just have to stick all that in a loop that runs 50 times (and simplify it, if you'd like). The finalized code looks like this:
+```python
+# A CTF exploit by FIGBERT
+# for UC Davis class ECS189M
+# twinpeaks.cs.ucdavis.net:30001
+# Category: Linux and miscellaneous
+# Challenge: addition
+# 04/01/2020
+from pwn import *
+
+#Connecting to the server
+connection = remote("twinpeaks.cs.ucdavis.edu", 30001)
+for i in range(0,50):
+ #Recieving the equation
+ equation = connection.recvline_contains("Question")
+ #Splitting the equation into the two numbers to add
+ numbers = [int(item.strip()) for item in ((equation.split(b":")[1]).strip()).split(b"+")]
+ num_one = numbers[0]
+ num_two = numbers[1]
+ #Adding the two numbers
+ num_sum = sum(numbers)
+ print("Equation %d: %d + %d = %d"%(i+1, num_one, num_two, num_sum))
+ connection.recv()
+ #Sending the password
+ connection.sendline(bytes("%d"%num_sum, "utf-8"))
+connection.recv()
+connection.interactive()
+```