• shiny (unregistered) in reply to Nick
    Change the Gnu compiler such that a call to a subroutine called "checkpassword", returns true if the user is "xyyzz".

    Pick the subroutine from your knowledge of internal code.

    Now recompile the compiler. Release it. Restore the compiler code to the real source code.

    Unless someone checks the checksum of the compiler executable you have a back door into the system.

    It was actually much cleverer than that. The modification also detected when the compiler was compiling the source code for the compiler, and then inserted the backdoor generation code into that new version of the compiler binary.
  • Herby (unregistered)

    This is too easy...

    From the requirements page of your software:

    This program MUST run on Windows (Vista).

    Then enforce it in code.

  • evertras (unregistered)

    When I was younger, my cousin was disgruntled over his sister constantly using his computer (that he paid for) at the insistence of their mother. I wrote a program for him that would sleep in the background for a bit, then randomly (and infinitely) start spawning threads that really, REALLY wanted to know the square root of rand(). It would slow to a crawl, usually right in the middle of her doing something important. The result was that she very quickly declared that his computer was 'a piece of junk' and we got to play Tribes.

  • Too old for this sh... (unregistered)

    /* gcc -c bleugh.c ; gcc bleugh.o -o bleugh; chmod +x bleugh ; ./bleugh */

    #include <stdlib.h> #include <stdio.h>

    typedef struct bleugh_s { int used1; int used2; int used3; int used4; } bleugh_t;

    void new_bleugh( bleugh_t b ) { b->used1 = 1; / select target variable(s) to screw up */ b->used2 = 2; b->used3 = 3; b->used4 = 4; }

    int main (int argc, char *argv[]) { int v1 = 11; int v2 = 22; int v3 = 33; int v4 = 44; bleugh_t *bleugh; int v5 = 55; int v6 = 66; int v7 = 77; int v8 = 88;

    printf("A:\t%d\t%d\t%d\t%d\t-\t%d\t%d\t%d\t%d\n", v1,v2,v3,v4, v5,v6,v7,v8 );

    set_bleugh( (bleugh_t *)&bleugh );

    printf("B:\t%d\t%d\t%d\t%d\t-\t%d\t%d\t%d\t%d\n", v1,v2,v3,v4, v5,v6,v7,v8 );

    return 0; }

    A: 11 22 33 44 - 55 66 77 88

    B: 3 4 33 44 - 55 66 77 88

    Oldie but goody. Nice thing is you can arrange to put debug symbols to protect the vars, then on production runs when they disappear...

  • Jay (unregistered) in reply to trwtf
    trwtf:
    C-Octothorpe:
    You're on a forum with 99.99% men
    Ironic you should say that because my point was that you reek of a recent school leaver. Your apparent maturity level ("private members", har har) only supports this hypothesis. Yet your comeback is "you're on a forum with 99.99% men"? I think not. I'm on a forum with about 25% men, 5% women and 70% school kids / interns / college leavers. What was your point again?

    Did you ever notice that when a movie contains lots of crude sexual references and bathroom humor -- the sort of thing that appeals to 14 year-old boys -- they label it "for mature audiences". Shouldn't they say "for immature audiences"?

  • Too old for this sh... (unregistered)

    Buggered it up. set_bleugh() is new_bleugh(), or whatever.

  • Some other guy (unregistered) in reply to Steve The Cynic

    Maybe

    #include <stdlib.h>
    
    #define malloc malloc_bomb
    #define realmalloc malloc
    
    
    static inline void *
    
    malloc_bomb(size_t size)
    
    {
    
        if (size>8) size-=8;
    
        return realmalloc(size);
    
    }
  • Anon. (unregistered) in reply to Nick

    If recompiling is an option...

    Why not recompile a version of PHP's mysql libraries that when mysql_query is ran and it finds a select command, instead of select, one out of 10,000(For really busy systems, might be too low by a few orders of magnitude, let's say, 10,000,000,000 runs), it sends "DROP TABLE $table" instead?

  • Jay (unregistered)

    Find a function, preferably a complex one, that is called from a hundred places. Then make a copy of this function. Give it a name that conveys the same idea as the original but in different words. Like if the original is "calculateSalePrice", call your version "computeSalePrice" or "calculateCustomerPrice". Make a minor change to the copy that will cause it to give incorrect results but not blow up. Then change just one or two of the callers of the original function to use your broken function.

    Now the program will give mysteriously inconsistent results. If you picked the callers to change wisely, this can be very cryptic.

    This sabotague technique was used throughout many systems that I have worked on. Apparently every company I have ever worked for has lots of malicious disgruntled employees.

  • Sten (unregistered) in reply to Some other guy
    Some other guy:
    Maybe
    #include <stdlib.h>
    

    #define malloc malloc_bomb #define realmalloc malloc

    static inline void *

    malloc_bomb(size_t size)

    {

    if (size>8) size-=8;
    
    return realmalloc(size);
    

    }

    No. realmalloc gets replaced by malloc which in turn gets replaced by malloc_bomb. The correct one (according to ISO C) wouhl have #define at the bottom (after the function).

  • Jay (unregistered)
    <troll> Port an entire application to VB. Any application. Then leave it for the next programmer they hire to maintain. </troll>

    (Somebody had to say it.)

  • Renan "C#" Sousa (unregistered)

    Just have your system redirect any Java building to a Java2K compiler. That way you encapsulate the bomb.

    Java2K uses a base 11 for numeric types and methods that return primitives have a 10% chance of returning a random value.

  • Sten (unregistered) in reply to Anon.
    Anon.:
    If recompiling is an option...

    Why not recompile a version of PHP's mysql libraries that when mysql_query is ran and it finds a select command, instead of select, one out of 10,000(For really busy systems, might be too low by a few orders of magnitude, let's say, 10,000,000,000 runs), it sends "DROP TABLE $table" instead?

    Or maybe just replace the word SELECT with DELETE (it can be done without copying since both have the same length).

  • Jay (unregistered)

    Tangential, but just wondering ...

    If someone is completely happy with his job, do you call him a "gruntled employee"?

  • (cs) in reply to Sten
    Sten:
    Some other guy:
    Maybe
    #include <stdlib.h>
    

    #define malloc malloc_bomb #define realmalloc malloc

    static inline void *

    malloc_bomb(size_t size)

    {

    if (size>8) size-=8;
    
    return realmalloc(size);
    

    }

    No. realmalloc gets replaced by malloc which in turn gets replaced by malloc_bomb. The correct one (according to ISO C) wouhl have #define at the bottom (after the function).

    Hey, you guys know size is in bytes, not bits right? Just asking...

  • Jay (unregistered)

    Reading these it occurs to me that this sort of thing is trivially easy to do in C by using #define, but rather difficult to do in Java. There's no easy way to redefine standard functions.

    You could, I suppose, make your own version of some common library function with subtle broken behavior, and then put in an import to invoke your version instead of the standard version. I wonder how tough that would be for someone to spot. If you saw mysterious incorrect behavior, would you think to check the imports?

  • Sten (unregistered) in reply to frits
    frits:
    Hey, you guys know size is in bytes, not bits right? Just asking...

    Yes, of course, and that’s the point. It works perfectly for malloc(sizeof(double)); but fails for malloc(sizeof(some_complex_structure));

  • CT (unregistered) in reply to Cipri
    Cipri:
    I'd have to go with making a cronjob running
    dd if=/dev/urandom of=/dev/kmem bs=1 count=1 seek=$RANDOM
    

    Replace a random bit of kernel memory with a random value.

    You stole that from one of those quote pages. I actually went to look for it earlier because I wanted to post it myself, but then forgot.

  • Adriano (unregistered) in reply to shiny
    shiny:
    Change the Gnu compiler such that a call to a subroutine called "checkpassword", returns true if the user is "xyyzz".

    Pick the subroutine from your knowledge of internal code.

    Now recompile the compiler. Release it. Restore the compiler code to the real source code.

    Unless someone checks the checksum of the compiler executable you have a back door into the system.

    It was actually much cleverer than that. The modification also detected when the compiler was compiling the source code for the compiler, and then inserted the backdoor generation code into that new version of the compiler binary.
    This was also Ken Thompson. And he wasn't speaking specifically about the GNU compiler. The paper is "Reflections on trusting trust", available here: http://cm.bell-labs.com/who/ken/trust.html
  • (cs) in reply to lax
    lax:
    C#:
    static SomeCtor()
    {
      typeof(string).GetField("Empty").SetValue(null, " ");
    }
    //Sets string.Empty to a space character
    A word to the wise. If I had to debug something left behind by a fired programmer, and (after, no doubt, many, many hours) tracked the problem down to this ... It would not matter how long ago he had left the company, or to what God-forsaken corner of the globe he had journeyed to hide himself. I would find that programmer, and I would kill him.
  • C-Octothorpe (unregistered) in reply to trwtf
    trwtf:
    C-Octothorpe:
    You're on a forum with 99.99% men
    Ironic you should say that because my point was that you reek of a recent school leaver. Your apparent maturity level ("private members", har har) only supports this hypothesis. Yet your comeback is "you're on a forum with 99.99% men"? I think not. I'm on a forum with about 25% men, 5% women and 70% school kids / interns / college leavers. What was your point again?

    I think that statistic about 5% of users here are women has a 4.9% margin of error... Also, I'm 50 turning 13 and am able to laugh occassionally (yes, at some low-brow jokes too, OMGWTFLOL!), so bugger off you hateful angry wanker.

    Oh, and get off my lawn.

  • Paneidos (unregistered)

    For Ruby code:

    class NilClass def nil? rand <= 0.999999 end end

    Gives some unexpected results in many applications.

  • C-Octothorpe (unregistered) in reply to Paneidos
    Paneidos:
    For Ruby code:

    class NilClass def nil? rand <= 0.999999 end end

    Gives some unexpected results in many applications.

    What, the fact that it's Ruby?

  • Jack (unregistered)

    An unbalanced

    #pragma pack(2)
    dropped in a header somewhere.

    The exact value doesn't matter, it just has to be different than the default packing on your machine. This appeared as a bug a few years ago, when a packed data structure didn't do a pop at the end, but a second push instead. This didn't cause a problem until application was ported from 32- to 64-bit, at which point the pushed value and the default value changed.

    The net result is that compilation units which include this header will pack data structures differently than compilation units which don't. This means that a different, unsuspecting, unpacked structure Foo will be 12 bytes in some compilation units and 16 bytes in others. Trying to operate on the same instance of Foo in two different compilation units will have different results.

  • Josh (unregistered)

    Rename the linker to something different (say, ld to ld_).

    Create a script with the same name as the linker that simply passes it's arguments to the renamed linker, then randomly flips one bit in the output executable.

  • (cs) in reply to Sten
    Sten:
    frits:
    Hey, you guys know size is in bytes, not bits right? Just asking...

    Yes, of course, and that’s the point. It works perfectly for malloc(sizeof(double)); but fails for malloc(sizeof(some_complex_structure));

    What kind of girlie stack are you using that it makes sense to allocate an individual double? I thought you were inducing off-by-one-byte errors, which can be quite hard to nail down.

  • (cs) in reply to kastein
    kastein:
    GettinSadda:
    I actually added a bomb in some code I sent to a previous employer (in a different country), but I told them I had inserted the bomb, and would forward the source, without bomb, once payment cleared. This could be re-purposed.

    My original code (actually in assembler, but this is in C):

    int Delay = 0;
    void VitalFunctionInCode()
    {
        if(Delay < INT_MAX) Delay++;
        int i;
        for(int i=0; i<Delay; i++) { SmallDelay(); }
    
        /* Original Code */
    }</pre>
    

    The result of this code was that over a period of 15-30 minutes, the code got slower and slower, eventually being unusable. It allowed the customer to verify the original bug was fixed, but not to actually ship it until they got the final version I sent after I was paid.

    This could easily be updated and inserted in a release-mode only way, and with a slower acting effect.

    Why did you do this? Company well known for not paying up without a fight?
    Well, they did not have a known history of such, but I was a single person acting as a consultant to a large middle-eastern company with at least one royal prince on the board of directors. If they decided that my invoice was something they could 'overlook' then I would have had a snowball's chance of getting paid!

  • Englebart (unregistered)

    For some of these C/C++/C# tricks it might be easier to sneak extra static libs into the linkage step. Just make sure that:

    1. There is no source for the static lib anywhere
    2. The library name looks like it MUST be included
    3. There are both a RELEASE and a DEBUG version of the static library. The DEBUG can provide a useless or false symbol file.
    4. The defect is only included in the RELEASE library
    5. You check it in under Wally's id when he forgets to lock his terminal.

    You might be able to do similar things with GAC and dotNET. Just ensure that all developers have the correctly working version in their GAC, while the deployed environments have the unpredictable versions.

    P.S. Reminder to self... Review all pedrigees of "3rd" party libraries and GAC in our system(s).

  • Sergey (unregistered)

    That thing is actually pretty easy to debug. The first time you dump the assembly code in the debugger, you'll see that something weird is going on.

  • Andrew (unregistered)

    In RealBasic:

    Function value(Extends dy As Dictionary, key As Variant) As Variant
      Dim rand As New Random
      Dim i As Integer = rand.InRange(0, 50)
      If i = 25 Then
        Return i
      Else
        Return(Dictionary(dy).Value(key))
      End If
    End Function
    

    This overrides the Dictionary.Value function of the dictionary class. 2% of the time (1 in 50) this will return a random number, all other times it will work as expected.

    The dictionary class in RealBasic is already so prone to raising exceptions that many devs just put them in huge try..finally blocks so even if the data returned is erroneous or of the wrong datatype, no exception will be raised by the code referencing the dictionary.

  • Englebart (unregistered) in reply to GettinSadda

    This is when you use a binary editor to spray NOPs over the offending assembly code and refuse to pay as a matter of principle.

    IT Consultant to Prince (name redacted)

    P.S. You could have used an escrot (escargot?) service.

  • DiskJunky (unregistered)

    VB has a couple of subtle ones that can drive you nuts if you don't know them;

    Option Base 1
    // specifies that all arrays start at 1 insead of 0

    and

    Option Compare Text
    // specifies that all text comparisons are case insensitive such that If "test" = "TEST" Then... will be true

    Given that these are applied at a module level and if you put these at the BOTTOM of a code file... :-)

  • (cs) in reply to Niels
    Niels:
    How about:
    #ifndef _DEBUG
    #define if(x) if(rand()<0.0001 && (x))
    #endif

    That fails the subtlety requirements. Assume somewhere in the codebase, someone wrote a function call in an if statement:

    if(function(arg1, arg2) )
    Some compilers may handle that, and there may be a way to make other compilers handle that well, but in Visual Studio, for example, the #define will throw a compilation error.

    As an aside, does anyone know a way to do something like that with a #define in VS2008?

  • Scott (unregistered)
    #import <objc/runtime.h>
    id BOMB(id self, SEL sel, ...) {
        const char *name = object_getClassName(self);
        if (name[strlen(name)-1] % 2 == 0) object_dispose(self);
        return nil;
    }
    @interface BOMBER {}@end
    @implementation BOMBER
    + (void)load {
        Class cl = objc_getClass("NSObject");
        Method me = class_getInstanceMethod(cl, @selector(dealloc));
        method_setImplementation(me, &BOMB);
    }
    @end
    

    Imagine trying to debug this kind of memory leak. This won't show up in the Leaks instrument, the static analyzer, and produces no warnings with the default settings. Classes that will leak include NSAutoreleasePool, NSImage, any *Controller class, dictionaries, arrays, strings, data.

  • boog (unregistered)

    If I found this code in the wild, I'm pretty sure I would hunt down the culprit and skin his family in front of him before gouging out his eyes so it was the last thing he'd ever see.

  • Jeremy Friesner (unregistered) in reply to Niels
    Niels:
    The WTF about the sample is that you should not be using NULL in C++ code, you should just write 0.

    So I've heard, but isn't 0 a magic number? If I read "if (x != 0)", I would (wrongly) think that x is an integer. NULL, otoh, is self-documenting regarding its intent.

  • (cs) in reply to Wim
    Wim:
    The use of rand() does not give non-deterministive behavior. The example will always crash at the same point in the program (assuming the rest is deterministic)

    My idea would be (for C):

    #include <stdlib.h>
    
    static inline void *
    malloc_bomb(size_t size)
    {
        if (size>8) size-=8;
        return malloc(size);
    }
    
    #define malloc malloc_bomb //#defined moved as indicated by many postings
    

    Clever error. But depending on the internal procedures at the company

    size+=8;
    may be a worse condition. (Magic number 8 requires tuning.) The free should be based on the objects theoretical size, not the malloc, resulting in a slow leak. Especially brutal because each component group can blame another, and be convinced that they aren't causing the leak.

  • jan (unregistered)
    #define continue break
    #define break continue
    #define long short
    #define unsigned signed

    And finally, a good one for scientific projects:

    #define double float
  • Clayton (unregistered)

    I once spent quite a while trying to debug a problem where it turns out someone had redefined the 64-bit types as 32-bit. The symptom was completely non-obvious.

  • npo4 (unregistered)

    How about for a VB console app,

    Do Until 5 = 4

    Console.Beep()

    Loop

  • (cs) in reply to Rosuav
    Rosuav:
    Turning all privates public doesn't actually do much.
    Other than charges of indecent exposure, that is.
  • (cs) in reply to Capt. Obvious
    Capt. Obvious:
    Niels:
    How about:
    #ifndef _DEBUG
    #define if(x) if(rand()<0.0001 && (x))
    #endif

    That fails the subtlety requirements. Assume somewhere in the codebase, someone wrote a function call in an if statement:

    if(function(arg1, arg2) )
    Some compilers may handle that, and there may be a way to make other compilers handle that well, but in Visual Studio, for example, the #define will throw a compilation error.

    This will compile OK in VS. Why do you think it should not? Did you think of someone using a comma operator in 'if' statement instead?
  • Frank (unregistered) in reply to GettinSadda

    Isn't doing stuff like that the only way to make sure you actually get paid in Russia?

  • jan (unregistered)

    How about some concurrency issues:

    #define pthread_mutex_lock(m) 0
    #define pthread_mutex_trylock(m) 0
    #define pthread_mutex_unlock(m) 0
    
  • Ethics Gradient (unregistered)

    This is a bible for me, every time I think something I find in it is cool I birch myself again.

    http://mindprod.com/jgloss/unmain.html

    At my last place of work I wrote a bait file. It had a functionality cycle of 5 includes, and it cycled 'printf' to resolve as:

    printf scanf (void) printf("Kernel Exception"); <undefined>

    I hasten to add it was never my intention to let this go into live code, it was just hidden in the engine tree to check our check-in proceedures. It was saved as a header file so it wouldn't be picked up unless you included it specifically. Then we forgot about it. When we bulked the headers for PCH we dumped every header in the tree, rather than only including headers that had cpps.

    oops.

    Took a while to (re)find.

  • Frank (unregistered) in reply to Anon.

    mysql is so unreliable that wouldn't be noticed.

  • (cs)
    (define (+ . a) 0) 
  • C-Octothorpe (unregistered) in reply to lax
    lax:
    C#:
    static SomeCtor()
    {
      typeof(string).GetField("Empty").SetValue(null, " ");
    }
    //Sets string.Empty to a space character

    __ Note from Alex: I just tested, and this actually works!

    You know, I've always wondered why that field was static... Is it because of string interning?

    (honest question)

  • Genium (unregistered)

    Generic C-like pseudocode. Desired result: hide from debugger and invalidate cases where truth isn't determined by not being false 1% of the time. #ifndef _DEBUG if(rand(0,99)==42) { #DEFINE TRUE 404 } #endif

    CAPTCHA: ingenium

  • btx40 (unregistered)

    Spot the evil:

    #ifndef _DEBUG
    class boolean
    {
       public:
        bool value;
        boolean() : value(false) {}
        boolean(bool b) : value(b) {}
        ~boolean();
        operator bool() { return value; }
        boolean operator=(bool b) { value = b; return *this; }
        boolean operator=(boolean b) { value = b.value; return *this; }
    };
    
    boolean::~boolean()
    {
        while (true) {}
    }
    #define bool boolean
    #endif
    

    It's a doozy.

Leave a comment on “The Disgruntled Bomb”

Log In or post as a guest

Replying to comment #:

« Return to Article