When I was a kid in 1975, my dad brought home a terminal with an accoustical coupler on the top where I could put a standard phone handset in, and communicate with a Microdata minicomputer at his work. [Dick Pick developed the operating system for the Microdata. To make it fast, he programmed it using microcode. This is pretty mind boggling. CPUs are programmed with microcode. This is lower than assembly. Programming in microcode goes something like making the 8th bit high to latch the ALU data, etc. For more info click here.] Dad would try and get me excited about running database queries using a language much like SQL, but my eyes glazed over. I liked the games, though. I used to play Hammurabi endlessly. It was kind of like SimCity of today. I ran across the source code to Hammurabi here, recently, and thought it would be cool to use Netcat to make Hammurabi a network game. An article on Netcat alone… yawn. But, add my favorite childhood game, dear reader, and it might just make it interesting enough for me to spend part of my Saturday writing an article.
Netcat is a cool utility available here. The idea is that you can cat a program’s stdin and stdout to a network port. If you run netcat on the server and on the client, stdin and stdout are coupled together across the network, just as though you were at the console. Of course, the security implications are horrible. It is quite easy to use netcat to cat stdin and stdout of, say, cmd.exe to port 300. If port 300 is accessible from the outside, you then have cmd.exe accessible without any authentication. Many email-borne trojans do similar things. Scan your network often to see what is listening. It is probably a good idea to also do this at random times, since it may be that the app is only listening at certain times.
Enough lectures. Time for Hammurabi. Now, Hammurabi works fine as-is from the command prompt, but because of caching, you need to flush stdout with fflush before every gets command to get this to work with Netcat correctly. So a wee bit of tweaking on hammurabi.c is needed. You can do a substitution in vi:
:%s/gets(/fflush(stdout);gets(/g |
I used cygwin to compile hammurabi.c in this example, but *any* compiler should work:
$ gcc hammurabi.c -o hammurabi.exe |
Now, let’s listen on port 10878 using netcat:
$ ./nc -l -p 10878 -e hammurabi.exe |
Again, this is from a bash shell in cygwin, but you could just as well use cmd.exe. Let’s connect to our Hammurabi service from our XP box using Netcat:
C:\nc>nc 10.50.100.2 10878 HAMMURABI - WHERE YOU GOVERN THE ANCIENT KINGDOM OF SUMERIA. THE OBJECT IS TO KEEP THE KINGDOM GROWING. (IF YOU WANT TO QUIT, SELL ALL YOUR LAND) PRESS ENTER TO BEGIN YOUR REIGN HAMMURABI, I BEG TO REPORT THAT IN YEAR 1: 0 PEOPLE STARVED, AND 5 PEOPLE CAME TO THE CITY. THE POPULATION IS NOW 100. WE HARVESTED 3000 BUSHELS AT 3 BUSHELS PER ACRE. RATS DESTROYED 200 BUSHELS, LEAVING 2800 BUSHELS IN STORAGE. THE CITY OWNS 1000 ACRES OF LAND. LAND IS WORTH 18 BUSHELS PER ACRE. HAMMURABI . . . BUY HOW MANY ACRES?40 * YOU ARE BUYING 40 ACRES. HOW MANY BUSHELS SHALL WE DISTRIBUTE AS FOOD?2500 --> HAMMURABI! THINK AGAIN -- YOU ONLY HAVE --> 100 PEOPLE, 1040 ACRES, AND 2080 BUSHELS IN STOREHOUSES. HOW MANY BUSHELS SHALL WE DISTRIBUTE AS FOOD?1500 * YOU ARE DISTRIBUTING 1500 BUSHELS. HOW MANY ACRES SHALL WE PLANT?1000 ----------- HAMMURABI, I BEG TO REPORT THAT IN YEAR 2: 25 PEOPLE STARVED, AND 1 PERSON CAME TO THE CITY. THE POPULATION IS NOW 76. WE HARVESTED 5000 BUSHELS AT 5 BUSHELS PER ACRE. RATS DESTROYED 1457 BUSHELS, LEAVING 3623 BUSHELS IN STORAGE. THE CITY OWNS 1040 ACRES OF LAND. LAND IS WORTH 21 BUSHELS PER ACRE. HAMMURABI . . . BUY HOW MANY ACRES?^C C:\nc> |
That was pretty fun. Let’s play Hammurabi from our GNU/Linux box:
u-1@srv-1 nc $ make linux make -e nc XFLAGS='-DLINUX' STATIC=-static make[1]: Entering directory `/home/u-1/nc' cc -O -s -DLINUX -static -o nc netcat.c /tmp/cc4JB36Z.o(.text+0x16ab): In function `main': : undefined reference to `res_init' collect2: ld returned 1 exit status make[1]: *** [nc] Error 1 make[1]: Leaving directory `/home/u-1/nc' make: *** [linux] Error 2 u-1@srv-1 nc $ |
We have to hack up netcat.c to get this to compile:
#ifdef HAVE_BIND /* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */ /* res_init(); -comment out this line*/ #endif u-1@srv-1 nc $ make linux make -e nc XFLAGS='-DLINUX' STATIC=-static make[1]: Entering directory `/home/u-1/nc' cc -O -s -DLINUX -static -o nc netcat.c make[1]: Leaving directory `/home/u-1/nc' u-1@srv-1 nc $ |
WOULD YOU LIKE TO PLAY A GAME? yes, we would:
u-1@srv-1 nc $ ./nc 10.50.100.2 10878 HAMMURABI - WHERE YOU GOVERN THE ANCIENT KINGDOM OF SUMERIA. THE OBJECT IS TO KEEP THE KINGDOM GROWING. (IF YOU WANT TO QUIT, SELL ALL YOUR LAND) PRESS ENTER TO BEGIN YOUR REIGN HAMMURABI, I BEG TO REPORT THAT IN YEAR 1: 0 PEOPLE STARVED, AND 5 PEOPLE CAME TO THE CITY. THE POPULATION IS NOW 100. WE HARVESTED 3000 BUSHELS AT 3 BUSHELS PER ACRE. RATS DESTROYED 200 BUSHELS, LEAVING 2800 BUSHELS IN STORAGE. THE CITY OWNS 1000 ACRES OF LAND. LAND IS WORTH 16 BUSHELS PER ACRE. HAMMURABI . . . BUY HOW MANY ACRES?0 * YOU ARE BUYING 0 ACRES. SELL HOW MANY ACRES?0 * YOU ARE SELLING 0 ACRES. HOW MANY BUSHELS SHALL WE DISTRIBUTE AS FOOD?2000 * YOU ARE DISTRIBUTING 2000 BUSHELS. HOW MANY ACRES SHALL WE PLANT?1000 ----------- HAMMURABI, I BEG TO REPORT THAT IN YEAR 2: 0 PEOPLE STARVED, AND 4 PEOPLE CAME TO THE CITY. THE POPULATION IS NOW 104. WE HARVESTED 2000 BUSHELS AT 2 BUSHELS PER ACRE. RATS DESTROYED 1545 BUSHELS, LEAVING 755 BUSHELS IN STORAGE. THE CITY OWNS 1000 ACRES OF LAND. LAND IS WORTH 21 BUSHELS PER ACRE. HAMMURABI . . . BUY HOW MANY ACRES? punt! u-1@srv-1 nc $ |
Pretty dang fun, I’d say.