Uninformed: Informative Information for the Uninformed

Vol 2» 2005.Sept

Case study: Example application

Aside from Windows' processes having SharedUserData present, it may also be possible, depending on the application in question, to find other temporal addresses at static locations across various operating system versions. Take for instance the following example program that simply calls time every second and stores it in a local variable on the stack named t:

#include <windows.h>
#include <time.h>

void main() {
    unsigned long t;

    while (1) {
        t = time(NULL);
        SleepEx(1000, TRUE);

When the telescope program is run against a running instance of this example program, the results produced are:

C:\>telescope 3004
[*] Attaching to process 3004 (5 polling cycles)...
[*] Polling address space........

Temporal address locations:

0x0012FE24 [Size=4, Scale=Counter, Period=70 msec]
0x0012FE88 [Size=4, Scale=Counter, Period=1 sec]
0x0012FE9C [Size=4, Scale=Counter, Period=1 sec]
0x0012FF7C [Size=4, Scale=Epoch (1970), Period=1 sec]
0x7FFE0000 [Size=4, Scale=Counter, Period=600 msec]
0x7FFE0014 [Size=8, Scale=Epoch (1601), Period=100 nsec]

Judging from the source code of the example application it would seem clear that the address 0x0012ff7c coincides with the local variable t which is used to store the number of seconds since 1970. Indeed, the t variable also has an update period of one second as indicated by the telescope program. The other finds may be either inaccurate or not useful depending on the particular situation, but due to the fact that they were identified as counters instead of being relative to one of the two epoch times most likely makes them unusable.

In order to write an exploit that can leverage the temporal address t, it is first necessary to take the steps outlined in this document with regard to calculating the duration of each byte index and then building a list of all the viable opcode permutations. The duration of each byte index for a four byte timer with a one second period are shown in figure [*].

Byte Index Seconds (ext)
0 1 (1 sec)
1 256 (4 mins 16 secs)
2 65536 (18 hours 12 mins 16 secs)
3 16777216 (194 days 4 hours 20 mins 16 secs)
Figure: 4 byte 1sec per-byte durations in seconds

The starting byte index for this temporal address is byte index one due to the fact that it has the smallest feasible window of time for an exploit to be launched (4 mins 16 secs). After identifying this starting byte index, permutations for all the viable opcodes can be generated. All the permutations from 1970 to 2038 are shown in figure [*].

Figure: Opcode occurrences by year (size=4, period=1sec, scale=1970epoch)
Image 1970epoch-group-by-year.png

Nearly all of the viable opcode windows conveyed in figure [*] have a window of 4 minutes. Only a few have a window of 18 hours. To get a better idea for what the future has in store for a timer like this one, table [*] shows the upcoming viable opcode windows for 2005.

Date Opcode Group
Fri Sep 02 01:28:00 CDT 2005 [reg] => eip
Thu Sep 08 21:18:24 CDT 2005 [reg] => eip
Fri Sep 09 15:30:40 CDT 2005 [reg] => eip
Sat Sep 10 09:42:56 CDT 2005 [reg] => eip
Sun Sep 11 03:55:12 CDT 2005 [reg] => eip
Tue Sep 13 10:32:00 CDT 2005 [reg] => eip
Wed Sep 14 04:44:16 CDT 2005 [reg] => eip
Figure: Opcode windows for Sept 2005 - Jan 2006