SlideShare a Scribd company logo
DharmalingamGanesan
(dganesan@fc-md.umd.edu)
Itzik Kotler
(xorninja@gmail.com)
1
int main(int argc, char **argv) {
char passwd[] = "foobar";
if (argc < 2) {
printf("usage: %s <given-password>n", argv[0]);
return 0;
}
if (!strcmp(passwd, argv[1])) {
printf("Green light!n");
return 1;
}
printf("Red light!n");
return 0;
}
2
 What if you do not know the passwd?
Reference: Reverse Engineering with LD_PRELOAD by Itzik Kotler
/*
* strcmp, Fixed strcmp function -- Always equal!
*/
int strcmp(const char *s1, const char *s2) {
printf("S1 eq %sn", s1);
printf("S2 eq %sn", s2);
// ALWAYS RETURN EQUAL STRINGS!
return 0;
}
3
 gcc -fPIC -c strcmp-hijack.c -o strcmp-hijack.o
 gcc -shared -o strcmp-hijack.so strcmp-hijack.o
 ./strcmp-target redbull
 Output: “Red light!”
 Attack using LD_PRELOAD
 LD_PRELOAD="./strcmp-hijack.so" ./strcmp-target redbull
 Output: “Green light!”
4
/*
* cerberus.c, Impossible statement
*/
#include <stdio.h>
int main(int argc, char **argv) {
int a = 13, b = 17;
if (a != b) {
printf("Sorry!n");
return 0;
}
printf("On a long enough timeline,"
" the survival rate for everyone drops to zeron");
exit(1);
}
5
Can we avoid “Sorry” and print the “On a long…”?
[~]$ ./cerberus
On a long enough timeline, the survival rate
for everyone drops to zero
080483d4 <main>:
80483d4: 55 push %ebp
80483d5: 89 e5 mov %esp,%ebp
80483d7: 83 e4 f0 and $0xfffffff0,%esp
80483da: 83 ec 20 sub $0x20,%esp
80483dd: c7 44 24 18 0d 00 00 movl $0xd,0x18(%esp)
80483e4: 00
80483e5: c7 44 24 1c 11 00 00 movl $0x11,0x1c(%esp)
80483ec: 00
80483ed: 8b 44 24 18 mov 0x18(%esp),%eax
80483f1: 3b 44 24 1c cmp 0x1c(%esp),%eax
80483f5: 74 13 je 804840a <main+0x36>
80483f7: c7 04 24 f0 84 04 08 movl $0x80484f0,(%esp)
80483fe: e8 ed fe ff ff call 80482f0 <puts@plt>
8048403: b8 00 00 00 00 mov $0x0,%eax
8048408: eb 11 jmp 804841b <main+0x47>
804840a: c7 04 24 f8 84 04 08 movl $0x80484f8,(%esp)
8048411: e8 da fe ff ff call 80482f0 <puts@plt>
8048416: b8 01 00 00 00 mov $0x1,%eax
804841b: c9 leave
804841c: c3 ret
6
Note: puts is used for printf
 Create our own “puts” wrapper
 Update the return address after the first puts
 Transfer control to the second puts
 Embed assembly code and adjust the ESP!
7
/* Pointer to the original puts call */
static int (*_puts)(const char *str) = NULL;
int puts(const char *str)
{
if (_puts == NULL) {
_puts = (int (*)(const char *str)) dlsym(RTLD_NEXT, "puts");
// Hijack the RET address and modify it to <main+xx>
__asm__ __volatile__ (
"movl 0x4(%ebp), %eax n"
"addl $7, %eax n"
"movl %eax, 0x4(%ebp)"
);
return 1;
}
__asm__ __volatile__ (
"addl $28, %%esp n“
“ jmp *%0 n"
:
: "g" (_puts)
: "%esp"
);
return -1;
}
8
• Why add 7 to eax?
• 0x804840a – 0x8048403
• Why add 28 to esp?
• Answered in next slides
00000000 <printf>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
6: a1 00 00 00 00 mov 0x0,%eax
b: 85 c0 test %eax,%eax
d: 75 2a jne 39 <printf+0x39>
f: b8 00 00 00 00 mov $0x0,%eax
14: 89 44 24 04 mov %eax,0x4(%esp)
18: c7 04 24 ff ff ff ff movl $0xffffffff,(%esp)
1f: e8 fc ff ff ff call 20 <printf+0x20>
24: a3 00 00 00 00 mov %eax,0x0
29: 8b 45 04 mov 0x4(%ebp),%eax
2c: 83 c0 0f add $0xf,%eax
2f: 89 45 04 mov %eax,0x4(%ebp)
32: b8 01 00 00 00 mov $0x1,%eax
37: eb 00 jmp 39 <printf+0x39>
39: c9 leave
3a: c3 ret
9
Esp got adjusted:
4 bytes (push %ebp)
0x18 bytes (sub $0x18, %esp)
Total: 0x18 + 4 = 24 + 4 = 28
 Create a shared lib of the wrapper:
 gcc -c -m32 megatron.c -o megatron.o –ldl
 gcc -shared -o megatron.so megatron.o -m32 –ldl
 export LD_PRELOAD=./megatron.so
