主頁 >  其他 > 一種linux平臺下演算法庫二進制檔案加密方法探討

一種linux平臺下演算法庫二進制檔案加密方法探討

2021-08-23 06:43:56 其他

最近做專案遇到一個需求,需要把我們的影像演算法庫提供給客戶使用,為防止演算法庫被對方濫用和逆向破解,需要對演算法庫二進制檔案做加密處理以及加密狗系結,同時防止庫檔案被反除錯跟蹤,演算法庫加密可以借助開源軟體 openssl實作,加密狗的使用也很簡單,從加密狗官方渠道即可拿到arm平臺下的支持庫和簡單的示例程式,接下來就是如何構建對二進制庫檔案的加解密以及如何安全的映射至行程地址空間中,一個最容易想到的思路是對演算法庫檔案套上一層外殼,由外殼程式完成演算法庫的自動解密以及完全脫離檔案系統的行程記憶體映射,整個程序中加密后的演算法由外殼行程直接解密到記憶體中,并由驅動程式直接映射至呼叫行程的地址空間中,完全不會暴露給檔案系統,配合一定的反除錯技術,使得用戶很難直接拿到演算法庫的二進制代碼,從而大大提高對演算法庫檔案的保護,防止惡意破解,

1. 借助內核編譯initramfs的方式將加密后的演算法庫二進制檔案嵌入到外殼中

利用開源的openssl開發例程很容易實作對演算法庫檔案的加密和解密,接下來的問題是如何將加密后的演算法庫檔案套上外殼,多年的內核編譯經驗讓我想到內核的一些奇技淫巧,早些年簡單研究過內核使用cpio打包initramfs的一些原理,內核也是將打包后的檔案系統嵌套進vmlinux中的,于是借鑒一下代碼,套殼的第一步就完成了,代碼如下:

.section .init.data,"a"
.globl __idata_start
__idata_start:
.incbin "../deplib/encrypt.so"
.globl __idata_end
__idata_end:

代碼里的關鍵指令是incbin匯編命令,該命令可以用來包含可執行檔案及其他任意資料,檔案內容將按位元組逐一添加到當前 ELF 節中,原樣包含不進行任何匯編,同時代碼中定義必要的全域變數定位該段位置,這樣就可以將加密后的演算法檔案encrypt.so嵌入到外殼程式的ELF段中,并在外殼程式初始化時將其解密至外殼行程的記憶體中,

2. 常規的動態庫載入方法和問題

解密后的演算法庫檔案位于記憶體中,如何將其作為動態庫檔案匯入到行程地址空間中是接下來要處理的問題,常規的動態庫加載方案主要有2種,第一種是最常用的方法,程式編譯時由gcc指定依賴的動態庫資訊,該資訊會記錄到ELF檔案中,并可由readelf -d獲取,應用程式加載時ld.so會根據指定的路徑加載相應的庫,第二種方法是利用libdl庫的dlopen/dlclose/dlsym等介面,在程式執行程序中動態載入庫檔案并決議其內部符號等,這2種方法有一個共同的問題是動態庫的載入必須通過檔案系統的方式匯入進來,而一旦將動態庫暴露給檔案系統,技術人員就很容易通過檔案系統拿到演算法庫的二進制檔案進行反編譯,且這2種方式都可以通過cat /proc/{pid}/maps直接定位到匯入的動態庫的具體位置,如下所示:

cat /proc/3639/maps 
00400000-00402000 r-xp 00000000 b3:02 797096                             /root/test/shtest
00411000-00412000 rw-p 00001000 b3:02 797096                             /root/test/shtest
00412000-00433000 rw-p 00000000 00:00 0                                  [heap]
...
7f9b56d000-7f9b57c000 ---p 00017000 b3:02 393672                         /lib/aarch64-linux-gnu/libpthread-2.23.so
7f9b57c000-7f9b57d000 r--p 00016000 b3:02 393672                         /lib/aarch64-linux-gnu/libpthread-2.23.so
7f9b57d000-7f9b57e000 rw-p 00017000 b3:02 393672                         /lib/aarch64-linux-gnu/libpthread-2.23.so

3. 間接借助檔案系統的幫助將動態庫匯入行程地址空間

