The Binary Bomb

by Dr. Evil

In our System Programming class we got this binary bomb here:

/***************************************************************************
* Dr. Evil's Insidious Bomb, Version 1.0
* Copyright 2002, Dr. Evil Incorporated. All rights reserved.
*
* LICENSE:
*
* Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the
* VICTIM) explicit permission to use this bomb (the BOMB). This is a
* time limited license, which expires on the death of the VICTIM.
* The PERPETRATOR takes no responsibility for damage, frustration,
* insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other
* harm to the VICTIM. Unless the PERPETRATOR wants to take credit,
* that is. The VICTIM may not distribute this bomb source code to
* any enemies of the PERPETRATOR. No VICTIM may debug,
* reverse-engineer, run "strings" on, decompile, decrypt, or use any
* other technique to gain knowledge of and defuse the BOMB. BOMB
* proof clothing may not be worn when handling this program. The
* PERPETRATOR will not apologize for the PERPETRATOR's poor sense of
* humor. This license is null and void where the BOMB is prohibited
* by law.
***************************************************************************/

#include <stdio.h>
#include "support.h"
#include "phases.h"

/*
* Note to self: Remember to erase this file so my victims will have no
* idea what is going on, and so they will all blow up in a
* spectaculary fiendish explosion. -- Dr. Evil
*/

FILE *infile;

int main(int argc, char *argv[])
{
char *input;

/* Note to self: remember to port this bomb to Windows and put a
* fantastic GUI on it. */

/* When run with no arguments, the bomb reads its input lines
* from standard input. */
if (argc == 1) {
infile = stdin;
}

/* When run with one argument <file>, the bomb reads from <file>
* until EOF, and then switches to standard input. Thus, as you
* defuse each phase, you can add its defusing string to <file> and
* avoid having to retype it. */
else if (argc == 2) {
if (!(infile = fopen(argv[1], "r"))) {
printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);
exit(8);
}
}

/* You can't call the bomb with more than 1 command line argument. */
else {
printf("Usage: %s [<input_file>]\n", argv[0]);
exit(8);
}

/* Do all sorts of secret stuff that makes the bomb harder to defuse. */
initialize_bomb();

printf("Welcome to my fiendish little bomb. You have 6 phases with\n");
printf("which to blow yourself up. Have a nice day!\n");

/* Hmm... Six phases must be more secure than one phase! */
input = read_line(); /* Get input */
phase_1(input); /* Run the phase */
phase_defused(); /* Drat! They figured it out!
* Let me know how they did it. */
printf("Phase 1 defused. How about the next one?\n");

/* The second phase is harder. No one will ever figure out
* how to defuse this... */
input = read_line();
phase_2(input);
phase_defused();
printf("That's number 2. Keep going!\n");

/* I guess this is too easy so far. Some more complex code will
* confuse people. */
input = read_line();
phase_3(input);
phase_defused();
printf("Halfway there!\n");

/* Oh yeah? Well, how good is your math? Try on this saucy problem! */
input = read_line();
phase_4(input);
phase_defused();
printf("So you got that one. Try this one.\n");

/* Round and 'round in memory we go, where we stop, the bomb blows! */
input = read_line();
phase_5(input);
phase_defused();
printf("Good work! On to the next...\n");

/* This phase will never be used, since no one will get past the
* earlier ones. But just in case, make this one extra hard. */
input = read_line();
phase_6(input);
phase_defused();

/* Wow, they got it! But isn't something... missing? Perhaps
* something they overlooked? Mua ha ha ha ha! */

return 0;
}

I copy pasted this on purpose so Google will hit it by most of the strings in it.

Since it's an exercise I will not post a solution here - but a way to make your work easier. Do not send me your bomb or mail me for help - I finished mine only with great difficulties and just in time for the deadline.

The story of the bomb

The idea is simple: You get a linux binary that asks you for certain values. If you type the right strings / numbers you earn points, wrong ones will make you lose points. At the ETH, each of the 6 phases is worth 10 points, each explosion 1/4. The seventh hidden phase gives no points. To get the right strings, you have to disassemble the bomb and read the assembly code.

The bomb is a lab project coming with the book "Computer Systems - A Programmer's Perspective" by Randal E. Bryant and David R. O'Hallaron and is distributed at http://csapp.cs.cmu.edu/ although the source code and some other things are only available to instructors.

Where to work

