Showing posts with label vi. Show all posts
Showing posts with label vi. Show all posts

Sunday, March 22, 2009

Funny Unix and Linux Pictures: Almost Windows

Hey there,

For this week's lazy Sunday post we went and found some great Unix/Linux OS photos at fiveprime.org. Some are jokes and some are just interesting ads from an earlier time. Check out the whole shebang if you have the chance :)

My favorite is the "vi paperclip" ;)

Enjoy your Sunday, I'm a little too tipsy to type much more. I can't believe I'm actually staying up to finish this post ;)

Cheers,



NOTE: If you miss the animation in the first photo of the vi Windows paperclip, just refresh the page. You won't be sorry :) It should run in a loop by default











, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Sunday, March 8, 2009

Sunday Unix And Linux Humor: Vi, Emacs And The Balloon

Hey there,

Hope you're having (or are about to have) a great Sunday. If you live in the U.S.A., you're probably temporarily disoriented because of daylight savings time. I've never been a fan of the give-one-hour take-on-hour-back system, but it was actually necessary a long long time ago (See the original rationale on Wikipedia's Daylight Savings Time Page - The first paragraph alone is enough to make anyone question why we still practice this tradition). Nowadays it just seems like I'm either waking up too late or too early twice a year ;)

I also seem to have offended a few folks yesterday with my meandering religious-philosophical greeting. By way of explanation, the ending, where I wrote "There's always apathy and, quite frankly, at this point I've stopped giving a shit how your day is going ;)" I was working under the assumption that the winky emoticon (as much as I hate it ;) would be enough to let everyone know (by way of symbolic inflection) that I was just kidding. It wasn't the finest line of "goofy" I've ever written, but everything on that line after the word "apathy" was a direct play on that word's meaning (for which Random House Dictionary's primary definition is: absence or suppression of passion, emotion, or excitement). If that sort of stuff offends you, I apologize in advance. If you continue to read this blog, it'll probably happen again. Sorry :)

Today's Linux/Unix humor comes in two forms. One is a straight up joke and the other is an excerpt from an email back-and-forth regarding the Emacs/Vi aspects of a Learning-Unix book (Harley Hahn's Unix Unbound) that's good for a quick laugh. We picked the balloon joke up at get.a.clue.de and we got the Emacs/Vi bit at www.feep.net. Both sites are worth visiting, if only for the fact that they each contain even more decent quality jokes and funnies.

Enjoy, laugh and be merry. Life is short. ...where does the time go? Oh, yeah; we're saving daylight. Which means, that you've officially read this post one hour earlier than your clock may lead you to believe (unless you're like me and have an old fashioned clock that doesn't adjust automatically, and you're also as lazy as me and you just compensate in your head until DST reverts ;)

Cheers,



EMACS AND VI - NO HTML FORMATTING DUE TO LACK OF ENTHUSIASM ;) SOME EMAIL HEADERS REMOVED TO SAVE SPACE.

Subject: Re: The UNIX-Haters' Handbook? (was Re: Who are the most obnoxious computer groupies?)
....

Matthew Crosby wrote:
>In article ,
>Loren Petrich wrote:
>>
>> In my experience, vi is the absolute worst full-screen
>>(character-mode GUI) text editor I have *ever* used.
>> [ and so on in the anti-vi mode ... ]
>
>vi has the fastest, most efficient keybindings around.
> [ and so on in the pro-vi mode ... ]

Harley Hahn's book _Unix Unbound_ (which I recommend, BTW,
to anyone learning Unix) has chapters on vi and emacs. The
vi chapter contains the following paragraph:

HINT: If you are learning vi and you become temporarily
discouraged, take a break and try a little emacs. emacs
will seem so complex and impossible that you will feel a
lot better about using vi.

While the emacs chapter contains this one:

HINT: If you are learning emacs and you become temporarily
discouraged, take a break and try a little vi. vi
will seem so complex and impossible that you will feel a
lot better about using emacs.

Says it all really, doesn't it? :-)




UNIX Humor - balloon






A man is flying in a hot air balloon and realizes he is
lost. He reduces height and spots a man down below. He
lowers the balloon further and shouts: "Excuse me, can
you tell me where I am?" - The man below says: "yes
you're in a hot air balloon, hovering 30 feet above this
field."

"You must work in Information Technology" says the
balloonist. - "I do" replies the man. "How did you know.
" - "Well" says the balloonist, "everything you have
told me is technically correct, but it's no use to
anyone."