[~]$ ./cerberus
On a long enough timeline, the survival rate for
everyone drops to zero
10
 The main function uses exit(1)
 If we replace it by return(1) and run:
[~]$ gcc -o cerberus cerberus.c -m32
[~]$
[~]$ export LD_PRELOAD=./megatron.so
[~]$
[~]$ ./cerberus
On a long enough timeline, the survival rate for everyone drops to zero
^C
[~]$
11
Why the program is not terminating?
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP
ESP
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP
ESP
EBP (main)96
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP
ESP
EBP (main)96
(a). Just before the 2nd printf.
(b). In the wrapper puts. (c). After pointers rewinding.
12
100
96
92
88
84
80
76
52
80
76
100
96
92
88
84
80
100
96
92
88
84
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of puts
(wrapper) 76
ESP
EBP
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of puts
(wrapper) 76
ESP
EBP
EIP
(d). Inside the real puts. (e). After returning from real puts.
13
76 76
100
96
92
88
84
80
100
96
92
88
84
*80
 Control comes back to main and will try to
run return 1:
 mov %ebp, %esp
 pop %ebp
 Pop %eip (or ret)
14
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of puts
(wrapper) 76
ESP
EBP
15
76
100
96
92
88
76
80
mov %ebp, %esp
84
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of puts
(wrapper) 76EBP
ESP
16
76
100
96
92
88
80
pop %ebp
84
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of puts
(wrapper) 76EBP
EIP
17
76
100
96
92
88
84
ret: pop %eip
ESP
• Now EIP points to leave-ret sequence!
• Never ending because EBP of mains is lost
*80
 We lost main’s EBP along the way
 There is an infinite loop when the control
comes to main
 mov %ebp, %esp
 pop %ebp
 Ret (or pop %eip)
 Program is not able to return to libc
 Fix:Why not restore the EBP!
18
OLD
__asm__ __volatile__ (
"addl $28, %%esp n“
"jmp *%0 n"
:
: "g" (_puts)
: "%esp"
);
NEW
__asm__ __volatile__ (
"addl $24, %%esp n"
"popl %%ebp n"
"jmp *%0 n"
:
: "g" (_puts)
: "%esp"
);
19
[~]$ export LD_PRELOAD=./megatron.so
[~]$
[~]$ ./cerberus
On a long enough timeline, the survival rate for
everyone drops to zero
[~]$
[~]$ echo $?
1
20
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP
ESP
EBP (main)
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP, ESP EBP (main)
(a). In the wrapper puts. (b). After ESP rewinding.
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printfESP
EBP (main)
(c). After pop EBP.
EBP
21
76
100
96
92
88
84
80
52
76
100
96
92
88
84
80
52
76
100
96
92
88
84
80
52
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of main
(96)
ESP
EBP
Ret2libc
EBP (libc)
17
13
Ptr to printf
input str
ret address
after printf
EBP of main
ESP
EBP
EIP
(d). Inside the real puts. (e). After returning from real puts.
22
76
100
96
92
88
84
80
52
76
76
100
96
92
88
84
*80
52
 LD_PRELOAD is a powerful way to hack
 Key idea:Wrapper to library functions
 Collect data such as input arguments!
 Modify control flow dynamically
 ESP and EBP rewinding is the core concept
 Try it out yourself
 Things to keep in mind:
 Number of byte adjustments in your wrapper
23
 Itzik Kotler
 Reverse Engineering with LD_PRELOAD
 http://securityvulns.com/articles/reveng/
 Dharma Ganesan and Itzik Kotler
 Reverse Engineering with LD_PRELOAD (Part 11)
 Article to be published
24

