Pastebin
API
tools
faq
paste
Login
Sign up
Please fix the following errors:
New Paste
Syntax Highlighting
-------------------------------------------------------------------- HITBSecConf Amsterdam 2018 Badge Challenge by Qihoo 360 Unicorn Team -------------------------------------------------------------------- Write-up by: Nikias Bassen (@pimskeks) April 17, 2018 -------------------------------------------------------------------- As a past speaker of HITB I was lucky to get hold of the cool badge that the Unicorn Team provided for the speakers and attendees at the HackInTheBox Amsterdam 2018 event last week: https://conference.hitb.org/hitbsecconf2018ams/commsec-village/#badge As announced on Twitter and mentioned on the above page the badge has a hidden challenge which made me curious and which actually was the reason why I wanted the badge in the first place. However I was told (not by the Unicorn Team!) that I _might_ have to solder wires to the breakout pins and connect it via USB or serial to get a link or something that would give me a clue how to solve the challenge. At the speakers reception I was finally checking out the badge and found a "Secret Menu" entry that is asking for a code. Using the Up, Down, Left, Right, OK, and ESC buttons on the badge it would allow to enter the characters 'U', 'D', 'L', 'R', 'O', and 'C'. After six characters I was greeted with "ACCESS DENIED!!! :(". A quick calculation shows that this would be a total of 6^6 = 46656 combinations, way to much to try them all ;) I didn't have soldering equipment with me so I wasn't really thinking I could solve the challenge easily. However since I wasn't following @sgniwx (how could I NOT follow him actually?) I only realized later that night that they published the source code + binary on GitHub earlier that day: --------------------------------------------------------------------------- Source code, binary and the schematic for #HITB2018AMS badge is available now. Follow @sgniwx @WhiteA10n3 @klks84 and look for us in the conference. Hint: crackme challenge is deep in the link. https://github.com/klks/hitb2018ams_badge --------------------------------------------------------------------------- (https://twitter.com/sgniwx/status/984106705037471744) So it looked like that I wouldn't have to solder after all (which I totally wouldn't mind doing - given the right equipment)! Anyway, I checked the source code and I found this: https://github.com/klks/hitb2018ams_badge/blob/master/src/hitb_secret.h#L58 Which compares the input to "OOOOOO". Of course I knew this wouldn't be the code since that would be too easy, also the next line saying 'display_qrcode("/*REDACTED*/");' was pretty obvious this is not exactly the same code that runs the badge. But wait, they released the BINARY too which can be found here: https://github.com/klks/hitb2018ams_badge/blob/master/hex/HITB.ino.bin When searching for "ACCESS DENIED" I found a string "LRDROC" just a few bytes before, at offset 0xC5FB, which immediately looked like that this would be the code, and also a short link is right behind it: goo.gl/PhVrhv (offset 0xC606). I tried the code on the badge and instead of "ACCESS DENIED!!! :(" it displayed a QR code which just represents the short link (yes, I checked it with my iPhone camera). Following the short link you will be redirected to: http://hardware.reverser.io/hitb2018ams/challange/ Which has some really clear instructions: ------------ [binary](http://hardware.reverser.io/hitb2018ams/challange/secretbox) 1. Download and reverse "secretbox" binary 2. ssh secretbox@secretbox.l4w.pw 3. password = secretbox 4. Look for "xwings" and show me your PoW. - Binary by l4w @ vnsec - xwings @ HITB Core Crew / Unicorn Core Team / vnsec ------------ So I downloaded the binary and opened it in IDA Pro. It is a 32-bit Linux binary. First I was a bit confused about all the 'extra' code but then quickly realized it was because of the use of ncurses library. Running it will display a "Token" which is random, and a keypad that you can navigate with the arrow keys and select with the space key: SAFEBOX KEYPAD Token: EA7D ┌───────────────────┐ │ │ │ │ │ [0] [1] [2] [3] │ │ [4] [5] [6] [7] │ │ [8] [9] [A] [B] │ │ [C] [D] [E] [F] │ │ │ │ │ └───────────────────┘ After entering 6 digits it will 'FAILED :(' if the code wasn't right. If you try 3 times and still didn't guess the code it will print 'self desctruct' all over the screen. Just connect to the server and see what happens. So, obviously the code depends on the random token. Looking at the main function, first thing it does is chdir to /home/secretbox. This will be used later. Right after that, there is a call to a sub function: .text:080490EF call sub_8049000 This function opens /dev/urandom, reads 2 bytes from it, and snprintf()s that to a global buffer with format %04X. I renamed the function to 'get_random_token' and the buffer to TOKEN_BUF. Back in main, the ncurses screen is initialized using initscr, start_color, init_pair, newwin, etc. You can also see the code that is writing the token onto the screen, using the global TOKEN_BUF I mentioned above: .text:080492DA mov ecx, 1 .text:080492DF mov edx, 5 .text:080492E4 lea esi, aTokenS ; "Token: %s" .text:080492EA lea edi, TOKEN_BUF .text:080492F0 mov dword ptr [esp], 1 ; int .text:080492F7 mov dword ptr [esp+4], 5 ; int .text:080492FF mov [esp+8], esi ; char * .text:08049303 mov [esp+0Ch], edi .text:08049307 mov [ebp+var_B0], eax .text:0804930D mov [ebp+var_B4], ecx .text:08049313 mov [ebp+var_B8], edx .text:08049319 call _mvprintw Looking further, there is another call to an unknown sub function: .text:080493A0 call sub_8049B50 It does some ncurses stuff that draws a border, prints a string with 6 chars (using mvwprintw with format %06s) from another global buffer, and then it loops 4 times, sequentially reading 4 chars from a global wide char string (0123456789ABCDEF) and printing it with format [%s] to different positions for all the 16 characters. This is the keypad drawing function obviously. I renamed it to draw_keypad. This function has one interesting piece here, since it has a buffer that is used to print whatever we entered so far onto the screen. This function is also redrawing the keypad because it highlights whatever 'key' we have selected and thus it needs to redraw every time we move the cursor. That global buffer, I named it ENTERED_WCHAR_BUF. I named the other global wide char string 'keypad_wchars'. Going from there I checked the XREFs to see where the code writes to the buffer, and found this: .text:08049623 mov eax, [ebp+var_14] .text:08049626 mov [ebp+var_18], eax .text:08049629 mov eax, [ebp+var_18] .text:0804962C mov eax, dword_804C0D0[eax*4] .text:08049633 mov cl, [eax] .text:08049635 mov eax, [ebp+var_20] .text:08049638 mov ds:dword_804C130[eax], cl .text:0804963F mov eax, [ebp+var_18] .text:08049642 mov eax, keypad_wchars[eax*4] .text:08049649 mov cl, [eax] .text:0804964B mov eax, [ebp+var_20] .text:0804964E mov ds:ENTERED_WCHAR_BUF[eax], cl Now what are those ebp+var_14 and ebp+var_20 ? If you browse through the code you easily figure out that ebp+var_20 is initially 0 and increases with every character that is selected through the keypad. It is the offset in the buffer. For ebp+var_14 it is the index of the keypad number selected (0..15). Now it reads something from address dword_804C0D0 + keypad_index * 4, so what is dword_804C0D0? If you check out its location you realize it is has some byte_* addresses there, each one of them pointing to the bytes (not chars!) 0, 1, 2, through 0xF. Let's rename it to 'array_00_0F'. Now it reads a byte from that array and stores that into another global buffer dword_804C130, that we rename to ENTERED_BUF, because that's what gets entered effectively. As for ENTERED_WCHAR_BUF, it uses the same keypad index ebp+var_14 (and ebp+var_18) to get the wide char from the 'keypad_wchars' we already figured out in the draw_keypad function. So, we have one buffer that stores the byte values selected through the keypad (ENTERED_BUF) and one buffer that stores the printable chars 0-9A-F (ENTERED_WCHAR_BUF). If you check the code right after the previous snippet, we see this: .text:08049655 mov eax, [ebp+var_20] .text:08049658 add eax, 1 .text:0804965B mov [ebp+var_20], eax .text:0804965E cmp [ebp+var_20], 6 .text:08049662 jnz loc_80498B7 .text:08049668 lea eax, ENTERED_BUF .text:0804966E lea ecx, TOKEN_BUF .text:08049674 mov [esp], eax ; int .text:08049677 mov [esp+4], ecx ; nptr .text:0804967B call sub_8048E80 .text:08049680 cmp eax, 0 .text:08049683 jz loc_80497FC After checking if the buffer index has reached 6 a sub function is called with the token buffer (TOKEN_BUF) and the buffer with the selected values (ENTERED_BUF). This pretty much looks like the verification function! So let's have a look inside: .text:08048E89 mov eax, [ebp+token] .text:08048E8C mov ecx, [ebp+entered] .text:08048E8F xor edx, edx .text:08048E91 mov esi, 10h .text:08048E96 mov edi, [ebp+token] .text:08048E99 mov [esp], edi ; nptr .text:08048E9C mov dword ptr [esp+4], 0 ; endptr .text:08048EA4 mov dword ptr [esp+8], 10h ; base .text:08048EAC mov [ebp+var_20], eax .text:08048EAF mov [ebp+var_24], ecx .text:08048EB2 mov [ebp+var_28], edx .text:08048EB5 mov [ebp+var_2C], esi .text:08048EB8 call _strtoul .text:08048EBD mov [ebp+var_10], eax .text:08048EC0 imul eax, [ebp+var_10], 1337h .text:08048EC7 mov [esp], eax ; seed .text:08048ECA call _srand First thing it does is getting the numerical value of the TOKEN_BUF string that is initialized as explained above using strtoul(). Then it multiplies that value with 0x1337 and calls srand() to initialize the pseudo-random number generator. Following is what must be the verification of every single digit entered. It looks like this: .text:08048ECF mov ecx, [ebp+entered] .text:08048ED2 movsx ecx, byte ptr [ecx] .text:08048ED5 mov [esp], ecx .text:08048ED8 mov [ebp+var_30], eax .text:08048EDB call sub_8048AE0 .text:08048EE0 mov bx, ax .text:08048EE3 mov [ebp+var_12], bx .text:08048EE7 mov eax, [ebp+entered] .text:08048EEA movsx eax, byte ptr [eax+1] .text:08048EEE mov [esp], eax .text:08048EF1 call sub_8048B30 .text:08048EF6 mov bx, ax .text:08048EF9 mov [ebp+var_14], bx .text:08048EFD mov eax, [ebp+entered] .text:08048F00 movsx eax, byte ptr [eax+2] .text:08048F04 mov [esp], eax .text:08048F07 call sub_8048B80 .text:08048F0C mov bx, ax .text:08048F0F mov [ebp+var_16], bx .text:08048F13 mov eax, [ebp+entered] .text:08048F16 movsx eax, byte ptr [eax+3] .text:08048F1A mov [esp], eax .text:08048F1D call sub_8048BE0 .text:08048F22 mov bx, ax .text:08048F25 mov [ebp+var_18], bx .text:08048F29 mov eax, [ebp+entered] .text:08048F2C movsx eax, byte ptr [eax+4] .text:08048F30 mov [esp], eax .text:08048F33 call sub_8048C40 .text:08048F38 mov bx, ax .text:08048F3B mov [ebp+var_1A], bx .text:08048F3F mov eax, [ebp+entered] .text:08048F42 movsx eax, byte ptr [eax+5] .text:08048F46 mov [esp], eax .text:08048F49 call sub_8048CE0 .text:08048F4E mov ecx, 0Ah .text:08048F53 mov edx, 1Eh .text:08048F58 lea esi, aUUUUUU ; "%u %u %u %u %u %u" .text:08048F5E mov bx, ax .text:08048F61 mov [ebp+var_1C], bx The pattern is pretty clear: Take a byte value from ENTERED_BUF and pass it to the distinctive sub function. The result is then stored in a corresponding local variable (var_12, var_14, var_16, var_18, var_1A, and var_1C). You can see this happening for each of the 6 digits entered. Let's rename the sub functions to calc_char_0 .. calc_char_5 so it looks like this: .text:08048ECF mov ecx, [ebp+entered] .text:08048ED2 movsx ecx, byte ptr [ecx] .text:08048ED5 mov [esp], ecx .text:08048ED8 mov [ebp+var_30], eax .text:08048EDB call calc_char_0 .text:08048EE0 mov bx, ax .text:08048EE3 mov [ebp+var_12], bx .text:08048EE7 mov eax, [ebp+entered] .text:08048EEA movsx eax, byte ptr [eax+1] .text:08048EEE mov [esp], eax .text:08048EF1 call calc_char_1 .text:08048EF6 mov bx, ax .text:08048EF9 mov [ebp+var_14], bx .text:08048EFD mov eax, [ebp+entered] .text:08048F00 movsx eax, byte ptr [eax+2] .text:08048F04 mov [esp], eax .text:08048F07 call calc_char_2 .text:08048F0C mov bx, ax .text:08048F0F mov [ebp+var_16], bx .text:08048F13 mov eax, [ebp+entered] .text:08048F16 movsx eax, byte ptr [eax+3] .text:08048F1A mov [esp], eax .text:08048F1D call calc_char_3 .text:08048F22 mov bx, ax .text:08048F25 mov [ebp+var_18], bx .text:08048F29 mov eax, [ebp+entered] .text:08048F2C movsx eax, byte ptr [eax+4] .text:08048F30 mov [esp], eax .text:08048F33 call calc_char_4 .text:08048F38 mov bx, ax .text:08048F3B mov [ebp+var_1A], bx .text:08048F3F mov eax, [ebp+entered] .text:08048F42 movsx eax, byte ptr [eax+5] .text:08048F46 mov [esp], eax .text:08048F49 call calc_char_5 .text:08048F4E mov ecx, 0Ah .text:08048F53 mov edx, 1Eh .text:08048F58 lea esi, aUUUUUU ; "%u %u %u %u %u %u" .text:08048F5E mov bx, ax .text:08048F61 mov [ebp+var_1C], bx Also you can see "%u %u %u %u %u %u" format string and if you continue looking you will find out that it will print the result of every function on the screen with mvprintw. After that it will verify the result for every digit, and logically AND the resulting values here: .text:08048FC5 movzx ecx, [ebp+var_12] .text:08048FC9 movzx edx, [ebp+var_14] .text:08048FCD and ecx, edx .text:08048FCF movzx edx, [ebp+var_16] .text:08048FD3 and ecx, edx .text:08048FD5 movzx edx, [ebp+var_18] .text:08048FD9 and ecx, edx .text:08048FDB movzx edx, [ebp+var_1A] .text:08048FDF and ecx, edx .text:08048FE1 movzx edx, [ebp+var_1C] .text:08048FE5 and ecx, edx .text:08048FE7 mov [ebp+var_48], eax .text:08048FEA mov eax, ecx So only if all of the sub functions returns TRUE this function (verify_code) will return TRUE, otherwise FALSE. Now let's find out how the code is calculated. Looking into first function it looks really simple. It calls rand() and does modulo 16 with the result, giving a number 0..15. That result is stored in a global variable, let's call it char_0_res. It is then compared to the value that was entered by the user. So calc_char_0 returns TRUE or FALSE, based on the input. In pseudo code it looks like this: BOOL calc_char_0(char a1) { char_0_res = rand() % 16; return a1 == char_0_res; } calc_char_1 is doing a little more. It also calls rand() and does modulo 16, and stores the result in another global that we call char_1_res. Now the result for the FIRST digit is multiplied by 8 and then modulo'ed with the char_1_res, finally comparing it to the input: BOOL calc_char_1(char a1) { char_1_res = rand() % 16; return (8 * char_0_res % char_1_res) == a1; } Next up is calc_char_2. After calculating the rand() modulo 16 again and storing it in another global char_2_res, it will add up that value with the result of the first and second value, and ANDs it with 15, then compares it with the input: BOOL calc_char_2(char a1) { char_2_res = rand() % 16; return ((char_2_res + char_1_res + char_0_res) & 0xF) == a1; } Now we have calc_char_3. This one is a little different. It will again do the usual rand() % 16 and store it it char_3_res. But then it subtracts the result of the 3rd digit (char_2_res) from the result of the 1st digit (char_0_res) and adds the result of ANOTHER call to rand() to it. Then it ANDs it with 15 and compares it with the input value: BOOL calc_char_3(char a1) { char v1; char_3_res = rand() % 16; v1 = char_0_res - char_2_res; return ((rand() + v1) & 0xF) == a1; } Then we have calc_char_4. This one again is different. We have the usual char_4_res = rand() % 16. Then it will do a loop with char_4_res iterations, and in very iteration it calls rand() (so minimum of 0, maximum of 15 iterations). After the loop it will do rand() % 4 giving a result that is then used in another calculation with yet another rand(). Just look at the pseudo-code, which will be easier to understand than words. Of course the final result is compared to the input value: BOOL calc_char_4(char a1) { int v1; unsigned int i; char_4_res = rand() % 16; for ( i = 0; i < char_4_res; ++i ) rand(); v1 = rand() % 4; return (rand() % 5 * v1 % 16) == a1; } Finally calc_char_5. This function is first doing the usual char_5_res = rand() % 16, and also, like calc_char_4, doing a loop with rand() calls based on that result as the number of iterations. After that, it does a calculation with all the previous results (calc_0_res through calc_5_res) and comparing it with the value passed as argument. Again, easier to just understand the pseudo-code: BOOL calc_char_5(char a1) { unsigned int v1; unsigned int i; char_5_res = rand() % 16; for ( i = 0; i < char_5_res; ++i ) rand(); v1 = char_3_res * ((char_0_res << char_1_res) / (unsigned int)char_2_res); return (((unsigned char)(rand() % 5) * (uint8_t)v1 - char_4_res % 7 / (char_5_res & 0xF)) & 0xF) == a1; } So now that we know how it verifies the code, we can easily write a keygen for it. Basically we just take all the 6 functions and remove the comparison with the input value. It will leave us with these 6 functions: uint8_t char_0_res = 0; uint8_t char_1_res = 0; uint8_t char_2_res = 0; uint8_t char_3_res = 0; uint8_t char_4_res = 0; uint8_t char_5_res = 0; static uint8_t calc_char_0() { char_0_res = rand() % 16; return char_0_res; } static uint8_t calc_char_1() { char_1_res = rand() % 16; return 8 * char_0_res % char_1_res; } static uint8_t calc_char_2() { char_2_res = rand() % 16; return (char_2_res + char_1_res + char_0_res) & 0xF; } static uint8_t calc_char_3() { char v1; char_3_res = rand() % 16; v1 = char_0_res - char_2_res; return ((unsigned char)rand() + v1) & 0xF; } static uint8_t calc_char_4() { unsigned int v1; unsigned int i; char_4_res = rand() % 16; for (i = 0; i < char_4_res; ++i) rand(); v1 = rand() % 4; return rand() % 5 * v1 % 16; } static uint8_t calc_char_5() { unsigned int v1; unsigned int i; char_5_res = rand() % 16; for (i = 0; i < char_5_res; ++i) rand(); v1 = char_3_res * ((char_0_res << char_1_res) / (unsigned int)char_2_res); return ((unsigned char)(rand() % 5) * (uint8_t)v1 - char_4_res % 7 / (char_5_res & 0xF)) & 0xF; } Now, the only thing we have to do is allowing to input a token value so we can initialize the pseudo random number generator. I ended up with this main function: int main(int argc, char **argv) { if (argc < 2) { char *prog = strrchr(argv[0], '/'); printf("Usage: %s TOKEN\n", (prog) ? prog+1 : argv[0]); return -1; } uint32_t token = strtoul(argv[1], NULL, 16); printf("TOKEN IS 0x%x\n", token); srand(token * 0x1337); uint8_t c0 = calc_char_0(); uint8_t c1 = calc_char_1(); uint8_t c2 = calc_char_2(); uint8_t c3 = calc_char_3(); uint8_t c4 = calc_char_4(); uint8_t c5 = calc_char_5(); printf("CODE: %x %x %x %x %x %x\n", c0, c1, c2, c3, c4, c5); return 0; } The full C file can be found here: https://pastebin.com/pGNp3hHY Just run this on your linux box passing the token value (expected to be hexadecimal), and it will calculate and print the corresponding code. Then you can log in to the secrebox server, pass the token from that session to the key generator, and enter the correct code. You will get the flag printed on screen. But hey. Couldn't we just extract the flag from the binary? No, because it's not included. So how is the flag retrieved? What happens when you enter the correct code, actually? Let's jump back to the main function. If verfiy_code returns TRUE, the jump after it will not be taken. The code following has a reference to a string "CORRECT" and also a "secret.txt", followed by a call to another sub function: .text:0804967B call verify_code .text:08049680 cmp eax, 0 .text:08049683 jz loc_80497FC .text:08049689 mov eax, 200h .text:0804968E xor ecx, ecx .text:08049690 mov edx, ds:stdscr .text:08049696 mov [esp], edx ; WINDOW * .text:08049699 mov dword ptr [esp+4], 200h ; attr_t .text:080496A1 mov dword ptr [esp+8], 0 ; void * .text:080496A9 mov [ebp+var_11C], eax .text:080496AF mov [ebp+var_120], ecx .text:080496B5 call _wattr_on .text:080496BA mov ecx, 3 .text:080496BF mov edx, 28h ; '(' .text:080496C4 lea esi, aCorrect ; "CORRECT" .text:080496CA mov dword ptr [esp], 3 ; int .text:080496D1 mov dword ptr [esp+4], 28h ; '(' ; int .text:080496D9 mov [esp+8], esi ; char * .text:080496DD mov [ebp+var_124], eax .text:080496E3 mov [ebp+var_128], ecx .text:080496E9 mov [ebp+var_12C], edx .text:080496EF call _mvprintw .text:080496F4 lea ecx, aSecretTxt ; "secret.txt" .text:080496FA mov [esp], ecx ; filename .text:080496FD mov [ebp+var_130], eax .text:08049703 call sub_8048DA0 The purpose of that function is easily identified. It opens a file, gets its size, calls 'malloc' with that size, and reads the contents of that file into that buffer. That's it. After returning from that function, you can see it will do some ncurses printing that will eventually print whatever is in that secret.txt file: .text:08049708 mov ecx, 5 .text:0804970D mov edx, 1Eh .text:08049712 lea esi, asc_8049F7C ; "+---------------------------------+" .text:08049718 mov [ebp+var_28], eax .text:0804971B mov dword ptr [esp], 5 ; int .text:08049722 mov dword ptr [esp+4], 1Eh ; int .text:0804972A mov [esp+8], esi ; char * .text:0804972E mov [ebp+var_134], edx .text:08049734 mov [ebp+var_138], ecx .text:0804973A call _mvprintw .text:0804973F mov ecx, 6 .text:08049744 mov edx, 1Eh .text:08049749 lea esi, a30s ; "|%30s |" .text:0804974F mov edi, [ebp+var_28] .text:08049752 mov dword ptr [esp], 6 ; int .text:08049759 mov dword ptr [esp+4], 1Eh ; int .text:08049761 mov [esp+8], esi ; char * .text:08049765 mov [esp+0Ch], edi .text:08049769 mov [ebp+var_13C], eax .text:0804976F mov [ebp+var_140], ecx .text:08049775 mov [ebp+var_144], edx .text:0804977B call _mvprintw .text:08049780 mov ecx, 7 .text:08049785 mov edx, 1Eh .text:0804978A lea esi, asc_8049F7C ; "+---------------------------------+" .text:08049790 mov dword ptr [esp], 7 ; int .text:08049797 mov dword ptr [esp+4], 1Eh ; int .text:0804979F mov [esp+8], esi ; char * .text:080497A3 mov [ebp+var_148], eax .text:080497A9 mov [ebp+var_14C], ecx .text:080497AF mov [ebp+var_150], edx .text:080497B5 call _mvprintw So if you enter the correct code, the output will look like this: SAFEBOX KEYPAD Token: A1F0 ┌───────────────────┐ │ 002530 │ CORRECT │ │ │ [0] [1] [2] [3] │ +---------------------------------+ │ [4] [5] [6] [7] │ | flag{welc0me_to_H1T13} │ [8] [9] [A] [B] │ +---------------------------------+ │ [C] [D] [E] [F] │ │ │ │ │ 1 1 1 1 1 1 └───────────────────┘ You've pressed [0] That's it! Now you know the flag :)
Optional Paste Settings
Category:
None
Cryptocurrency
Cybersecurity
Fixit
Food
Gaming
Haiku
Help
History
Housing
Jokes
Legal
Money
Movies
Music
Pets
Photo
Science
Software
Source Code
Spirit
Sports
Travel
TV
Writing
Tags:
Syntax Highlighting:
None
Bash
C
C#
C++
CSS
HTML
JSON
Java
JavaScript
Lua
Markdown (PRO members only)
Objective C
PHP
Perl
Python
Ruby
Swift
4CS
6502 ACME Cross Assembler
6502 Kick Assembler
6502 TASM/64TASS
ABAP
AIMMS
ALGOL 68
APT Sources
ARM
ASM (NASM)
ASP
ActionScript
ActionScript 3
Ada
Apache Log
AppleScript
Arduino
Asymptote
AutoIt
Autohotkey
Avisynth
Awk
BASCOM AVR
BNF
BOO
Bash
Basic4GL
Batch
BibTeX
Blitz Basic
Blitz3D
BlitzMax
BrainFuck
C
C (WinAPI)
C Intermediate Language
C for Macs
C#
C++
C++ (WinAPI)
C++ (with Qt extensions)
C: Loadrunner
CAD DCL
CAD Lisp
CFDG
CMake
COBOL
CSS
Ceylon
ChaiScript
Chapel
Clojure
Clone C
Clone C++
CoffeeScript
ColdFusion
Cuesheet
D
DCL
DCPU-16
DCS
DIV
DOT
Dart
Delphi
Delphi Prism (Oxygene)
Diff
E
ECMAScript
EPC
Easytrieve
Eiffel
Email
Erlang
Euphoria
F#
FO Language
Falcon
Filemaker
Formula One
Fortran
FreeBasic
FreeSWITCH
GAMBAS
GDB
GDScript
Game Maker
Genero
Genie
GetText
Go
Godot GLSL
Groovy
GwBasic
HQ9 Plus
HTML
HTML 5
Haskell
Haxe
HicEst
IDL
INI file
INTERCAL
IO
ISPF Panel Definition
Icon
Inno Script
J
JCL
JSON
Java
Java 5
JavaScript
Julia
KSP (Kontakt Script)
KiXtart
Kotlin
LDIF
LLVM
LOL Code
LScript
Latex
Liberty BASIC
Linden Scripting
Lisp
Loco Basic
Logtalk
Lotus Formulas
Lotus Script
Lua
M68000 Assembler
MIX Assembler
MK-61/52
MPASM
MXML
MagikSF
Make
MapBasic
Markdown (PRO members only)
MatLab
Mercury
MetaPost
Modula 2
Modula 3
Motorola 68000 HiSoft Dev
MySQL
Nagios
NetRexx
Nginx
Nim
NullSoft Installer
OCaml
OCaml Brief
Oberon 2
Objeck Programming Langua
Objective C
Octave
Open Object Rexx
OpenBSD PACKET FILTER
OpenGL Shading
Openoffice BASIC
Oracle 11
Oracle 8
Oz
PARI/GP
PCRE
PHP
PHP Brief
PL/I
PL/SQL
POV-Ray
ParaSail
Pascal
Pawn
Per
Perl
Perl 6
Phix
Pic 16
Pike
Pixel Bender
PostScript
PostgreSQL
PowerBuilder
PowerShell
ProFTPd
Progress
Prolog
Properties
ProvideX
Puppet
PureBasic
PyCon
Python
Python for S60
QBasic
QML
R
RBScript
REBOL
REG
RPM Spec
Racket
Rails
Rexx
Robots
Roff Manpage
Ruby
Ruby Gnuplot
Rust
SAS
SCL
SPARK
SPARQL
SQF
SQL
SSH Config
Scala
Scheme
Scilab
SdlBasic
Smalltalk
Smarty
StandardML
StoneScript
SuperCollider
Swift
SystemVerilog
T-SQL
TCL
TeXgraph
Tera Term
TypeScript
TypoScript
UPC
Unicon
UnrealScript
Urbi
VB.NET
VBScript
VHDL
VIM
Vala
Vedit
VeriLog
Visual Pro Log
VisualBasic
VisualFoxPro
WHOIS
WhiteSpace
Winbatch
XBasic
XML
XPP
Xojo
Xorg Config
YAML
YARA
Z80 Assembler
ZXBasic
autoconf
jQuery
mIRC
newLISP
q/kdb+
thinBasic
Paste Expiration:
Never
Burn after read
10 Minutes
1 Hour
1 Day
1 Week
2 Weeks
1 Month
6 Months
1 Year
Paste Exposure:
Public
Unlisted
Private
Folder:
(members only)
Password
NEW
Enabled
Disabled
Burn after read
NEW
Paste Name / Title:
Create New Paste
Hello
Guest
Sign Up
or
Login
Sign in with Facebook
Sign in with Twitter
Sign in with Google
You are currently not logged in, this means you can not edit or delete anything you paste.
Sign Up
or
Login
Public Pastes
Free Crypto Method
CSS | 24 min ago | 0.72 KB
+12,000$ in 2 days
CSS | 24 min ago | 0.72 KB
Documents
24 min ago | 0.43 KB
Crypto admin access
24 min ago | 0.43 KB
Silk
2 hours ago | 3.74 KB
fleet_agent
11 hours ago | 5.04 KB
Altur Song Lyrics
22 hours ago | 13.27 KB
CC:T GPS Beacon
1 day ago | 0.49 KB
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the
Cookies Policy
.
OK, I Understand
Not a member of Pastebin yet?
Sign Up
, it unlocks many cool features!