如何不通過檔案系統將動態庫映射到行程的地址空間就是接下來需要面對的問題,顯而易見的想法是硬杠glibc,直接改寫dlopen等介面的實作,將其動態庫的載入脫離檔案系統,后來發現自己迷失在glibc盤根錯節的層層套用和復雜的符號決議參考中,之后還考慮借鑒內核的vdso及uselib機制,但對ELF檔案的符號決議并不是一件短時間內容易做到并可以確保無誤的事情,最好的方法就是仍然沿用dlopen那一套機制,由glibc來處理動態庫的符號決議和參考問題,躊躇之際突然想到驅動程式的設備節點也是一種檔案,也有自己的file_operations操作,也支持read/write/mmap等基本的檔案操作介面,把它用作動態庫的代理入口交由dlopen處理,由驅動程式配合完成dlopen對動態庫的所有操作,用這種斗轉星移的方法,將處于用戶態記憶體中的演算法庫映射到用戶行程地址空間中,間接脫離檔案系統的支持,

3.1 將演算法庫二進制檔案匯入到內核空間

首先通過ioctl將用戶態下解密后的演算法庫檔案匯入到驅動程式申請的一段記憶體空間中,如果記憶體足夠,使用dma_alloc_coherent直接從CMA區域拿到一段連續記憶體即可,更加普適的方法是使用alloc_page申請足夠的物理頁幀(成功概率高于連續記憶體段),將用戶態演算法庫資料分頁拷貝至內核空間中,然后使用vmap機制將page頁面陣列對應的物理記憶體映射到vmalloc地址空間中,核心代碼摘錄如下:

wxcoder_dev->pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL);
	if (!wxcoder_dev->pages)
		goto oom;
	for (i = 0; i < npages; i++) {
		struct page *p;
		p = alloc_page(GFP_KERNEL);
		if (!p){
			goto oom;
		}
		wxcoder_dev->pages[i] = p;
		if (copy_from_user(page_address(p), (const void __user *)usr_data->algo_start+i*PAGE_SIZE, 
								(usr_data->algo_len - i*PAGE_SIZE) > PAGE_SIZE ? PAGE_SIZE : (usr_data->algo_len - i*PAGE_SIZE))){
			debug("err copy %d pages, left: %d pages\n", i, npages - i);
			ret = -EFAULT;
			goto oom;
		}
	}

	wxcoder_dev->vbase = vmap(wxcoder_dev->pages, npages, 0, PAGE_KERNEL);
	if (!wxcoder_dev->vbase){
		ret = -EFAULT;
		goto oom;
	}

演算法庫二進制檔案拷貝到內核空間后,接下來驅動程式需要支撐dlopen的實作,首先需要了解dlopen的具體執行程序,涉及到哪些系統呼叫,最簡單的方法是使用strace除錯工具追蹤dlopen的呼叫程序,其中dlopen使用RTLD_NOW引數呼叫,結果如下:

...
openat(AT_FDCWD, "/dev/wxcoder", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\340\351\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFCHR|0600, st_rdev=makedev(10, 41), ...}) = 0
mmap(NULL, 515904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7ca5e000
mprotect(0x7f7cac8000, 65536, PROT_NONE) = 0
mmap(0x7f7cad8000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6a000) = 0x7f7cad8000
mmap(0x7f7cadb000, 3904, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7cadb000
close(3)                                = 0
...

可以看出dlopen先后呼叫了openat、read、mmap、mprotect和close等系統呼叫,看起來dlopen讀取了動態庫的程式頭表等資訊,分析其內部段資訊后將其映射到行程地址空間中,顯而易見,我們只需在驅動里實作read/mmap介面即可支撐dlopen的功能,read的實作比較簡單,只要利用copy_to_user函式配合vmap回傳的內核虛擬地址即可將dlopen需要的資料回傳給用戶態空間,要注意的是dlopen完成后需關閉驅動的read和mmap通道,防止資料通過設備節點外泄給惡意用戶,另外還可以在外殼程式和驅動程式間使用ioctl時加上簡易的口令,以進一步保護資料,

3.2 自定義mmap實作演算法庫檔案到行程地址空間的映射

mmap的實作有多種方式,如果先前用的是dma_alloc_coherent申請的一段連續物理記憶體,mmap實作最簡單,只要使用remap_pfn_range函式將相應的物理頁幀映射到用戶行程地址空間的vma段即可,該函式的底層實作即建立物理頁幀至用戶空間vma段的頁表實體,代碼如下:

static int wzalgo_mmap(struct file *filp, struct vm_area_struct *vma)
{
	unsigned long size = PAGE_ALIGN(vma->vm_end - vma->vm_start);

	debug("wzalgo_mmap - start: 0x%lx, end: 0x%lx, size: %ld\n\tpgoff: %lu, flags: %lu\n", \
					vma->vm_start, vma->vm_end, size, vma->vm_pgoff, vma->vm_flags);
	if (false == readable || false == loadok){
		return -EINVAL;
	}
	...
	vma->vm_pgoff += (wxcoder_dev->rxdma_addr >> PAGE_SHIFT);

	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, vma->vm_page_prot);
}

如果先前采用的是alloc_page申請的一組物理不連續頁幀保存的演算法庫二進制檔案,除了采用分頁單獨remap_pfn_range映射的方法,還可以借助缺頁中斷來實作,代碼如下:

static vm_fault_t wzcoder_mapping_fault(struct vm_fault *vmf)
{
	struct vm_area_struct *vma = vmf->vma;
	pgoff_t pgoff;
	struct page **pages;

	debug("wzcoder_mapping_fault vmf->pgoff: %lu\n", vmf->pgoff);
	pages = vma->vm_private_data;
	for (pgoff = vmf->pgoff; pgoff && *pages; ++pages)
		pgoff--;

	if (*pages) {
		struct page *page = *pages;
		get_page(page);
		vmf->page = page;
		return 0;
	}

	return VM_FAULT_SIGBUS;
}

static const struct vm_operations_struct wzcoder_mapping_vmops = {
	.close = wzcoder_mapping_close,
	.fault = wzcoder_mapping_fault,
};

static int wzalgo_mmap(struct file *filp, struct vm_area_struct *vma)
{
	unsigned long size = PAGE_ALIGN(vma->vm_end - vma->vm_start);

	if (false == readable || false == loadok || !wxcoder_dev->vbase){
		return -EINVAL;
	}

	debug("wzalgo_mmap - start: 0x%lx, end: 0x%lx, size: %ld\n\tpgoff: %lu, flags: %lu\n", vma->vm_start, vma->vm_end, size, \
						vma->vm_pgoff, vma->vm_flags);
	vma->vm_ops = &wzcoder_mapping_vmops;
	vma->vm_private_data = (void *)wxcoder_dev->pages;

	return 0;
}

在用戶態行程mmap該段vma區域時,注冊vm_operations_struct結構,缺頁中斷處理函式wzcoder_mapping_fault把vmf->pgoff對應的物理頁幀回傳給vmf->page,其中vmf->pgoff指示當前頁在vma區域中邏輯頁的偏移量,由于該段vma的邏輯頁和實際的物理頁幀是一一對應的,所以很容易找到對應的page實體,

更深入一點的方法可以參考remap_pfn_range的底層實作,自己建立所需的頁表結構,強化對內核建立頁表程序的理解,代碼摘錄如下:

#define pte_alloc_wz(mm, pmd, address)         \
			(unlikely(pmd_none(*(pmd))) && __pte_alloc_wz(mm, pmd, address))

#define pte_alloc_map_lock_wz(mm, pmd, address, ptlp)  \
			(pte_alloc_wz(mm, pmd, address) ? NULL : pte_offset_map_lock(mm, pmd, address, ptlp))


int __pte_alloc_wz(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
{
	spinlock_t *ptl;
	pgtable_t new = pte_alloc_one(mm, address);
	if (!new)
		return -ENOMEM;

	smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */

	ptl = pmd_lock(mm, pmd);
	if (likely(pmd_none(*pmd))) {	/* Has another populated it ? */
		mm_inc_nr_ptes(mm);
		pmd_populate(mm, pmd, new);
		new = NULL;
	}
	spin_unlock(ptl);
	if (new)
		pte_free(mm, new);
	return 0;
}

int __pmd_alloc_wz(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
	spinlock_t *ptl;
	pmd_t *new = pmd_alloc_one(mm, address);
	if (!new)
		return -ENOMEM;

	smp_wmb(); /* See comment in __pte_alloc */

	ptl = pud_lock(mm, pud);
#ifndef __ARCH_HAS_4LEVEL_HACK
	if (!pud_present(*pud)) {
		mm_inc_nr_pmds(mm);
		pud_populate(mm, pud, new);
	} else	/* Another has populated it */
		pmd_free(mm, new);
#else
	if (!pgd_present(*pud)) {
		mm_inc_nr_pmds(mm);
		pgd_populate(mm, pud, new);
	} else /* Another has populated it */
		pmd_free(mm, new);
#endif /* __ARCH_HAS_4LEVEL_HACK */
	spin_unlock(ptl);
	return 0;
}

static inline pmd_t *pmd_alloc_wz(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
	return (unlikely(pud_none(*pud)) && __pmd_alloc_wz(mm, pud, address))? 
			NULL: pmd_offset(pud, address);
}

static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
			unsigned long addr, unsigned long end,
			unsigned long pfn, pgprot_t prot)
{
	pte_t *pte;
	spinlock_t *ptl;
	int err = 0;

	pte = pte_alloc_map_lock_wz(mm, pmd, addr, &ptl);
	if (!pte)
		return -ENOMEM;
	arch_enter_lazy_mmu_mode();
	do {
		BUG_ON(!pte_none(*pte));
		if (!pfn_modify_allowed(pfn, prot)) {
			err = -EACCES;
			break;
		}
		set_pte_at(mm, addr, pte, pte_mkspecial(pfn_pte(pfn, prot)));
		pfn++;
	} while (pte++, addr += PAGE_SIZE, addr != end);
	arch_leave_lazy_mmu_mode();
	pte_unmap_unlock(pte - 1, ptl);
	return err;
}

static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud,
			unsigned long addr, unsigned long end,
			unsigned long pfn, pgprot_t prot)
{
	pmd_t *pmd;
	unsigned long next;
	int err;

	pfn -= addr >> PAGE_SHIFT;
	pmd = pmd_alloc_wz(mm, pud, addr);
	if (!pmd)
		return -ENOMEM;
	VM_BUG_ON(pmd_trans_huge(*pmd));
	do {
		next = pmd_addr_end(addr, end);
		err = remap_pte_range(mm, pmd, addr, next,
				pfn + (addr >> PAGE_SHIFT), prot);
		if (err)
			return err;
	} while (pmd++, addr = next, addr != end);
	return 0;
}