More Related Content

PDF
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
PDF
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
PDF
Bytes in the Machine: Inside the CPython interpreter
PDF
Python opcodes
PDF
GeoGebra JavaScript CheatSheet
PPTX
TCO in Python via bytecode manipulation.
PDF
함수형사고 4장 열심히보다는현명하게
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
Bytes in the Machine: Inside the CPython interpreter
Python opcodes
GeoGebra JavaScript CheatSheet
TCO in Python via bytecode manipulation.
함수형사고 4장 열심히보다는현명하게

What's hot (20)

PDF
Are we ready to Go?
PDF
A CTF Hackers Toolbox
PDF
Hello Swift 3/5 - Function
PDF
Protocol handler in Gecko
DOCX
Wap to implement bitwise operators
PDF
Go Concurrency
PPTX
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
PDF
PDF
Apache PIG - User Defined Functions
ZIP
Intro to Pig UDF
PDF
Something about Golang
KEY
Agile Iphone Development
PDF
Introduction to Swift programming language.
PDF
Python meetup: coroutines, event loops, and non-blocking I/O
KEY
XpUg Coding Dojo: KataYahtzee in Ocp way
PDF
ESCMAScript 6: Get Ready For The Future. Now
PDF
EcmaScript 6 - The future is here
KEY
Gevent what's the point
PDF
Implementing Software Machines in C and Go
Are we ready to Go?
A CTF Hackers Toolbox
Hello Swift 3/5 - Function
Protocol handler in Gecko
Wap to implement bitwise operators
Go Concurrency
Numba-compiled Python UDFs for Impala (Impala Meetup 5/20/14)
Apache PIG - User Defined Functions
Intro to Pig UDF
Something about Golang
Agile Iphone Development
Introduction to Swift programming language.
Python meetup: coroutines, event loops, and non-blocking I/O
XpUg Coding Dojo: KataYahtzee in Ocp way
ESCMAScript 6: Get Ready For The Future. Now
EcmaScript 6 - The future is here
Gevent what's the point
Implementing Software Machines in C and Go

Viewers also liked (20)

PDF
Exploiting Cryptographic Misuse - An Example
PPTX
Model-based Testing of a Software Bus - Applied on Core Flight Executive
PDF
Model-based Testing using Microsoft’s Spec Explorer Tool: A Case Study
PPTX
Linux binary analysis and exploitation
PPTX
Explaining my Phd Thesis to layman
PDF
Interface-Implementation Contract Checking
PDF
Testing of C software components using Models
PPTX
Verifying Architectural Design Rules of a Flight Software Product Line
PDF
Reverse Engineering of Software Architecture
PDF
Automated Test Case Generation and Execution from Models
PPTX
Threat Modeling: Applied on a Publish-Subscribe Architectural Style
PDF
Ivv workshop model-based-testing-of-nasa-systems
PPTX
Reverse Architecting of a Medical Device Software
PPTX
Assessing Model-Based Testing: An Empirical Study Conducted in Industry
PPTX
Secure application programming in the presence of side channel attacks
PPTX
Architecture Analysis of Systems based on Publish-Subscribe Systems
PPTX
Automated testing of NASA Software - part 2
PPTX
Automated Testing of NASA Software
PDF
Carbon Finance
PDF
How to Release Rock-solid RESTful APIs and Ice the Testing BackBlob
Exploiting Cryptographic Misuse - An Example
Model-based Testing of a Software Bus - Applied on Core Flight Executive
Model-based Testing using Microsoft’s Spec Explorer Tool: A Case Study
Linux binary analysis and exploitation
Explaining my Phd Thesis to layman
Interface-Implementation Contract Checking
Testing of C software components using Models
Verifying Architectural Design Rules of a Flight Software Product Line
Reverse Engineering of Software Architecture
Automated Test Case Generation and Execution from Models
Threat Modeling: Applied on a Publish-Subscribe Architectural Style
Ivv workshop model-based-testing-of-nasa-systems
Reverse Architecting of a Medical Device Software
Assessing Model-Based Testing: An Empirical Study Conducted in Industry
Secure application programming in the presence of side channel attacks
Architecture Analysis of Systems based on Publish-Subscribe Systems
Automated testing of NASA Software - part 2
Automated Testing of NASA Software
Carbon Finance
How to Release Rock-solid RESTful APIs and Ice the Testing BackBlob

Similar to Load-time Hacking using LD_PRELOAD (20)

