Malware resistance
Outline
• Preliminaries– Virtual Address Layout– Stack Layout– Verification Problem
• Remote Attestation– Methods– Code Injection
• Interrupts• Identification
Virtual Address Space (Linux)
• 1 Gb is given for Kernel mapping
• 3 GB for User app– Code, data
segment, BSS– Stack and Heap
• Which is where?– “Stack grows
down”
– “Heap grows up”
0
4GB
Stack and Heap
VAS
• DS– Static int q =5;
• BSS– Block Started by Symbol
– Static int q;
4 GB
0
Stack and Heap
Text Segment ELF image
Data Segment Static initialized variables
BSS Static uninitialized variables
3 GB
Stack Grows Down
Heap Grows Up
Kernel
Sample Program
int main(){
char *ptr;
ptr = (char *) malloc((sizeof(char)*10));
printf("ptr on stack = %x", &ptr);
printf("ptr on heap = %x", ptr);
free(ptr);
return 0;}
Results
[rsriniv8@calypso4:~]$ ./stack_heap_t.o
ptr on stack = bffaf194 ptr on heap = 9f2d008
Stack – bffaf194 = 3220499860 = 2.99 GB
Heap – 9f2d008 = 166907912 = .15 GB
Stack layout
• Function call – Push context
address on Stack– Jump to function– Subtract Stack
pointer to accommodate Local variables
Arguments
Return Add
Local variables
High Address
LowAddress
Program (Buffer Overflow)
int main()
{
….
foo();
printf(“something”);
return 0;
}
int foo()
{
int a[4];
for (int i=0;i<=7;i++)
scanf(“%d”, &a[i]);
return 0;
}
•Program most likely crashes and never executes the printf in main•Or may jump to a new address and execute
int i;
int function(int);
int main()
{
int a= 4;
printf("\n address of main %x, address of function %x",main, function);
function(a);
return 0;
}
int function(int x)
{
int a[3]= {-1, -1,-1};
for (i=0;i<=10;i++)
printf("\n a[%d] = %x", i, a[i]);
return 0;
}
address of main 8048368, address of function 80483ba
a[0] = ffffffff
a[1] = ffffffff
a[2] = ffffffff
a[3] = 80484f8
a[4] = bfe74b6c
a[5] = 91aff4
a[6] = bfe74b88 a[7] = 80483b0 (Return address)
a[8] = 4 (argument)
a[9] = 8048368
a[10] = 80483ba
80483a5: 83 ec 0c sub $0xc,%esp 80483a8: ff 75 fc pushl 0xfffffffc(%ebp) 80483ab: e8 0a 00 00 00 call 80483ba <function> 80483b0: 83 c4 10 add $0x10,%esp
Excerpt from the objdump of main
Output
Prevention and Detection
• Prevention– Create genetic diversity among binaries– Memory randomization
• Stack Randomization• Heap Randomization
– Code Randomization• How?
• Detection– Is It done?
Verified Code Execution
• Assume Viruses have unlimited potential
• Can patch on detectors– Why?
• Same image
• Difficult to find if any code actually executed– Results may be pre computed– Verification can be bounced
Remote Attestation (hardware)
• Make an external entity check the system
• Typically through TPM– Computes
checksums
• Plenty of literature on pros and cons
Client OS
Programs
Client HW
TPM
Trusted External Server
Network
Remote Attestation (Software)
• No hardware support– Opens issues
• Did the code actually execute• Is the attestation program patched• Was it bounced to another machine• Was it bounced to another process
Bounce to another machine
Client OS
Patched Program
Client HW
Trusted External Server
Network
Machine 1
Client OS
Clean Program
Client HW
Relay
Machine 2
Program
•Send data to compute checksum•Send code to compute checksum
Bounce to another Process
Client OS
Client HW
Trusted External Server
Network
Machine 1
Patched Program
Clean Program
Attestation Process
Client OS
Patched Program
Client HW
Trusted External Server
Machine 1
op-code
Network
Results
Characteristics
• Inject code in the running process– Make the process inject code on itself
• Use schemes to identify machine– Connection details should suffice
• IP, port, etc
• Use schemes to identify process– Identify all open ports to see if more than one
process is communicating to server
ASM code
• Injected code • No library calls• Required calls have to be written• Either C code, or ASM code if it is a system
call– socket()
– ioctl
– send()
– receive()
– helper functions like write(), read(), exit(), getpid(), etc
Example: socket()int sock_d(int sock){
sock = socket(PF_INET, SOCK_STREAM, 0);
return sock;}
int sock_d(int sock){
__asm__("sub $12,%%esp\n"
"movl $2,(%%esp)\n"
"movl $1,4(%%esp)\n"
"movl $0,8(%%esp)\n"
"movl $102,%%eax\n"
"movl $1,%%ebx\n"
"movl %%esp,%%ecx\n"
"int $0x80\n"
"add $12,%%esp\n"
: "=a" (s)
);
return sock;}
http://www.digilife.be/quickreferences/QRC/LINUX%20System%20Call%20Quick%20Reference.pdf
102 socketcall socket system calls net/socket.c
linux/include/net.h
30 #define SYS_SOCKET 1 /* sys_socket(2) */ 31 #define SYS_BIND 2 /* sys_bind(2) */ 32 #define SYS_CONNECT 3 /* sys_connect(2) */ 33 #define SYS_LISTEN 4 /* sys_listen(2) */ 34 #define SYS_ACCEPT 5 /* sys_accept(2) */ 35 #define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ 36 #define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ 37 #define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ 38 #define SYS_SEND 9 /* sys_send(2) */ 39 #define SYS_RECV 10 /* sys_recv(2) */ 40 #define SYS_SENDTO 11 /* sys_sendto(2) */ 41 #define SYS_RECVFROM 12 /* sys_recvfrom(2) */ 42 #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ 43 #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ 44 #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ 45 #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ 46 #define SYS_RECVMSG 17 /* sys_recvmsg(2) */
Attestation Process
• Identify the Machine– IP add works if there is no NAT
• Take random checksums– Must differ each time
• Why?• How?
• Check open ports– How?
• /proc/net/tcp, compare with open /proc/<pid>/fd which has symbolic links.
• Identify Process ID– How?
• Return results
Questions?