static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d,
			unsigned long addr, unsigned long end,
			unsigned long pfn, pgprot_t prot)
{
	pud_t *pud;
	unsigned long next;
	int err;

	pfn -= addr >> PAGE_SHIFT;
	pud = pud_alloc(mm, p4d, addr);
	if (!pud)
		return -ENOMEM;
	do {
		next = pud_addr_end(addr, end);
		err = remap_pmd_range(mm, pud, addr, next,
				pfn + (addr >> PAGE_SHIFT), prot);
		if (err)
			return err;
	} while (pud++, addr = next, addr != end);
	return 0;
}

static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd,
			unsigned long addr, unsigned long end,
			unsigned long pfn, pgprot_t prot)
{
	p4d_t *p4d;
	unsigned long next;
	int err;

	pfn -= addr >> PAGE_SHIFT;
	p4d = p4d_alloc(mm, pgd, addr);
	if (!p4d)
		return -ENOMEM;
	do {
		next = p4d_addr_end(addr, end);
		err = remap_pud_range(mm, p4d, addr, next,
				pfn + (addr >> PAGE_SHIFT), prot);
		if (err)
			return err;
	} while (p4d++, addr = next, addr != end);
	return 0;
}

int wx_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
		    unsigned long pgoff, unsigned long size, pgprot_t prot)
{
	pgd_t *pgd;
	unsigned long end = addr + PAGE_ALIGN(size);
	struct mm_struct *mm = vma->vm_mm;
	int err, i = 0;

	if (is_cow_mapping(vma->vm_flags)) {
		if (addr != vma->vm_start || end != vma->vm_end){
			return -EINVAL;
		}
		vma->vm_pgoff = page_to_pfn(wxcoder_dev->pages[pgoff]);
	}

	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
	BUG_ON(addr >= end);
	pgd = pgd_offset(mm, addr);
	flush_cache_range(vma, addr, end);
	for (i = 0; i < (PAGE_ALIGN(size) >> PAGE_SHIFT); i++){
		err = remap_p4d_range(mm, pgd, addr, addr + PAGE_SIZE, page_to_pfn(wxcoder_dev->pages[i+pgoff]), prot);
		if (err){
			printk("remap_p4d_range: %d\n", err);
			break;
		}
		addr += PAGE_SIZE;
	}

	return err;
}