The man below says "you must work in Management." - "I
do" replies the balloonist, "but how did you know?" -
"Well", says the man, "you don't know where you are, or
where you're going, but you expect me to be able to help
. You're in the same position you were before we met,
but now it's my fault."


, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Thursday, May 15, 2008

Finding An "Invisible" Proc's Working Directory Without lsof On Linux Or Unix

Ahoy there,

Today, we're going to take a look at something that gets taken for granted a lot these days. lsof (a fine program, to be sure. No debate here) has become a very common staple for finding out information about processes, and where they're hanging out, on most Linux and Unix systems today. Much like the command "top," it provides a simple and robust frontend to having to do a lot of grunt-work to achieve the same results.

I find that, for the most part, lsof is used to find out where a process is, or what filesystems, etc, it's using, in order to troubleshoot issues. One of the most common is the "mysteriously full, yet empty, disk" phenomenon. Every once in a while that will turn out to be an issue where all of the inodes in a partition have been used before all of the blocks have, which produces confusing output in df, leading to the mistaken assumption that there is plenty of space left a device even when there isn't.

However, many times, that empty-yet-full disk is the victim of a process that met an untimely demise and never cleaned up a lot of temporary space in memory (or virtual disk, to split hairs). Another issue that lsof is used for is to find out which dag-nabbed process is holding onto a mount-point that claims it's in use when no one is logged on and no user processes are running that would access it (for instance, a really specific, user-defined, mountpoint like /whereILikeToPutMyStuff - Hopefully the OS isn't depending on this to be around ;) Both problems are, essentially, the same.

However, should you find yourself in a situation where lsof either doesn't come with your Operating System, and/or hasn't been installed, you can still break down these two (and I'm just limiting the post to these two particulars so I don't end up writing an embellished manpage ;) separate issues into one, and find the solution to your problems using the commonly available "pwdx" utility.

pwdx will print out the working directory of any given process (using the process ID as input) at its best. But this is enough to get you to the answer you need.

For instance, we'll take this common scenario: /tmp is reporting 100% full, but df -k shows that /tmp is only at 1% capacity (99% of it is unused). My thinking here almost immediately gravitates toward vi, or some other program that opened up a buffer in memory (using /tmp or /var/tmp), got clipped unexpectedly and never let the system know that it was done with the space it allocated for itself. This would normally not be an issue but, since your Linux or Unix machine "thinks" /tmp is full, whether or not it actually is makes no difference. It won't let you use the free space :(

This command line could be used to figure out what process was using that space in /tmp or /var/tmp:

host # ps -ef|awk '{print $2}'|xargs pwdx 2>&1|grep -iv cannot|grep /tmp
2969: /tmp


Taking it a step further (assuming we trust our own output), we could just skip right to the process in question by adding a bit more to the pipe-chain:

host # ps -ef|awk '{print $2}'|xargs pwdx 2>&1|grep -iv cannot|grep /tmp|sed 's/^\([^:]*\).*$/\1/'|xargs -n1 ps -fp
UID PID PPID C STIME TTY TIME CMD
root 2969 2966 0 Mar 21 ? 0:05 /bin/vi /home/george/myHumungousFile


Since it's May already, we can fairly assume that this PID is pointing to a dead process (especially since it has no TTY associated with it), and (double-checking, just to be sure) we can probably solve our problem by killing that PID. See our previous post on killing zombie processes if it won't seem to go away and "ps -el" shows it in a Z state.

Yes, that example was pretty simplistic, but the same methodology can be used to find other programs using up other filesystems. Just like "lsof -d," you'll be able to find out what processes are using what filesystems and narrow down your list of suspects, if you don't nail the correct one right away. Since pwdx comes with your Linux or Unix OS, it's actually statistically more likely than lsof to be correct about what process is using what filesystem :)

Cheers,

, Mike

Monday, May 5, 2008

Restricted Accounts And Vi(m) Tricks in Linux And Unix

Greetings,

Today we're going to take a look at restricted shells on Linux and Unix and a few ways to break out of those shells. We'll also be looking at the ways these security holes can be plugged so that any sysadmin can make his/her restricted shell more bullet-proof.

To keep this article in scope (and under 10,000 words ;) we're going to limit the potential "escapes," and their countermeasures, to restricted shells and the vi (or vim) editor (We'll leave chroot'ing, and all the other ways to make life difficult, for another time. If you're interested in an alternative method of making a shell available for you to goof with, check out our previous post on using perl to bind a shell to a Linux or Unix network socket :)

