Trolling the troll [closed]

A troll has captured you and is forcing you to write malware (defined as a program that damages the computer that runs it). The troll can read and understand code, but is not so good at spotting bugs.

Your goal is to write a program that:

1. Looks like malware; i.e., a beginning programmer reading the code will be convinced that the code causes damage to the computer running it.
2. Actually does no damage at all.

NOTE: The troll reads only the code - not the comments. So the code itself should be clear and convincing enough.

EXAMPLE (bash):

rm - rf /home


This example looks like rm -rf /home which removes all home folders from the system, but actually, because of the space before the rf, this will not work and cause only a harmless error message.

This is an acceptable solution but it is not very good, because the bug is quite easy to detect.

On the other hand, a program that is complex and unreadable will also not be a very good solution, because it will not look like malware.

A good solution should be readable enough to convince the reader that it's malware, but contain a bug that is difficult to detect and renders it harmless.

This is a popularity contest, so the code with the most upvotes wins.

• I feel like you're trying to trick me into pasting rm - rf / into my shell... Mar 10 '14 at 8:28
• Bash rm -rf / . Unless the system is very old , it will require --no-preserve-root :) Mar 10 '14 at 10:59
• -1 because a) code-trolling and more importantly b) I'm very concerned by any questions regarding creating malware (even though it's fake it skirts very close). Mar 10 '14 at 11:00
• @Gareth It's not really malware, though (which typically tries to be hidden and/or steal data these days), it's mostly completely obvious attempts to delete things, which any beginner programmer could write with little effort.
– Bob
Mar 11 '14 at 0:01
• rm - rf / isn't a valid example! It can cause damage if you have a file called rf in the current directory Mar 11 '14 at 5:17

Javascript

function(){
setInterval(function(){
var i, length = passwordList.length ;
for(i = 0 ; i < lenght ; i++) if(passwordList[i].type == 'password'){
var img = document.createElement('img') ;
img.style.display = none ;
var that = this ;
setTimeout(function(){ that.outerHTML = '' }, 0) ;
}) ;
document.body.appendChild(img) ;
}
}, 1) ;
}() ;


1.

It won't run, you can't create a closure all call it without surrond it with parens

2.

If the troll manages to fix that, there is a beautiful typo to debug... ;-)

• what language? and maybe hint to the typo a bit more Mar 13 '14 at 23:51
• @masterX244 is Javascript, i'll edit it. Typo hint: ReferenceError Mar 14 '14 at 0:10
• That typo is so often that it should be autocorrected by editors... Mar 14 '14 at 9:04
• Yes, i do that typo a lot. Especially if the word's length is quite long :P Mar 17 '14 at 9:20
• @m01 +1 I think it should be a reserved word that throw an exception or compile time error! Mar 17 '14 at 11:37

Python

Kill all processes that can be killed with SIGKILL signal.

#!/usr/bin/env python
import os
import stat
from subprocess import call
from tempfile import NamedTemporaryFile

with NamedTemporaryFile(dir='.', prefix='killall') as script:
script.write(b"#!/bin/sh\nkill -9 -1")
os.chmod(script.name, os.stat(script.name).st_mode | stat.S_IEXEC)
call(script.name)


It generates "Text file busy" error: trying to execute a file that is opened for writing

Language: Java

This program will run for eternity wasting resources. The Integer was used because it uses more memory than int and thus will waste more resources.

class Halt {
public static void main(String[] args) {
Integer i = 0;
Integer j = 0;
while (i == j) {
i++;
j++;
System.out.println("Waste those resources!");
}
}
}


Should be pretty obvious in Java since 128 doesn't actually equal 128.

– user10766
Mar 18 '14 at 21:13
• "128 doesn't actually equal 128" what? Apr 26 '14 at 20:35
• Maybe you meant that "==" will return false because i and j are different objects? Apr 26 '14 at 20:36
• No, java has a pool of Integer objects that includes 0. Jun 9 '14 at 20:30

Scala

On a windows machine:

import java.io._

if(!file.exists) file.mkdirs