Obviously the computer on which you run the bomb with your test-strings has to be connested to the internet, otherwise noone would know if you really made it or not. To ensure this, the bomb has 2 possibilities: It checks on which machine it's being run and whether it can open a connection to port 80 of a special server, e.g. www.google.com

1. Fake a machine

Really easy, just go to the directory where your bomb is saved and run
strings bomb > strings.txt
Open the file strings.txt and have a look at it. It will look somewhat like this:

strings.txt
/lib/ld-linux.so.2
libc.so.6
strcpy
stdout
connect
getenv
__strtol_internal
fgets
tmpfile
puts
system
sleep
socket
fflush
cuserid
fprintf
stdin
signal
strcasecmp
bcopy
sscanf
gethostbyname
gethostname
sprintf
fclose
fputc
__ctype_b_loc
fwrite
rewind
exit
fopen
_IO_stdin_used
__libc_start_main
__gmon_start__
GLIBC_2.3
GLIBC_2.1
GLIBC_2.0
PTRh
%s: Error: Couldn't open %s
Usage: %s [<input_file>]
That's number 2. Keep going!
Halfway there!
Good work! On to the next...
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
So you got that one. Try this one.
Verbosity leads to unclear, inarticulate things.
Wow! You've defused the secret stage!
so.inf.ethz.ch
ics-16.inf.ethz.ch
scatola.inf.ethz.ch
pitcairn.inf.ethz.ch
mulaku.inf.ethz.ch
bong.inf.ethz.ch
ikdesk10.inf.ethz.ch
slab39
slab40
slab41
slab42
slab43
slab44
slab45
slab46
slab47
slab48
slab49
slab50
slab51
slab56
slab57
slab58
slab59
slab60
slab61
slab62
slab63
slab64
slab65
slab66
slab67
slab68
slab69
slab70
slab71
slab72
slab73
slab74
slab75
slab76
slab77
slab78
slab79
slab80
slab81
slab82
slab83
slab84
slab85
slab86
slab87

Well...
OK. :-)
Invalid phase%s
%d %d %d %d %d %d
Bad host (1).
Bad host (2).
Bad host (3).
Bad host (4)
Bad host (5).
www.google.com
GRADE_BOMB
Error: Premature EOF on stdin
Error: Input line too long
ERROR: dup(0) error
ERROR: close error
ERROR: tmpfile error
Subject: Bomb notification
nobody
defused
exploded
bomb-header:%s:%d:%s:%s:%d
bomb-string:%s:%d:%s:%d:%s
bomb
/usr/sbin/sendmail -bm
%s %s@%s
ERROR: notification error
ERROR: fclose(tmp) error
ERROR: dup(tmpstdin) error
ERROR: close(tmpstdin)
BOOM!!!
The bomb has blown up.
%d %s
austinpowers
So you think you can stop the bomb with ctrl-c, do you?
Your instructor has been notified.
Curses, you've found the secret phase!
But finding it and solving it are quite different...
Congratulations! You've defused the bomb!
Your instructor has been notified and will verify your solution.
sysprog-ws2004

The big part marked in red is the interesting one. It will differ from class to class and from school to school, so just look for something similar. Then change your hostname on your linux-machine to one of these values. I changed it to "slab41".

Fake google

OK, in the strings.txt above you find www.google.com, just below the Bad Host-strings. The bomb tries to open a connection to port 80 on this server, so you have to make sure that something answers the call. The easiest way is to install a webserver on your linux, e.g. apache. Then add the following to your /etc/hosts

127.0.0.1 www.google.com
This way your own computer will answer the call.

Disconnecting everything and deleting the mail

Yeah, disconnecting the computer. You have to! Unless you installed your linux in a sandbox on a virtual machine. First look up your connections to networks with
ifconfig
Then shut down all the interfaces of which you know they're connecting to a network. Don't forget the wireless LAN!
ifdown ethX
ifdown wlanX

After all this you can run your bomb for the first time on your own machine. If it doesn't print "Bad Host (X)" you did it.

But everytime you have an explosion or defused a phase, a mail will be sent with sendmail. Always check this with
mailq
If there are some mails you know you didn't send them kill them with
postsuper -d MESSAGEID
You get the messageid with mailq. If you tried too much and you have more than hundred mails, you can also use
postsuper -d ALL
But be very careful with this!

Our bombs we got here and they where graded here

If you need some help defusing the bomb have a look here.