Prepare before continuing:
- A machine with a virtual machine (VMware(recommended)/VirtualBox/WSL/Hyper V) or bare metal running Linux distro (
Debian
is recommended) because some tools require a Linux environment to run, find more here - Knowledge of
Programming
,Compiler
, andAssembly language
(alias ASM), details here
Computer unit:
Binary
includes only 0 and 1 (bit), this is machine languageDecimal
from 0 to 9. Basic number in daily lifeHexadecimal
is the same as decimals but include A to F
ASCII
table:
Standing for American Standard Code for Information Interchange
. Below is the ASCII
character table, including descriptions of the first 32 characters. ASCII
was originally designed for use with teletypes, so the descriptions are somewhat obscure, and their use is frequently not as intended, more details at here
Moreover, get started with this playlist or start from this roadmap. Some relative notes I wrote details can be found here
Basic knowledge to start anything in this field, help to solve a lot of challenge or understand how the code work. In this session, there are 2 recommended programming languages: C/C++ and Python
A traditional language is used to make system, kernel, and thread, because of its benefits. Recommend to getting started
A high-level language support multiple useful libraries to help to code easier. Recommend writing tools
Central Processing Unit
(CPU) loads instructions from memory and executes them. Instructions are decided to execute by Instruction pointer
- a register of CPU
, used for storing the next instruction address. 2 noticeable conditions:
- What instructions loaded into memory
- The instruction pointer has value addresses of the above instructions
A fast memory inside the CPU has the same length as the structure CPU (32-bit for Intel 32-bit). Some kinds of register:
General register
used for calculating, variable, parameters (EAX
,EBX
,ECX
, andEDX
)String handling register
string actions including copy string or get string length (EDI
, andESI
)Stack register
manage data stack (EBP
, andESP
)Special register
includesEIP
(Instruction pointer), andEFLAGS
contains1-bit
flag sign flag, carry flag, zero flags, etc.Partition register
manages the size of memory (DS
,ES
, andCS
)
Memory
and Linear address
:
- Using
RAM
to get the address of 2 other registers, so the computer can get more space withswap partition
Data bus
andAddress bus
used for transmitting 32-bit data toCPU
every timeEndianness
is the order or sequence of bytes of a word of digital data in computer memory.Little-endian
is an order in which the "little end" (least significant value in the sequence) is stored first, helping theCPU
know how to get specific bits in 32-bit data
Some definitions:
Instructions
are what the CPU can doMachine code
is code that is ready to be executed by the machine processorOpcode
is code to be executed by an interpreterAssembly language
is often referred to simply as Assembly and commonly abbreviated as ASM or any low-level programming
Some useful tools to get started
Using GDB
with peda to gdb-peda
- useful to debug binary files. Some commands to get started:
checksec
: various security options of binaryCANARY
: protect stack (can overflow if it is disabled)FORTIFY
: the compiler will try to intelligently read the code it is compiling/building if it is enabledNX
: can execute shellcode inside the program if it is disabledPIE
: contain address in binary being not changed if it is disabledRELRO
: Global Offset Table (and Procedure Linkage Table) are marked read-only too in theFull RELRO
pdis
main`view inside the main functionstart
: run header of binary, list some information of registers, code, etc.vmmap
: get virtual mapping address ranges of section(s) in debugged processstack <number>
: get more<number>
stacks to viewx/ <address>
: get value from<address>
x/<number> <address>
: get<number>
value started from<address>
x/<number>i <address>
: get<number>
value started from<address>
and print command in assembly languageb* <address>
: set breakpoint at<address>
, usec
/continue
to continue program til breakpoint after start program, usen
/next
to execute next commandr
/run
: run program from the beginning
Popular tools for Python, get details here. Get started with pip install pwntools
. Some commands to get started
from pwn import *
r = process("./file") # load target file tto run local
gdb.attach
r = remote("123.123.123.123",123) # connect to server with ip and port
payload = "this is payload"
# use to send payload
r.sendline(payload)
r.sendlineafter("abc",payload)
# do until receive needed data
r.recv()
r.recvuntil("abc")
r.interactive() # active shell
Useful tools to disassembler files, find more here
Here are some examples of techniques to exploit binary file
Happen when input is too long for limitation of memory. 3 points to take advantage of buffer overflow:
Key data
should be behind (at the right side)Injected data
can be buffer overflowInjected data
must overflow tokey data
- Modified
Key data
must have meaning to execute the program
Happen by logic in code, for example, get from here and run the binary file with this. In this case, we need to run to win()
function in the code. It has input data from the command scanf("%64s", your_try);
and scanf
is one of the dangerous functions
Run a program with gdb-peda
with the command start
. Using pdis main
to view the main of the program then set a breakpoint at strncmp
to see what happens. Next, type something into the program after using r
to run the program. If the input is below 64 characters:
It seems when input is above 64 characters, it changes the value of flag 0xa796d6d7564
to 0xxa796d6d7500
, simply last 64
becomes 00
or NULL so the value of the variable flag is NULL now. The reason why can be seen from the manual of scanf
with option string:
Matches a sequence of non-white-space characters; the next pointer must be a pointer to the initial element of a character array that is long enough to hold the input sequence and the terminating null byte ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first
Method to exploit including:
- Type an above 64 string to make the variable flag become NULL
- The condition will compare 2 NULL string
Using pwntools
to exploit, then it will active shell (trigger win()
function)
from pwn import *
r = process("./chall")
payload = "\x00"*64 # create 64 byte null string
r.sendline(payload)
r.interactive()