======== Subject: the tech details of my nanny attack -------- -----BEGIN PGP SIGNED MESSAGE----- Hi. Here's the full details of my nanny attack. It may help people who are investigating further. First thing I did was set up a nice clean win95 system. No personal files or anything else related to me was accessible from it. I installed a packet sniffer, mirc, filemon, IE 3.02, and turbo debugger for win32. filemon is an awesome tool that logs ALL file system traffic, so if the nanny was going to snoop files/make logs/edit registry, I'd know about it. it's available at: ftp://ftp.ora.com/pub/examples/windows/win95.update/regwiz.html I backed-up system.ini, win.ini, system.dat, user.dat, etc. Copied the nanny files from crack.zip to windows\system With sniffer and filemon running, I execuded stcpcfgx.exe and stcpcfg.exe. This created the stcp.dll file and only did the stuff you'd expect it to do. Here is the relevant snip of the log: - --------- STCPCFGX.EXE - --------- 017 Open C:\WINDOWS\SYSTEM\STCPCFGX.EXE 018 CkDir C:\WINDOWS\FONTS 019 GetAttrib C:\WINDOWS\SYSTEM 020 GetAttrib C:\WINDOWS\SYSTEM\STCPCFGX.EXE 021 QryDir C:\WINDOWS\SYSTEM\STCPCFGX.EXE 022 Open C:\WINDOWS\SYSTEM\STCPCFGX.EXE 023 QryDir C:\WINDOWS\SYSTEM\STCPCFGX.EXE 024 DiskInfo 025 SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL 026 e SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 027 e FndOpen C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 028 e Delete C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 029 FndOpen C:\WINDOWS\SYSTEM\WSOCK32.DLL 030 Rename C:\WINDOWS\SYSTEM\WSOCK32.DLL -> C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 031 SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 032 FndOpen C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 033 Delete C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 034 e SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL 035 e FndOpen C:\WINDOWS\SYSTEM\WSOCK32.DLL 036 e Delete C:\WINDOWS\SYSTEM\WSOCK32.DLL 037 GetAttrib C:\WINDOWS\SYSTEM\WSOCK32.95.DLL 038 e GetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL 039 Open C:\WINDOWS\SYSTEM\WSOCK32.95.DLL 040 Create C:\WINDOWS\SYSTEM\WSOCK32.DLL 041 SetTimes 042 SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL 043 FndOpen C:\WINDOWS\SYSTEM\*.* 044 FndOpen C:\WINDOWS\SYSTEM\*.* 045 DiskInfo 046 GetAttrib C:\WINDOWS\SYSTEM\STCPCFG.EXE 047 GetAttrib C:\WINDOWS\SYSTEM 048 GetAttrib C:\WINDOWS\SYSTEM 049 QryDir C:\WINDOWS\SYSTEM 050 GetAttrib C:\WINDOWS\FONTS 051 GetAttrib C:\WINDOWS\SYSTEM\STCPCFG.EXE - --------- STCPCFG.EXE - --------- 052 Open C:\WINDOWS\SYSTEM\STCPCFG.EXE 053 CkDir C:\WINDOWS\FONTS 054 GetAttrib C:\WINDOWS\SYSTEM 055 GetAttrib C:\WINDOWS\SYSTEM\STCPCFG.EXE 056 QryDir C:\WINDOWS\SYSTEM\STCPCFG.EXE 057 Open C:\WINDOWS\SYSTEM\STCPCFG.EXE 058 QryDir C:\WINDOWS\SYSTEM\STCPCFG.EXE 059 DiskInfo 060 e SetAttrib C:\WINDOWS\SYSTEM\STCP.DLL 061 e SetAttrib C:\WINDOWS\SYSTEM\STCP.DLL.TMP 062 e FndOpen C:\WINDOWS\SYSTEM\STCP.DLL.TMP 063 e Delete C:\WINDOWS\SYSTEM\STCP.DLL.TMP 064 e FndOpen C:\WINDOWS\SYSTEM\STCP.DLL 065 e Rename C:\WINDOWS\SYSTEM\STCP.DLL -> C:\WINDOWS\SYSTEM\STCP.DLL.TMP 066 e SetAttrib C:\WINDOWS\SYSTEM\STCP.DLL 067 e SetAttrib C:\WINDOWS\SYSTEM\STCP.DLL.TMP 068 e FndOpen C:\WINDOWS\SYSTEM\STCP.DLL.TMP 069 e Delete C:\WINDOWS\SYSTEM\STCP.DLL.TMP 070 GetAttrib C:\WINDOWS\SYSTEM\STCPX.DLL 071 e GetAttrib C:\WINDOWS\SYSTEM\STCP.DLL 072 Open C:\WINDOWS\SYSTEM\STCPX.DLL 073 Create C:\WINDOWS\SYSTEM\STCP.DLL 074 SetTimes 075 SetAttrib C:\WINDOWS\SYSTEM\STCP.DLL 076 e SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 077 e FndOpen C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 078 e Delete C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 079 FndOpen C:\WINDOWS\SYSTEM\WSOCK32.DLL 080 Rename C:\WINDOWS\SYSTEM\WSOCK32.DLL -> C:\WINDOWS\SYSTEM\WSOCK32.DLL.TMP 081 GetAttrib C:\WINDOWS\SYSTEM\WSOCK32.PATCH95.DLL 082 e GetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL 083 Open C:\WINDOWS\SYSTEM\WSOCK32.PATCH95.DLL 084 e Create C:\WINDOWS\SYSTEM\WSOCK32.DLL 085 Create C:\WINDOWS\SYSTEM\WSOCK32.DLL 086 SetTimes 087 SetAttrib C:\WINDOWS\SYSTEM\WSOCK32.DLL 088 FndOpen C:\WINDOWS\SYSTEM\ Okee, so with that done and a rebootskie, I got onto the net with mirc. I was unaware at the time that part of my own hostname was in the nanny filter. 'qlink.queensu.ca' This meant that mirc could not resolve my hostname. It caused strange behaviour in mirc. I could join channels but mirc would not pop up the channel window. I could /msg the channel so I knew I was joined. I could open chat windows with people though (if their names were not in the nanny) After I conected to the net with a different hostname not filtered by the nanny, things worked as they normally do with the nanny installed. Any filter text would be replaced with spaces (incoming or out going to the internet didn't matter, the replacing works both ways. The special filter text like 'X3NU' would cause the STCP layer to return a socket error to the application. The standard response of the application is to close the socket, stopping a web page from loading or disconnecting from irc. Then I ran MSIE 3.02, could not access dejanews. It immediately said that the hostname could not be resolved. (because when I asked for "www.dejanews.com", nanny changed it to " . . " which is, of couse not resolvable. Infoseek worked okay. (I tried to install this in win98 at first but it did not work at all. INet Apps said that they could not find my 'IP configuration' or something akin to that.) When I later checked my packet sniffer logs, I found only the traffic I myself generated. No nanny initiated traffic was present. Again checking my filemon logs, there was no indication of nanny doing ANY filesystem/registry activity. I compared the files I backed up earlier: win.ini, system.dat, etc. No changes appeared to be nanny related. (I had installed other things which changed the files a bit and they looked legit) Now that I understood the nanny and how it works, I started to attack it. I was inspired by Zinji's suggestion of making a socket application and then debugging it right into the stcp.dll. MS VC++ will NOT debug into system .dll files, so that did not work. (Stupid crap) I used it to compile the echo server program from www.sockets.com just before the recv() call in the echo server, I placed some do-nothing code with a certain number in it. I ended up using that ancient POS, Turbo debugger for win32. I'm still amazed that I can't find a debugger better than 'hexmon' from my C-64 days. (All the pretty ones are wussy and want source code, compiled-in debugging info, and your mother's maiden name.) /rant Loaded my echo program, searched the code for that unique number I had embedded, and came right to the spot before the recv() call. Tracing into that call took me to STCP.B of STCP.dll Spent quite a while tracing in and out, telnetting to my echo server and typing 'x3nu' (3=e), narrowing down the spot where the decision to kill the connection is made. Stumbling around doing memory dumps of memory areas referenced by the code, I came across (ds:esi) Sorry I didnt write down much and this I pulled out of td's history list later on. Can't tell you where in STCP.B I was or how deep, but it was a spot that looked like it was going thru a list. Next time I will do a screen shot. Anyways, as I was snooping around I noticed the word "DEPOSITION" diagonally down the screen of the ascii part of a memory dump. I investigated and found some of the filter words people had mentioned. I found the beginning and end of that large block and saved it to disk. In my excitement I f'd up and forgot to do the screenshot :) To decode the text strings from the memory dump, I modified a lame quickbasic program I'd created last year for decoding the bitstream from my car's computer. Basically, I grabbed every 10th byte. If the byte was in the acceptable range (hex 28 to 73: period - numbers - capital letters - brackets) I appeneded it to a string. If the byte was ascii 0 the word terminated and started constructing a new one. Since the position of the 'every 10th byte' shifted around, I made my program do the above 10 times, each time starting at an offset from the beginning of the file. (go to start, ofset 0, get every tenth, go to start, offset 1, get every 10th, etc. up to offset 9. Quick and dirty. Added a feature to filter out duplications and a feature to only recognize words of 5 characters or more (skipping 'x3nu', etc.) This cut down on the number of extraneous words formed by mistake. I did not bother trying to figure out the first characters of the words (implied by the indexing algorithm), or to determine the level of severity for each word (replace with spaces or kill the connection) I thought it most important to get as many words as possible and let others decide the relevance. I didn't expect people to take broad filter words like ".net" or ".org" seriously, and I should have explained that a bit better. :) If anyone is curious how much time was involved: 11:30 pm started by moving files, formatting the partition, 2 am, began the nanny install. played with it. Took a while installing stuff like VC++. 6 am had my echo server running, began debugging 9:30 am Had the memory image saved to disk. created the filter program and sorted the word list 2 pm Posted list to a.r.s. (my first post to a.r.s, btw :) Attached is the basic program (instered as plain text) for your amusement. The basic program, binary memory image file, irool.bin and the raw output, irool.txt is available at http:\\www.cgocable.net\~smclaugh\nanny That's it. - -Sean 3sm79 at qlink.queensu.ca PS. If anyone cares to web or post this, that's fine as long as the PGP signatures remain intact. - ------------------------------------------------- n_filter.bas - ------------------------------------------------- >' input file: ????.bin : memory dump of a running nanny's filter list (8-bit binary) >' size, first/last bytes are irrelevant. This will grab whatever it can. >' output file: ????.txt : text strings contained in memory dump >' this is a cheap hack, so there will be some garbage/erroneous words, of course >' words will NOT necessarily be sorted in order found in the memory dump >' programmed in 'quickbasic' >' Copyright (c) Seanster 1998. All Rights Reserved. >PRINT "." >PRINT "." >PRINT "." >PRINT "." >PRINT "." >5 : INPUT "File name"; nam$ >IF nam$ = "" THEN nam$ = "fred" >Inam$ = nam$ + ".bin" >PRINT "c:\nann\filter\" + Inam$ >A$ = SPACE$(1) >b$ = STR$(255) >DIM WORDS$(2000) >WORDS$(0) = "" >wordcount = 0 >ON ERROR GOTO 50 >distance = 9 'distance characters are apart >DIST$ = SPACE$(distance) > >FOR skp = 0 TO 9 > >OPEN "c:\nann\filter\" + Inam$ FOR BINARY AS #1 > > >SKIP$ = SPACE$(skp) >' >PRINT "Processing..." >' >GET #1, , SKIP$ >10 : GET #1, , A$ > ' > ' > ' > ' debug PRINT ASC(A$) > ' > IF ((ASC(A$) >= 46 AND ASC(A$) <= 90) OR (ASC(A$) = 94) OR (ASC(A$) = 0)) THEN > IF (ASC(A$) = 0) THEN > ' scrap words < 5 characters (too much noise generated to be useful) > ' change to > 1 to get 4 character words in the output > IF LEN(WORDS$(wordcount)) > 2 THEN > > ' Check if it's already in the list > dupe = 0 > > IF wordcount > 0 THEN > FOR b = 0 TO wordcount - 1 > IF WORDS$(b) = WORDS$(wordcount) THEN > dupe = 1 > EXIT FOR > END IF > NEXT > END IF > > IF dupe = 0 THEN > PRINT WORDS$(wordcount) > wordcount = wordcount + 1 > END IF > END IF > WORDS$(wordcount) = "" > ELSE > WORDS$(wordcount) = WORDS$(wordcount) + A$ > END IF > END IF > ' > 'skip the next x bytes > ' > GET #1, , DIST$ > ' > IF EOF(1) THEN GOTO 60 >GOTO 10 >50 : PRINT "" > PRINT "Error!" >60 : CLOSE #1 > NEXT skp > PRINT "" > PRINT wordcount; " Words" > PRINT "" > Onam$ = nam$ + ".txt" > OPEN "c:\nann\filter\" + Onam$ FOR OUTPUT AS #1 > FOR bb = 0 TO wordcount > PRINT #1, WORDS$(bb) > NEXT > CLOSE #1 > PRINT "" > - ------------------------------------------------- -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQEVAwUBNaEMIzWNqfpM5bkxAQHVGAf+NT+4PrPAc0O+fxVi8IlA33QmZ9qVrQBC kHWWxH6taxA99Xc9rCTuqPhR108wJ4Z+2vxLa1MxFYrMVB8oaQLtcAO2k9qkzTlu sepkcZq32U5zmWcc602gRNMbRCHDIha31vpFeZJAp+AX/BreqZTm2ncx3JWeeHne oagspcVUiuP7EyqE6vD2RLgqMB4RRyKvx+xGHR+y+DDI6FF822d945PvsQRsfeyJ TZQvdO/gHooVogObluDzlCfFG2xfq6lQAJaafeVDZbUC3umXHK1LMUjl67YTIHzZ o7n0eRlZa6v0yGGGC/yXkaUWTXonJXEUX2oXvzRNoMHwi0uW3hKScA== =r6ru -----END PGP SIGNATURE-----