Usage of snmpenum - perl

snmpenum.pl is introduced in many materials about penetration testing, although it's already a very ancient program.
I downloaded it from here.
And this is the problem I encountered.
$ perl snmpenum.pl 192.168.1.36 public linux.txt # official usage
----------------------------------------
SYSTEM INFO
----------------------------------------
" is expected in dotted decimal notation..1.2.1.1.1
I have no knowledge about Perl. Can anyone tell me whether there's a problem in linux.txt or where the real problem lies? Thanks.

I've been doing a little debugging of the snmpenum.pl script and the NEt::SNMP is doing fine, the problem is the way the script splits the values when reading the lines from the OID values file (linux.txt, windows.txt, cisco.txt).
SOLUTION:
If you add a \t at the end of each line in the windows.txt/linux.txt/cisco.txt file the script is working again!
I've found that if you replace the read OID value by a hardcoded string such as "1.3.6.1.2.1.1.5" (or whatever value you want) the Net::SNMP->session.get_bulk_request() query works.
my $result = $session-get_bulk_request(){
-callback => [\&table_cb, {}],
-maxrepetitions => 10,
-varbindlist => [$v]
};
With the hardcoded strings:
my $result = $session-get_bulk_request(){
-callback => [\&table_cb, {}],
-maxrepetitions => 10,
-varbindlist => ["1.3.6.1.2.1.1.5"]
};
So I went to see how the var $v is created, and it is read from the file and the code does a split based on the \t char, which is not present at the end of the line. So I assumed the last value will perhaps contain any bogus char ascii code from the end of the line (line feed or carriage return?):
while (<CONFIG>){
chomp $_;
my #system= split /\t+/,$_;
Finally I added a \t (Tab) at the end of the line on the windows.txt, linux,txt and cisco.txt files that are distributed with snmpenum.pl and all worked fine!. For ex with this:
for filename in $(ls *.txt); do perl -i -p -e 's/\r\n/\t\r\n/' ./$filename; done
The other solution would be to make a code modification for snmpenum.pl...
Cheers,
Morgan

The files containing the OID's that came with snmpenum (e.g. linux.txt) are in DOS format. Simply convert them to UNIX format (e.g. dos2unix) and it should work fine.

Related

Error in Linkdatagen : Use of uninitiated value $chr in concatenation (.) or string

Hi I was trying to use linkdatagen, which is a perl based tool. It requires a vcf file (using mpileup from SAMtools) and a hapmap annotation file (provided). I have followed the instructions but the moment I use the perl script provided, I get this error.
The codes I used are:
samtools mpileup -d10000 -q13 -Q13 -gf hg19.fa -l annotHapMap2U.txt samplex.bam | bcftools view -cg -t0.5 - > samplex.HM.vcf
Perl vcf2linkdatagen.pl -variantCaller mpileup -annotfile annotHapMap2U.txt -pop CEU -mindepth 10 -missingness 0 samplex.HM.vcf > samplex.brlmm
Use of uninitiated value $chr in concatenation (.) or string at vcf2linkdatagentest.pl line 487, <IN> line 1.... it goes on and on.. I have mailed the authors, and haven't heard from them yet. Can anyone here please help me? What am I doing wrong?
The perl script is :
http://bioinf.wehi.edu.au/software/linkdatagen/vcf2linkdatagen.pl
The HapMap file can be downloaded from the website mentioned below.
http://bioinf.wehi.edu.au/software/linkdatagen/
Thanks so much
Ignoring lines starting with #, vcf2linkdatagen.pl expects the first field of the first line of the VCF to contain something of the form "chrsomething", and your file doesn't meet that expectation. Examples from a comment in the code:
chr1 888659 . T C 226 . DP=26;AF1=1;CI95=1,1;DP4=0,0,9,17;MQ=49;FQ=-81 GT:PL:GQ 1/1:234,78,0:99
chr1 990380 . C . 44.4 . DP=13;AF1=7.924e-09;CI95=1.5,0;DP4=3,10,0,0;MQ=49;FQ=-42 PL 0
The warning means that a variable used in a string is not initialized (undefined). It is an indication that something might be wrong. The line in question can be traced to this statement
my $chr = $1 if ($tmp[0] =~ /chr([\S]+)/);
It is bad practice to use postfix if statements on a my statement.
As ikegami notes a workaround for this might be
my ($chr) = $tmp[0] =~ /chr([\S])/;
But since the match failed, it will likely return the same error. The only way to solve is to know more about the purpose of this variable, if the error should be fatal or not. The author has not handled this case, so we do not know.
If you want to know more about the problem, you might add a debug line such as this:
warn "'chr' value not found in the string '$tmp[0]'" unless defined $chr;
Typically, an error like this occurs when someone gives input to a program that the author did not expect. So if you see which lines give this warning, you might find out what to do about it.

Read from csv file and write output to a file

I am new to Perl and would like your help on following scenario, can you please help on this subject.
I have a CSV files with following information and I am trying to prepare a key-value pair from CSV file. Can you please help me with below scenario.
Line 1: List,ID
Line 2: 1,2,3
Line 3: 4,5,6
Line 4: List,Name
Line 5: Tom, Peter, Joe
Line 6: Jim, Harry, Tim
I need to format the above CSV file to get an output in a new file like below:
Line 1: ID:1,2,3 4,5,6
Line 2: Name:Tom,Peter,Joe Jim, Harry, Tim
Can you please direct me on how I can use Perl functions for this scenario.
You're in luck, this is extremely easy in Perl.
There's a great library called Text::CSV which is available on CPAN, docs are here: https://metacpan.org/pod/Text::CSV
The synopsis at the top of the page gives a really good example which should let you do what you want with minor modifications.
I don't think the issue here is the CSV format so much as the fact that you have different lists broken up with header lines. I haven't tried this code yet, but I think you want something like the following:
while (<>) { # Loop over stdin one line at a time
chomp; # Strip off trailing newline
my ($listToken, $listName) = split(',');
next unless $listToken; # Skip over blank lines
if ($listToken =~ /^List/) { # This is a header row
print "\n$listName: "; # End previous list, start new one
} else { # The current list continues
print "$_ "; # Append the entire row to the output
}
}
print "\n"; # Terminate the last line
Note that this file format is a little dubious, as there is no way to have a data row where the first value is the literal "List". However, I'm assuming that either you have no choice in file format or you know that List is not a legal value.
(Note - I fixed a mistake where I used $rest as a variable; that was caused by my renaming them as I went along and missing one)

Using a .fasta file to compute relative content of sequences

So me being the 'noob' that I am, being introduced to programming via Perl just recently, I'm still getting used to all of this. I have a .fasta file which I have to use, although I'm unsure if I'm able to open it, or if I have to work with it 'blindly', so to speak.
Anyway, the file that I have contains DNA sequences for three genes, written in this .fasta format.
Apparently it's something like this:
>label
sequence
>label
sequence
>label
sequence
My goal is to write a script to open and read the file, which I have gotten the hang of now, but I have to read each sequence, compute relative amounts of 'G' and 'C' within each sequence, and then I'm to write it to a TAB-delimited file the names of the genes, and their respective 'G' and 'C' content.
Would anyone be able to provide some guidance? I'm unsure what a TAB-delimited file is, and I'm still trying to figure out how to open a .fasta file to actually see the content. So far I've worked with .txt files which I can easily open, but not .fasta.
I apologise for sounding completely bewildered. I'd appreciate your patience. I'm not like you pros out there!!
I get that it's confusing, but you really should try to limit your question to one concrete problem, see https://stackoverflow.com/faq#questions
I have no idea what a ".fasta" file or 'G' and 'C' is.. but it probably doesn't matter.
Generally:
Open input file
Read and parse data. If it's in some strange format that you can't parse, go hunting on http://metacpan.org for a module to read it. If you're lucky someone has already done the hard part for you.
Compute whatever you're trying to compute
Print to screen (standard out) or another file.
A "TAB-delimite" file is a file with columns (think Excel) where each column is separated by the tab ("\t") character. As quick google or stackoverflow search would tell you..
Here is an approach using 'awk' utility which can be used from the command line. The following program is executed by specifying its path and using awk -f <path> <sequence file>
#NR>1 means only look at lines above 1 because you said the sequence starts on line 2
NR>1{
#this for-loop goes through all bases in the line and then performs operations below:
for (i=1;i<=length;i++)
#for each position encountered, the variable "total" is increased by 1 for total bases
total++
}
{
for (i=1;i<=length;i++)
#if the "substring" i.e. position in a line == c or g upper or lower (some bases are
#lowercase in some fasta files), it will carry out the following instructions:
if(substr($0,i,1)=="c" || substr($0,i,1)=="C")
#this increments the c count by one for every c or C encountered, the next if statement does
#the same thing for g and G:
c++; else
if(substr($0,i,1)=="g" || substr($0,i,1)=="G")
g++
}
END{
#this "END-block" prints the gene name and C, G content in percentage, separated by tabs
print "Gene name\tG content:\t"(100*g/total)"%\tC content:\t"(100*c/total)"%"
}

how do I get rid of single quotes around a doubly quoted string in perl? e.g ' "json_text" '

So I am having a ruby app write json response to the console which is read by another perl program that tries to convert the json response back to a perl hash. Here's my problem:
ruby app outputs the correct json output but the console adds a single quote to it like so:
my $ruby_json_out = '"{\"return\":{\"sync_enabled\":false,\"local\":true,\"name\":{\"name\":\"Sam\"}}}"'
my $ret = JSON->new->allow_nonref->decode($ruby_json_out);
Now I expect to get hash_ref in $ret but I get a string: '{"return":{"sync_enabled":false,"local":true,"name":{"name\":"Sam"}}}'.
I have searched all over the net and can't find a solution to this. When I manually stripout the single quote:
"{\"return\":{\"sync_enabled\":false,\"local\":true,\"name\":{\"name\":\"Sam\"}}}",
and run it works.
I am stuck on this for more than a day now and it's driving me crazy. I am new to perl and ruby too so I might be missing something. Any help will be appreciated greatly.
Why do you try to solve the problem on the Perl side? Woudln't it be easier to solve it on the Ruby side?
At any rate, you can use regexps to remove those doble quotes in the same way you do it manually:
my ($good_json) = ($ruby_json_out =~ /^"(.+?)"$/ ;
And then
$good_json=~ s/\\"/"/g;
Which results in
x JSON->new->allow_nonref->decode($good_json)
0 HASH(0xe4b158)
'return' => HASH(0xe4b1b8)
'local' => JSON::XS::Boolean=SCALAR(0xd22f00)
-> 1
'name' => HASH(0xe4afd8)
'name' => 'Sam'
'sync_enabled' => JSON::XS::Boolean=SCALAR(0xd22fd8)
-> 0

(3 lines) from bash to perl?

I have these three lines in bash that work really nicely. I want to add them to some existing perl script but I have never used perl before ....
could somebody rewrite them for me? I tried to use them as they are and it didn't work
note that $SSH_CLIENT is a run-time parameter you get if you type set in bash (linux)
users[210]=radek #where 210 is tha last octet from my mac's IP
octet=($SSH_CLIENT) # split the value on spaces
somevariable=$users[${octet[0]##*.}] # extract the last octet from the ip address
These might work for you. I noted my assumptions with each line.
my %users = ( 210 => 'radek' );
I assume that you wanted a sparse array. Hashes are the standard implementation of sparse arrays in Perl.
my #octet = split ' ', $ENV{SSH_CLIENT}; # split the value on spaces
I assume that you still wanted to use the environment variable SSH_CLIENT
my ( $some_var ) = $octet[0] =~ /\.(\d+)$/;
You want the last set of digits from the '.' to the end.
The parens around the variable put the assignment into list context.
In list context, a match creates a list of all the "captured" sequences.
Assigning to a scalar in a list context, means that only the number of scalars in the expression are assigned from the list.
As for your question in the comments, you can get the variable out of the hash, by:
$db = $users{ $some_var };
# OR--this one's kind of clunky...
$db = $users{ [ $octet[0] =~ /\.(\d+)$/ ]->[0] };
Say you have already gotten your IP in a string,
$macip = "10.10.10.123";
#s = split /\./ , $macip;
print $s[-1]; #get last octet
If you don't know Perl and you are required to use it for work, you will have to learn it. Surely you are not going to come to SO and ask every time you need it in Perl right?