static int wzalgo_mmap(struct file *filp, struct vm_area_struct *vma)
{
	unsigned long size = PAGE_ALIGN(vma->vm_end - vma->vm_start);

	if (false == readable || false == loadok){
		return -EINVAL;
	}

	debug("wzalgo_mmap - start: 0x%lx, end: 0x%lx, size: %ld\n\tpgoff: %lu, flags: %lu\n", vma->vm_start, vma->vm_end, size, \
						vma->vm_pgoff, vma->vm_flags);
	if (!wxcoder_dev->vbase){
		return -EINVAL;
	}

	vma->vm_ops = &wzcoder_mapping_vmops;
	vma->vm_private_data = (void *)wxcoder_dev->pages;

	return wx_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, vma->vm_page_prot);
}

函式wx_remap_pfn_range完成行程虛擬地址區域vma到物理頁幀間的映射,即一一建立頁表項,pgd_offset根據傳入的addr拿到當前行程的全域頁目錄,考慮到我們需要映射的物理頁幀是非連續的,因此分頁呼叫remap_p4d_range建立第5級頁表,remap_p4d_range函式根據待映射的地址范圍分段呼叫remap_pud_range建立第四級頁表,依次下去直至set_pte_at為每個虛擬記憶體頁建立頁表項,需要注意的是較新的linux內核采用了5級頁表的模式,實際使用的頁表級數依賴于cpu平臺的定義,不同cpu平臺下各級頁表的頁表處理宏的實作是不一樣的,內核使用這種方式將頁表的建立程序統一到5級模式之下,

4. 借助內核ptrace機制設計初步的反除錯手段

以上作業完成后,設計的內核驅動程式就足以支撐用戶態行程使用dlopen/dlsym等libdl庫中的函式匯入動態庫并決議其符號等,加密后的演算法庫二進制檔案嵌入到外殼程式中,并配合內核驅動程式完成其記憶體映射的方法大大提高了對演算法庫檔案的保護,為進一步提高安全性,防止用戶使用strace等除錯工具追蹤其執行程序,我們可以借助內核的ptrace機制建立初步的反除錯技術,ptrace是linux內核支持的一種行程除錯手段,值得慶幸的是即使是常用的gdb的實作也完全依賴于ptrace機制,為此可以采用在檢測到用戶使用ptrace追蹤外殼行程時回傳錯誤碼等反制手段,

檢測外殼程式是否被ptrace跟蹤除錯有2種簡易方法,一種是在驅動程式中添加獲取當前行程task_struct->ptrace值的功能,當用戶態行程被采用PTRACE_ATTACH除錯時,內核會修改該值為一個非0值,指示當前行程的除錯狀態,外殼程式可以據此判定自己是否被跟蹤除錯,另一種方法可以在用戶態監測/proc/self/status,檢查其TracerPid項是否非0,如果非0值則表示當前行程被監控跟蹤了,示例如下:

lyfan@MV:/home/lyfan/shtest$ cat /proc/3629/status    
Name:   shtest
State:  t (tracing stop)
Tgid:   3629
Pid:    3629
PPid:   3627
TracerPid:      3627
...

TracerPid為3627,可以看到行程3629被其父行程3627跟蹤除錯了,

5. 不足和待研究的地方

采用這種外殼加固的方法雖然可以將原SO檔案完全抹去,但外殼程式在動態加載演算法庫檔案后,仍然會將解密后的部分動態庫內容暴露到行程地址空間,需要進一步配合反dump技術的使用,加強外殼在記憶體安全強度方面的不足,prctl(PR_SET_DUMPABLE, 0)可以關閉行程的coredump功能,但仍需結合其他方面的記憶體安全技術來提升外殼程式的防御能力,另外針對ELF段分別加解密也是一種思路,前提是需要深入了解ELF檔案的詳細組織方式,及其內部符號的決議方法等,

至此,對演算法庫二進制檔案的加密和匯入的研究算是全部完成了,文中討論的相關技術的示例工程已上傳到gitee上,考慮到安全性,示例工程中的具體實作以及使用的密鑰口令等均做了較大調整,測驗采用的內核版本是Linux 4.19.0,cpu是arm64平臺,gcc版本8.2.0,

附上專案地址:https://gitee.com/liangyuf/linux_so_encrypt

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

標籤:其他

上一篇:002-windowa基礎(DOS命令:net user 用戶 密碼 /add)

下一篇:Suricata/Snort規則參考

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(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
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more