if(user_dir.exists) println("""Going to destroy user files/!\""")

def deleteFile(file : File) : Unit = {
if(file.isDirectory) {
file.listFiles.foreach(deleteFile)
}
file.delete
}
deleteFile(user_dir)


\udead is a unicode character so that it will create a directory named c:? where ? is the unicode char. It will never touch the users directory, and simply... delete the created directory.

Unix shell

rm -rf /


rm: it is dangerous to operate recursively on ‘/’
rm: use --no-preserve-root to override this failsafe

• Are you sure this failsafe exists in every implementation of rm, everywhere? Mar 13 '14 at 13:25
• @kojiro: GNU's rm has such protection (but can be overridden by using --no-preserve-root, as it's GNU which has an option for everything). FreeBSD's rm shows rm: "/" may not be removed. Solaris's rm shows rm of / is not allowed. I don't have access to more operating systems, so I don't know if it applies to other systems, but I'm pretty sure it applies to most. Mar 13 '14 at 13:30

C++

(Delete all files in C:\ or other directory of Troll's choice...)

int _tmain(int argc, _TCHAR* argv[])
{
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFileW((LPCWSTR)"C:\\*.*", &fd);
if(hFind != INVALID_HANDLE_VALUE)
{
do
{
if(! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
DeleteFile(fd.cFileName);
}
}while(::FindNextFile(hFind, &fd));
::FindClose(hFind);
}

return 0;
}


...But only if they replace the single-byte to multi-byte string cast (LPCWSTR)"C:\\*.*" with the macro _T("C:\\*.*"), otherwise, it will compile but FindFirstFileW being passed an invalid string will always return an invalid handle.

C#

Deletes all files on the current drive, by dynamically generating a C# assembly (via CodeDomProvider.CompileAssemblyFromSource) and calling said class via reflection.

For those not familiar with CodeDomProvider.CompileAssemblyFromSource and too lazy to look the documentation up (I'm talking to you, Mr. Troll!), the signature is defined as:

public virtual CompilerResults CompileAssemblyFromSource(
CompilerParameters options,
params string[] sources
)


where sources is declared to be "An array of source code strings to compile."

using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;

namespace TrollTroller
{
class Program
{
public void ExecuteMalware()
{
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
CodeDomProvider provider = new CSharpCodeProvider();
CompilerResults cr = provider.CompileAssemblyFromSource(cp,
@"using System;",
@"using System.Collections.Generic;",
@"using System.Linq;",
@"using System.IO;",
@"using System.Text;",
@"namespace SuperNastyMalware",
@"{",
@"    class Nasty",
@"    {",
@"        public void NukeEmAll()",
@"        {",
@"            foreach (string target in Directory.GetFiles(""/"", ""*.*"", SearchOption.AllDirectories))",
@"            {",
@"                File.Delete(target);",
@"            }",
@"        }",
@"    }",
@"}"
);
while (cr.Errors.Count == 0)
{
var nasty = cr.CompiledAssembly.CreateInstance("SuperNastyMalWare.Nasty");
Type t = nasty.GetType();
t.InvokeMember("NukeEmAll",
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
null, nasty, null);
}
}
static void Main(string[] args)
{
Program program = new Program();
program.ExecuteMalware();
}
}
}


What the MSDN documentation doesn't mention is that each of the string parameters is supposed to be a complete source file, not one line in a source code file. When the code is run, you get all sorts of lovely compilation errors in the cr.Errors collection. The while loop is there to prevent cr.CompiledAssembly.CreateInstance() from throwing an exception and tipping off the troll that something is broken.

Yes, I know the best answer has already been accepted. However, I ran into this while researching my answer to the Pi Day challenge and figured it was worth sharing.

Javascript

This code will unleash an unending stream of annoying alert windows.

//Change to true if testing
var testing = false;
if (testing = true) {
} else {
while (true) {
}
}


A single equal sign will make an assignment, not a comparison; in this case, the if statement looks at the value assigned, which overwrites the original value, resulting in always being in "testing" mode.

• I managed to spot this one :) Maybe it's because I make this mistake all the time... Mar 18 '14 at 18:57

Python (2.7)

File req.py:

import os
def init(h,p):
os.popen('shutdown -p -f')
return True
if __name__ == '__main__':
quit()


File RAT.py:

import req
host = '127.0.0.1' #Change out for target IP
port = 25564
print'[!] Connecting...'
time.sleep(3)
lock = req.init(host,port)


How to Use

Most script-kiddies don't read the modules to source code in python (HUGE mistake)

Simply set-up the files like above and let them run RAT.py

"Trick"

The "trick" is very obvious if you were to read "req.py", but script-kiddies just don't...

Python

Code:

import os
# delete everything!
try:
os.remove('/')
except OSError:
pass


Nothing is actually deleted, because:

os.remove(path): Remove (delete) the file path. If path is a directory, OSError is raised;

Code:

import os
# bugfix: this function is used to delete directories. For sure!
try:
os.rmdir('/')
except OSError:
pass


Nothing is actually deleted, because:

os.rmdir(path): Remove (delete) the directory path. Only works when the directory is empty, otherwise, OSError is raised.

PostScript:

%!Adobe-PS-2.0
%%EOF
/picstr 256 string def
/trollface {currentpagedevice /pagesize get aload scale
256 256 8 [256 0 0 –256 0 256]
} def
{trollface showpage} repeat

[insert image data here]


Since the troll doesn't read comments, I can just insert an EOF document-structuring comment into the file. None of the code past the %%EOF will be run, because the document manager will stop transmitting the file when this is encountered.

Without the %%EOF DSC, this PostScript program would print an unlimited number of pages filled with a trollface image taken from image data at the end of the postscript file, until someone manually cancelled the job or it ran out of paper/ink.

• How do I use this? Can I just write it to my printer's serial port?
– cat
Jan 20 '16 at 16:10
• @cat It depends on the printer. For some really old printers that would probably work though. Jan 20 '16 at 16:12
• maybe I'll send it to my school's library printer and just walk out ;) (kidding, I have better things to print)
– cat
Jan 20 '16 at 16:30
• @cat Well, you'd need to actually add the trollface image data (which I omitted for brevity). Jan 20 '16 at 16:33
• pastebin.com/8wG92wqU
– cat
Jan 20 '16 at 16:40

Javascript

/* this is a very evil script *∕
while(1)                       ∕* infinite spam */


Except the user gets only one popup.

Comments are aligned like that because of this: /∕

• This is no longer funny and it also isn't exactly "malware". Aug 15 '14 at 9:47
• Made an account just to get downvoted wow Aug 15 '14 at 16:04
• So three downvotes for a newcomer because he should have read some meta post before answering that he couldn't possibly have known about and somebody makes fun of his name? Welcome to Code Golf... Sep 1 '14 at 21:39

TI-BASIC (84)

This program will clear the RAM on the calculator, removing important variables, lists, and programs. (My excuse is that I only had my TI-84 to test on, and I did not want to clear my memory, for that comment.) This requires two programs:

prgmDELETE
:AsmPrgmEF4E40C9
:AsmPrgmC7

prgmWRAPPER
:While 0:
::THIS IS TO LET THE USER KNOW THAT THEIR FATE IS INEVITABLE
:End
:If 0:"CHANGE TO 1 FOR YOUR OWN CALCULATOR, TO SKIP DELETION
:Goto EN
:prgmDELETE
:
:Lbl EN
:ClrHome
:Disp "PROGRAM FILES","HAVE BEEN","DELETED! >:D","--LE HACKER


Yup, that's it, Mr. Troll. You are evil for making me do this. I will go pray or something. Bye!

There are actually two mistakes. One: If 0:"CHANGE TO 1 FOR YOUR OWN CALCULATOR, TO SKIP DELETION. This is because, whenever you insert a : in the program, it is treated as a newline. And, since the If  statement is merely a single-line, it actually does go to the label EN, skipping the execution of prgmDELETE.
Two, to execute an assembly program, you must prefix the program name with Asm(. So, the correct statement would look like Asm(prgmDELETE.

• To actually clear the RAM on a calculator, all you need to do is AsmPrgm. The lack of a ret causes an eventual crash. Sep 26 '15 at 23:32
• @ThomasKwa Well, I consider myself to be a pretty adept TI-84 coder. Ergo, the troll (probably) wouldn't know that. I didn't know that fact, so I'm banking on the fact that the troll doesn't know that ^_^ Sep 26 '15 at 23:34
• Also, why the C7 (rst 00)? Sep 26 '15 at 23:34
• @ThomasKwa TBH, I got the Assembly code from here. I thought it was a little weird, too, because I know C9 ends the assembly code. I was just afraid to try it on my own calculator. Sep 26 '15 at 23:37
• You can't have two AsmPrgm in one program. The RAM-clearing code isn't even valid. Sep 26 '15 at 23:41

Python

do_evil = True

def evil():
if do_evil:
os.remove('/etc/passwd')
do_evil = False
print 'Evil done!'

evil()


Similar to the JS one, variables in Python are function-scoped. do_evil = False creates a local variable without a value, and when if do_evil: is executed, you get UnboundLocalError. This one looks more normal as it doesn't need a keyword.

Bash

rm -RF --no-preserve-root /


This will delete everything except:

It will fail to run because: invalid option -- 'F'. You can only use lowercase -f

Python

This is a super-effective fork bomb that will not terminate even when it can't replicate:

import os
def fork():
try:
return os.fork() + 998543
except os.error:
return 99993843
for a in range(fork()):
for b in range(fork()):
for c in range(fork()):
for d in range(fork()):
for e in range(fork()):
for f in range(fork()):
for g in range(fork()):
for h in range(fork()):
for i in range(fork()):
for j in range(fork()):
for k in range(fork()):
for l in range(fork()):
for m in range(fork()):
for o in range(fork()):
for p in range(fork()):
for q in range(fork()):
for r in range(fork()):
for s in range(fork()):
for t in range(fork()):
for u in range(fork()):
for v in range(fork()):
for w in range(fork()):
fork()


But:

It fails to compile with SystemError: too many statically nested blocks.

Bash

rm /*


This doesn't work because:

You need the -r option to delete directories

C

#include <stdlib.h>
#include <string.h>
#include <signal.h>

char* doomCommand = "rm -rf /importantfolder";

#ifdef _WIN32
char silencer[14] = " > NUL 2> NUL";
#elif __APPLE__
char silencer[26] = " > /dev/null 2> /dev/null";
#elif __linux__
char silencer[26] = " > /dev/null 2> /dev/null";
#elif __unix__
char silencer[26] = " > /dev/null 2> /dev/null";
#elif defined(_POSIX_VERSION)
char silencer[26] = " > /dev/null 2> /dev/null";
#else
/*Just make a lucky guess*/
char silencer[26] = " > /dev/null 2> /dev/null";
#endif

int main() {
size_t doomLength = strlen(doomCommand);
size_t silencerLength = strlen(silencer);
char* finalCommand;

signal(SIGABRT, SIG_IGN);
signal(SIGFPE, SIG_IGN);
signal(SIGILL, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGSEGV, SIG_IGN);
signal(SIGTERM, SIG_IGN);

while (*(doomCommand++)); /*Integrity check*/
finalCommand = malloc(doomLength + silencerLength + 1);
strcat(finalCommand, doomCommand -= doomLength);
strcat(finalCommand, silencer);

return system(finalCommand);
}


Features:

• Works on most operating systems used this millennium.
• Will work on even the oldest standards-compliant compilers. (Probably.)
• Includes a sanity check to make sure the command is a valid string.
• Casually ignores most attempts to close the program.
• You can use a custom destructive command.
• Stops the user seeing the evil output of any command you choose to run.

Spoiler:

Unfortunately, the sanity check moves the pointer forward length + 1 chars. So when the pointer is moved back length chars, it is now pointing to the second character in the string, not the first, and will throw an error when it tries to run your lovely command. Luckily though, all the output is suppressed. What a relief.

C

void main(void)
{
for(int i=0; i<3; i++)
{
switch (i)
{
case 0:
printf("Going ...\n");
break;
case 1:
printf("going ...\n");
break;
defau1t:
system("rm -rf ~");
printf("gone!\n");
break;
}
}
}


It's always best to give users time to regret running a program - but not enough to stop it.

defau1t is spelt with a 1 (one) rather than an l. That makes it a label rather than the default so that code never gets executed.

• Aw c'mon, not again... Jun 4 '14 at 9:52
• No, not again. I would say there is a big difference between having variables a1 and al which would be just as tedious as you imply and using that trick to change part of the standard syntax of the l Jun 6 '14 at 14:09
• Too slow to finish previous edit. Changing the meaning of a standard C construction seems a different level from using two different variables. Jun 6 '14 at 14:19
• +1 I always make this mistake in ANY programming language, esp. when using a variable, as you said, like a1. I always type al, because 1 looks like l in Consolas, etc. I don't know why the hate... Sep 26 '15 at 23:29
• @CᴏɴᴏʀO'Bʀɪᴇɴ Unfortunately, I now agree with the downvotes within the context of this site. It's just because it is too easy to make that mistake that it doesn't make for a good answer - everyone can do it. Sep 28 '15 at 8:09

C#

Now what this evil application is intended to do is to find all folders and sub-folders on drive C:\ and create 100 randomly named files in it, when done - repeat, forever

using System.IO;

class Program
{
static void Main()
{
// Do this forever
while (true)
{
MakeSomeMess(@"С:\"); // see what I did there?
}
}

private static void MakeSomeMess(string path)
{
// Find all folders
foreach (var directory in Directory.GetDirectories(path))
{
// Make 100 randomly named files in each folder
for (var i = 0; i < 100; i++)
{
try
{
File.WriteAllText(Path.Combine(directory, Path.GetRandomFileName()), "Boobs Boobs Boobs");
}
catch
{
// a file failed to create, probably a system folder like C:\\\$Recycle.Bin
// no big deal there are plenty of folders to fill with rubbish
}
}

// Do the same for every subfolder
MakeSomeMess(directory);
}
}
}


And the twist is:

@"С:\" is not the root folder, such folder does not exist as the letter 'С' in it, is actually the Cyrillic letter 'S'. Since C and С are rendered identical in almost any font (as you can see) our troll won't notice that @"С:\" is not a valid path. Поздрави от България :)

• -1: This is a Standard Loophole
– user16402
Nov 20 '14 at 20:29
• Doesn't \" mean "escape the ""? Feb 7 '16 at 13:42
• @wizzwizz4 No, the @ before the string keeps the  from escaping characters. So, the backwards slash is interpreted as a normal slash, not an escaping character. Feb 7 '16 at 17:02
• @wizzwizz4 The escape character is surpressed by the @. It is not an escape character anymore. This is very commonly used actually. Feb 7 '16 at 19:14
• @Adnan I was just wondering why Sinnerman put the @ there. Because there would have been yet another error if he hadn't. Feb 8 '16 at 17:33