It sounds like you understand basically what you're trying to do, so this is more a programming puzzle than a security one, at this point.

If the buffer has the shellcode placed before the %Nu%n sequence, I won't know how many characters have been printed before I get to the first %n, since the shellcode will contain non-printable characters.

Getting the length of characters printed by just treating the shellcode itself as a format string is trivial: all the *printf functions return the number of characters printed, so just running int c = printf(<SHELLCODE>);printf("\n%d\n", c); will tell you how many characters are printed in the course of treating the shellcode as a format string. However, putting the shellcode before the format specifiers like this imposes a limit on the minimum value you could put with %n specifiers after the shellcode.

If it's placed after it, I won't know the address of the shellcode itself, since the amount of digits for each N may vary.

Easily solved by padding the string (with spaces, or zeroes, or whatever you want except format specifiers) between the format specifiers and the shellcode, and deleting a padding character every time a format specifier gets one character longer. In practice, since the number of digits in N will only change when you the value of N crosses a power of 10, you can also achieve this by just making minor tweaks.


If you want to make this really easy, pad the input string between your format specifiers and your shellcode with single-byte no-ops (the canonical one for x86 is 0x90), and then you only have to land somewhere between the end of the format specifiers (exclusive) and the start of the shellcode (inclusive), rather than on the start of the shellcode exactly. This technique is called a "NOP sled" because when the instruction pointer winds up anywhere in it, it just "slides" all the way into your shellcode.

Answer from CBHacking on Stack Exchange
🌐
Infosec Institute
resources.infosecinstitute.com › topic › exploiting-format-strings-getting-the-shell
Exploiting format strings: Getting the shell - Infosec Resources
July 5, 2016 - In this article, we will have a look at how to exploit format String vulnerabilities to get a shell. In this article, we will briefly have a look at how to overwrite specific memory location, how to inject our shellcode in current memory of program and further overwrite the some desired memory ...
🌐
Infosec Institute
infosecinstitute.com › resources › hacking › exploiting-format-strings-getting-the-shell
Exploiting format strings: Getting the shell | Infosec
July 5, 2016 - In this article, we will have a look at how to exploit format String vulnerabilities to get a shell. In this article, we will briefly have a look at how to overwrite specific memory location, how to inject our shellcode in current memory of program and further overwrite the some desired memory ...
🌐
Stack Overflow
stackoverflow.com › questions › 19167776 › format-string-exploit-opening-root-shell
c - Format String exploit - opening root shell - Stack Overflow
I'm trying to overwrite the instruction pointer register (eip) with the address of the array containing my shellcode. I always end up with segmentation fault though. The following is a snippet I'm trying to exploit: //Prints version static void print_version(char* cmd) { char txt[640+1]; snprintf(txt, 640, "Submission program version 0.1 (%s)\n", cmd); printf(txt); } I'm calling this function through execve(). The format string is the argv[0] here, which is successfully passed to the function above.
Top answer
1 of 1
1

It sounds like you understand basically what you're trying to do, so this is more a programming puzzle than a security one, at this point.

If the buffer has the shellcode placed before the %Nu%n sequence, I won't know how many characters have been printed before I get to the first %n, since the shellcode will contain non-printable characters.

Getting the length of characters printed by just treating the shellcode itself as a format string is trivial: all the *printf functions return the number of characters printed, so just running int c = printf(<SHELLCODE>);printf("\n%d\n", c); will tell you how many characters are printed in the course of treating the shellcode as a format string. However, putting the shellcode before the format specifiers like this imposes a limit on the minimum value you could put with %n specifiers after the shellcode.

If it's placed after it, I won't know the address of the shellcode itself, since the amount of digits for each N may vary.

Easily solved by padding the string (with spaces, or zeroes, or whatever you want except format specifiers) between the format specifiers and the shellcode, and deleting a padding character every time a format specifier gets one character longer. In practice, since the number of digits in N will only change when you the value of N crosses a power of 10, you can also achieve this by just making minor tweaks.


If you want to make this really easy, pad the input string between your format specifiers and your shellcode with single-byte no-ops (the canonical one for x86 is 0x90), and then you only have to land somewhere between the end of the format specifiers (exclusive) and the start of the shellcode (inclusive), rather than on the start of the shellcode exactly. This technique is called a "NOP sled" because when the instruction pointer winds up anywhere in it, it just "slides" all the way into your shellcode.