PPTX
Software to the slaughter
PDF
Hacking parse.y (RubyKansai38)
PDF
Hacking Parse.y with ujihisa
PPTX
Как работает LLVM бэкенд в C#. Егор Богатов ➠ CoreHard Autumn 2019
PDF
Call Return Exploration
PDF
Go Go Gadget! - An Intro to Return Oriented Programming (ROP)
PDF
Rust LDN 24 7 19 Oxidising the Command Line
PDF
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
ODP
CompilersAndLibraries
PPT
Unit 4
PDF
please help me with this and explain in details also in the first qu.pdf
PPTX
MuVM: Higher Order Mutation Analysis Virtual Machine for C
PDF
Stop Monkeys Fall
PDF
Reverse Engineering Dojo: Enhancing Assembly Reading Skills
PDF
プログラム実行の話と
OSとメモリの挙動の話
TXT
Mona cheatsheet
ODP
Exploiting Memory Overflows
PDF
Compiled Python UDFs for Impala
PDF
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
Software to the slaughter
Hacking parse.y (RubyKansai38)
Hacking Parse.y with ujihisa
Как работает LLVM бэкенд в C#. Егор Богатов ➠ CoreHard Autumn 2019
Call Return Exploration
Go Go Gadget! - An Intro to Return Oriented Programming (ROP)
Rust LDN 24 7 19 Oxidising the Command Line
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
CompilersAndLibraries
Unit 4
please help me with this and explain in details also in the first qu.pdf
MuVM: Higher Order Mutation Analysis Virtual Machine for C
Stop Monkeys Fall
Reverse Engineering Dojo: Enhancing Assembly Reading Skills
プログラム実行の話と
OSとメモリの挙動の話
Mona cheatsheet
Exploiting Memory Overflows
Compiled Python UDFs for Impala
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321

More from Dharmalingam Ganesan (20)

PDF
.NET Deserialization Attacks
PDF
Reverse Architecting using Relation Algebra.pdf
PDF
How to exploit rand()?
PDF
Cyclic Attacks on the RSA Trapdoor Function
PDF
An Analysis of RSA Public Exponent e
PDF
An Analysis of Secure Remote Password (SRP)
PDF
Thank-a-Gram
PDF
Active Attacks on DH Key Exchange
PDF
Can I write to a read only file ?
PPTX
How do computers exchange secrets using Math?
PDF
On the Secrecy of RSA Private Keys
PDF
Computing the Square Roots of Unity to break RSA using Quantum Algorithms
PDF
Analysis of Short RSA Secret Exponent d
PDF
Dependency Analysis of RSA Private Variables
PDF
Analysis of Shared RSA Modulus
PDF
RSA Game using an Oracle
PDF
RSA Two Person Game
PDF
RSA without Integrity Checks
PPTX
RSA without Padding
PDF
Solutions to online rsa factoring challenges
.NET Deserialization Attacks
Reverse Architecting using Relation Algebra.pdf
How to exploit rand()?
Cyclic Attacks on the RSA Trapdoor Function
An Analysis of RSA Public Exponent e
An Analysis of Secure Remote Password (SRP)
Thank-a-Gram
Active Attacks on DH Key Exchange
Can I write to a read only file ?
How do computers exchange secrets using Math?
On the Secrecy of RSA Private Keys
Computing the Square Roots of Unity to break RSA using Quantum Algorithms
Analysis of Short RSA Secret Exponent d
Dependency Analysis of RSA Private Variables
Analysis of Shared RSA Modulus
RSA Game using an Oracle
RSA Two Person Game
RSA without Integrity Checks
RSA without Padding
Solutions to online rsa factoring challenges

Recently uploaded (20)

PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Autodesk AutoCAD Crack Free Download 2025
PDF
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
PPTX
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
DOCX
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Nekopoi APK 2025 free lastest update
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Computer Software and OS of computer science of grade 11.pptx
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
Oracle Fusion HCM Cloud Demo for Beginners
Design an Analysis of Algorithms II-SECS-1021-03
Autodesk AutoCAD Crack Free Download 2025
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
Designing Intelligence for the Shop Floor.pdf
Complete Guide to Website Development in Malaysia for SMEs
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Nekopoi APK 2025 free lastest update
How to Choose the Right IT Partner for Your Business in Malaysia
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
wealthsignaloriginal-com-DS-text-... (1).pdf
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
L1 - Introduction to python Backend.pptx
Computer Software and OS of computer science of grade 11.pptx
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
CHAPTER 2 - PM Management and IT Context
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Oracle Fusion HCM Cloud Demo for Beginners