Of course, the first thing you'll want to do to moderately secure your system against a user that you want to keep contained, is to make sure that their default shell is restricted. Most distributions of Linux and Unix already come with predefined links to /usr/bin/rbash (the restricted version of /bin/bash) or /bin/rksh (the restricted version of /bin/ksh), etc. In the instances where these links aren't installed, you can still create them with the same effect (using symlinks to the real shell, like: ln -s /bin/ksh /bin/rksh), since the shell's restricted mode is "turned on" by the manner in which it's called. That is to say that /bin/ksh and /bin/rksh are both the same executable; the shell just contains initialization code that makes it start up differently when it notes the name under which it's being invoked.

At first, the restricted shell seems like it's the only thing you'll ever need, since the user can't even move and (in most cases) can't run fully qualified commands, as shown below:

rbash # mkdir b
rbash # cd b
-rbash: cd: restricted
rbash # ls /tmp
-rbash: /bin/ls: restricted: cannot specify `/' in command names


But they're far from secure to start out. Below, we'll go through a few ways users can escape the restricted shell using vi (or vim), and ways to counter each potential breaking point.

1a. Using the systems predictable temporary files, expreserve and the IFS.

This hack has been around forever, and still comes back every once and a while. The breakout basically consists of the user setting the IFS (Internal Field Separator, which is normally a space, tab or newline) and then using an editor to execute files in his/her local directory using the "preserve" function of vi. It's only really a trivial hack if the system is setup improperly.

Example below, with the assumption that "[esc]:pre" uses /bin/mail to notify the user of a vi crash.

rbash # touch bin mail <--- These files would be edited to include bad commands and made executable
rbash # chmod 777 bin mail
rbash # export IFS="/"
rbash # vi
[esc]:pre
File preserved.
[esc]:q!


Now, when the [esc]:pre function runs /bin/mail, it would (theoretically) be running "bin" and "mail" in the user's home directory, since he/she changed the IFS to "/".

1b. How to easily counter this attack (assuming your system is vulnerable)

There's one huge step you can take to prevent this from happening forever (just in case your system ever has been vulnerable and you don't want to have to worry about it anymore). By default, your restricted shell should not let the user redefine the IFS variable. Here's the one thing you can do to make it impossible for this hack to work (although it will come at some cost, since no one will be able to preserve crashed vi files. And, we should note that part of this vulnerability is that this command used to be setuid root!):

host # chmod a-x /usr/lib/expreserve

Now, no one can execute that command by running [esc]:pre in vi or vim! (Note also that this file may be in a different directory depending on your distro, and may also be differently titled. For instance, the "elvis" program - a vi clone - uses the "elvprsv" command to do its preserves.)

2a. The shell escape is available by default in vi and vim, even if you are running in a restricted shell (the short version).

This allows a user to run [esc]:shell within vi and escape to a subshell within vi.

2b. The easiest fix, if it's available, is included in some versions of vi and in most versions of vim.

If you invoke them as rvi or rvim, the shell escape is disabled by default :) In some instances, invoking vi as rvi will dump your user to the "ex" editor. That's bordering on cruelty ;)

3a. Assuming you can't run vi, or vim, securely, your user can set his/her shell variable from within the editor.

All they have to do is type:

[esc]:set shell=/bin/bash

and then execute [esc]:shell from within vi to get to a regular, unrestricted bash shell. Most restricted shells won't fall for this cheap trick, but some still do.

The user can also access the shell indirectly, via the

[esc]:! /bin/whatever

type of one-line command execution.

3b. Here's a very simple way to ensure this will never happen (at least, not the unoriginal way ;)

First, set the restricted user's home directory up with an .exrc file. Normally, these are considered bad to have, but, in fact, it's generally better practice to have an existing .exrc file, that the user can't access, than none at all (since that leaves it for them to create if they can figure out a way).

bash # touch /home/restricted/.exrc
bash # chown root:root /home/restricted/.exrc
bash # chmod 644 /home/restricted/.exrc
bash # vi /home/restricted/.exrc
set exrc
set shell=/bin/false


And you're all set. Now, whenever your user uses vi (or vim - the same method is used to implement the above), the .exrc file will get processed and the default "shell" will be set to /bin/false. So, when they type:

[esc]:shell

It will knock them right back to the editor. As an added bonus, this will prevent them from being able to use the [esc]:! one-line command functionality, since it will try to exec that command using /bin/false. This will fail if /bin/false exists (because it returns failure no matter what) and also if it doesn't (because the invocation of the non-existent shell will return failure also). If you want to play it safe, make sure your system has a /bin/false before you set this (to avoid any bizarre unanticipated OS behaviour). Another common "useless" shell is /sbin/nologin, but /bin/false should be on almost every flavor and distro of Linux and Unix out there.

Hopefully you found some of these tips helpful in fixing things that, again hopefully, may not be broken yet :)

Best wishes,

, Mike

Monday, March 31, 2008

Minor Fix Update - Script To Unpack Solaris Datastream Pkg Files Without Sun's Pkg Utils

Hello again,

Updated 4/4/08 to output pkgproto results to a file named prototype. Originally had it writing to a file named pkgproto. Typo corrected :)

It's been a while since I started looking for a way to finish up our series of articles on RPM and pkg ripping and creating. We started out with creating our own RPM's and did pretty much everything I could think of to those poor packages, all the way through creating RPM's from already installed RPM's and converting RPM's to Solaris pkg's ;)

The only project I had left over (from that bunch) was how to extract the binary contents of Solaris Unix datastream pkg files.

Unfortunately, unlike the "rpm2cpio" command that Solaris includes, they have no regular program for converting a datastream package to an unpackable file (like a cpio or tar), unless you count all the basic pkg commands. What I was looking for was a way to extract a datastream pkg file, and get all the binary contents, without actually installing it. I got no love from Solaris, but I got some free time for myself and eventually figured it out ;)

I've included a script, below, to rip apart a Solaris datastream pkg and create a subdirectory (named the name of the pkg) into which I dump the pkginfo, pkgmap, pkgproto (which I derive from the pkgmap) and all the binary files that the pkg contains. The script, itself, is far from perfect, but if you check it out you can see, fairly easily, how you can manually pull apart a Solaris datastream pkg file and get to the binary contents that you really want (At least, I'm assuming you do - just like me ;)

Note that the version of cpio that comes with Solaris (in the SUNWcsu coreutils package) will complain about garbage bits in your cpio header, when you've clipped off the top of the pkg file. There are really only 2 garbage bits you have to delete (which you can do with vi), but I prefer to use the Gnu version of cpio which will "magically" ignore garbage bits and extract the cpio file no matter what. This version of cpio comes standard on Linux and can be downloaded (in Solaris datastream pkg format) from sunfreeware.com or (in source format, with links to all sorts of OS ports) Gnu's CPIO Download site - just in case you don't want to have to rip apart your Solaris pkg's on Linux (or don't have both OS's at your workplace).

Another strange thing is that Sun's version of cpio won't make directories, by default, that don't exist when you unpack a cpio archive (???) All I'm really saying is: Get the Gnu version - It's free and it'll save you many a gray hair ;)

I've tested today's script on multiple packages from sunfreeware.com and had great success with it working right the first time (assuming that I have Gnu's cpio). The script has broken on a few custom pkg's I've put together myself and can use a lot of work in the "additional" areas (like ensuring pre and post-install scripts get accounted for, depend files get tagged, checkinstall programs are properly extracted, etc). Still, it's a good beginning :)

Hopefully this will be of help to you, if you've been looking all over for something like this, and, almost definitely, can be the starting point for a fully functional Solaris datastream pkg ripper :)

If you want to do this manually, in short terms, just vi the pkg file you're interested in and delete everything up to the final instance of "pkginfo" in the file (after the final "pkgmap" line) and save the rest into another file, which you can manipulate with cpio. Who'd have thought it would end up being that simple? :)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# rip_pkg - rip apart Solaris pkg's and get the binaries out
#
# 2008 - Mike Golvach - eggi@comcast.net
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

if ( $#ARGV != 0 ) {
print "Usage: $0 pkg_file\n";
exit(1);
}

$pkg_name = $ARGV[0];

# check and make sure it's a SVR4 DataStream Pkg

chomp($simple_header_check=`grep -i "package datastream" $pkg_name >/dev/null 2>&1;echo \$?`);

if ( $simple_header_check != 0 ) {
print "This doesn't appear to be a valid SVR4 DataStream pkg file. Exiting...\n";
exit;
}

# Memory Hogging Here - Until This Cold Quits Me And I Can Think My Way Out Of This ;)

open(PKG, "<$pkg_name");
@pkg_file = <PKG>;
close(PKG);

# Split out header information and kludgey cpio file with binary contents

$header_end = 0;
$cpio_start = 0;
open (P_HEADERS, ">$pkg_name.headers");
foreach $line (@pkg_file) {
if ( $header_end == 0 && $line =~ /TRAILER/ && $line =~ /pkginfo/ ) {
print P_HEADERS $line;
$header_end = 1;
} elsif ( $header_end == 1 && $line =~ /pkginfo/ ) {
print P_HEADERS $line;
close(P_HEADERS);
$cpio_start = 1;
open(P_CPIO, ">$pkg_name.cpio");
} elsif ( $cpio_start == 0 ) {
print P_HEADERS $line;
} elsif ( $cpio_start == 1 ) {
print P_CPIO $line;
} else {
print STDERR "WTF?\n";
}
}
close(P_CPIO);

open(P_HEADERS, "<$pkg_name.headers");
@p_headers = <P_HEADERS>;
close(P_HEADERS);

$output_dir = 0;
$pkginfo_start = 0;
$pkginfo_seek = 0;
$pkgmap_start = 0;
foreach $p_head (@p_headers) {
if ( $output_dir eq 1 && $pkginfo_seek == 0 ) {
$output_dir = $p_head;
$output_dir =~ s/^(\w+)\W*.*$/$1/;
chomp($output_dir);
$pkginfo_seek = 1;
} elsif ( $output_dir eq 0 && $p_head =~ /datastream/i ) {
$output_dir = 1;
} elsif ( $output_dir eq 0 && $pkginfo_start == 0 ) {
next;
} elsif ( $output_dir ne 0 && $p_head =~ /pkgmap/ ) {
$pkgmap_start = 1;
$pkginfo_start = 0;
} elsif ( $pkgmap_start == 1 && $p_head =~ /pkginfo/ ) {
chomp($p_head);
push(@pkgmap, $p_head);
last;
} elsif ( $output_dir ne 0 && $p_head =~ /pkginfo.*PKG=/ ) {
$pkginfo_start = 1;
} elsif ( $output_dir ne 0 && $pkgmap_start == 1 ) {
chomp($p_head);
push(@pkgmap, $p_head);
} elsif ( $output_dir ne 0 && $pkginfo_start == 1 ) {
chomp($p_head);
push(@pkginfo, $p_head);
} else {
print "WTF NOTHING MATCHED\n OD $output_dir PST $pkginfo_start PS $pkginfo_seek PMST $pkgmap_start\n$p_head\n";
}
}

mkdir("$output_dir");
chdir("$output_dir");
open(PKGINFO_OUT, ">>pkginfo");
foreach $info (@pkginfo) {
print PKGINFO_OUT "$info\n";
}
open(PKGMAP_OUT, ">>pkgmap");
foreach $map (@pkgmap) {
print PKGMAP_OUT "$map\n";
}
open(PROTO_OUT, ">>prototype");
foreach $proto (@pkgmap) {
@proto = split(" ", $proto);
print PROTO_OUT "$proto[1] $proto[2] $proto[3] $proto[4] $proto[5] $proto[6]\n";
}
system("cpio -iv <../$pkg_name.cpio >/dev/null 2>&1");
chdir("reloc");
system("tar cpf - *|(cd ../;tar xpf -)");
chdir("../");
system("rm -r reloc");
chdir("../");
unlink "$pkg_name.headers";
unlink "$pkg_name.cpio";


, Mike




Tuesday, October 30, 2007

An Easy To Understand Shell Script To Save You Some Hassle

Hey again,

Just to round off the day, I thought this might be of interest to someone other than me.

Personally, I hate editing a shell script and then writing it to disk, chmod'ing it and then running it. I know it's petty and not that big of a deal, but that's what shell scripting's for, right? Taking care of all those boring things you have to do over and over and over again.

This little script I call "vix" and I call it instead of "vi" or "vim" (Your preference; just modify the script - use emacs if you want ;) when I'm going to be writing a new executable script.


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/bin/ksh

#
# 2007 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

/usr/bin/touch $@
/usr/bin/chmod 755 $@
/usr/bin/vi $@


Simple, right? $@ is just your command line arguments (the names of the scripts you're going to edit/write), so you can call:

vix scripta.sh scriptb.sh ...

instead of

vi scripta.sh scriptb.sh ...

and your script will be executable when you're done editing it. Silly and simplistic? Yes. Useful, too, if you're sick and tired of typing chmod 755 (or whatever) after every script you write :)

, Mike