🌐
Samsclass
samsclass.info › 127 › proj › p6-fs.htm
Proj 6: Exploiting a Format String Vulnerability (20 pts.)
chmod a+x f5.py gdb ./fs break ... when it hits the 0xcc values--that is, at the dummy shellcode. This exploit is a bit finicky--the injected code is passed in as a format string....
🌐
Stanford
cs155.stanford.edu › papers › formatstring-1.2.pdf pdf
Exploiting Format String Vulnerabilities scut / team teso September 1, 2001
September 1, 2001 - articles describing this method of exploitation and if this example is not fully ... It creates a string that is 497 characters long. Together with the error · string (“ERR Wrong command: ”) this exceeds the outbuf buffer by four · bytes. Although the ‘user’ string is only allowed to be as long as 400 bytes, we can extend its length by abusing format string parameters.
Find elsewhere
🌐
Medium
medium.com › @danielorihuelarodriguez › format-string-vulnerability-439acbe81ddf
Format string vulnerability. What’s a format string vulnerability? | by DanielOrihuela | Medium
November 5, 2024 - One of them is printf (e.g. printf("I am %i years old", 999);). An attacker can exploit them to read and write to arbitrary memory locations, execute arbitrary code or make the program crash.
🌐
tuonilabs
tuonilabs.wordpress.com › tag › format-string-vulnerability
Tag: format string vulnerability - tuonilabs - WordPress.com
January 12, 2017 - Solution: cd /behemoth file behemoth3 ... *main+95 r Input: aaaa x/50x $esp+600 # The 90’s preceding our shellcode start at 0xffffd8b4 ”’ Let’s use the magic formula to calculate our format string exploit:...
🌐
System Overlord
systemoverlord.com › 2014 › 02 › 12 › printf-format-string-exploitation
printf Format String Exploitation | System Overlord
February 12, 2014 - The general format at this point is: <destination address><destination address + 2>%<0xdef2 - 8>c%6$n%<0xffff-0xdef2>c%7$n · Putting it together: ./printf $'\xb0\x95\x04\x08\xb2\x95\x04\x08W066c%6$n�61c%7$n' sh$ Tags: Security, Wargames, ...
🌐
Syracuse University
surface.syr.edu › cgi › viewcontent.cgi pdf
Buffer Overflow and Format String Overflow Vulnerabilities
For example, a format string “Q2d” (the content · of safebuf ) will result in printing 512 characters to vulnbuf due to the minimum field width · specifier 512, which in effect overflows vulnbuf. Figure 31 shows the exploit that overflows the · vulnbuf and overwrites the return address with the address of a shellcode.
🌐
Fengweiz
fengweiz.github.io › 20fa-cs315 › labs › lab3-format-string.pdf pdf
SEED Labs – Format String Vulnerability Lab 1 Format String Vulnerability Lab
memory, and then use the format string vulnerability to modify the return address field of a function, so · when the function returns, it jumps to our injected code. To delete a file, we want the malicious code to · execute the /bin/rm command using a shell program, such as /bin/bash.
🌐
Exploit-DB
exploit-db.com › papers › 23985
[French] Une simple Exploitation de vulnérabilité Format String
January 8, 2013 - (y or n) y Starting program: /root/exploit/formatstring AA`echo $'\x04\xa0\x04\x08\x06\xa0\x04\x08'`790x1\$hn4282x2\$hnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AA�� . . . . . . 804851bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Program exited with code 012. Ca marche bien. Mais ce cas la était idéal, les octets à écrire étaient dans le bon ordre (0x3200 < 0xb7ea), pour écrire un shellcode de 20 ou 30 octets ca risque de pas être aussi rose.
🌐
Gts3
tc.gts3.org › cs6265 › tut › tut05-fmtstr.html
Tut05: Format String Vulnerability - CS6265: Information Security Lab
NOTE: Be sure to use single quotes (') rather than double quotes ("), to prevent your shell from trying to interpret the $ itself (e.g., like $PATH). If you do later need a format-string argument that includes interpolation, use " and backslash-escape the format-specifier $s (i.e., "\$"). Let's exploit this format-string bug to write an arbitrary value to an arbitrary memory address.
🌐
ired.team
ired.team › offensive-security › code-injection-process-injection › binary-exploitation › format-string-bug
Format String Bug | Red Team Notes
October 31, 2021 - Format string vulnerabilities make it possible to write to arbitrary memory locations inside the vulnerable program. To see this in action, we're going to use the following purposely vulnerable code from: Format One :: Andrew Griffiths' Exploit ...
🌐
MCSI Library
library.mosse-institute.com › articles › 2022 › 06 › linux-exploitation-format-string-vulnerabilities-and-exploitation › linux-exploitation-format-string-vulnerabilities-and-exploitation.html
Linux Exploitation: Format String Vulnerabilities and Exploitation — MCSI Library
Using a format string vulnerability, we achieved a write-what-where condition. In this instance, a suitable target for the overwrite is: The return address - allowing us to return from the vuln() function to arbitrary code. If ASLR is not present, we can store shellcode in environment variables and then use its address to overwrite a strategic pointer.
🌐
Seedsecuritylabs
seedsecuritylabs.org › Labs_20.04 › Files › Format_String_x64 › Format_String_x64.pdf pdf
SEED Labs – Format String Vulnerability Lab (64-bit) 1
memory, and then use the format string vulnerability to modify the return address field of a function, so · when the function returns, it jumps to our injected code. This malicious code is called shellcode, and it is
🌐
GitHub
github.com › whatsyourask › basics-of-pwn › blob › main › content › format-string › format-string.md
basics-of-pwn/content/format-string/format-string.md at main · whatsyourask/basics-of-pwn
We need to decrease it by subtracting 4 bytes and then the length of the shellcode which is 23 bytes = 27 bytes. 4294954721 is our value. gef➤ r $(python -c 'print "\xdc\xcf\xff\xff" + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" + "B94954721u" + "%6$n"') Starting program: /home/shogun/repos/basics-of-pwn/content/format-string/format-string $(python -c 'print "\xdc\xcf\xff\xff" + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" + "B94954721u" + "%6$n"') Breakpoint 1, 0x0804921c in main () gef➤ x
Author   whatsyourask
🌐
Invicti
invicti.com › blog › web-security › format-string-vulnerabilities
What Are Format String Vulnerabilities?
Combined with other format function specifiers, it can be used by attackers to overwrite specific memory locations, for example to redirect function pointers to a shellcode or simply cause a segmentation fault to crash an application for a denial ...
🌐
NVISO Labs
blog.nviso.eu › 2024 › 05 › 23 › format-string-exploitation-a-hands-on-exploration-for-linux
Format String Exploitation: A Hands-On Exploration for Linux – NVISO Labs
May 23, 2024 - During the exploitation process, our goal is to overwrite entries in the GOT with addresses of our choosing. By doing so, we can redirect the program’s execution to arbitrary locations, such as shellcode or other parts of memory under our control.