Load-time Hacking using LD_PRELOAD

  • 2. int main(int argc, char **argv) { char passwd[] = "foobar"; if (argc < 2) { printf("usage: %s <given-password>n", argv[0]); return 0; } if (!strcmp(passwd, argv[1])) { printf("Green light!n"); return 1; } printf("Red light!n"); return 0; } 2  What if you do not know the passwd? Reference: Reverse Engineering with LD_PRELOAD by Itzik Kotler
  • 3. /* * strcmp, Fixed strcmp function -- Always equal! */ int strcmp(const char *s1, const char *s2) { printf("S1 eq %sn", s1); printf("S2 eq %sn", s2); // ALWAYS RETURN EQUAL STRINGS! return 0; } 3
  • 4.  gcc -fPIC -c strcmp-hijack.c -o strcmp-hijack.o  gcc -shared -o strcmp-hijack.so strcmp-hijack.o  ./strcmp-target redbull  Output: “Red light!”  Attack using LD_PRELOAD  LD_PRELOAD="./strcmp-hijack.so" ./strcmp-target redbull  Output: “Green light!” 4
  • 5. /* * cerberus.c, Impossible statement */ #include <stdio.h> int main(int argc, char **argv) { int a = 13, b = 17; if (a != b) { printf("Sorry!n"); return 0; } printf("On a long enough timeline," " the survival rate for everyone drops to zeron"); exit(1); } 5 Can we avoid “Sorry” and print the “On a long…”? [~]$ ./cerberus On a long enough timeline, the survival rate for everyone drops to zero
  • 6. 080483d4 <main>: 80483d4: 55 push %ebp 80483d5: 89 e5 mov %esp,%ebp 80483d7: 83 e4 f0 and $0xfffffff0,%esp 80483da: 83 ec 20 sub $0x20,%esp 80483dd: c7 44 24 18 0d 00 00 movl $0xd,0x18(%esp) 80483e4: 00 80483e5: c7 44 24 1c 11 00 00 movl $0x11,0x1c(%esp) 80483ec: 00 80483ed: 8b 44 24 18 mov 0x18(%esp),%eax 80483f1: 3b 44 24 1c cmp 0x1c(%esp),%eax 80483f5: 74 13 je 804840a <main+0x36> 80483f7: c7 04 24 f0 84 04 08 movl $0x80484f0,(%esp) 80483fe: e8 ed fe ff ff call 80482f0 <puts@plt> 8048403: b8 00 00 00 00 mov $0x0,%eax 8048408: eb 11 jmp 804841b <main+0x47> 804840a: c7 04 24 f8 84 04 08 movl $0x80484f8,(%esp) 8048411: e8 da fe ff ff call 80482f0 <puts@plt> 8048416: b8 01 00 00 00 mov $0x1,%eax 804841b: c9 leave 804841c: c3 ret 6 Note: puts is used for printf
  • 7.  Create our own “puts” wrapper  Update the return address after the first puts  Transfer control to the second puts  Embed assembly code and adjust the ESP! 7
  • 8. /* Pointer to the original puts call */ static int (*_puts)(const char *str) = NULL; int puts(const char *str) { if (_puts == NULL) { _puts = (int (*)(const char *str)) dlsym(RTLD_NEXT, "puts"); // Hijack the RET address and modify it to <main+xx> __asm__ __volatile__ ( "movl 0x4(%ebp), %eax n" "addl $7, %eax n" "movl %eax, 0x4(%ebp)" ); return 1; } __asm__ __volatile__ ( "addl $28, %%esp n“ “ jmp *%0 n" : : "g" (_puts) : "%esp" ); return -1; } 8 • Why add 7 to eax? • 0x804840a – 0x8048403 • Why add 28 to esp? • Answered in next slides
  • 9. 00000000 <printf>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 18 sub $0x18,%esp 6: a1 00 00 00 00 mov 0x0,%eax b: 85 c0 test %eax,%eax d: 75 2a jne 39 <printf+0x39> f: b8 00 00 00 00 mov $0x0,%eax 14: 89 44 24 04 mov %eax,0x4(%esp) 18: c7 04 24 ff ff ff ff movl $0xffffffff,(%esp) 1f: e8 fc ff ff ff call 20 <printf+0x20> 24: a3 00 00 00 00 mov %eax,0x0 29: 8b 45 04 mov 0x4(%ebp),%eax 2c: 83 c0 0f add $0xf,%eax 2f: 89 45 04 mov %eax,0x4(%ebp) 32: b8 01 00 00 00 mov $0x1,%eax 37: eb 00 jmp 39 <printf+0x39> 39: c9 leave 3a: c3 ret 9 Esp got adjusted: 4 bytes (push %ebp) 0x18 bytes (sub $0x18, %esp) Total: 0x18 + 4 = 24 + 4 = 28
  • 10.  Create a shared lib of the wrapper:  gcc -c -m32 megatron.c -o megatron.o –ldl  gcc -shared -o megatron.so megatron.o -m32 –ldl  export LD_PRELOAD=./megatron.so [~]$ ./cerberus On a long enough timeline, the survival rate for everyone drops to zero 10
  • 11.  The main function uses exit(1)  If we replace it by return(1) and run: [~]$ gcc -o cerberus cerberus.c -m32 [~]$ [~]$ export LD_PRELOAD=./megatron.so [~]$ [~]$ ./cerberus On a long enough timeline, the survival rate for everyone drops to zero ^C [~]$ 11 Why the program is not terminating?
  • 12. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP ESP Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP ESP EBP (main)96 Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP ESP EBP (main)96 (a). Just before the 2nd printf. (b). In the wrapper puts. (c). After pointers rewinding. 12 100 96 92 88 84 80 76 52 80 76 100 96 92 88 84 80 100 96 92 88 84
  • 13. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of puts (wrapper) 76 ESP EBP Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of puts (wrapper) 76 ESP EBP EIP (d). Inside the real puts. (e). After returning from real puts. 13 76 76 100 96 92 88 84 80 100 96 92 88 84 *80
  • 14.  Control comes back to main and will try to run return 1:  mov %ebp, %esp  pop %ebp  Pop %eip (or ret) 14
  • 15. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of puts (wrapper) 76 ESP EBP 15 76 100 96 92 88 76 80 mov %ebp, %esp 84
  • 16. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of puts (wrapper) 76EBP ESP 16 76 100 96 92 88 80 pop %ebp 84
  • 17. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of puts (wrapper) 76EBP EIP 17 76 100 96 92 88 84 ret: pop %eip ESP • Now EIP points to leave-ret sequence! • Never ending because EBP of mains is lost *80
  • 18.  We lost main’s EBP along the way  There is an infinite loop when the control comes to main  mov %ebp, %esp  pop %ebp  Ret (or pop %eip)  Program is not able to return to libc  Fix:Why not restore the EBP! 18
  • 19. OLD __asm__ __volatile__ ( "addl $28, %%esp n“ "jmp *%0 n" : : "g" (_puts) : "%esp" ); NEW __asm__ __volatile__ ( "addl $24, %%esp n" "popl %%ebp n" "jmp *%0 n" : : "g" (_puts) : "%esp" ); 19
  • 20. [~]$ export LD_PRELOAD=./megatron.so [~]$ [~]$ ./cerberus On a long enough timeline, the survival rate for everyone drops to zero [~]$ [~]$ echo $? 1 20
  • 21. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP ESP EBP (main) Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP, ESP EBP (main) (a). In the wrapper puts. (b). After ESP rewinding. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printfESP EBP (main) (c). After pop EBP. EBP 21 76 100 96 92 88 84 80 52 76 100 96 92 88 84 80 52 76 100 96 92 88 84 80 52
  • 22. Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of main (96) ESP EBP Ret2libc EBP (libc) 17 13 Ptr to printf input str ret address after printf EBP of main ESP EBP EIP (d). Inside the real puts. (e). After returning from real puts. 22 76 100 96 92 88 84 80 52 76 76 100 96 92 88 84 *80 52
  • 23.  LD_PRELOAD is a powerful way to hack  Key idea:Wrapper to library functions  Collect data such as input arguments!  Modify control flow dynamically  ESP and EBP rewinding is the core concept  Try it out yourself  Things to keep in mind:  Number of byte adjustments in your wrapper 23
  • 24.  Itzik Kotler  Reverse Engineering with LD_PRELOAD  http://securityvulns.com/articles/reveng/  Dharma Ganesan and Itzik Kotler  Reverse Engineering with LD_PRELOAD (Part 11)  Article to be published 24