In both versions of the code you just posted, you are attempting to refer to a movieclip with a reference that has been changed by the loop. In the first version, buttons[i] does not exist because the loop has already exited and i is now buttons.length. There's nothing in the array at that spot, so you get an undefined term error when attempting to access it.

You have a very similar problem in the second version, but b IS still a valid reference. It just points to the last button. Which is not what you want.

In both versions, you are assigning two listeners for the same event to the same button. When you do that, BOTH of those listeners will be called. Since you don't want buttonPress2 to happen on the first press, you should not add it as a listener to begin with. Instead, have buttonPress add buttonPress2 as a listener after it removes itself.

I don't think you want the first press to set current, but I'm not sure about that.

Try something like this:
Code:
import flash.display.*;
import flash.events.*;

var buttons:Array = [box1, box2, box3];
var current:MovieClip = null;

for (var i:int = 0; i < buttons.length; i++){
  var b:MovieClip = buttons[i];
  b.addEventListener(MouseEvent.MOUSE_DOWN, buttonPress);
  b.gotoAndPlay("out2");
}

function buttonPress(e:MouseEvent):void{
  //by declaring a variable here inside the function, it is a function local variable.  This is NOT the same b as that declared in the loop above, though it may refer to the same instance.
  var b:MovieClip = MovieClip(e.currentTarget); 
  b.gotoAndPlay("clickthis");
  b.removeEventListener(MouseEvent.MOUSE_DOWN, buttonPress);
  b.addEventListener(MouseEvent.MOUSE_DOWN, buttonPress2);
}

function buttonPress2(e:MouseEvent):void{
  if (current != null){
     current.gotoAndPlay("out2");
  }
  current = MovieClip(e.currentTarget);
  current.gotoAndPlay("over2");
}